Persistent subprocess connection pool for MCP servers — 10-40x faster tool calls
Project description
mcp-subprocess-pool
Persistent subprocess connection pool for MCP servers. 10-40x faster tool calls.
Instead of spawning a fresh MCP server process per tool call (~200-500ms overhead from process spawn + JSON-RPC handshake), this pool keeps a single process alive and reuses it (~5-20ms per call).
Works with any MCP server binary that speaks JSON-RPC over stdio.
Built by NexVigilant | mcp.nexvigilant.com
Installation
pip install mcp-subprocess-pool
Quick Start
Pool (persistent MCP server connection)
from mcp_subprocess_pool import McpPool
# Connect to any MCP server binary
pool = McpPool("/path/to/your-mcp-server")
# First call: ~60ms (spawn + handshake)
result = pool.call("your_tool", {"arg": "value"})
# Subsequent calls: ~5ms (reuses connection)
result = pool.call("another_tool", {"arg": "value"})
pool.close()
Context manager
with McpPool("/path/to/mcp-server") as pool:
result = pool.call("tool_name", {"key": "value"})
Unified dispatcher
Some MCP servers expose a single mega-tool that routes internally:
pool = McpPool(
"/path/to/mcp-server",
dispatcher="nexcore", # All calls route through this tool
)
# Internally sends: tools/call(name="nexcore", arguments={command="levenshtein", params={...}})
result = pool.call("levenshtein", {"source": "cat", "target": "bat"})
Daemon (persistent stdin/stdout dispatcher)
For parent processes (Rust, Go, etc.) that need to call Python handlers without per-call Python startup:
from mcp_subprocess_pool import McpDaemon
def handle(tool_name: str, arguments: dict) -> dict:
# Your routing logic here
return {"result": "ok"}
daemon = McpDaemon(
handler=handle,
on_startup=lambda: print("Warming up...", file=sys.stderr),
)
daemon.run() # Reads JSON lines from stdin until shutdown
Protocol:
{"id": 1, "tool": "my_tool", "arguments": {"key": "value"}}
Response:
{"id": 1, "result": "ok"}
Shutdown:
{"method": "shutdown"}
Performance
Measured on NexVigilant Station (228 configs, 1,954 tools):
| Mode | Latency | vs Subprocess |
|---|---|---|
| Subprocess per call | 77ms avg | baseline |
| Pool (warm) | 5ms avg | 15x faster |
| Daemon (warm) | 6ms avg | 13x faster |
| Pool cold start | 60ms | one-time cost |
Thread Safety
McpPool is thread-safe via internal threading.Lock. Multiple threads can call pool.call() concurrently — calls are serialized internally.
Auto-respawns if the MCP server process dies.
API
McpPool(binary, client_name, client_version, request_timeout, protocol_version, dispatcher)
binary: Path to MCP server binaryclient_name: Name in MCP handshake (default: "mcp-subprocess-pool")client_version: Version in MCP handshake (default: "0.1.0")request_timeout: Seconds before timeout (default: 25.0)protocol_version: MCP protocol version (default: "2024-11-05")dispatcher: Unified dispatch tool name, or None for direct calls
McpDaemon(handler, on_startup, on_shutdown)
handler:(tool_name: str, arguments: dict) -> dicton_startup: Optional warmup functionon_shutdown: Optional cleanup function
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_subprocess_pool-0.1.0.tar.gz.
File metadata
- Download URL: mcp_subprocess_pool-0.1.0.tar.gz
- Upload date:
- Size: 7.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a4b227df8ad02c864ead1dd557923d2ac354e7d3f7ebfd10028c856fa62e2ae
|
|
| MD5 |
c3129bf98958997522487eaf379068fe
|
|
| BLAKE2b-256 |
d3ffc48efbfef6d2a0e1b28e96de47eef6d2c96f042e8b088b5453336e3ae26e
|
File details
Details for the file mcp_subprocess_pool-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcp_subprocess_pool-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5b176822f54a99afbae7cda8777c91753b2c7a8acefd7d9b4997807b199b3a6
|
|
| MD5 |
c27cb3ac990c4ecee5857a76cf8f6e51
|
|
| BLAKE2b-256 |
a323318a89344ffcd2fda337302f1edb79173e1903e8a7a83ab1a2783d224f78
|