@anyshift/mcp-proxy 0.6.2 → 0.6.3

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.
Files changed (2) hide show
  1. package/dist/index.js +48 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -417,6 +417,51 @@ async function main() {
417
417
  console.debug('[mcp-proxy] Standalone mode - no child MCP');
418
418
  }
419
419
  // ------------------------------------------------------------------------
420
+ // 2.5. STORE ORIGINAL TOOL SCHEMAS FOR SMART PARAMETER SANITIZATION
421
+ // ------------------------------------------------------------------------
422
+ // Create a map of original tool schemas (before proxy param injection)
423
+ // This allows us to detect if description/isRetryAttempt/originalToolId were
424
+ // originally part of the child tool's schema (to handle parameter name collisions)
425
+ const originalToolSchemas = new Map();
426
+ if (childToolsResponse.tools) {
427
+ for (const tool of childToolsResponse.tools) {
428
+ const originalParams = new Set();
429
+ if (tool.inputSchema?.properties) {
430
+ for (const paramName of Object.keys(tool.inputSchema.properties)) {
431
+ originalParams.add(paramName);
432
+ }
433
+ }
434
+ originalToolSchemas.set(tool.name, originalParams);
435
+ }
436
+ }
437
+ /**
438
+ * Sanitize tool arguments before forwarding to child MCP.
439
+ * Removes proxy parameters (description, isRetryAttempt, originalToolId)
440
+ * ONLY if they weren't originally part of the child tool's schema.
441
+ * This handles parameter name collisions gracefully.
442
+ */
443
+ function sanitizeToolArgs(toolName, args) {
444
+ const originalParams = originalToolSchemas.get(toolName);
445
+ if (!originalParams) {
446
+ // If we don't have schema info, pass through all args (safer than stripping)
447
+ return args;
448
+ }
449
+ const sanitized = {};
450
+ const proxyParamNames = Object.keys(PROXY_PARAMS);
451
+ for (const [key, value] of Object.entries(args)) {
452
+ // Keep the parameter if:
453
+ // 1. It's NOT a proxy parameter, OR
454
+ // 2. It WAS in the original tool's schema (collision case)
455
+ if (!proxyParamNames.includes(key) || originalParams.has(key)) {
456
+ sanitized[key] = value;
457
+ }
458
+ else if (ENABLE_LOGGING) {
459
+ console.debug(`[mcp-proxy] Stripping proxy parameter '${key}' from ${toolName} call`);
460
+ }
461
+ }
462
+ return sanitized;
463
+ }
464
+ // ------------------------------------------------------------------------
420
465
  // 3. CREATE PROXY SERVER
421
466
  // ------------------------------------------------------------------------
422
467
  const server = new Server({
@@ -641,9 +686,11 @@ async function main() {
641
686
  if (ENABLE_LOGGING) {
642
687
  console.debug(`[mcp-proxy] Forwarding to child MCP: ${toolName}`);
643
688
  }
689
+ // Sanitize arguments: remove proxy parameters that weren't in original tool schema
690
+ const sanitizedArgs = sanitizeToolArgs(toolName, toolArgs);
644
691
  result = await childClient.callTool({
645
692
  name: toolName,
646
- arguments: toolArgs
693
+ arguments: sanitizedArgs
647
694
  });
648
695
  // Check if child MCP returned an error
649
696
  const childReturnedError = !!result.isError;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anyshift/mcp-proxy",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Generic MCP proxy that adds truncation, file writing, and JQ capabilities to any MCP server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",