Add tier-aware MCP tool batching#79
Conversation
why: Enable ordered bulk calls while preserving each nested tool's schemas, middleware, and safety checks. what: - Add readonly, mutating, and destructive batch wrappers with per-operation results - Preserve nested FastMCP content, structured_content, and meta - Extend audit redaction for nested batch arguments - Cover tier enforcement, continuation, recursion rejection, and audit redaction
why: Keep the published tool catalog and Sphinx FastMCP collector aligned with the new batch tools. what: - Add batch tool reference pages and overview navigation - Register batch tools and models in docs configuration and API reference - Update README, architecture, and safety summaries
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #79 +/- ##
==========================================
- Coverage 84.91% 84.73% -0.18%
==========================================
Files 42 43 +1
Lines 3042 3197 +155
Branches 412 438 +26
==========================================
+ Hits 2583 2709 +126
- Misses 340 359 +19
- Partials 119 129 +10 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
why: The unreleased notes did not yet announce the readonly, mutating, and destructive batch wrappers, which are user-facing. what: - Add a What's new entry for the tier-aware tool batch family - Describe the per-tier safety ceiling and per-operation results
Code reviewFound 1 issue:
Lockstep contract: libtmux-mcp/src/libtmux_mcp/tools/server_tools.py Lines 269 to 281 in 6f635d1 Stale prose (unchanged by this PR): libtmux-mcp/src/libtmux_mcp/server.py Lines 67 to 72 in 6f635d1 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
why: Batches of output-heavy read tools could multiply the normal response backstop by embedding each nested result payload in one outer batch envelope. what: - Add batch-level truncation metadata and payload elision - Limit serialized batch envelopes before returning them - Cover oversized readonly batches with a regression test
why: MCP clients only see the outer batch tool annotations when building approval UI, so wrapper hints must disclose the strongest nested behavior each wrapper can invoke. what: - Mark side-effecting batch wrappers destructive and open-world - Add registration tests for mutating and destructive batch hints
why: The mutating batch docs passed window_name to split_window, whose schema rejects that argument. what: - Show rename_window and split_window targeting the same known window_id - Avoid implying batches feed a created window id into later operations
Code reviewRe-reviewed after the three new commits (response capping, annotation changes, docs example). Found 1 issue:
libtmux-mcp/src/libtmux_mcp/tools/batch_tools.py Lines 275 to 288 in ea60d44 Same for Still open from the earlier review, not addressed by the new commits: the three batch tools are in libtmux-mcp/src/libtmux_mcp/server.py Lines 67 to 72 in ea60d44 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
why: FastMCP serializes typed tool returns as both text content and structuredContent, so measuring only the batch model could still leave large batched responses above the server response cap. what: - Measure batch truncation against the FastMCP response envelope - Extend the oversized batch regression to cover content plus structuredContent
why: A batch with enough small row results can exceed the response cap even after nested payload truncation, because row metadata alone still serializes into the FastMCP response envelope. what: - Reject generic tool batches above a fixed operation-count cap - Add a public FastMCP regression for row-only oversized batch responses
why: The unreleased batch entry predated response capping, which keeps large aggregate results within the server response limit and reports the truncation to callers. what: - Note bounded batch responses in the tier-aware tool batching entry
why: The unreleased batch entry documented the silent response bound but not the hard rejection callers hit when a batch carries too many operations. what: - Note that oversized batch operation lists are rejected
Summary
Verification
uv run ruff format .uv run pytest(602 passed)uv run ruff check .uv run mypy $(fd -e py -t f .)just build-docsuv run fastmcp inspect fastmcp.json