Repository navigation
feat(web): render MCP tool calls, resources and tool_search as cards - #695
Merged
Merged
Conversation
This was referenced Oct 9, 2026
danyaberezun
force-pushed
the
mcp-stack/7-mcp-tool-cards
branch
from
October 9, 2026 06:58
d3013c3 to
26a68e9
Compare
danyaberezun
added this pull request to stack #696
October 9, 2026 07:52
danyaberezun
marked this pull request as ready for review
October 9, 2026 08:01
danyaberezun
requested review from
Olga Lavrichenko (OLavrik),
Rustam Sadykov (SBOne-Kenobi) and
Rinat S (rsolmano)
as code owners
October 9, 2026 08:01
danyaberezun
force-pushed
the
mcp-stack/7-mcp-tool-cards
branch
from
October 9, 2026 10:56
26a68e9 to
d40331f
Compare
danyaberezun
force-pushed
the
mcp-stack/7-mcp-tool-cards
branch
from
October 9, 2026 11:08
d40331f to
b7aa2f4
Compare
danyaberezun
force-pushed
the
mcp-stack/7-mcp-tool-cards
branch
from
October 9, 2026 11:25
b7aa2f4 to
edb6884
Compare
danyaberezun
force-pushed
the
mcp-stack/7-mcp-tool-cards
branch
from
October 9, 2026 11:44
edb6884 to
d2b5494
Compare
danyaberezun
force-pushed
the
mcp-stack/7-mcp-tool-cards
branch
from
October 9, 2026 11:52
d2b5494 to
35c97a0
Compare
Rinat S (rsolmano)
force-pushed
the
mcp-stack/7-mcp-tool-cards
branch
from
October 13, 2026 13:04
3b3def0 to
b5f85b7
Compare
Rinat S (rsolmano)
force-pushed
the
mcp-stack/7-mcp-tool-cards
branch
from
October 13, 2026 13:19
b5f85b7 to
b32aeee
Compare
Rinat S (rsolmano)
force-pushed
the
mcp-stack/7-mcp-tool-cards
branch
from
October 13, 2026 13:26
b32aeee to
b11067c
Compare
Rinat S (rsolmano)
force-pushed
the
mcp-stack/7-mcp-tool-cards
branch
from
October 13, 2026 13:48
b11067c to
5f453cf
Compare
- registerToolRendererPrefix: exact names, then the longest prefix. - MCP cards render from the durable details.thinkrail summary: one image strip, a collapsed JSON tree, Full output through mcp.readOutput, and a Sign in link into Settings › MCP servers. - Resource listing/read and tool_search cards with a raw-text fallback.
…gn in button replaces it Call output and a listing's per-server error keep the server's message but lose the "Run /mcp …" sentence when the in-app action is offered; a standalone render keeps pi's text verbatim.
… Sign in button replaces it
Rinat S (rsolmano)
force-pushed
the
mcp-stack/7-mcp-tool-cards
branch
from
October 13, 2026 14:23
5f453cf to
282006d
Compare
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 13, 2026
2 of 5 tasks
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
MCP calls in the chat fall back to the default tool card:
/mcp login"), which don't apply in ThinkRail.pi names MCP tools per server (
mcp__<server>__<tool>), so an exact-name registration cannot catch them.Approach
registerToolRendererPrefix.name first, then the longest app-local prefix, then the default.
mcp__.details.thinkrailsummary (feat(server): run the MCP servers from mcp.json in chats on pi's built-in engine #691) andpi's own result details (
{ server, tool, fullOutputPath }), so a card looks the same live, after atranscript reload, and on another client.
mcp.readOutput(feat(server): serve MCP server management, status and sign-in to clients #692), which serves onlythe result's recorded output file.
expiredandunavailablehave their own states.Settings › Providers for
auth.provider; the latter keeps the provider identity instead of hiding it. On a host without MCP, or in the plan page's chat, the actions are hidden.list_mcp_resources,list_mcp_resource_templates,read_mcp_resourceandtool_searchget their own cards, with a raw-text fallback for a truncated listing.Changes
pi-compatibility.md: an architecture-design spec directly underarchitecture, linked fromAGENTS.md; it records host adaptations, owning specs, upgrade checks and removal gates, separately from deliberate ThinkRail policy.apps/web/src/chat/toolRegistry.tsx:registerToolRendererPrefixand the single resolver(+ tests).
apps/web/src/chat/tools/mcp/(new sub-module with its ownSPEC.md):mcpResult.ts: parsingdetails.thinkrail, pi's flat result details (server,tool,fullOutputPath) and the content;McpToolCard,McpResourceCards,ToolSearchCard;McpCardParts,McpJsonTree,McpActions;register.ts;ChatActions: gains the optionalreadMcpOutput(toolCallId)/openMcpSettings()pair.ChatViewsupplies it only on an MCP-capable host.McpToolDetailsin contracts is the web's copy of pi's result details formcp__*and the three MCPresource tools (the web app cannot import pi-coding-agent).
that cards exist.
e2e/mcp-tool-cards.spec.ts: seeds historical results and pins:mcp.readOutput, for a recorded file and an expired one;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).
mcp__*call with structured content and an imageStructured content expanded (new in this PR)
Truncated result
Full output (new in this PR)
list_mcp_resourcestool_searchProvider-backed authentication recovery
Same persisted MCP error fixture on this PR's updated base (#694,
693f5e44) and the updated cards. A provider-backed failure now keeps the provider name and opens Settings → Providers, rather than routing to MCP OAuth. Captured through the isolated browser harness without provider credentials.Related issues
No tracked issue. This is part of the MCP support stack (milestone 1); review and merge in order:
Base: #694, 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.pi-compatibility.mdis an architecture-design spec withparent: architecture, linked fromAGENTS.md, with owners, upgrade checks and removal gates. Deliberate host policy is explicitly separate from temporary workarounds.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→ 1680 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 (497 tests)bun run build:binary && bun run smoke:binary→ smoke OK, including the MCP artifact probebun run e2e:full(complete suite, real Central) on this tree: no-agent phase all 8 shards passed (497 tests); agent phase 53 passed and 2 failed, both of which also fail onorigin/main:error-turn.live.spec.ts:35(its bad-model injection only rewrites asession.createthat carries an explicit model, which New Workspace doesn't send by default) andvisualize.live.spec.ts:62(the model doesn't always mark a recommended option: 2 of 4 runs passed onorigin/main, 4 of 5 reruns passed here).Focused live specs on this tree (real Central,
bun run e2e:full <files>):agent,chat-resources,queueandtool-cards→ 9 passed.Desktop:
@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