mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
Two MCP code paths both spawned the servers declared in a workspace's `.mcp.json`: the persistent engine in `agent/x/agentmcp` (which owns tool-call execution via `CallTool`) and an ephemeral one-shot runner in `agent/agentcontext` (`mcprunner.go`) that connected, listed tools, and immediately closed each server purely for discovery. Every declared server was launched twice, and the discovery path duplicated the engine's `.mcp.json` parse, transport-build, env-resolve, and connect logic. This makes `agent/x/agentmcp` the single persistent MCP engine. The `agentcontext` manager now reads that engine's per-server catalog in-process through an injected `MCPCatalog` option and surfaces each server as a `KindMCPServer` resource. The engine wires `SetOnReload` to the manager's `Trigger`, so a reload (startup connect or `.mcp.json` edit) re-resolves and re-pushes the pinned resources. Tool-call execution is unchanged: it still flows through the engine's `CallTool` over `POST /api/v0/mcp/call-tool`. The now-dead HTTP discovery surface is removed: the agent `GET /api/v0/mcp/tools` route with `agentmcp.API.handleListTools`, and `workspacesdk.AgentConn.ListMCPTools` with `ListMCPToolsResponse` (mock regenerated). The change nets roughly `-1370` lines, mostly the deleted duplicate runner and its tests. <details> <summary>Decision log</summary> The merge of #26585 made pinned `chat_context_resources` the sole source of workspace context, which surfaced the duplicate spawning. Two options were considered: - **Option A + dependency injection (chosen):** keep `agent/x/agentmcp` as the single persistent engine; `agentcontext` consumes its catalog in-process and stays the orchestrator/owner at the API boundary (it still pushes `KindMCPServer` resources). This is low-risk because `agentcontext` already exposed the `resolver.MCPResources` seam, so the change just rebinds it from the ephemeral runner to the shared engine. - **Option B (rejected):** reimplement persistent pooling, reconnect, singleflight, and race handling inside `agentcontext` and delete `agentmcp`. Too broad, and it discards the engine's tested lifecycle for no behavioral gain. `agentcontext`'s discovery was never what kept servers alive; its runner closed each server immediately after listing tools. The component holding persistent connections was always `agentmcp`, which is why execution already lived there. Consolidating onto it removes the duplicated stack rather than a whole package: both packages survive with distinct roles (`agentmcp` is the engine, `agentcontext` is the orchestrator/owner). </details> Coder Agents generated on behalf of @kylecarbs
35 lines
1.9 KiB
Go
35 lines
1.9 KiB
Go
// Package agentcontext consolidates the agent-side plumbing that
|
|
// resolves, watches, and pushes workspace context (instruction
|
|
// files, skills, and MCP configuration) to coderd.
|
|
//
|
|
// This is the agent half of the design described in
|
|
// "RFC: Workspace Context Sources for Coder Agents". It owns:
|
|
//
|
|
// - User-declared scan roots (Sources) layered on top of
|
|
// built-in defaults and the working directory.
|
|
// - A resolver that classifies files at fixed locations under
|
|
// each scan root into typed Resources (instruction files,
|
|
// skills, MCP configs, MCP servers). Discovery is shallow:
|
|
// instruction files (AGENTS.md, CLAUDE.md, .cursorrules) and
|
|
// .mcp.json are read only at a scan root's top level, skills
|
|
// only from fixed container directories (skills, .agents/skills,
|
|
// .claude/skills, .codex/skills), and the resolver never walks
|
|
// the tree downward or up to a parent directory.
|
|
// - A fixed-location fsnotify watcher that signals a re-resolve
|
|
// when any recognized file changes.
|
|
// - An HTTP API at /api/v0/context/sources for source CRUD
|
|
// and /api/v0/context/resync for synchronous push barriers.
|
|
// - A Pusher abstraction so the latest Snapshot can be shipped
|
|
// to coderd without coupling this package to any particular
|
|
// drpc client version.
|
|
//
|
|
// Live MCP server tool lists come from the shared MCP engine in
|
|
// agent/x/agentmcp, which owns the single set of MCP server connections
|
|
// used for both tool discovery and tool-call execution. This package
|
|
// reads that engine's catalog through the injected MCPCatalog option and
|
|
// surfaces the servers and their tools as KindMCPServer resources, so
|
|
// MCP servers are pushed to coderd alongside instruction files and
|
|
// skills. The engine notifies this package through the Manager's Trigger
|
|
// when its catalog changes, driving a re-resolve and re-push.
|
|
package agentcontext
|