cloudflare / cloudflare/agents

Validate McpConnector inputs against advertised schemas before remote calls

Open
#2,117 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
5.6k
Forks
711
Avg merge
1d 20h
Merged PRs (30d)
53

Description

## Problem

`McpConnector` preserves each remote tool's advertised `inputSchema` for discovery and TypeScript generation, but its execution closure forwards runtime arguments directly to `client.callTool` without validating them first.

That means invalid enum values, missing required fields, wrong primitive types, unexpected properties, and nested constraint violations can reach the remote MCP server. A permissive server may execute them; a conforming server rejects only after the network call and after Codemode has recorded its decision.

## Current boundary

The common boundary is `packages/codemode/src/connectors/mcp.ts`, where the derived tool has both:

- the exact advertised `tool.inputSchema`; and
- the runtime `args` immediately before `connection.client.callTool`.

Validating there would cover every `McpConnector` subclass without host-specific wrappers.

## Expected behavior

- Compile/cache a validator while deriving each MCP tool.
- Validate `args ?? {}` before calling the remote client.
- Reject locally with the server/tool name and failing JSON path.
- Do not call the remote client when validation fails.
- Preserve the original arguments and `AbortSignal` for valid calls.
- Keep output-schema validation unchanged.

## Minimal red regression

Use a descriptor such as:

```ts
{
name: "search_threads",
inputSchema: {
type: "object",
properties: {
view: {
type: "string",
enum: ["THREAD_VIEW_MINIMAL", "THREAD_VIEW_METADATA_ONLY"],
},
},
required: ["view"],
additionalProperties: false,
},
}
```

Execute it with `{ view: "THREAD_VIEW_FULL" }` and assert:

1. the call rejects locally with `search_threads` and `view` in the error; and
2. the MCP client's `callTool` spy is never invoked.

This affects every remote MCP tool projected through Codemode, not one provider. Downstream investigation: WebMCP-org/rook.

Contributor guide

Open the contributing guide

Research direction

Start in packages/codemode/src/connectors/mcp.ts, where each derived tool retains inputSchema and forwards args to connection.client.callTool. Add the validator at that boundary, then exercise the provided search_threads descriptor with an invalid view and verify the error names the tool and path while the callTool spy is not invoked; confirm valid calls preserve arguments and AbortSignal and output-schema validation remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend-api-design, testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.