UniFi tools were unusable from non-Claude agents. A tool result over 2000
chars is replaced with a table of contents and re-read by calling the tool
again with _resultId/_section, but those params were never declared on the
tool's inputSchema — and unifi-network and my-grafana ship
`additionalProperties: false`, so for a client that validates arguments the
drill-down call was illegal and the data unreachable. The stub's own wording
made it worse: "Use section parameter" names a param that does not exist;
sending it fell through to the upstream, re-paginated, and minted a fresh
_resultId. An unbounded loop.
UniFi took the blame because it is the one server whose results always trip
the threshold: get_devices was 11,718 chars, get_clients 136,696 across 19
pages with a 92-char page-1. Grafana and Gitea return compact results.
- content-pipeline gains onToolsList, declaring _resultId/_section on every
tool it can paginate (gate tools excluded — they are intercepted before the
pipeline runs). additionalProperties stays false: a property listed in
`properties` is already legal under it, so declaring is enough and the
upstream keeps its typo protection.
- createDefaultPlugin wired only the gate's onToolsList, so the pipeline's
would have been dropped on the floor. Both now chain, gate first.
- _resultId without _section re-shows the table of contents instead of
forwarding an unknown argument to a strict upstream.
- The stub names the tool, the live _resultId and a real section id.
- Nested MCP envelopes are collapsed. A server fronting another MCP server
returns the inner result wrapped in its own content/structuredContent pair,
so the payload arrives two or three times over. A layer is peeled only when
it carries nothing the inner value lacks, which keeps it lossless. Live
against the sre project: get_devices 11,718 -> 5,210 chars and no longer
paginates at all; get_clients 136,696 -> 62,358 across 8 pages instead of 19.
- deploy/mcplocal.service shipped MCPLOCAL_MCPD_URL=http://10.0.0.194:3100,
which is dead — every working machine had a hand-written drop-in. Points at
the k8s ingress now.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JNXFvxanvM6uiFcb4Mp3xU