1# Chapter 25: mcp, how a client reaches the window in milliseconds 2 3An MCP client such as Claude Code starts its servers when it starts, and 4gives each one 30 seconds to answer `initialize`. This repository's 5`../../.mcp.json` names one server, `jev`, and its command is 6`tools/mcp/launch.sh`. Everything in this folder exists to make that 7command answer fast, every time. 8 9It used to be `nix develop -c buck2 run //apps/native:native -- mcp`. On a 10cold cache that is a build of minutes; the client gave up after 30 seconds, 11and the connection failed at startup twice (2026-09-20 and 2026-09-21). 12 13So now there are two steps, and only the fast one is on the client's clock: 14 15```mermaid 16sequenceDiagram 17 participant You 18 participant I as install.sh 19 participant C as MCP client 20 participant L as launch.sh 21 participant P as run/bin/native mcp 22 You->>I: after a build you want the proxy to be 23 I->>I: build //apps/native, copy it to run/bin/native, root its store paths 24 C->>L: start the "jev" server 25 L->>P: exec (bash builtins only, no build, no devshell) 26 P-->>C: initialize answered in milliseconds 27``` 28 29If there is no copy yet, `launch.sh` answers `initialize` with a JSON-RPC 30error saying to run `install.sh`, which the client shows, and exits. 31 32> **Aside: why a copy that may be old is fine.** The proxy (chapter 8) is a 33> pass-through. It asks the window for its tool list and forwards calls by 34> name, so the tools a client sees are the running *window's*, whatever 35> build the proxy came from, and it speaks to the window over MCP's own 36> streamable HTTP, which does not change with our code. A proxy several 37> commits older than the window is normal and correct. Re-run `install.sh` 38> only when `packages/mcp/src/proxy.rs` itself changes, then reconnect the 39> client (`/mcp` in Claude Code), since the running proxy keeps its own 40> copy. 41 42> **Try it.** 43> 44> tools/mcp/install.sh 45> tools/mcp/test.sh 46> 47> The second times `initialize` and `tools/list` through `launch.sh` in a 48> bare environment, with and without a binary. 49 50## For the people who maintain it 51 52### In this folder 53 54| Path | What | 55| --- | --- | 56| [install.sh](install.sh) | Builds `//apps/native:native` and copies it to `run/bin/native`, with the devshell's library path in `run/bin/native.env` and every store path it links rooted under `run/bin/roots/`. Re-execs itself inside `nix develop` if it is not already. | 57| [launch.sh](launch.sh) | What `.mcp.json` runs. Execs the copy; if there is none, answers `initialize` with a JSON-RPC error saying to run `install.sh`, and exits. Bash builtins only, so it runs in a bare environment. | 58| [test.sh](test.sh) | Times `initialize` and `tools/list` through `launch.sh` in a bare environment, with and without a binary, against a scratch copy of the layout. | 59 60← Previous: [Chapter 24, tools/](../) · Up: [tools](../) · Next: [Chapter 26, watch/](../watch/) →