One host for all your MCP servers.
Every MCP client — Claude Code, Claude Desktop, Cursor — spawns its own copy of every server you've configured, per window. Dozens of invisible processes, gigabytes of RAM, no way to see any of it.
mcpd is a single daemon that owns your servers instead:
- One shared instance per server, across every client and window
- Lazy start — servers spawn on first call, stop after 5 idle minutes
- Visibility — live dashboard and
mcpd status: state, memory, calls, last used - Zero dependencies — plain Node 20+
$ mcpd status
daemon pid 75164 · port 11431 · 6 servers
filesystem running pid 75186 · 74.4MB calls 1 last used 51s ago
memory running pid 75272 · 73.0MB calls 6 last used 3s ago
sequential-thinking idle calls 0 last used never
github running pid 75190 · 67.7MB calls 1 last used 17s ago
total server memory: 460.0MB
Bonus: sessions share server state — store a fact in the memory server from one Claude session, recall it from another.
$ git clone https://github.com/milind-soni/mcpd && cd mcpd && npm link
$ mcpd import claude-code # or claude-desktop / cursor
$ mcpd startDashboard: http://127.0.0.1:11431/
Point your clients at mcpd instead of spawning servers:
Add a server:
$ mcpd add github -- npx -y @modelcontextprotocol/server-githubClaude Code ──┐
Cursor ───────┼── HTTP ──► mcpd daemon ──┬── filesystem (shared)
more windows ─┘ :11431 ├── github (shared)
└── memory (shared)
mcpd speaks streamable HTTP to clients and stdio to the servers it supervises. Each server's initialize handshake happens once; every client's handshake is answered from cache, and requests are forwarded with remapped ids. To each client it looks like a private server.
mcpd supervises any command — including MCP servers compiled to native binaries with scriptc.
examples/sequential-thinking-native is Anthropic's official sequential-thinking server ported to 259 lines of plain TypeScript and compiled statically. Tool outputs byte-identical to the original:
| native (scriptc) | official (node) | |
|---|---|---|
| size on disk | 554KB | ~102MB (package + Node) |
| startup | 1.9ms | 86ms |
| memory | 1.6MB | 79MB |
45 copies of the binary use less RAM than one copy of the Node original.
mcpd start [--foreground] start the daemon
mcpd stop stop the daemon and all servers
mcpd status servers, memory, calls, last used
mcpd add <name> -- <cmd> register a server
mcpd remove <name> unregister a server
mcpd url <name> print a server's HTTP endpoint
mcpd connect <name> stdio bridge for legacy clients
mcpd import <source> claude-code | claude-desktop | cursor
Config: ~/.mcpd/config.json · Logs: ~/.mcpd/mcpd.log
- Server-initiated messages (sampling, notifications) are not routed — tools/resources/prompts work fine
- Config changes need a restart
- Shared-by-default; per-server
isolatemode is planned - macOS/Linux
$ npm testMIT © Milind Soni