sdk+mcp: surface saved queries as first-class tools#7
Conversation
Pairs with omnigraph PR (server-side /queries CRUD). The MCP server now fetches every saved query at startup and registers one MCP tool per saved query under the `q_<name>` prefix, with a zod input schema built from the persisted parameter signature. Agents see saved queries in their tool catalogue alongside `read` / `change` / etc., instead of having to know to call `read` with a hand-rolled source string. Surface: - New `og.queries` SDK resource (list/get/save/delete), camelCased like the rest of the public types. - `createOmnigraphMcpServer` is now async (calls into the server during setup). `bin.ts` updated; no other callers in-tree. - On older omnigraph-server (no /queries endpoint), the list call 404s, we log to stderr and skip per-query registration — built-in tools remain functional. Tested. - A new `omnigraph://queries` resource exposes the same list as JSON for clients that prefer browsing over the tool catalogue. Param-type → zod mapping is intentionally permissive (`I32`, `String`, etc. constrained; `Vector(N)`, `[String]`, future scalars passed as `z.unknown()`). The server still parses and typechecks against the live schema, so duplicating the typecheck client-side would only introduce false negatives. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Joan Reyero <joan@reyero.io>
There was a problem hiding this comment.
1 issue found across 11 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/mcp/src/server.ts">
<violation number="1" location="packages/mcp/src/server.ts:118">
P2: Saved-query parameters named `branch` or `snapshot` are silently shadowed by transport-level options, making it impossible to pass those values as actual query parameters.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| // Every saved query is dispatched through `/read`, so the caller may | ||
| // also pin a branch or a snapshot at invocation time without having | ||
| // to bake it into the saved source. | ||
| shape.branch = z.string().optional(); |
There was a problem hiding this comment.
P2: Saved-query parameters named branch or snapshot are silently shadowed by transport-level options, making it impossible to pass those values as actual query parameters.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/mcp/src/server.ts, line 118:
<comment>Saved-query parameters named `branch` or `snapshot` are silently shadowed by transport-level options, making it impossible to pass those values as actual query parameters.</comment>
<file context>
@@ -67,7 +71,67 @@ function plainText(text: string) {
+ // Every saved query is dispatched through `/read`, so the caller may
+ // also pin a branch or a snapshot at invocation time without having
+ // to bake it into the saved source.
+ shape.branch = z.string().optional();
+ shape.snapshot = z.string().optional();
+ return shape;
</file context>
|
Closing in favor of a server-side MCP surface. We're moving MCP tool projection into omnigraph-server (RFC-003): one Cedar-gated This PR's approach (client-side Ideas we'll carry into the server-side work: the Thanks @joanreyero for the prototype — it mapped the shape well. |
Summary
og.queriesSDK resource (list/get/save/delete) wrapping the new/queriesendpoints. CamelCased like the rest of the public types.q_<name>so user-defined tools cannot shadow built-ins (read,change, …). The tool's input schema is built from the parameter signature the server persisted alongside the source.omnigraph://queriesresource exposes the full list as JSON for clients that prefer browsing over scrolling the tool catalogue.createOmnigraphMcpServeris now async (it calls into the server during setup).bin.tsupdated; no other callers in-tree./queriesreturns malformed JSON), we log to stderr and skip per-query registration. All built-in tools remain functional. Covered by a dedicated test.Why this shape
Agents currently have to know how to author
.gqsource and feed it toread. Saved queries let an operator (or another agent) author a query once, give it a name and a description, and have every downstream MCP client see it as a discoverable, typed tool —q_find_person({ name: "Alice" }).The
q_prefix is deliberate defence-in-depth on top of the server-side reserved-name check; the prefix also keeps the catalogue obviously partitioned (built-ins vs user-saved) for humans browsing it.Param-type → zod mapping
Intentionally permissive. Scalar types (
String,Bool,I32/I64/U32/U64,F32/F64,Date/DateTime) get specific zod schemas. Anything else (Vector(N),[String],Blob, future scalars) is passed through asz.unknown(). The server still parses and typechecks the saved query against the live schema at execution time, so duplicating that typecheck client-side would only introduce false negatives.Test plan
pnpm typecheck— clean.pnpm test— SDK 60 pass / 18 e2e-skipped (4 new queries-resource tests); MCP 15 pass (3 new tests covering tool registration, snapshot routing, older-server fallback).pnpm build— both packages build.pnpm check-coverage— 18 call sites bound to 18 spec operations.@modelcontextprotocol/inspector: bothq_<name>tools appear with correct input schemas and dispatch to/readwith the saved source.check-drift— expected to fail until server: add saved-query CRUD at /queries omnigraph#96 merges and a release is tagged. Bumpomnigraph.serverVersionin rootpackage.jsonto that tag at that point.🤖 Generated with Claude Code
Summary by cubic
Expose saved queries as first-class tools. The SDK adds
og.queriesCRUD for/queries, and the MCP server auto-registers aq_<name>tool per saved query with typed inputs that dispatch throughread.New Features
og.queriesresource (list/get/save/delete), with camelCased types.q_<name>tool per saved query; input schema derives from saved params; supports optionalbranch/snapshot; routes toread.omnigraph://queriesreturns the full saved-query list as JSON./queriesis missing or fails, we log and skip per-query tools; built-ins still work.Migration
createOmnigraphMcpServeris now async. Update call sites toawait createOmnigraphMcpServer(...)before connecting.Written for commit 2e71af0. Summary will update on new commits.