Repository navigation
feat(web): track MCP status and list each chat's MCP servers in its resources - #693
Merged
Merged
Conversation
This was referenced Oct 9, 2026
danyaberezun
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 9, 2026 06:58
362381b to
514bc9e
Compare
danyaberezun
marked this pull request as ready for review
October 9, 2026 08:00
danyaberezun
requested review from
Olga Lavrichenko (OLavrik),
Rustam Sadykov (SBOne-Kenobi) and
Rinat S (rsolmano)
as code owners
October 9, 2026 08:00
danyaberezun
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 9, 2026 10:42
514bc9e to
5592dc3
Compare
danyaberezun
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 9, 2026 11:08
5592dc3 to
e9122cd
Compare
danyaberezun
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 9, 2026 11:25
e9122cd to
4939d80
Compare
danyaberezun
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 9, 2026 11:43
4939d80 to
0103b02
Compare
danyaberezun
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 9, 2026 11:52
0103b02 to
9968e95
Compare
danyaberezun
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 9, 2026 12:12
9968e95 to
dbb0ee7
Compare
Rinat S (rsolmano)
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 13, 2026 10:59
b09f78e to
4846eee
Compare
Rinat S (rsolmano)
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 13, 2026 11:21
4846eee to
cab5eec
Compare
Rinat S (rsolmano)
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 13, 2026 11:56
cab5eec to
f14b296
Compare
Rinat S (rsolmano)
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 13, 2026 12:57
f14b296 to
2533c3a
Compare
Rinat S (rsolmano)
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 13, 2026 13:19
2533c3a to
7e25338
Compare
…esources - A generation-guarded store slice folds mcp.list reads and mcp.status pushes per workspace and session. - watchMcpWorkspace re-reads with bounded backoff while a server starts. - The Resources inspector lists the chat's MCP servers with state, tool count and transport, and offers disable/enable in this chat and Reconnect. - pi's startup MCP attention notice becomes status only now that the inspector shows it.
…p.status channel The interceptor turned the startup notice into a status update for every client, but only clients at MCP_PROTOCOL_VERSION receive mcp.status. The notice is now re-sent as a toast to sockets below that version.
…ration The inspector's bounded mcp.list re-read was never reset after a disconnect, so a reconnect could leave a server stuck at Starting.
Two watchers reading from the same revision could land out of order and drop a chat the newer list had installed, leaving its server at Starting.
…ration A read captured before a reconnect would be rejected at installation, so a watcher started after the reconnect issues its own read instead.
Rinat S (rsolmano)
force-pushed
the
mcp-stack/5-web-mcp-state
branch
from
October 13, 2026 13:26
7e25338 to
6db2497
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.
Problem
The host now reports MCP servers and their per-chat status (#692), but the web app has nowhere to keep
that state, and a chat doesn't show which MCP servers it runs or whether they connected.
Approach
installMcpListfolds anmcp.listanswer. The answer is the authoritative set of live chats as ofthe read token captured before the request.
applyMcpStatusfoldsmcp.statuspushes. Status generations only grow, so a late or stalesnapshot never overwrites a newer one.
MCP_PROTOCOL_VERSIONdrops everything.watchMcpWorkspacereadsmcp.listonce; a host capture that outlives its caller’s wait budget can still publish the connected state.It then re-reads with bounded backoff (1 → 13 s, six attempts per streak) only while a live chat of
that workspace still reports a server as
starting.lib/mcpState: labels, tones, and the active and attention sets.SessionResources.mcpServers)in a third section, with attention states first.
mcp.setSessionOverride), and Reconnect. Anextension-registered server can't be disabled per chat.
Changes
apps/web/src/lib/mcpState.ts;apps/web/src/store/mcp.ts, with the fold and its guards;apps/web/src/store/selectMcpServers.ts:selectMcpRead,selectMcpWorkspaceStarting;apps/web/src/transport/mcp.ts: the read path andwatchMcpWorkspace;mcp.statussubscription inwireTransport.ts.appStore.ts:mcpByWorkspace,mcpRevision,installMcpList,applyMcpStatus, and cleanup onchat delete, workspace removal and reconnect.
selectors.ts:selectSupportsMcp;orderMcpResources;selectChatResourceGroups(mcpServers,mcpActiveCount), gated on host support.chat/resources/mcpRow.tsx, plus the inspector section and the trigger'sworkingprop;useChatResourcesgainssetMcpEnabled/reconnectMcp;ChatViewwatchesmcp.listwhile the inspector shows MCP rows.UI-TERMINOLOGY.md.Notes for reviewers:
mcp.listanswer that theslice keeps (servers, file errors, handled elsewhere) is what Settings reads in feat: manage MCP servers in Settings #694.
(
mcpSessions.ts, one line + its test and spec).workingprop, so an idleconnected server doesn't animate the header.
resources.test.tsx's import-boundary regex allows.transportproperty access (mcpRowreadsserver.transport).e2e/mcp-settings.spec.ts(it adds the server throughthe Settings form).
/mcp login <name>, and arepository-defined server can't be approved in the app; its row shows the state without an action.
packages/contracts/SPEC.mdandpackages/server/src/agent/SPEC.mdonlyname the new "Disable in this chat" action.
Screenshots
Captured with the e2e harness's hermetic fixture project, 1440×900 at 2×, dark theme; the same throwaway scenario ran on the base PR's tree (before) and on this PR's tree (after).
Chat header with one connected MCP server
Resources inspector
Related issues
No tracked issue. This is part of the MCP support stack (milestone 1); review and merge in order:
Base: #692, so this diff shows only this layer. The branches remain stacked for merge order; checks on the current head are listed by GitHub.
Review hardening (2026-10-12)
Rebased onto
mainat9d6ad0b2, preserving Extensions Settings/reload integration. MCP uses protocol 83; the extension catalog retains 82. Existing MCP product policy and pi engine ownership are unchanged.Latest verification
These results supersede the earlier counts/environment limitations below. The latest combined stack tree was compared byte-for-byte with the locally verified canonical tree; each restacked layer also received focused tests and server/web typechecks.
check:deps, boundaries, seams, spec-surface, compiler, lint) and typecheck → green; all 20 packages, including desktop. Compiler baseline was not relaxed.bun run test, with isolated HOME/data/agent directories and no ambient provider credentials → all 20 package tasks plus root scripts passed. After the last UI-only preset correction, all 1,831 frontendsrctests were rerun successfully; other package inputs were unchanged.2451693b) complete no-agent browser suite → 552 passed, all four isolated shards, using the repository’s standard CI retry configuration. Earlier local repeats exposed the unchanged touch-momentum flake, reproduced on cleanmain3/8 times; no scroll code/assertion was changed or skipped. The final suite includes the preset opt-in recovery and JSON partial-add regressions.bun apps/cli/scripts/build-binary.ts) +bun run smoke:binary→ passed, including the shared MCP artifact probe; vanilla-pi package parity passed under Node 22.19.0.Stack status (2026-10-13): rebased onto
mainbf4da661on top of #723 (pi 1.2.0), which fixes the vanilla-pi parity gate broken by thepi-codemode1.2.0 release. #723 merges first; this stack then rebases to drop that commit. The branches remain stacked in the originalorder and merge one at a time through the merge queue.
Pi 1.2.0 (2026-10-13)
Every pi adaptation in this layer was re-checked against the installed 1.2.0 package (see
pi-compatibility.mdin #695): the publicMCP exports, loader/writer code, shutdown ordering and startup dispatch are unchanged, so nothing is removed. Pi 1.2 widens
structuredContentto any JSON value and stops listing resources on connect (connected · N tools · resources); the status parser nowcounts tools in that dotted wording (it previously read 0 for it) and both changes have fixtures.
Testing
bf4da661: fast gates +bun run typecheck20/20; isolatedbun run test20/20 packages;bun run check:pi-packagesOK (fresh npm install of pi 1.2.0 under Node 22.19);bun run e2e551 passed + the known touch-momentumflaky (passed on retry);
build-binary+smoke:binarypassed; focused liveagent/queue/chat-resources/tool-cards/subagentsspecs 11 passed; independent review of the upgrade and the new stack commits → no findings.
On this PR's tree:
bunx turbo run typecheck --filter='!@thinkrail/desktop'→ 19/19bun test packages/server packages/pi-delegation packages/pi-subagents packages/pi-background-commands packages/pi-todos packages/pi-dag packages/pi-thinkrail-workflow packages/contracts packages/shared packages/artifact-tests→ 2001 pass, 10 skip, 0 failcd apps/web && bun test→ 1596 passbun test ./scripts/→ 91 pass;bunx turbo run test --continuefor every other package (desktop excluded) → 17/17 tasksbun run lint→ clean, no warnings;check:deps,check:boundaries,check:seams,check:spec-surface→ OKbun run e2e→ all 8 shards passed (491 tests)bun run build:binary && bun run smoke:binary→ smoke OKDesktop:
@thinkrail/desktop's typecheck could not run as configured on this machine. Itselectrobun preparestep waits on a shared cache lock that another process holds. Run withoutprepare,cd apps/desktop && tsc --noEmitreports the same 18 electrobun-declaration errors (TS7016/TS7006/TS7031) as onorigin/mainand none from this change. Itsbun testpasses (123 pass, 1 skip, as onorigin/main). This change touches no desktop file.Checklist
bun run lint,bun run typecheck,bun run testbun run e2e, orbun run e2e:fullwhen touching agent behavior)SPEC.md/ top-level specs updated to reflect any boundary, contract, or behavior change