Serve a unified MCP server for all projects on the admin service - #9816
Serve a unified MCP server for all projects on the admin service#9816begelundmuller wants to merge 2 commits into
Conversation
| }, &mcp.StreamableHTTPOptions{ | ||
| Stateless: true, | ||
| // Respond with application/json instead of text/event-stream. | ||
| // The spec allows either, and it means the admin service's unified MCP server can forward tool calls with a plain HTTP request. |
There was a problem hiding this comment.
Nit: The comment feels slightly odd. Isn't JSONResponse: true means we only expect JSON ?
| In the workflow, do not proceed with the next step until the previous step has been completed. If the information from the previous step is already known (let's say for subsequent queries), you can skip it. | ||
| If a response contains an "ai_instructions" field, you should interpret it as additional instructions for how to behave in subsequent responses that relate to that tool call. | ||
|
|
||
| ## Project Development |
There was a problem hiding this comment.
I wonder if this should be gated with a if block and completely skipped when exposing instructions via unified MCP server
There was a problem hiding this comment.
Pull request overview
This PR adds a unified MCP (Model Context Protocol) server on the admin service at <admin>/v1/mcp, exposing every project a caller has access to through a single endpoint instead of one MCP endpoint per project. The admin service answers the MCP protocol itself, advertises the runtime's metrics-view tools (augmented with a required project argument), and forwards each tool call to the correct project's runtime by minting an ephemeral runtime JWT and issuing a plain JSON-RPC request. Tool definitions remain owned by runtime/ai, keeping a single source of truth.
Changes:
- Adds
admin/server/mcp.go: the unified MCP handler, alist_projectsadmin tool, per-project session derivation, tool-argument injection/stripping, and JSON-RPC forwarding to runtimes. - Refactors
admin/server/runtime_proxy.gointo reusable helpers (resolveDeploymentForOrgAndProject,issueEphemeralRuntimeToken,runtimeHTTPHost,errNoProdAccess) shared with the new MCP path. - Extends
runtime/aito exportMCPInstructionsandMCPToolSpecs(), and updatesRunner.Sessionso a caller-chosenSessionIDis created whenCreateIfNotExistsis set; the runtime MCP server forwards the client user agent and now responds with JSON (JSONResponse: true).
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
admin/server/mcp.go |
New unified MCP server: forwards metrics tools to project runtimes, serves list_projects, derives per-project sessions, and parses/strips the project arg. |
admin/server/mcp_test.go |
Unit tests for forwarded-tool spec building and project argument parsing. |
admin/server/runtime_proxy.go |
Extracts deployment resolution, ephemeral token issuance, and runtime-host rewriting into shared helpers. |
admin/server/server.go |
Wires the MCP handler at /v1/mcp with observability, CORS, lenient auth, and an anon-rejecting auth guard. |
runtime/ai/ai.go |
Session now creates a session with a caller-supplied ID when CreateIfNotExists is set and the ID is unknown. |
runtime/ai/mcp.go |
Exports MCPInstructions and adds MCPToolSpecs() so the admin service can advertise tools it cannot run. |
runtime/ai/mcp_test.go |
Tests that specs build without a runtime and that CreateIfNotExists addressing works. |
runtime/server/mcp.go |
Forwards the real client user agent and responds with JSON so admin can forward tool calls over plain HTTP. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Adds
<admin>/v1/mcp, which serves every project a caller has access to on one URL, instead of one MCP endpoint per project.runtime/ai; the admin service reads their specs, injects a requiredprojectargument, and strips it again before forwarding the call to that project's runtime.list_projectstool, served by the admin service since the runtime is not aware of projects.