crawlforge-mcp-server 3.0.8 â 3.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +2 -10
- package/README.md +32 -9
- package/package.json +1 -2
- package/server.js +1 -1
- package/setup.js +155 -1
- package/src/constants/config.js +1 -1
- package/src/core/AuthManager.js +1 -1
- package/src/tools/search/adapters/crawlforgeSearch.js +1 -1
- package/src/tools/search/searchWeb.js +1 -1
package/CLAUDE.md
CHANGED
|
@@ -418,21 +418,13 @@ export class ToolName {
|
|
|
418
418
|
|
|
419
419
|
### Search Provider Architecture
|
|
420
420
|
|
|
421
|
-
|
|
421
|
+
All search requests are proxied through the CrawlForge.dev API:
|
|
422
422
|
|
|
423
|
-
**Production (users with CrawlForge API key):**
|
|
424
423
|
- `crawlforgeSearch.js` - Proxies through CrawlForge.dev API (Google Search backend)
|
|
425
424
|
- No Google API credentials needed from users
|
|
425
|
+
- Users only need their CrawlForge API key
|
|
426
426
|
- Credit cost: 2 credits per search
|
|
427
427
|
|
|
428
|
-
**Creator Mode (development with Google API credentials):**
|
|
429
|
-
- `googleSearch.js` - Direct Google Custom Search API
|
|
430
|
-
- Requires: `GOOGLE_API_KEY` and `GOOGLE_SEARCH_ENGINE_ID` environment variables
|
|
431
|
-
- Console shows: "đ Creator Mode: Using Google Search API directly"
|
|
432
|
-
- Get credentials at:
|
|
433
|
-
- API Key: https://console.cloud.google.com/apis/credentials
|
|
434
|
-
- Search Engine ID: https://programmablesearchengine.google.com/
|
|
435
|
-
|
|
436
428
|
Factory in `src/tools/search/adapters/searchProviderFactory.js`
|
|
437
429
|
|
|
438
430
|
### Browser Management
|
package/README.md
CHANGED
|
@@ -32,11 +32,12 @@ npx crawlforge-setup
|
|
|
32
32
|
This will:
|
|
33
33
|
- Guide you through getting your free API key
|
|
34
34
|
- Configure your credentials securely
|
|
35
|
+
- **Auto-configure Claude Code and Cursor** (if installed)
|
|
35
36
|
- Verify your setup is working
|
|
36
37
|
|
|
37
38
|
**Don't have an API key?** Get one free at [https://www.crawlforge.dev/signup](https://www.crawlforge.dev/signup)
|
|
38
39
|
|
|
39
|
-
### 3. Configure Your IDE
|
|
40
|
+
### 3. Configure Your IDE (if not auto-configured)
|
|
40
41
|
|
|
41
42
|
<details>
|
|
42
43
|
<summary>đ¤ For Claude Desktop</summary>
|
|
@@ -62,17 +63,39 @@ Restart Claude Desktop to activate.
|
|
|
62
63
|
</details>
|
|
63
64
|
|
|
64
65
|
<details>
|
|
65
|
-
<summary
|
|
66
|
+
<summary>đĨī¸ For Claude Code CLI (Auto-configured)</summary>
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
The setup wizard automatically configures Claude Code by adding to `~/.claude.json`:
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"mcpServers": {
|
|
72
|
+
"crawlforge": {
|
|
73
|
+
"type": "stdio",
|
|
74
|
+
"command": "crawlforge"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
After setup, restart Claude Code to activate.
|
|
81
|
+
</details>
|
|
82
|
+
|
|
83
|
+
<details>
|
|
84
|
+
<summary>đģ For Cursor IDE (Auto-configured)</summary>
|
|
85
|
+
|
|
86
|
+
The setup wizard automatically configures Cursor by adding to `~/.cursor/mcp.json`:
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"mcpServers": {
|
|
90
|
+
"crawlforge": {
|
|
91
|
+
"type": "stdio",
|
|
92
|
+
"command": "crawlforge"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
73
96
|
```
|
|
74
97
|
|
|
75
|
-
|
|
98
|
+
Restart Cursor to activate.
|
|
76
99
|
</details>
|
|
77
100
|
|
|
78
101
|
## đ Available Tools
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crawlforge-mcp-server",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.10",
|
|
4
4
|
"description": "CrawlForge MCP Server - Professional Model Context Protocol server with 19 comprehensive web scraping, crawling, and content processing tools.",
|
|
5
5
|
"main": "server.js",
|
|
6
6
|
"bin": {
|
|
@@ -95,7 +95,6 @@
|
|
|
95
95
|
"compromise": "^14.14.4",
|
|
96
96
|
"diff": "^8.0.2",
|
|
97
97
|
"dotenv": "^17.2.1",
|
|
98
|
-
"duck-duck-scrape": "^2.2.7",
|
|
99
98
|
"franc": "^6.2.0",
|
|
100
99
|
"isomorphic-dompurify": "^2.26.0",
|
|
101
100
|
"jsdom": "^26.1.0",
|
package/server.js
CHANGED
|
@@ -97,7 +97,7 @@ if (configErrors.length > 0 && config.server.nodeEnv === 'production') {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
// Create the server
|
|
100
|
-
const server = new McpServer({ name: "crawlforge", version: "3.0.
|
|
100
|
+
const server = new McpServer({ name: "crawlforge", version: "3.0.10" });
|
|
101
101
|
|
|
102
102
|
// Helper function to wrap tool handlers with authentication and credit tracking
|
|
103
103
|
function withAuth(toolName, handler) {
|
package/setup.js
CHANGED
|
@@ -6,8 +6,101 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import readline from 'readline';
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import os from 'os';
|
|
9
12
|
import AuthManager from './src/core/AuthManager.js';
|
|
10
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Add CrawlForge to an MCP client configuration file
|
|
16
|
+
* @param {string} configPath - Path to the config file
|
|
17
|
+
* @param {string} clientName - Name of the client (for messages)
|
|
18
|
+
* @returns {object} Result with success status and message
|
|
19
|
+
*/
|
|
20
|
+
function addToMcpConfig(configPath, clientName) {
|
|
21
|
+
// Check if config exists
|
|
22
|
+
if (!fs.existsSync(configPath)) {
|
|
23
|
+
return {
|
|
24
|
+
success: false,
|
|
25
|
+
message: `${clientName} config not found (${configPath}). You may need to configure manually.`,
|
|
26
|
+
notInstalled: true
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
// Read existing config
|
|
32
|
+
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
33
|
+
const config = JSON.parse(configContent);
|
|
34
|
+
|
|
35
|
+
// Ensure mcpServers object exists
|
|
36
|
+
if (!config.mcpServers) {
|
|
37
|
+
config.mcpServers = {};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Check if crawlforge is already configured
|
|
41
|
+
if (config.mcpServers.crawlforge) {
|
|
42
|
+
return {
|
|
43
|
+
success: true,
|
|
44
|
+
message: `CrawlForge already configured in ${clientName}`,
|
|
45
|
+
alreadyConfigured: true
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Add crawlforge MCP server configuration
|
|
50
|
+
config.mcpServers.crawlforge = {
|
|
51
|
+
type: "stdio",
|
|
52
|
+
command: "crawlforge",
|
|
53
|
+
args: [],
|
|
54
|
+
env: {}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Write updated config
|
|
58
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
success: true,
|
|
62
|
+
message: `CrawlForge added to ${clientName} MCP config`
|
|
63
|
+
};
|
|
64
|
+
} catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
success: false,
|
|
67
|
+
message: `Failed to update ${clientName} config: ${error.message}`
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Configure all detected MCP clients
|
|
74
|
+
* @returns {object} Results for each client
|
|
75
|
+
*/
|
|
76
|
+
function configureMcpClients() {
|
|
77
|
+
const results = {
|
|
78
|
+
claudeCode: null,
|
|
79
|
+
cursor: null
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// Claude Code config path
|
|
83
|
+
const claudeConfigPath = path.join(os.homedir(), '.claude.json');
|
|
84
|
+
results.claudeCode = addToMcpConfig(claudeConfigPath, 'Claude Code');
|
|
85
|
+
|
|
86
|
+
// Cursor config path (macOS)
|
|
87
|
+
const cursorConfigPath = path.join(os.homedir(), '.cursor', 'mcp.json');
|
|
88
|
+
if (fs.existsSync(path.join(os.homedir(), '.cursor'))) {
|
|
89
|
+
// Cursor directory exists, try to configure
|
|
90
|
+
if (!fs.existsSync(cursorConfigPath)) {
|
|
91
|
+
// Create mcp.json if it doesn't exist
|
|
92
|
+
try {
|
|
93
|
+
fs.writeFileSync(cursorConfigPath, JSON.stringify({ mcpServers: {} }, null, 2));
|
|
94
|
+
} catch (e) {
|
|
95
|
+
// Ignore creation errors
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
results.cursor = addToMcpConfig(cursorConfigPath, 'Cursor');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return results;
|
|
102
|
+
}
|
|
103
|
+
|
|
11
104
|
const rl = readline.createInterface({
|
|
12
105
|
input: process.stdin,
|
|
13
106
|
output: process.stdout
|
|
@@ -74,8 +167,69 @@ async function main() {
|
|
|
74
167
|
console.log('');
|
|
75
168
|
console.log('đ Setup complete! You can now use CrawlForge MCP Server.');
|
|
76
169
|
console.log('');
|
|
170
|
+
|
|
171
|
+
// Auto-configure MCP clients (Claude Code, Cursor)
|
|
172
|
+
console.log('đ§ Configuring MCP client integrations...');
|
|
173
|
+
const clientResults = configureMcpClients();
|
|
174
|
+
let anyConfigured = false;
|
|
175
|
+
let needsRestart = false;
|
|
176
|
+
|
|
177
|
+
// Report Claude Code status
|
|
178
|
+
if (clientResults.claudeCode) {
|
|
179
|
+
if (clientResults.claudeCode.success) {
|
|
180
|
+
anyConfigured = true;
|
|
181
|
+
if (clientResults.claudeCode.alreadyConfigured) {
|
|
182
|
+
console.log('â
Claude Code: Already configured');
|
|
183
|
+
} else {
|
|
184
|
+
console.log('â
Claude Code: Added to MCP config (~/.claude.json)');
|
|
185
|
+
needsRestart = true;
|
|
186
|
+
}
|
|
187
|
+
} else if (!clientResults.claudeCode.notInstalled) {
|
|
188
|
+
console.log(`â ī¸ Claude Code: ${clientResults.claudeCode.message}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Report Cursor status
|
|
193
|
+
if (clientResults.cursor) {
|
|
194
|
+
if (clientResults.cursor.success) {
|
|
195
|
+
anyConfigured = true;
|
|
196
|
+
if (clientResults.cursor.alreadyConfigured) {
|
|
197
|
+
console.log('â
Cursor: Already configured');
|
|
198
|
+
} else {
|
|
199
|
+
console.log('â
Cursor: Added to MCP config (~/.cursor/mcp.json)');
|
|
200
|
+
needsRestart = true;
|
|
201
|
+
}
|
|
202
|
+
} else if (!clientResults.cursor.notInstalled) {
|
|
203
|
+
console.log(`â ī¸ Cursor: ${clientResults.cursor.message}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Show restart warning if any client was configured
|
|
208
|
+
if (needsRestart) {
|
|
209
|
+
console.log('');
|
|
210
|
+
console.log('â ī¸ IMPORTANT: Restart your IDE to load the new MCP server');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Show manual config instructions if no clients detected
|
|
214
|
+
if (!anyConfigured && clientResults.claudeCode?.notInstalled && !clientResults.cursor) {
|
|
215
|
+
console.log('âšī¸ No MCP clients detected. Manual configuration needed:');
|
|
216
|
+
console.log('');
|
|
217
|
+
console.log(' Add this to your MCP client config:');
|
|
218
|
+
console.log(' {');
|
|
219
|
+
console.log(' "mcpServers": {');
|
|
220
|
+
console.log(' "crawlforge": {');
|
|
221
|
+
console.log(' "type": "stdio",');
|
|
222
|
+
console.log(' "command": "crawlforge"');
|
|
223
|
+
console.log(' }');
|
|
224
|
+
console.log(' }');
|
|
225
|
+
console.log(' }');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
console.log('');
|
|
229
|
+
console.log('ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ');
|
|
230
|
+
console.log('');
|
|
77
231
|
console.log('Quick start:');
|
|
78
|
-
console.log('
|
|
232
|
+
console.log(' crawlforge # Start the MCP server');
|
|
79
233
|
console.log(' npm run test # Test your setup');
|
|
80
234
|
console.log('');
|
|
81
235
|
console.log('Need help? Visit: https://www.crawlforge.dev/docs');
|
package/src/constants/config.js
CHANGED
|
@@ -11,7 +11,7 @@ export const config = {
|
|
|
11
11
|
// CrawlForge API Configuration
|
|
12
12
|
crawlforge: {
|
|
13
13
|
apiKey: process.env.CRAWLFORGE_API_KEY || '',
|
|
14
|
-
apiBaseUrl: process.env.CRAWLFORGE_API_URL || 'https://
|
|
14
|
+
apiBaseUrl: process.env.CRAWLFORGE_API_URL || 'https://www.crawlforge.dev'
|
|
15
15
|
},
|
|
16
16
|
|
|
17
17
|
// Performance
|
package/src/core/AuthManager.js
CHANGED
|
@@ -9,7 +9,7 @@ import path from 'path';
|
|
|
9
9
|
|
|
10
10
|
class AuthManager {
|
|
11
11
|
constructor() {
|
|
12
|
-
this.apiEndpoint = process.env.CRAWLFORGE_API_URL || 'https://
|
|
12
|
+
this.apiEndpoint = process.env.CRAWLFORGE_API_URL || 'https://www.crawlforge.dev';
|
|
13
13
|
this.configPath = path.join(process.env.HOME || process.env.USERPROFILE, '.crawlforge', 'config.json');
|
|
14
14
|
this.config = null;
|
|
15
15
|
this.creditCache = new Map();
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
export class CrawlForgeSearchAdapter {
|
|
11
|
-
constructor(apiKey, apiBaseUrl = 'https://
|
|
11
|
+
constructor(apiKey, apiBaseUrl = 'https://www.crawlforge.dev') {
|
|
12
12
|
if (!apiKey) {
|
|
13
13
|
throw new Error('CrawlForge API key is required for search functionality');
|
|
14
14
|
}
|
|
@@ -79,7 +79,7 @@ export class SearchWebTool {
|
|
|
79
79
|
throw new Error('CrawlForge API key is required for search functionality');
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
// Create the search adapter (CrawlForge API or
|
|
82
|
+
// Create the search adapter (CrawlForge API proxy or Google Search API direct in Creator Mode)
|
|
83
83
|
try {
|
|
84
84
|
this.searchAdapter = SearchProviderFactory.createAdapter(apiKey, {
|
|
85
85
|
apiBaseUrl,
|