fix(agent): emit a valid schema when capping oversized MCP tool schemas - #3192
Open
noah-shipley-centric wants to merge 1 commit into
Open
Conversation
`cap_schema` replaced any tool schema over MAX_SCHEMA_BYTES with a bare
`{}`. That is not a valid JSON Schema: Anthropic's /v1/messages requires
`input_schema.type` and rejects the request with
400 invalid_request_error
tools.N.custom.input_schema.type: Field required
Because the API validates the whole `tools` array, a single oversized
tool takes down *every* turn for that session rather than just becoming
an unusable tool — the agent connects, lists tools, then fails on each
prompt with no obviously related error.
Observed against an MCP server with two large tool schemas (4376 and
7680 bytes): both were capped, and every subsequent prompt 400'd.
Replace the bare `{}` with the smallest valid equivalent,
`{"type":"object","properties":{}}`, preserving the existing intent
(drop the oversized schema, keep the tool callable with no arguments)
while remaining acceptable to providers.
Adds a test module for `cap_schema` covering pass-through, replacement,
the `<=` boundary at exactly MAX_SCHEMA_BYTES, that the replacement is
itself within the cap, and that it declares `type: object` — the last
of which fails against the previous implementation.
Signed-off-by: Noah Shipley <nshipley@centricsoftware.com>
This was referenced Jul 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
cap_schemaincrates/buzz-agent/src/mcp.rsreplaces any tool schema overMAX_SCHEMA_BYTESwith a bare{}. That isn't a valid JSON Schema — Anthropic's/v1/messagesrequiresinput_schema.type:Because the API validates the entire
toolsarray, one oversized tool breaks every turn in that session rather than just becoming an unusable tool. The failure is also hard to trace: the agent connects, lists tools, reports healthy, and then every prompt 400s with an error that never names the offending tool.Reproduction
Connect
buzz-agentto an MCP server exposing tools with schemas above the 4096-byte cap. Observed with a server whose two largest tools were 4376 and 7680 bytes:Every subsequent prompt failed identically until the oversized tools were removed.
Fix
Emit the smallest valid equivalent instead of a bare object:
{ "type": "object", "properties": {} }This preserves the original intent — drop the oversized schema, keep the tool callable with no arguments — while remaining acceptable to providers. The replacement is well under the cap, so the guard can't recurse.
Tests
Adds a
cap_schematest module (the function had no direct coverage):type: objectand carriesproperties— this one fails against the previous implementationMAX_SCHEMA_BYTES<=)Verified red-then-green: reverting only the one-line behaviour change fails
replacement_declares_object_typeand passes the other four.cargo fmtandcargo clippy -p buzz-agent --all-targets -- -D warningsare clean.Notes
Only the provider-facing shape changes; the capping policy and threshold are untouched. A follow-up worth considering separately (happy to open an issue rather than expand this PR): rather than discarding the schema wholesale, a large schema could be pruned — keeping
type,required, and top-level property names — so oversized tools stay usable instead of becoming argument-less.