@aiwerk/mcp-bridge 2.6.6 → 2.6.8
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/dist/src/security.js
CHANGED
|
@@ -155,6 +155,18 @@ function truncateJsonAware(value, limit) {
|
|
|
155
155
|
return null;
|
|
156
156
|
}
|
|
157
157
|
function truncateArray(arr, limit) {
|
|
158
|
+
// For very large arrays, skip binary search (too many JSON.stringify calls)
|
|
159
|
+
// and use progressive halving instead
|
|
160
|
+
if (arr.length > 1000) {
|
|
161
|
+
let count = arr.length;
|
|
162
|
+
while (count > 1) {
|
|
163
|
+
count = Math.ceil(count / 2);
|
|
164
|
+
if (JSON.stringify(arr.slice(0, count)).length <= limit) {
|
|
165
|
+
return arr.slice(0, count);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return arr.slice(0, 1);
|
|
169
|
+
}
|
|
158
170
|
// Binary search for the number of elements that fit
|
|
159
171
|
let lo = 0;
|
|
160
172
|
let hi = arr.length;
|
|
@@ -213,20 +225,19 @@ export function processResult(result, serverName, serverConfig, clientConfig) {
|
|
|
213
225
|
const wasTruncated = processed !== null && typeof processed === "object" && processed._truncated === true;
|
|
214
226
|
// Sanitize step (only for trust=sanitize, handled inside applyTrustLevel)
|
|
215
227
|
processed = applyTrustLevel(processed, serverName, serverConfig);
|
|
216
|
-
// If both truncated and untrusted
|
|
217
|
-
// to avoid double-wrapping ({ _trust, result: { _truncated, result: actual } })
|
|
228
|
+
// If both truncated and untrusted, flatten the metadata to top level
|
|
229
|
+
// to avoid double-wrapping ({ _trust, result: { _truncated, result: actual } }).
|
|
230
|
+
// Note: sanitize mode does NOT wrap — it sanitizes in-place, so the truncation
|
|
231
|
+
// markers (_truncated, _originalLength) are already at the right level.
|
|
218
232
|
const trust = serverConfig.trust ?? "trusted";
|
|
219
|
-
if (wasTruncated &&
|
|
220
|
-
|
|
233
|
+
if (wasTruncated && trust === "untrusted") {
|
|
234
|
+
return {
|
|
235
|
+
_trust: "untrusted",
|
|
236
|
+
_server: serverName,
|
|
221
237
|
_truncated: true,
|
|
222
238
|
_originalLength: processed.result?._originalLength,
|
|
223
239
|
result: processed.result?.result,
|
|
224
240
|
};
|
|
225
|
-
if (trust === "untrusted") {
|
|
226
|
-
flat._trust = "untrusted";
|
|
227
|
-
flat._server = serverName;
|
|
228
|
-
}
|
|
229
|
-
return flat;
|
|
230
241
|
}
|
|
231
242
|
return processed;
|
|
232
243
|
}
|
|
@@ -30,6 +30,14 @@ export class StandaloneServer {
|
|
|
30
30
|
if (this.isRouterMode()) {
|
|
31
31
|
this.router = new McpRouter(config.servers ?? {}, config, logger);
|
|
32
32
|
}
|
|
33
|
+
else {
|
|
34
|
+
// Warn if security config is used in direct mode where processResult() doesn't run
|
|
35
|
+
const hasSecurityConfig = Object.values(config.servers ?? {}).some(s => s.trust && s.trust !== "trusted" || s.maxResultChars || s.toolFilter);
|
|
36
|
+
if (hasSecurityConfig || config.maxResultChars) {
|
|
37
|
+
logger.warn("[mcp-bridge] Security config (trust/maxResultChars/toolFilter) detected in direct mode. " +
|
|
38
|
+
"These settings only apply in router mode. Consider switching to mode: \"router\".");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
33
41
|
}
|
|
34
42
|
isRouterMode() {
|
|
35
43
|
return (this.config.mode ?? "router") === "router";
|
|
@@ -106,6 +106,8 @@ export class BaseTransport {
|
|
|
106
106
|
this.scheduleReconnect();
|
|
107
107
|
}
|
|
108
108
|
}, reconnectInterval);
|
|
109
|
+
// Allow Node.js process to exit gracefully even if reconnect is pending
|
|
110
|
+
this.reconnectTimer.unref();
|
|
109
111
|
}
|
|
110
112
|
/** Cancel any scheduled reconnection timer. */
|
|
111
113
|
cleanupReconnectTimer() {
|
package/package.json
CHANGED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 2,
|
|
3
|
+
"id": "firecrawl",
|
|
4
|
+
"name": "Firecrawl",
|
|
5
|
+
"description": "Web scraping, crawling, search, and structured data extraction — turn any website into clean markdown or structured data for AI agents",
|
|
6
|
+
"repository": "https://github.com/firecrawl/firecrawl-mcp-server",
|
|
7
|
+
"transports": [
|
|
8
|
+
{
|
|
9
|
+
"type": "stdio",
|
|
10
|
+
"command": "npx",
|
|
11
|
+
"args": [
|
|
12
|
+
"-y",
|
|
13
|
+
"firecrawl-mcp@3.12.1"
|
|
14
|
+
],
|
|
15
|
+
"env": {
|
|
16
|
+
"FIRECRAWL_API_KEY": "${FIRECRAWL_API_KEY}"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"auth": {
|
|
21
|
+
"required": true,
|
|
22
|
+
"type": "api-key",
|
|
23
|
+
"envVars": [
|
|
24
|
+
"FIRECRAWL_API_KEY"
|
|
25
|
+
],
|
|
26
|
+
"credentialsUrl": "https://www.firecrawl.dev/app/api-keys",
|
|
27
|
+
"instructions": "Sign up at firecrawl.dev and copy your API key from the dashboard."
|
|
28
|
+
},
|
|
29
|
+
"install": {
|
|
30
|
+
"method": "npx",
|
|
31
|
+
"package": "firecrawl-mcp",
|
|
32
|
+
"version": "3.12.1"
|
|
33
|
+
},
|
|
34
|
+
"metadata": {
|
|
35
|
+
"homepage": "https://www.firecrawl.dev/",
|
|
36
|
+
"author": "Firecrawl (Mendable)",
|
|
37
|
+
"tags": [
|
|
38
|
+
"scraping",
|
|
39
|
+
"crawling",
|
|
40
|
+
"web",
|
|
41
|
+
"extraction",
|
|
42
|
+
"search",
|
|
43
|
+
"markdown"
|
|
44
|
+
],
|
|
45
|
+
"category": "data",
|
|
46
|
+
"pricing": "byok",
|
|
47
|
+
"maturity": "stable",
|
|
48
|
+
"subcategory": "web-scraping",
|
|
49
|
+
"origin": "official",
|
|
50
|
+
"countries": [
|
|
51
|
+
"global"
|
|
52
|
+
],
|
|
53
|
+
"audience": "developer",
|
|
54
|
+
"selfHosted": true,
|
|
55
|
+
"sideEffects": "read-only",
|
|
56
|
+
"authSummary": "api-key"
|
|
57
|
+
},
|
|
58
|
+
"capabilities": {
|
|
59
|
+
"tools": true,
|
|
60
|
+
"resources": false,
|
|
61
|
+
"prompts": false,
|
|
62
|
+
"sampling": false
|
|
63
|
+
}
|
|
64
|
+
}
|