Skip to content

First response in a new session blocks up to 10s on MCP server startup (since 0.99.1) #10212

Closed

Description

@fyeeme

What happened?

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

  1. pi or /new start a new session
  2. send msg and wait for response
  3. first response will take 8-10s ,and later response is normal

-- env
os: 27.0.1 (26A434)
chip: Apple M1 Pro

Expected behavior

  1. first response should be normal before 0.99.1

Version

0.99.1

Activity

  1. github-actions commented on Sep 30, 2026

    @github-actions
    Contributor

    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.

    See CONTRIBUTING.md.

  2. added
    untriagedThis issue has been auto closed and has not been triaged
    on Sep 30, 2026
  3. fyeeme commented on Sep 30, 2026

    @fyeeme
    Author

    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:

    • 5 stdio servers spawned via npx -y <pkg>@latest (npm registry check + cold start each)
    • 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) 0.04s
    Same config on 2b0a123 (pre-MCP, 09-26) 1.5–2.7s

    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.

    This comment is AI-generated by pi.

  4. fyeeme commented on Sep 30, 2026

    @fyeeme
    Author
  5. 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
  6. removed
    untriagedThis issue has been auto closed and has not been triaged
    on Sep 30, 2026
  7. mitsuhiko commented on Sep 30, 2026

    @mitsuhiko
    Member

    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.

  8. fyeeme commented on Sep 30, 2026

    @fyeeme
    Author

    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

  9. mitsuhiko commented on Sep 30, 2026

    @mitsuhiko
    Member

    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).

    This comment is AI-generated by /wr

  10. added a commit that references this issue on Sep 30, 2026
    e029c3e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions