Repository navigation
feat(mcp-server): pre-check tool scopes and retire plugin configuration - #2995
Draft
legreffier[bot] wants to merge 5 commits into
Draft
legreffier[bot] wants to merge 5 commits into
legreffier[bot] wants to merge 5 commits into
Conversation
Open
4 of 5 tasks
legreffier
Bot
force-pushed
the
mcp-sdk-3-cleanup
branch
from
November 9, 2026 07:46
091cc41 to
cd79de2
Compare
This was referenced Nov 9, 2026
Refuse a tool call whose token lacks a declared scope with the scope error and insufficient_scope challenge, without a REST round trip or error-text matching. REST denials beyond the declaration still get the challenge. Refs #2967 MoltNet-Diary: d57601d4-d9f4-4691-8944-cad58232be24 Task-Group: mcp-official-sdk
Drop MCP_REDIS_* and ORY_HYDRA_REGISTRATION_URL with their compose, Fly and example env entries, retire the @getlarge/fastify-mcp catalog, release-age and Renovate entries, and name the official SDK in discovery and agent instructions. Refs #2967 MoltNet-Diary: d66c468f-f1ee-4eac-9348-7c9053ae817e Task-Group: mcp-official-sdk
Refs #2967 MoltNet-Diary: 36592d0d-bca5-42ab-a39e-64944c3bc4a2 Task-Group: mcp-official-sdk Task-Completes: true
Its premise (the MCP plugin could not validate format: 'uuid') no longer holds: the server now validates with TypeBox, which enforces it. No CI job runs the eval batch. Refs #2967 MoltNet-Diary: c76312dc-9681-4c62-a4ed-0dece3ec9987 Task-Group: mcp-official-sdk
The official SDK emits no telemetry. Wrap tool calls, resource reads and prompt gets in spans with the MCP semantic-convention attributes, record tool errors and exceptions, and tag the HTTP request span with the JSON-RPC method. Refs #2967 MoltNet-Diary: 0a1f1621-f8ef-497e-bbfe-1e7e822af3d1 Task-Group: mcp-official-sdk
getlarge
force-pushed
the
mcp-sdk-3-cleanup
branch
from
November 10, 2026 09:12
cd79de2 to
16bcb6f
Compare
This branch has not been deployed
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.
Stacked on #2994, which sits on #2993 and #2990. Completes the
@modelcontextprotocol/servermigration for #2967.Summary
Missing required scope: <scope>and the OpenAI-styleinsufficient_scopechallenge, without calling the REST API. Declared scopes equal the routes'requiredScopes, so it refuses exactly what REST would refuse, without a round trip or error-text matching. Parsing REST errors stays as a fallback for anything the API demands beyond the declaration.traceparent/tracestate/baggage_metakeys and never reads them.mcp-format-uuid-validationscenario.Why not the SDK's
scopeChallengeThe official server can refuse a tool call before it runs, with HTTP 403 and
WWW-Authenticate: insufficient_scope. It's deliberately not wired: that 403 would pre-empt the tool-result_meta["mcp/www_authenticate"]challenge, which is what OpenAI documents as the trigger for re-linking. Worth revisiting once a production test shows how ChatGPT handles the 403.Changes
apps/mcp-server/src/mcp-registry.ts: the pre-check.tool-security.spec.tscovers the refusal without a handler call, the pass-through with the scope, and the REST fallback.MCP_REDIS_*andORY_HYDRA_REGISTRATION_URLremoved from the schema,docker-compose.e2e.yaml,deploy/self-host/compose.yaml,fly.tomlcomments andenv.local.example. The loader only reads declared keys, so leftover Fly secrets are ignored. valkey stays in self-host because the REST API uses it.pnpm-workspace.yaml,renovate.json:@getlarge/fastify-mcpcatalog, release-age and Fastify-group entries removed.libs/discovery:mcp_libraryis now@modelcontextprotocol/server.AGENTS.md(andCLAUDE.mdthrough the symlink),.github/copilot-instructions.md: the MCP stack line.apps/mcp-server/src/mcp-telemetry.ts(new): the registry wraps every tool call, resource read and prompt get in anINTERNALspan named<method> <target>(for exampletools/call diaries_list). Each span carries the MCP semconv attributes the plugin used (mcp.method.name,mcp.tool.name,mcp.resource.uri,mcp.prompt.name). A tool result withisErrorsetserror.type: tool_error; a thrown exception is recorded on the span. The route also tags the@fastify/otelHTTP span with the JSON-RPC method, soinitializeand the*/listcalls stay visible. Spans are no-ops without a tracer provider.mcp-telemetry.spec.tschecks them with an in-memory exporter.evals/moltnet-practices/mcp-format-uuid-validation/removed, along with itsevals/batch.jsonentry. Its premise was that the plugin couldn't validateformat: 'uuid', and TypeBox now enforces it. No CI job runs the batch.docs/reference/mcp-server.md: stateless transport,_meta.securitySchemes, the pre-check.docs/understand/architecture.md: diagram label and the JWT library note.Operator follow-up (not in this PR)
MCP_REDIS_*Fly secrets on the MCP app are now unused and can be unset after deploy.Not done
_meta(traceparent) isn't extracted yet; spans nest under the HTTP request span.mcp-telemetry.tsis a stopgap. feat: built-in OpenTelemetry tracing and metrics modelcontextprotocol/typescript-sdk#3115 (merged 2026-11-03, not yet in a release; 2.4.0 is the latest) builds OpenTelemetry intoMcpServer. It addsSERVERspans for every request, includinginitializeand the list calls,traceparentextraction from_meta, andmcp.server.operation.durationmetrics. When the SDK bump lands, deletewithMcpSpanandannotateRequestSpan, or passopenTelemetry: false, to avoid duplicate spans. The SDK names the toolgen_ai.tool.name(the semconv), notmcp.tool.name.Test plan
pnpm exec nx run-many -t typecheck lint test check:externals --projects=@moltnet/mcp-server,@moltnet/mcp-server-e2e,@moltnet/discovery: 238 unit testspnpm install --frozen-lockfilepnpm exec nx run @moltnet/mcp-server-e2e:e2ewith the image rebuilt from this branch and the container running withoutMCP_REDIS_*: 79/79/mcp, list and search diariesNo UI impact.