feat(coderd/x/chatd): serve workspace MCP tools and read_skill from pinned context - #26581
Merged
Merged
Conversation
…inned context Wire the consumer side of the agent-pushed workspace context snapshot so a chat uses its pinned context instead of live-pulling from the workspace agent. - Build workspace MCP tools from the chat's pinned chat_context_resources instead of dialing the agent for a live tool list. resolveWorkspaceMCPTools prefers the pin and falls back to live discovery for chats whose agent has not reported context yet, mirroring resolveTurnWorkspaceContext for instructions and skills. Pushed tool names are re-prefixed to "<server>__<tool>" and the pushed JSON Schema is split into properties and required to match the shape the live path produces. - Serve read_skill's SKILL.md body from the pinned snapshot (SkillMeta.Meta) so a pinned chat keeps returning the same instructions even when the workspace is unreachable. The supporting-file list stays a best-effort live lookup, since the snapshot carries only the meta file. Tool calls still proxy through the workspace agent connection; the snapshot carries tool definitions, not a way to execute them. The legacy live paths remain as fallback for agents that have not pushed context.
sreya
approved these changes
Jun 22, 2026
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
This wires the last two consumer-side gaps of the agent-pushed workspace context refactor. coderd already hydrates each chat's pinned context (
chat_context_resources), andresolveTurnWorkspaceContextalready prefers the pin for instruction files and skill metadata. This change extends that preference to workspace MCP tools and theread_skillbody.Workspace MCP tools are now built from the chat's pinned
mcp_serverresources instead of a liveListMCPToolspull.resolveWorkspaceMCPToolsprefers the pin and falls back to live discovery for chats whose agent has not reported context yet, gated the same way as the instruction/skills pin: the pin wins whenever the chat has any pinned rows, so a workspace with no MCP servers contributes no tools rather than resurrecting stale ones. Because the agent reports tool names unprefixed, each tool is re-prefixed to the{server}__{tool}form and the pushed JSON Schema is split intopropertiesandrequiredso the result matches what live discovery produced. Calls still proxy through the workspace agent connection; the snapshot carries tool definitions, not a way to execute them.read_skillnow serves a workspace skill'sSKILL.mdbody from the pinned snapshot (SkillMeta.Meta) instead of dialing the agent, so a pinned chat keeps returning the same instructions even when the workspace is unreachable. The supporting-file list stays a best-effort live lookup, since the snapshot carries only the meta file per the agent push contract.The legacy live paths remain as the fallback for agents that have not pushed context; RFC Release-5 cleanup of those paths is out of scope here.
Implementation plan and decisions
Background
The agentcontext refactor is mostly shipped across earlier PRs (#25983, #26526, #26533, #26577, #26570, #26573): the agent resolves instruction files, skills, and MCP servers into a snapshot, pushes it via
PushContextState, and coderd hydrates each chat's pinned context (chat_context_resources). This PR closes the two remaining consumer-side gaps.Key facts established from the code
mcprunnerstorestool.Name); the agent MCP proxy andCallMCPToolexpect the{server}__{tool}form (agentmcp.ToolNameSep). The pinned path reconstructs the prefix for execution, matching the model-facing names the legacy path produced.agentmcpsetsMCPToolInfo.Schema = InputSchema.PropertiesandRequired = InputSchema.Requiredseparately. The pushedinput_schemais the full JSON Schema object, so the pinned builder extractspropertiesandrequiredto match that shape.SkillMetaBody.metais the verbatim SKILL.md. The supporting-file list is not in the snapshot, so it is fetched live on demand (best-effort).resolveTurnWorkspaceContext: the pin wins when the chat has any pinned rows; otherwise the live path is used.Changes
chattool/skill.go: addSkillMeta.Meta []byte; extractlistSkillFilesfromLoadSkillBody; inreadWorkspaceSkillBody, whenMetais present, parse the body from it without dialing and list files best-effort, else use the legacy live read.context_prompt.go: populateSkillMeta.MetaincontextResourcesToPrompt; addworkspaceMCPToolInfosFromResources(pinnedmcp_serverrows to[]workspacesdk.MCPToolInfowith prefixed names and split properties/required) andsplitMCPInputSchema.chatd.go: addpinnedWorkspaceMCPTools(build tools from the pin, ok-gated) andresolveWorkspaceMCPTools(pin-first, fall back todiscoverWorkspaceMCPTools).generation_preparer.go: callresolveWorkspaceMCPToolsinstead ofdiscoverWorkspaceMCPTools.Tests
chattool/skill_test.go: read_skill serves the pinned body without dialing, lists files via LS, and still returns the body when the workspace is unreachable.context_prompt_internal_test.go:SkillMeta.Metais populated;workspaceMCPToolInfosFromResourcesprefixing/properties/required/skip behavior;pinnedWorkspaceMCPToolsok-gating and fallback dispatch.Opened by Coder Agents on behalf of @kylecarbs.