You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
McpServer: unknown tool-call keys are silently stripped; Tool.StrictJsonSchema is not honoured and there is no way to decode strictly #8218
4.0.0-rc.115 (also current main, packages/effect/src/unstable/ai/McpServer.ts and Toolkit.ts)
What steps can reproduce the bug?
Register a tool with a struct parameter schema through McpServer.toolkit and call it with an extra, unknown key (for example a misspelled parameter).
import{Effect,Layer,Schema}from"effect"import{McpServer,Tool,Toolkit}from"effect/unstable/ai"constEcho=Tool.make("echo",{parameters: {text: Schema.String,limit: Schema.optionalKey(Schema.Number)},success: Schema.String})consttoolkit=Toolkit.make(Echo)constToolkitLayer=toolkit.toLayer({echo: ({ text })=>Effect.succeed(text)})// Serve over stdio with McpServer.layerStdio and call:// { "method": "tools/call", "params": { "name": "echo",// "arguments": { "text": "hi", "limti": 5 } }}
What is the expected behavior?
Some way for the server to reject the call, since limti is not an accepted parameter. Either:
McpServer honours the existing Tool.StrictJsonSchema annotation: when a tool is strict, tools/list serves additionalProperties: false on every object level of inputSchema, and tools/call decodes with onExcessProperty: "error" and returns the same InvalidParams / isError path used for a wrong type; or
McpServer.toolkit (or Toolkit.toLayer) accepts Schema parse options so a server can opt in.
What do you see instead?
The call succeeds. Toolkit.ts decodes parameters with a bare Schema.decodeUnknownEffect(tool.parametersSchema) (line 254), so Schema's default onExcessProperty: "ignore" silently drops limti, and the handler runs with limit unset. The served inputSchema has no additionalProperties, so clients cannot detect the problem either.
Tool.StrictJsonSchema exists but is only consulted by LLM provider clients (it maps to OpenAI's strict: true); McpServer never reads it.
Additional information
This matters more for an MCP server than for an ordinary API: the caller is a model that cannot see that a key was dropped, so a typo turns into a silently different tool call with a default value. We worked around it with a custom registration over McpServer.McpServer.addTool that walks the raw payload for unknown keys and rewrites the served schema with additionalProperties: false; happy to upstream that shape if option 1 is the preferred direction.
Related but distinct: #6355 is about a client rejecting additionalProperties in a served schema; this issue is about the server accepting keys it never declared.
might want to wait til the next rc cause I just rewrote a lot of the McpServer in order to get the new v2026-07-28 protocol working and part of that was a shopping list of issues:
🤖 We made 34 correctness-focused repairs:
9 fixed bugs already present on main, including JSON-RPC error handling, cancellation, batch replies, request metadata, elicitation schemas, notification scheduling, and request context.
4 fixed existing RPC/MCP weaknesses exposed by the new work, mainly queue backpressure, disconnected-client cleanup, HTTP streaming, and response framing.
21 fixed issues introduced while implementing the July protocol, including routing headers, capability checks, multi-round-trip requests, subscriptions, notification isolation, reverse-response ownership, and request lifecycle cleanup.
Of the 20 concrete bugs raised directly in PR review comments, 5 existed on main and 15 were introduced by the branch.
You can check #7265 and #8201. But if its still an issue once thats live, let me know and I'll have a look
Activity
lloydrichards commentedon Sep 13, 2026
might want to wait til the next rc cause I just rewrote a lot of the McpServer in order to get the new v2026-07-28 protocol working and part of that was a shopping list of issues:
You can check #7265 and #8201. But if its still an issue once thats live, let me know and I'll have a look
Edit: actually I can just check now and see 💡
spencerbeggs commentedon Sep 14, 2026
@lloydrichards Awesome. Looking forward to it. I migrated 3 mcps from
@modelcontextprotocol/*to Native MCP atrc.115and it went really well.