Skip to content

Send MCP bridge tools only the variables their schema declares - #1443

Merged
helpcodeai merged 3 commits into
mainfrom
fix/mcp-bridge-env-args
Nov 2, 2026
Merged

helpcodeai merged 3 commits into
mainfrom
fix/mcp-bridge-env-args

Conversation

@helpcodeai

@helpcodeai helpcodeai commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

On every call to a bridged MCP tool, all of the connector's environment variables were added to the tool arguments. Credentials were included. DynamicMcpTools.injectEnvVars does this for real calls, and ConnectorsService.executeConnectorCall does it for "Run Test" and the setup check.

As a result, the remote MCP server received the connector's own API key or token, and every other variable, as tool arguments on every call. A vendor may log those arguments. A server with a strict schema may also refuse them as unknown.

The variables were already sent to the vendor's own server. Its auth header carries the same key, so the key did not go to a third party. It did end up in a field that is not meant for credentials.

REST, GraphQL, SOAP, database and OData connectors are not affected. They take the merged parameters only as input to their mappings, and a mapping uses only the variables it names ($name, {{VAR}}). Nothing is forwarded verbatim.

On Cloud today, these MCP-type connectors are affected (count only, no values read):

Connector Count
GitHub 19
Apify 9
Odoo MCP 6
Atlassian 2
Splunk 1
hand-made 1

Changes

  • envVarsForMcpTool(envVars, parameters) in connectors/mcp-connector-config.util.ts keeps only the variables that are top-level properties of the remote tool's input schema. A variable with the same name as a parameter still fills it, as before, and a value the caller passes still wins.
  • DynamicMcpTools.executeTool uses this filter for MCP connectors. Other connector types still get every variable.
  • ConnectorsService.executeConnectorCall does the same, so "Run Test" and the setup check send the same arguments as a real call.
  • docs/connectors/mcp-bridge.md documents this, and llms-full.txt is regenerated.

Cloud vs self-hosted

Both behave the same. Nothing here depends on DEPLOYMENT_MODE.

Existing connectors pick up the change at their next call. There is no migration and no "Apply update".

Type

  • Bug fix

Testing

  • Added/updated unit tests: src/mcp-server/dynamic-mcp-tools.mcp-bridge.spec.ts
    • The filter keeps only schema properties: none without a schema, and nothing taken from the object prototype.
    • An MCP call sends the caller's arguments plus schema-named variables, never the token.
    • A caller's value wins over a variable of the same name.
    • A REST tool still gets every variable.
    • executeConnectorCall sends the same arguments for an MCP tool.

Commands and results, after npx prisma generate:

Command Directory Result
npx tsc --noEmit -p tsconfig.json packages/backend exit 0
npm run lint:check packages/backend 0 errors, 11 warnings (all existing, none in changed files)
npx jest --maxWorkers=4 src/mcp-server/dynamic-mcp-tools src/connectors/connectors.service src/connectors/engines/mcp-client src/adapters/mcp-adapter src/adapters/intl packages/backend 580 suites passed, 1 skipped; 8386 tests passed, 1607 skipped (gated live specs)
node scripts/validate-adapters.mjs root exit 0
node scripts/adapter-count.mjs --check root OK, 691 adapters
node scripts/generate-llms-txt.mjs --check root exit 0 after regenerating llms-full.txt
node --test scripts/validate-adapters.test.mjs scripts/adapter-new.test.mjs scripts/generate-llms-txt.test.mjs root 58 pass, 0 fail
node --test scripts/satellites/satellites.test.mjs root 18 pass, 0 fail
node --test scripts/check-runtime-deps.test.mjs && node scripts/check-runtime-deps.mjs root 2 pass, exit 0
node scripts/regenerate-catalog.mjs root no change

I ran only the targeted suites above, not the full backend npm test.

Checklist

  • My code follows the existing code style
  • I have tested my changes locally
  • I have updated documentation (if applicable)
  • All existing tests pass (npm test): only the targeted suites, see above
  • This PR has a descriptive title

Related Issues

Split out of #1442 so it can ship first. #1442 should merge after this PR and after #1437.

Possible behaviour change: a remote tool that relied on receiving a connector variable under a name its schema does not list would no longer get it. No catalog MCP adapter does this.

Every connector variable, credentials included, was added to the
arguments of every bridged MCP tool call, so the remote server received
the connector's own API key or token as a tool argument. REST, GraphQL
and the other engines are unaffected: they only use the variables their
mappings reference.

An MCP tool now gets a connector variable only when it is a top-level
property of the tool's input schema, on real calls and in "Run Test" and
the setup check alike.
@helpcodeai
helpcodeai enabled auto-merge (squash) November 2, 2026 09:26
@helpcodeai
helpcodeai merged commit afebda1 into main Nov 2, 2026
14 checks passed
@helpcodeai
helpcodeai deleted the fix/mcp-bridge-env-args branch November 2, 2026 09:46
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant