You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
First response in a new session blocks up to 10s on MCP server startup (since 0.99.1) #10212
In pi version 0.991, the first response in a new session takes significantly longer to arrive — about 8–10 seconds. Subsequent responses are normal, with no noticeable delay. Removing all extensions has no effect on the latency at all. Previous versions did not have this issue.
Steps to reproduce
pi or /new start a new session
send msg and wait for response
first response will take 8-10s ,and later response is normal
This issue was auto-closed. All issues from new contributors are auto-closed by default.
Maintainers review auto-closed issues daily and reopen worthwhile ones. Issues that do not meet the quality bar in CONTRIBUTING.md will not be reopened or receive a reply.
If a maintainer replies lgtmi on one of your issues, your future issues will stay open. If a maintainer replies lgtm, your future issues and PRs will stay open. The command must be at the start of the reply (optionally after one or more @username mentions) or at the end.
I reproduced and root-caused this. The regression comes from 8562bcf (feat(coding-agent): codemode and MCP, the commit that introduced MCP support in 0.99.x). Before it, pi ignored mcp.json entirely; after it, the first prompt blocks on MCP server startup.
Mechanism
In packages/coding-agent/src/extensions/mcp/index.ts:
session_start kicks off MCP runtime loading + connections for all enabled servers in the background (the TUI is ready in <0.3s, so startup feels fast).
before_agent_start — fired when you submit the first prompt — does await Promise.race([startup, timeout(DEFAULT_STARTUP_WAIT_MS)]) with DEFAULT_STARTUP_WAIT_MS = 10_000 (line 79). So the first response is delayed by however much of the 10s budget the MCP connections still need.
My mcp.json has 10 servers, and their combined connect time exceeds the 10s cap, so every new session pays the full timeout:
3 MySQL MCP servers that enumerate the whole schema as resources (8334 / 2189 / 1001 resources)
3 HTTP servers
After the timeout the request finally goes out, and /mcp shows "MCP servers are still connecting" plus all servers eventually connected. The waitedForStartup flag is why only the first response is slow.
Reproduction (network removed from the equation)
Pointing pi at a local mock provider (instant responses) with my real mcp.json, interactive mode on main (1b34779):
Scenario
Enter → first response
Submit immediately after TUI ready
10.17s (= 10s MCP wait + request)
Same session, submit after MCP finished connecting (~60s)
Request body size is also worth noting: 52.8KB with MCP tools declared (serena's 22 direct-exposure tools etc.) vs 27KB without — larger prefill adds first-token latency on top.
A secondary contributor is 30a1d18 (defaultTools+name/-name): it fixed ["+codemode"] previously resolving to zero tool declarations (13KB request). The fix is correct, but it restored the full tool set, making the request bigger and the first token slower. That's a fix, not a bug — the dominant factor is the MCP startup wait.
Suggestions
Don't let the first prompt eat the full 10s: connect lazily (deferred servers on first use), shorten the default cap, or only wait for servers whose tools are actually declared to the model.
Surface remaining MCP connect time as part of the "waiting" indicator so it doesn't look like the model is slow.
Workaround for now: trim mcp.json (disable unused servers, drop @latest from stdio specs) or set autoEnableCodemode: false if codemode isn't needed.
changed the title [-]Regression: first response in a new session takes ~8-10s in v0.991 (not extension-related)[/-][+]First response in a new session blocks up to 10s on MCP server startup (since 0.99.1)[/+]on Sep 30, 2026
I'm not sure what I should do there. If you have 10 MCPs configured, then they will be loaded. What is the ask here? We're already deferring to the last moment possible I think.
//EDIT: I guess we can defer the startup with codemode until the tools are requested.
In fact, I was using pi-mcp-adapter before, and this problem only occurred after I switched to codemode + the built-in mcp. Before that, it was the only one that was not loaded by default, and only exposed tools. It would tell the startup process which mcp it needed.
The problem is that when this mechanism encounters a long MCP (I have three databases here, so it might take a little longer), the user gets stuck without knowing why, and there are no prompts.
Could we also enable lazy loading by default, instead of waiting for all MCP connections before responding to the user when it's uncertain whether it will be used?
Additionally, when I tried disabling the built-in MCP using pi-mcp-adapter, it caused a freeze. I haven't investigated the specific root cause of the problem in this scenario, so I'm still waiting for a better solution. @mitsuhiko
The 10s wait comes from pi connecting every server in mcp.json at session start and the first prompt waiting for all of them. Before 0.99.1 core pi did not read ~/.pi/agent/mcp.json; pi-mcp-adapter used to read that file and connected lazily, which is likely why this looks like a regression.
First step is on main: the codemode description no longer depends on live server data. MCP servers with the default codemode exposure are listed by name and an optional description from mcp.json, without tool counts, tool declarations, or server instructions. Scripts find tools with searchTools() and read instructions with describeNamespace(). codemode-deferred is now an alias for codemode.
Next step is connecting servers on first use, so the first prompt only waits for servers whose tools are declared directly (direct).
Activity
github-actions commentedon Sep 30, 2026
This issue was auto-closed. All issues from new contributors are auto-closed by default.
Maintainers review auto-closed issues daily and reopen worthwhile ones. Issues that do not meet the quality bar in CONTRIBUTING.md will not be reopened or receive a reply.
If a maintainer replies
lgtmion one of your issues, your future issues will stay open. If a maintainer replieslgtm, your future issues and PRs will stay open. The command must be at the start of the reply (optionally after one or more@usernamementions) or at the end.See CONTRIBUTING.md.
fyeeme commentedon Sep 30, 2026
I reproduced and root-caused this. The regression comes from 8562bcf (
feat(coding-agent): codemode and MCP, the commit that introduced MCP support in 0.99.x). Before it, pi ignoredmcp.jsonentirely; after it, the first prompt blocks on MCP server startup.Mechanism
In
packages/coding-agent/src/extensions/mcp/index.ts:session_startkicks off MCP runtime loading + connections for all enabled servers in the background (the TUI is ready in <0.3s, so startup feels fast).before_agent_start— fired when you submit the first prompt — doesawait Promise.race([startup, timeout(DEFAULT_STARTUP_WAIT_MS)])withDEFAULT_STARTUP_WAIT_MS = 10_000(line 79). So the first response is delayed by however much of the 10s budget the MCP connections still need.My
mcp.jsonhas 10 servers, and their combined connect time exceeds the 10s cap, so every new session pays the full timeout:npx -y <pkg>@latest(npm registry check + cold start each)After the timeout the request finally goes out, and
/mcpshows "MCP servers are still connecting" plus all servers eventuallyconnected. ThewaitedForStartupflag is why only the first response is slow.Reproduction (network removed from the equation)
Pointing pi at a local mock provider (instant responses) with my real
mcp.json, interactive mode onmain(1b34779):Request body size is also worth noting: 52.8KB with MCP tools declared (serena's 22
direct-exposure tools etc.) vs 27KB without — larger prefill adds first-token latency on top.A secondary contributor is 30a1d18 (
defaultTools+name/-name): it fixed["+codemode"]previously resolving to zero tool declarations (13KB request). The fix is correct, but it restored the full tool set, making the request bigger and the first token slower. That's a fix, not a bug — the dominant factor is the MCP startup wait.Suggestions
Workaround for now: trim
mcp.json(disable unused servers, drop@latestfrom stdio specs) or setautoEnableCodemode: falseif codemode isn't needed.This comment is AI-generated by pi.
fyeeme commentedon Sep 30, 2026
@mitsuhiko
[-]Regression: first response in a new session takes ~8-10s in v0.991 (not extension-related)[/-][+]First response in a new session blocks up to 10s on MCP server startup (since 0.99.1)[/+]mitsuhiko commentedon Sep 30, 2026
I'm not sure what I should do there. If you have 10 MCPs configured, then they will be loaded. What is the ask here? We're already deferring to the last moment possible I think.
//EDIT: I guess we can defer the startup with codemode until the tools are requested.
fyeeme commentedon Sep 30, 2026
In fact, I was using pi-mcp-adapter before, and this problem only occurred after I switched to codemode + the built-in mcp. Before that, it was the only one that was not loaded by default, and only exposed tools. It would tell the startup process which mcp it needed.
The problem is that when this mechanism encounters a long MCP (I have three databases here, so it might take a little longer), the user gets stuck without knowing why, and there are no prompts.
Could we also enable lazy loading by default, instead of waiting for all MCP connections before responding to the user when it's uncertain whether it will be used?
Additionally, when I tried disabling the built-in MCP using pi-mcp-adapter, it caused a freeze. I haven't investigated the specific root cause of the problem in this scenario, so I'm still waiting for a better solution. @mitsuhiko
feat(coding-agent): list MCP servers instead of their tools in codemode
mitsuhiko commentedon Sep 30, 2026
The 10s wait comes from pi connecting every server in
mcp.jsonat session start and the first prompt waiting for all of them. Before 0.99.1 core pi did not read~/.pi/agent/mcp.json;pi-mcp-adapterused to read that file and connected lazily, which is likely why this looks like a regression.First step is on
main: the codemode description no longer depends on live server data. MCP servers with the defaultcodemodeexposure are listed by name and an optionaldescriptionfrommcp.json, without tool counts, tool declarations, or server instructions. Scripts find tools withsearchTools()and read instructions withdescribeNamespace().codemode-deferredis now an alias forcodemode.Next step is connecting servers on first use, so the first prompt only waits for servers whose tools are declared directly (
direct).This comment is AI-generated by
/wrfeat(coding-agent): stop waiting for MCP servers on the first prompt
feat(coding-agent): list MCP servers instead of their tools in codemode
feat(coding-agent): stop waiting for MCP servers on the first prompt
fix(deps): update dependency @earendil-works/pi-coding-agent to v1 (#…
feat(coding-agent): list MCP servers instead of their tools in codemode
feat(coding-agent): stop waiting for MCP servers on the first prompt