Skip to content

MCP: Slice summary reads with document.node depth and childLimit - #405

Merged
bflatastic merged 2 commits into
storytold:mainfrom
fahrim:mcp-pagination
Oct 8, 2026
Merged

bflatastic merged 2 commits into
storytold:mainfrom
fahrim:mcp-pagination

Conversation

@fahrim

@fahrim fahrim commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Sliced summary reads for large containers.

vectorcraft://object/{id} returns the whole subtree: on a 2,000-object document a group read is 1.5 MB and a layer read 1.8 MB. The cost left after #328 is the reply size itself. This adds depth and childLimit to document.node {summary: true} so agents can read containers in slices.

Design (no new commands, no URI changes — slicing lives at the command layer, where the MCP spec leaves it; resources/read takes only a URI):

  • depth: child levels included (None: all, the old behavior). 0 is the node alone.
  • childLimit: children shown per node, top of the stack first (None: all).
  • Truncation is never silent: a level that shows fewer children than it has reports childCount. With no truncation the output is byte-identical to before (no childCount appears).
  • The full (non-summary) object JSON is never truncated — exactness is its contract.
  • A present-but-invalid value (depth: -1, childLimit: "many") is rejected with -32602 rather than silently reinterpreted.
  • The object template keeps its full-depth default; its description and docs/mcp.md point large-container readers at run_command document.node {id, summary, depth, childLimit}.

Measured over stdio on a 2,000-rectangle group, release build:

read time bytes
full (unchanged default) 30.1 ms 1,516,377
depth: 0 0.43 ms 203 (+ childCount: 2000)
childLimit: 10 0.6 ms 7,813 (~194x smaller)

Quality gates: the default path is byte-identical to current main (engine test equates summary: true with the document.inspect subtree; live A/B of leaf/group reads matches hash-for-hash), and a new engine test covers nesting (depth: 1 shows children while the nested group reports childCount), limits, and invalid values.

cargo xtask ci: all 7 steps pass.

@fahrim fahrim changed the title Slice summary reads with document.node depth and childLimit MPC: Slice summary reads with document.node depth and childLimit Oct 7, 2026
@fahrim fahrim changed the title MPC: Slice summary reads with document.node depth and childLimit MCP: Slice summary reads with document.node depth and childLimit Oct 7, 2026
fahrim and others added 2 commits October 8, 2026 07:43
…them (review of storytold#405)

`depth` / `childLimit` without `summary: true` used to return the whole
full-JSON subtree silently; it is now an invalid-params error. docs/mcp.md
describes the slice parameters and childCount, the engine test covers
fractional values, unsliced reads and limits past the tree, and the CLI
stdio sweep reads a sliced group through run_command.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bflatastic
bflatastic merged commit c5f0859 into storytold:main Oct 8, 2026
@bflatastic

Copy link
Copy Markdown
Member

Thanks @fahrim, merged! This is a clean follow-up to #328. Keeping the slicing in the command layer, and reporting childCount only when a level is cut, is the right design, and your measurements made it easy to review. I rebased it on main and added one commit on top:

  • Rejected: depth/childLimit without summary: true is now an error. Before, a request that looked sliced quietly returned the whole full-JSON subtree.
  • Docs: docs/mcp.md has a paragraph on the slice parameters, childCount and the validity rules.
  • Tests: fractional and oversized values, limits past the end of the tree (byte-identical to the full summary), and a sliced group read through run_command in the CLI stdio sweep.

Checked end to end over MCP stdio on a 2,000-child group: childLimit: 10 cut the reply from 810 KB to 4.5 KB, with childCount: 2000 reported. A small note on the PR body: through run_command, invalid values come back as a tool result with isError: true rather than a -32602 protocol error. That's the right behaviour for tool calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants