Skip to content

feat(agent): serve context sources over the agent socket#26526

Draft
kylecarbs wants to merge 1 commit into
mainfrom
kylecarbs/agent-context-socket
Draft

feat(agent): serve context sources over the agent socket#26526
kylecarbs wants to merge 1 commit into
mainfrom
kylecarbs/agent-context-socket

Conversation

@kylecarbs

@kylecarbs kylecarbs commented Jun 18, 2026

Copy link
Copy Markdown
Member

Overview

Split from #26466, scoped to agent-only changes. This PR exposes the
agent's context sources and snapshots over the existing agent socket. There
are no changes outside agent/.

What's included

  • agentsocket: context source CRUD (ContextSources, GetContextSource,
    AddContextSource, RemoveContextSource) plus GetContextSnapshot and
    ResyncContext RPCs, with matching client methods and proto. The server
    receives the context Manager via WithContextManager and returns a clean
    error when it is absent.
  • agentcontext: the resync JSON response now carries the per-resource
    Name, keeping the HTTP resync payload in sync with the drpc
    PushContextState path in agentsocket.
  • agent: passes the context Manager to the socket server via
    WithContextManager.

What's intentionally NOT here

  • No MCP wiring. There are no MCP additions in agent.go or agentcontext.
    MCP ownership will land later in agentcontext; this PR does not build on
    agent/x/agentmcp.
  • No changes to agent/x/agentmcp or the agentcontext resolver. The socket
    serves whatever context resources the Manager already resolves.
Context for reviewers

This is one of several PRs split out of #26466. Earlier revisions also wired
live MCP servers through the socket; that scope was removed so this PR stays
purely socket + context plumbing inside agent/. The agentcontext resolver,
agent/x/agentmcp, and agent.go MCP startup behavior are unchanged from
main.


Created by Coder Agents on behalf of @kylecarbs.

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review

coder-agents-review Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Chat: Spend limit reached | View chat
Requested: 2026-06-18 18:52 UTC by @kylecarbs
Spend: $105.93 / $100.00 (limit reached)

Review history
  • R1 (2026-06-18): 21 reviewers, 4 Nit, 2 Note, 2 P2, 5 P3, COMMENT. Review
  • R2 (2026-06-18): 6 reviewers, 6 Nit, 2 Note, 2 P2, 8 P3, COMMENT. Review
  • R3 (2026-06-18), 6 Nit, 2 Note, 2 P2, 8 P3, COMMENT. Review
  • R4 (2026-06-18): 4 reviewers, 8 Nit, 2 Note, 2 P2, 8 P3, APPROVE. Review

deep-review v0.8.0 | Round 4 | 023a1c9..f634c18

Last posted: Round 4, 20 findings (2 P2, 8 P3, 8 Nit, 2 Note), APPROVE. Review

Finding inventory

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 Nit Author fixed (a9283c6) configwatcher_internal_test.go:35 Comment references deleted function name cachedTools (should be CachedTools) R1 Netero Yes
CRF-2 Note Author fixed (a9283c6) contextmcp.go:115 resourceID duplicated across packages (contextmcp.go and resolve.go) R1 Netero, Robin P3, Knov Note Yes
CRF-3 P2 Author fixed (a9283c6) contextmcp.go:119 hashMCPServer/hashMCPServerError comments falsely claim hashes flip the aggregate drift hash R1 Leorio P2, Razor P3 Yes
CRF-4 P2 Author fixed (a9283c6) manager.go:568 Server map and health map updated in separate lock acquisitions; CachedServers sees inconsistent state R1 Hisoka P2, Meruem P3 Yes
CRF-5 P3 Author fixed (a9283c6) manager.go:848 CachedServers returns in nondeterministic map-iteration order R1 Komugi Yes
CRF-6 P3 Author fixed (a9283c6) context_test.go:177 NoManagerErrors test exercises only 1 of 6 context RPCs R1 Chopper Yes
CRF-7 P3 Author fixed (a9283c6) contextmcp.go:130 hashMCPServer silently drops schema from hash when json.Marshal fails R1 Hisoka P3, Chopper P3 Yes
CRF-8 P3 Author fixed (a9283c6) contextmcp.go:157 writeHashField duplicates writeLengthPrefixed from resolve.go:1062 R1 Zoro P3, Robin Nit Yes
CRF-9 P3 Author fixed (a9283c6) agent.go:1558 8-line inline comment duplicates syncMCPServersFromContext's doc comment 22 lines below R1 Gon Yes
CRF-10 Nit Author fixed (a9283c6) agent.go:1642 Map-to-sorted-slice could use slices.Sorted(maps.Keys(seen)) R1 Ging-Go Yes
CRF-11 Nit Author fixed (a9283c6) manager.go:163 ServerStatus.Err is Error everywhere else R1 Gon Yes
CRF-12 Nit Author fixed (a9283c6) agentsocket.proto:107 ContextResource comment says "minus the payload" but also omits Tools R1 Razor Yes
CRF-13 Note Author accepted R2 (verbose comments trimmed where rework removed them; kept mcp.go comments for determinism/hashing contracts) contextmcp.go:39 Comment verbosity pattern: 30 of 54 comments longer than minimum R1 Gon Yes
CRF-14 Note Dropped by orchestrator (structural observation, not actionable defect) agent.go:1588 syncMCPServersFromContext wakes on every snapshot broadcast including irrelevant tool changes R1 Meruem P3, Ryosuke P3 No
CRF-15 Note Dropped by orchestrator (correct by default: new kinds hash unless excluded) resolve.go:1012 driftResources is a manually maintained allow-list R1 Meruem, Chopper No
CRF-16 P4 Dropped by orchestrator (transport-only consumer today; premature to move) service.go:30 ContextManager interface lives in transport layer instead of domain layer R1 Ryosuke No
CRF-17 P3 Author fixed (f634c18) mcp.go:82 buildMCPServerResources drops Required from MCPToolInfo; required-field changes invisible to content hash R2 Meruem P3, Razor P3 Yes
CRF-18 P3 Author fixed (f634c18) agent.go:1622 lastPaths set before Reload succeeds; transient failure permanently skips reload for those paths R2 Hisoka Yes
CRF-19 P3 Author fixed (f634c18) service.go:309 contextSnapshotToProto duplicates snapshotResponse conversion; Name field already drifted R2 Robin Yes
CRF-20 Nit Author fixed (f634c18) mcp.go:92 Map-to-sorted-slice manual pattern; CRF-10 fix not applied to new instance R2 Robin Yes
CRF-21 Nit Author fixed (f634c18) resolve.go:510 validateMCPConfig iterates map nondeterministically; error message varies for multi-entry invalid files R2 Komugi (downgraded from P3) Yes
CRF-22 Nit Open client.go:15 Option type comment says "for NewClient" but Option is used by both NewClient and NewServer R4 Mafuuu Yes
CRF-23 Nit Open mcp.go:94 Required marshal-error path omits sentinel, unlike InputSchema path (CRF-7 pattern) R4 Mafuuu Yes

Law analysis

Effective LOC: 1476 (813 production, 663 test, 1429 generated). Head SHA: 0c574da. Verdict: Don't split. Enforcement: Advisory.
Reasoning: Single risk domain (all under agent/), moderate effective LOC, already a split of #26466, layered dependent concerns with clean topological order.

Contested and acknowledged

CRF-13 (Note, contextmcp.go:39) - Comment verbosity pattern

  • Finding: 30 of 54 production comments are longer than the minimum text needed to deliver their category. Proposed trimming each to minimum draft.
  • Author accepted: Partly addressed by the rework (verbose contextmcp.go/driftResources blocks gone). Remaining mcp.go comments kept deliberately because they document non-obvious determinism and hashing contracts.

Round log

Round 1

Panel (20 reviewers). 2 P2, 5 P3, 3 Nit, 2 Note new. 3 dropped. Reviewed against 023a1c9..0c574da.

Round 2

Churn guard: PROCEED. 12 addressed, 1 acknowledged. Panel (6 reviewers). 3 P3, 2 Nit new. 0 dropped. Reviewed against 023a1c9..a9283c6.

Round 3

BLOCKED. All 5 open findings silent. No review.

Round 4

Churn guard: PROCEED. 5 addressed. Panel (4 reviewers). 2 Nit new. 0 P-level findings. All R2 fixes verified correct. Reviewed against 023a1c9..f634c18.

About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Komugi flake/determinism
Kurapika security
Law decomposition
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well-structured agent-side feature. The provider seam, drift-hash exclusion, and feedback-loop dedup are clean. The test suite (44.9% density) covers every new code path including real subprocess failures and hash sensitivity. Particularly nice: the slices.Equal(paths, last) guard that prevents reload storms from MCP tool broadcasts, and the default-include switch in driftResources that makes new resource kinds hash-safe by default.

Severity count: 2 P2, 5 P3, 3 Nit, 2 Note.

The two P2s are (1) false claims in doc comments about aggregate-hash participation, and (2) a stale-data window between installServers and recordServerHealth that Resync can observe. Both are fixable in-place.

"Two tools identical in name and description but differing only in schema would hash identically, producing a false negative in drift detection." (Hisoka, on the silent schema drop)


agent/x/agentmcp/configwatcher_internal_test.go:35

Nit [CRF-1] The awaitTools doc comment still says cachedTools after the rename to CachedTools.

(Netero)

🤖

🤖 This review was automatically generated with Coder Agents.

Comment thread agent/contextmcp.go Outdated
Comment thread agent/x/agentmcp/manager.go Outdated
Comment thread agent/x/agentmcp/manager.go Outdated
Comment thread agent/agentsocket/context_test.go
Comment thread agent/contextmcp.go Outdated
Comment thread agent/agent.go Outdated
Comment thread agent/agent.go Outdated
Comment thread agent/x/agentmcp/manager.go Outdated
Comment thread agent/agentsocket/proto/agentsocket.proto
Comment thread agent/contextmcp.go Outdated
@kylecarbs kylecarbs force-pushed the kylecarbs/agent-context-socket branch 2 times, most recently from 025644d to a9283c6 Compare June 18, 2026 17:55
@kylecarbs

Copy link
Copy Markdown
Member Author

Reworked the MCP wiring and addressed the prior review (all 12 threads replied to and resolved).

What changed since the first push

  • No changes to agent/x/agentmcp. That package is reverted to main; the provider reads its existing Tools() cache instead of new CachedServers/SetOnToolsChanged accessors. This dissolves both P2s (the doc-comment false claims and the installServers/recordServerHealth cross-lock race).
  • MCP-to-Resource conversion moved into agent/agentcontext/mcp.go, next to the MCPProvider seam, built from a non-blocking func() []workspacesdk.MCPToolInfo source. It reuses the package's resourceID/writeLengthPrefixed helpers (no duplication).
  • driftResources removed: MCP resources now participate in the snapshot aggregate hash normally. Deciding when a connecting server re-pins a chat moves to the coderd layer in a follow-up.
  • Applied the surviving P3/Nits directly (all-six-RPC nil-manager test, slices.Sorted(maps.Keys), marshal-error sentinel, trimmed comment, proto comment).

Force-pushed as a single clean commit (a9283c6). make pre-commit passes with no make gen diff.

This update was made by Coder Agents on behalf of @kylecarbs.

@kylecarbs

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean rework. The agentmcp revert eliminates both R1 P2s (the false-claim comments and the cross-lock race), and the MCP-to-Resource conversion landing in agentcontext dissolves the duplication findings. All 13 R1 findings are resolved.

The reworked code is well-structured: the provider reads the manager's existing Tools cache via an atomic.Pointer, the sync loop deduplicates by both path-set and tool-set equality, and the marshal-error sentinel from CRF-7 is properly carried over.

R2 severity count: 3 P3, 2 Nit.

"When a tool changes which parameters are required without changing property definitions, hashMCPServer produces the same hash." (Meruem, on the Required gap)

🤖 This review was automatically generated with Coder Agents.

Comment thread agent/agentcontext/mcp.go Outdated
Comment thread agent/agent.go Outdated
Comment thread agent/agentsocket/service.go
Comment thread agent/agentcontext/mcp.go Outdated
Comment thread agent/agentcontext/resolve.go Outdated
@kylecarbs kylecarbs force-pushed the kylecarbs/agent-context-socket branch from a9283c6 to 5d4b950 Compare June 18, 2026 18:37
@kylecarbs

Copy link
Copy Markdown
Member Author

Follow-up simplification (per review feedback): removed the MCPProvider interface seam now that the MCP-to-Resource conversion lives in agentcontext itself. The resolver takes a plain MCPToolSource (func() []workspacesdk.MCPToolInfo) and calls buildMCPServerResources in-package — no NewMCPProvider/mcpToolProvider indirection. Tests were updated to drive the resolver through the tool source; the byte-cap test became a count-cap test (MCP resources carry Tools, not Payload). Pushed as 5d4b950.

This update was made by Coder Agents on behalf of @kylecarbs.

@kylecarbs

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Further review is blocked until the author responds to or pushes fixes for the 5 open R2 findings. The 5d4b950 push removed the MCPProvider interface but did not address any of the open items.

Open findings awaiting response:

  • P3 CRF-17 (mcp.go:82): buildMCPServerResources drops Required from MCPToolInfo. Required-field changes are invisible to the content hash. Fix: add Required []string to MCPTool and include it in hashMCPServer.
  • P3 CRF-18 (agent.go:1619): lastPaths committed before Reload succeeds. A transient failure permanently skips reload for those paths. Fix: set lastPaths after Reload succeeds.
  • P3 CRF-19 (service.go:309): contextSnapshotToProto duplicates snapshotResponse at api.go:180. Name field has already drifted between the two.
  • Nit CRF-20 (mcp.go:92): Map-to-sorted-slice manual pattern reintroduced (CRF-10 fix was applied to mcpConfigPaths but not here).
  • Nit CRF-21 (resolve.go:510): validateMCPConfig iterates map nondeterministically; error message flickers for multi-entry invalid files.

For each: fix in this PR, file a GitHub issue, or explain why it should not be fixed.

🤖 This review was automatically generated with Coder Agents.

@kylecarbs kylecarbs force-pushed the kylecarbs/agent-context-socket branch from 5d4b950 to f634c18 Compare June 18, 2026 18:50
@kylecarbs

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All 18 prior findings resolved (13 from R1, 5 from R2). The R2 fixes in f634c18 are verified correct by all four reviewers:

  • CRF-17 (Required in hash): MCPTool.Required populated, hashed, tested.
  • CRF-18 (lastPaths after success): assignment moved to the else branch; transient failures retry.
  • CRF-19 (converter drift): Name synced, cross-reference comments added.
  • CRF-20/21 (sorted iteration): both now use slices.Sorted(maps.Keys(...)).

The MCPProvider-to-MCPToolSource simplification (5d4b950) is clean: plain function type, no interface indirection, conversion and hashing in-package. The sync loop terminates correctly, the atomic.Pointer usage is safe, and the socket RPCs follow the existing nil-guard + thin-delegation pattern.

Two new Nits below (cosmetic, non-blocking).

"The code held up." (Hisoka)


agent/agentsocket/client.go:15

Nit [CRF-22] The Option type comment says "for NewClient" but NewServer (server.go:38) also accepts ...Option, and WithContextManager is exclusively a server concern. Consider: "Option configures the agent socket client or server."

(Mafuuu)

🤖

🤖 This review was automatically generated with Coder Agents.

Comment thread agent/agentcontext/mcp.go Outdated
Split from #26466 (agent-only changes); no behavior outside agent/.

- agentsocket: add context source CRUD (ContextSources, GetContextSource,
  AddContextSource, RemoveContextSource) plus GetContextSnapshot and
  ResyncContext RPCs, with matching client methods and proto. The server
  takes the context Manager via WithContextManager and returns a clean
  error when it is absent.
- agentcontext: include the per-resource Name in the resync JSON response
  so the HTTP resync payload stays in sync with the drpc PushContextState
  path in agentsocket.
- agent: pass the context Manager to the socket server via
  WithContextManager.

No MCP wiring and no changes to agent/x/agentmcp or the agentcontext
resolver; the socket simply serves whatever context resources the
Manager already resolves.
@kylecarbs kylecarbs force-pushed the kylecarbs/agent-context-socket branch from f634c18 to 750fad8 Compare June 18, 2026 19:18
@kylecarbs kylecarbs changed the title feat(agent): serve context sources and live MCP servers over the agent socket feat(agent): serve context sources over the agent socket Jun 18, 2026
@kylecarbs

Copy link
Copy Markdown
Member Author

Scope update (force-pushed 750fad8698): this PR is now socket + context plumbing only. All MCP additions from this PR have been reverted to main:

  • agent/agentcontext/{mcp,resolve,manager}.go (+ their tests) and agent/agent_internal_test.go are back to main; mcp_internal_test.go removed. No MCPToolSource/buildMCPServerResources/validateMCPConfig/MCPTool.Required.
  • agent/agent.go is identical to main except one line: agentsocket.WithContextManager(a.contextManager) in initSocketServer. The MCP tool cache, syncMCPServersFromContext, and mcpConfigPaths are gone; main's one-shot MCP Reload at startup is restored.
  • agent/x/agentmcp is unchanged from main.

Kept: the agentsocket context RPCs (CRUD + snapshot + resync) and the agentcontext resync Name field that keeps the HTTP resync JSON in sync with the drpc push path. MCP ownership will land later inside agentcontext as a separate change rather than building on the current mcp.go/agentmcp path.

The prior approval was on f634c180, which still carried the MCP code, so re-requesting a review on the narrowed diff.

Posted by Coder Agents on behalf of @kylecarbs.

@kylecarbs

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review

Copy link
Copy Markdown
Contributor

@kylecarbs ⛔ This review has reached its per-chat spend limit ($105.93 / $100.00). Further review rounds are paused.

To raise the limit and continue, comment:

/coder-agents-review set-spend-limit:150

This is a per-chat budget, separate from any account-level usage limit.

🤖 Managed by Coder Agents.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant