feat: push MCP server context and tools from agentcontext#26533
Open
kylecarbs wants to merge 1 commit into
Open
feat: push MCP server context and tools from agentcontext#26533kylecarbs wants to merge 1 commit into
kylecarbs wants to merge 1 commit into
Conversation
agentcontext now starts its own MCP servers from the .mcp.json files its watcher discovers, lists their tools, and surfaces them as KindMCPServer resources pushed to coderd alongside instruction files and skills. This runs independently of agent/x/agentmcp (which serves the agent's MCP HTTP API); the two MCP paths share no state during the rollout, so removing the old package later touches nothing here. - agentcontext/mcprunner.go: self-contained one-shot MCP runner (connect, initialize, list tools, close) with its own .mcp.json parser. A Manager goroutine (runMCPSync) reloads it when the discovered KindMCPConfig path:contenthash set changes, then re-resolves to publish the tools. - agentcontext/mcp.go: MCPProvider builds KindMCPServer resources from the runner's non-blocking per-server snapshot (connected->OK with tools, failed->unreadable issue, no-tools-yet skipped). - agentcontext/resolve.go: MCP resources are excluded from the drift/aggregate hash so a server connecting does not dirty hydrated chats; structurally broken .mcp.json is flagged StatusInvalid. - agent.go: wires the runner via ManagerOptions.MCPExecer/MCPUpdateEnv; agent/x/agentmcp is left untouched.
aa6c115 to
6409edf
Compare
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
Live MCP servers and their tools now flow into the
agentcontextsnapshot and are pushed to coderd viaPushContextState, stored alongside instruction files and skills. Previously the resolver'sMCPProviderseam was unimplemented, so live MCP tool lists never reached the pushed snapshot.agentcontextis now fully self-contained for MCP: it connects to the MCP servers declared in the.mcp.jsonfiles its own watcher already discovers, lists their tools, and emitsKindMCPServerresources. It does not depend on or modifyagent/x/agentmcp— that package is left pristine and keeps serving the agent's MCP HTTP API. The two MCP paths run independently, which means the legacy package can be deleted later without touching this code.How
agentcontext/mcprunner.go): a one-shot MCP client (connect → initialize → list tools → close) with its own.mcp.jsonparser. A Manager goroutine (runMCPSync) reloads it whenever the discoveredKindMCPConfigpath:contenthashset changes, then re-resolves so the new tools are published. Per-server connects run in parallel (bounded) with a per-server timeout; a server that fails to connect is recorded as a failure rather than aborting the batch.agentcontext/mcp.go): buildsKindMCPServerresources from the runner's non-blocking per-server snapshot. Connected servers carry their sorted tools (StatusOK); failed servers surface asStatusUnreadableissues instead of vanishing; connected-but-no-tools-yet are skipped until a later reload. The content hash is tool-set sensitive.driftResources). MCP servers connect asynchronously after boot; without this, a server finishing its connect would dirty every hydrated chat even though nothing the user pinned changed.agent.go): the manager is givenManagerOptions.MCPExecer/MCPUpdateEnv;agent/x/agentmcpis untouched..mcp.jsonnow surfaces asStatusInvalidrather than silently dropping all its servers.coderd already persists
mcp_server/mcp_configresource bodies (including tools), so no coderd or proto changes were required.Testing
buildMCPServerResources(grouping/sort/skip/failed/hash sensitivity),NewMCPProviderdelegation, the resolver MCP option, MCP exclusion from the aggregate hash,.mcp.jsonparsing (transport inference, env expansion, reserved-name rejection),toolInputSchema, andmcpConfigSetchange detection.TestAgent_MCPServerToolsPushed): boots an agent with a.mcp.jsonpointing at a re-exec'd fake stdio MCP server and asserts the connected server'sechotool appears in aPushContextStatesnapshot (passes under-race).go build ./...,go vet, andgolangci-lintare clean on the touched packages.Scope / follow-ups
This is the agent-side production+push half. The chatd consumer (reading the pinned MCP resources for prompt/tool injection) and removing the legacy
workspaceMCPToolsCachepull path remain follow-ups, per the RFC rollout. While bothagent/x/agentmcpandagentcontextexist, stdio MCP servers are spawned by both; this is intentional and temporary untilagentmcpis removed.Implementation plan and decisions
Goal: produce live MCP server resources (with tools) from
agentcontextand push them to coderd.Starting state (main): proto (
PushContextState,MCPServerBody,MCPTool), the drpc adapter, coderd storage (workspace_agent_context_resources, body kindmcp_server), and the resolver'sMCPProviderseam already existed; nothing implemented the seam or fed live tools into the snapshot.Decision (agentcontext fully separate from agentmcp):
agentcontextstarts and lists its own MCP servers using only the connect-and-list half of an mcp-go client, driven by the.mcp.jsonfiles its existing watcher discovers. It shares no state withagent/x/agentmcpand does not import it. Two earlier revisions of this branch were discarded: (1) relocatingagentmcpintoagentcontext(rejected — it duplicates config parsing and file watchingagentcontextalready does); (2) readingagentmcp's cached server snapshot via new accessors (rejected — unnecessary coupling between two packages that should simply run independently while one is being retired). The temporary double-spawn of stdio servers is the accepted cost of keeping the two paths cleanly separated untilagentmcpis removed.Invariants held: no secrets (env/headers) in pushed resources, only server/tool metadata; MCP excluded from the drift hash; the provider is non-blocking so the resolver never stalls on MCP I/O.
This PR was created by Coder Agents on behalf of @kylecarbs.