feat: add pre-execution tool policy interface - #377
Draft
barryroodt wants to merge 12 commits into
Draft
Conversation
Absorbs the plan's `feat: normalize MCP structured tool results` boundary. Structured result normalization and the policy seam cannot be split into two byte-safe commits. A policy-free tool must keep its `tools/list` and `tools/call` bytes identical to fc54ea2 on every serving path, and on the frozen public surface an attached `policy` is the only thing that can activate normalization: `formatResult` must never change byte shape, no new normalization toggle may be added, and `outputSchema` stays required on `Tool` so its presence cannot discriminate. A commit introducing normalization before the policy seam existed would therefore either normalize unconditionally, breaking policy-free bytes, or carry no observable normalization contract at all. Landing both together keeps every commit individually byte-safe with its own tests green.
Coverage Report for CI Build 32894951660Coverage increased (+0.001%) to 96.521%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Guard the decision before the audit record is built, so an unrecognized decision can no longer reach the sink as a raw string outside the declared union, and a nullish decision no longer throws before any record exists. The union narrows first; the fire-and-forget callback is then scheduled exactly once per request, ahead of all three branches. `decision` widens to 'execute' | 'result' | 'rejected', where 'rejected' is this package's own outcome for a decision it could not recognize. Also correct two JSDoc claims: the audit callback is not awaited and its completion is neither ordered before the response nor guaranteed, and `resolveParameters` guarantees one shared hook call, not identical advertised and enforced schemas, since `.strict()` applies at parse only.
Assert the 'rejected' audit record on both fail-closed shapes, an unknown decision type and a nullish decision, and that a never-settling audit sink cannot delay the tool result. Repair the widening fixture so it demonstrates a servable pattern: the resolution carries the era and execute satisfies the schema the request advertised. The added modern call pins the hook-supplied input schema on the call path, and a legacy call pins that a contextually hidden tool stays callable while absent from tools/list. Drop the racing negative console assertion from the no-telemetry test; the positive record assertion carries that invariant.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds the product-neutral tool policy interface described in RFC v0.4 to
mcp-utils: publicToolPolicy,ToolPolicyDecision, andToolRequestContexttypes.Policies can select contextual schemas, normalize known fields before strict parsing, return a result without business execution, or pass a typed resolution into exact
(args, resolution)execution. Policy-backed structured results are normalized, and telemetry failures cannot change the tool result.requestState?: ServerOptions['requestState']passes to the SDK unchanged. The SDK continues to own verification fields and-32602errors. Policy-free tool discovery, call ordering, and result bytes remain unchanged.Why
This creates the public policy interface needed by PR B while keeping
mcp-utilsproduct-neutral. It adds no user-visible elicitation or Supabase-specific policy.Verification
All checks below passed.
CI=1 mise exec -- pnpm --filter @supabase/mcp-utils test runCI=1 mise exec -- pnpm --filter @supabase/mcp-server-supabase test run --project unitmise exec -- pnpm buildmise exec -- pnpm format:checkmcp-server-postgrestbase/head differential reproduced the same failure set with identical normalized received valuespackages/mcp-utils