Skip to main content

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 binary
  • client_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) -> dict
  • on_startup: Optional warmup function
  • on_shutdown: Optional cleanup function

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_subprocess_pool-0.1.0.tar.gz (7.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_subprocess_pool-0.1.0-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

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

Hashes for mcp_subprocess_pool-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7a4b227df8ad02c864ead1dd557923d2ac354e7d3f7ebfd10028c856fa62e2ae
MD5 c3129bf98958997522487eaf379068fe
BLAKE2b-256 d3ffc48efbfef6d2a0e1b28e96de47eef6d2c96f042e8b088b5453336e3ae26e

See more details on using hashes here.

File details

Details for the file mcp_subprocess_pool-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for mcp_subprocess_pool-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a5b176822f54a99afbae7cda8777c91753b2c7a8acefd7d9b4997807b199b3a6
MD5 c27cb3ac990c4ecee5857a76cf8f6e51
BLAKE2b-256 a323318a89344ffcd2fda337302f1edb79173e1903e8a7a83ab1a2783d224f78

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page