Repository navigation
feat(server): run the MCP servers from mcp.json in chats on pi's built-in engine - #691
Merged
Merged
Conversation
This was referenced Oct 9, 2026
danyaberezun
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 9, 2026 06:58
0c6ea0f to
f1577d7
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/3-mcp-engine
branch
from
October 9, 2026 10:32
f1577d7 to
331320b
Compare
danyaberezun
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 9, 2026 12:12
331320b to
6bc56f9
Compare
danyaberezun
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 9, 2026 12:24
6bc56f9 to
7d16eaf
Compare
danyaberezun
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 9, 2026 12:43
7d16eaf to
521dc15
Compare
danyaberezun
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 9, 2026 13:17
521dc15 to
627cbed
Compare
danyaberezun
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 9, 2026 13:39
627cbed to
2240947
Compare
danyaberezun
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 11, 2026 07:13
2240947 to
a3974a7
Compare
Rinat S (rsolmano)
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 12, 2026 11:25
a3974a7 to
a3f26d1
Compare
Collaborator
|
Rebased the stack onto current
The |
Rinat S (rsolmano)
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 12, 2026 17:58
da8850e to
6c7afbf
Compare
Rinat S (rsolmano)
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 13, 2026 08:24
6c7afbf to
940b3f2
Compare
This was referenced Oct 13, 2026
Rinat S (rsolmano)
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 13, 2026 10:59
940b3f2 to
9d1b2dd
Compare
5 tasks done
🌐 Website previewPreview retired when this pull request closed. |
…t-in engine - Parent sessions load pi's mcp and tool-search built-ins as replaceable descriptors, with a host loader at parity with pi's; -builtin:mcp and an extension owning /mcp turn the built-in off; subagents get no engine. - Repository-defined servers load only in a trusted project and at their approved fingerprint (Project.mcpApprovals); any edit lapses approval. Approvals are read here; the next changes write them. - Tools not marked read-only ask Deny / Allow once / Allow in this chat, fail closed, and an accepted steer cancels the pending confirmation. - pi's MCP shutdown runs first in the bounded session_shutdown. - MCP results carry a durable, base64-free summary in details.thinkrail.
blocks copied every URI, name and MIME string of every returned content item unbounded. Blocks are now kept in order until the budget is spent (omittedBlocks counts the rest) and structuredContent gets what remains.
Rinat S (rsolmano)
force-pushed
the
mcp-stack/3-mcp-engine
branch
from
October 13, 2026 11:56
9d1b2dd to
b8ef58a
Compare
Rinat S (rsolmano)
dismissed
jetbrains-air[bot]’s stale review
October 13, 2026 12:26
Pushed back on the single finding (see the thread): #693 in this stack already makes ProjectTrustSummary.mcpServers optional and derives a missing count as zero, the layers merge in order, and UI and host ship together, so no protocol capability is needed.
Rinat S (rsolmano)
approved these changes
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
pi ships an MCP engine, but ThinkRail never activated it: pi's SDK leaves built-in extensions to the
embedder, so the
mcp.jsonservers a user already has for pi are not available in ThinkRail chats.Turning pi's built-in on as-is would be unsafe for an IDE that opens arbitrary repositories:
.pi/mcp.jsonwould start local commandsas soon as a chat opens.
session_shutdownhandler, and aslow handler of another extension delays it.
Approach
mcpbuilt-in as a replaceable built-indescriptor (
createMcpEngine), together withtool-search.mcp.jsonloader, pinned byparity tests against pi's error messages.
/mcpreplaces the built-in instead of runningalongside it.
-builtin:mcpin pi settings turns it off, as in pi. This is resolved by namethrough feat: upgrade pi to 1.1.0, gate session reloads and teardown, import the login env #689's loader.
Agenttool's description says so, so the parent calls MCPtools itself and passes the results in the task.
~/.pi/agent/mcp.json) run as configured. The project record can disablea user-level server or change its exposure, and it never writes the user's file.
.pi/mcp.jsonloads only when the project is trusted (feat: pass each project's trust to pi and name what trusting it loads #690)and the entry is approved at its exact fingerprint (
Project.mcpApprovals, covering the wholeentry). Any edit lapses the approval.
them.
readOnlyHint) runs unasked.this chat.
pending dialog.
tool_searchis activated when an extension registers a server, so deferred tools stayreachable.
session_shutdownhandlers and runs them first infeat: upgrade pi to 1.1.0, gate session reloads and teardown, import the login env #689's bounded
session_shutdown. Servers stop within the budget even when another extension's handlernever settles. That also holds after a session whose preparation failed once pi had started its
servers.
structuredContentfrom finalized messages, and images makeresults large. A
tool_resulthandler therefore writesdetails.thinkrail: a bounded (64 KiBstructured content), base64-free summary of the content blocks. It stays the same after a reload and
on another client.
Changes
packages/server/src/agent/mcp/(new sub-module with its ownSPEC.md), with tests and a stdiofixture:
config.ts: pi-parity loader, host exposure normalization, fingerprints, approval gating;engine.ts: the built-in descriptors and shutdown capture;sessionHost.ts: the per-session host extension, with confirm and the summary writer;results.ts.agentSessionManager.ts:setMcpPolicyResolver);emitSessionShutdownruns the engine's shutdown first.mcpPolicyOf(project)(inagent/mcp/config.ts) wired as the policy resolver inhost/server.ts.Project.mcpApprovals/Project.mcpOverrides,ProjectTrustSummary.mcpServers;McpResultSummary,McpExposure/McpProjectOverride.projectTrust.tscounts.pi/mcp.jsonentries, and the web trust notice namesthem.
Agentdescription says subagents cannot call MCP tools.goal-and-requirements.md("Trust is explicit") andpackages/shared/SPEC.md: the loginenvironment import now also names
mcp.json${VAR}references and stdio MCP servers.Notes for reviewers:
trust alone does not start a repository's MCP servers.
details.thinkrailhas no reader until feat(web): render MCP tool calls, resources and tool_search as cards #695's cards; it lands here so every stored MCP result carries it.Lifecycle bullets under it.
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).
Welcome trust notice — repository with one
.pi/mcp.jsonserverRelated issues
No tracked issue. This is part of the MCP support stack (milestone 1); review and merge in order:
Base: #690, 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.session_startor registration event.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→ 1943 pass, 10 skip, 0 failbun test packages/server/src/agent/mcpEngine.test.ts packages/server/src/agent/mcpConfirm.test.ts, run twice → 15 pass each time. They use a real stdio server, a faux provider and pi's real engine, and cover:-builtin:mcp, replacement by an installed extension, and subagents;cd apps/web && bun test→ 1580 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 OKFocused live specs (real Central,
bun run e2e:full <files>):agent,subagentsandqueue→ 4 passed. No live spec drives an MCP server; the engine tests above run pi's real engine against a stdio server. The completebun run e2e:fullsuite was not run.The complete
bun run e2e:fullsuite ran on the top of the stack (#695), which contains this change: no-agent 8/8 shards; agent 53 passed, 2 failed —error-turn.live.spec.ts:35andvisualize.live.spec.ts:62, which fail onorigin/maintoo.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