Skip to content

feat(mcp)!: rename pond_sql_query to pond_sql and make the tool surface route#102

Open
tenequm wants to merge 3 commits into
mainfrom
feat/mcp-surface-routing
Open

feat(mcp)!: rename pond_sql_query to pond_sql and make the tool surface route#102
tenequm wants to merge 3 commits into
mainfrom
feat/mcp-surface-routing

Conversation

@tenequm

@tenequm tenequm commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Why

Clients that matter (Claude Code, Codex) defer MCP tool descriptions behind tool search. The surfaces that actually route an agent are the always-loaded server instructions, the bare tool names, an installed skill, and error messages at the point of failure - not the carefully-written descriptions nobody sees before choosing. A field-tested misroute proved it: "analyze this session" bound to the SQL tool via the word "analytic" in the instructions, when the right call was one pond_get(session_id).

This PR makes every routing surface carry its weight, and folds in the highest-leverage finding from the retrieval ergonomics field test (#59): the supersession blind spot.

Breaking

  • MCP tool pond_sql_query -> pond_sql - matches the pond sql CLI verb and drops the generic "query" attractor from the always-visible tool name. No other wire change.

What changed

Routing surfaces

  • Server instructions now carry all routing: analyze/review/summarize a session binds to pond_get(session_id); latest-state questions steer to session_from="end" / sort_by="recency" (supersession guard); pond_sql self-demotes to the escape hatch; cookbook detail evicted to the schema:// resources.
  • Tool descriptions lead with the verbs they claim (find / read / escape hatch) and shrink to ToolSearch-bait + contract.
  • The sql query param keeps the column lists and gains the tool_call body-shape map ({call_id, name, params} - a Bash command is $.params.command), fixing a real observed failure (agents guessing $.command, silently getting 0 rows).
  • Error hints teach at the failure point: the schema hint gains the body shapes; the timeout hint names the remote-store round-trip cost and the pond_get alternative.
  • pond_get later-messages page marker now warns that conclusions may have been revised and names session_from="end" (the docs: pond retrieval ergonomics field test (external session) #59 core finding, verified live).

Skill

  • SKILL.md rewritten: trigger verbs in the description (analyze/review/summarize/"check pond"), a which-tool router, and "rules that prevent wrong conclusions" (absence is not proof, supersession, tool-body shapes, remote parts cost).
  • pond init installs the bundled skill to ~/.claude/skills/pond/SKILL.md under the same consent as MCP registration - idempotent on re-runs, and a hand-edited copy is never overwritten without an explicit confirm (+ unit test).

Latent release bug

  • SKILL.md was in Cargo.toml exclude while being include_str!'d into the binary - the next cargo publish verify build would have failed on the missing file. It now ships in the package (verified with cargo package --list).

Verified against the real binary (local store, read-only)

  • The docs: pond retrieval ergonomics field test (external session) #59 "200 empty system carrier messages" artifact is already fixed: page 1 of a session with 15,500 system messages renders 16 assistant + 4 user, zero carriers.
  • The "later messages" count marker existed; only the supersession phrasing was missing (added here).
  • The fat-cell problem is real and confirmed worse than reported: one 42,487-char cell rendered a 214KB response (row-halving budget loop has a shown > 1 floor; table padding amplifies ~5x). Fixed in the follow-up commit on this branch: inline table cells now clip at 1000 chars with a full-value marker - the same query renders 5,534 bytes (was 214,556), verified end-to-end. Export modes are never clipped.

Validation

cargo fmt --check clean, cargo clippy --all-targets -- -D warnings clean, cargo test green: 195 lib + 29 bin + 49 integration, 0 failures. Rename verified end-to-end by the sql::pond_sql_over_mcp integration test (tools/list + call over stdio MCP).

tenequm added 2 commits July 8, 2026 12:11
…ce route

Clients that matter (Claude Code, Codex) defer MCP tool descriptions behind
tool search, so the surfaces that actually route are the always-loaded server
instructions, the bare tool names, and an installed skill. A field-tested
misroute proved it: 'analyze this session' bound to the SQL tool via the word
'analytic' in the instructions, when the right call was pond_get(session_id).

- BREAKING: MCP tool pond_sql_query is now pond_sql - matches the pond sql
  CLI verb and drops the generic 'query' attractor from the always-visible
  name. No other wire change.
- Server instructions carry all routing: analyze/review/summarize a session
  binds to pond_get(session_id); latest-state questions steer to
  session_from=end / sort_by=recency (supersession guard); pond_sql
  self-demotes to the escape hatch; cookbook detail evicted to the schema://
  resources.
- Tool descriptions lead with the verbs they claim (find / read / escape
  hatch) and shrink; the sql query param keeps the column lists and gains the
  tool_call body-shape map ({call_id, name, params} - $.params.command).
- sql.rs error hints teach at the failure point: schema hint gains the body
  shapes, timeout hint names the remote-store round-trip cost and the
  pond_get alternative.
- SKILL.md rewritten: trigger verbs in the description, which-tool router,
  rules that prevent wrong conclusions (absence is not proof, supersession,
  remote parts cost).
- pond init installs the bundled skill with the same consent as MCP
  registration (idempotent; a hand-edited copy is never clobbered without an
  explicit confirm); pond skill remains the manual path.
- Cargo.toml: stop excluding SKILL.md from the package - it is include_str!'d
  into the binary, so the exclusion would fail the next publish verify build.
When a pond_get session page has later messages, the page-down marker now
also says conclusions may have been revised and names session_from=end /
--session-from end. Guards the field-tested failure (docs/researches
retrieval field test, PR #59): an agent reads an early page of a long
evolving session and reports a since-overturned conclusion as current.
@tenequm tenequm self-assigned this Jul 8, 2026
…rker

One fat cell (tool bodies reach 56KB) defeated the inline byte budget two
ways: the row-halving loop cannot drop below one row, and the table renderer
pads every row to the widest cell (~5x amplification). Measured on the real
corpus: a single 42,487-char tool_result cell rendered a 214,556-byte
response; with the per-cell clip the same query renders 5,534 bytes and the
marker names the unclipped paths (format=ndjson, or a narrower json_extract
projection). Export modes are never clipped.
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.

1 participant