Shared-daemon MCP gateway that multiplexes many backend servers behind one stable MCP endpoint.
Gatemini is the runtime and binary name. The source repository and release channel live under the PrismGate GitHub project.
Most MCP clients launch one process tree per session. If you configure a few dozen backends, each new terminal or editor session pays the same startup and memory cost again.
Gatemini changes that model:
- One daemon owns the backend connections.
- Lightweight proxy processes bridge each client session over stdio.
- The daemon is reused until it has been idle for the configured timeout.
- Agents discover backend tools through 7 gateway meta-tools instead of receiving every schema up front.
| Capability | What the code does today |
|---|---|
| Shared daemon | Proxy mode connects to a single Unix socket daemon instead of starting backends per session |
| Auto-start and restart | First proxy spawns gatemini serve; gatemini restart drains clients and lets proxies reconnect |
| Progressive discovery | search_tools, list_tools_meta, tool_info, get_required_keys_for_tool, call_tool_chain, register_manual, deregister_manual |
| Multiple backend transports | stdio, streamable-http, and cli-adapter backends in one config |
| Health management | Periodic pinging, failure thresholds, internal circuit-breaker tracking, restart backoff, pending-backend retry |
| Tool cache | Cached namespaced tools load before backends reconnect; cache version is currently 4 |
| TypeScript execution | call_tool_chain fast-paths JSON/simple calls and falls back to the V8 sandbox when needed |
| Secrets | Environment interpolation, .env loading, secretref: resolution, and Bitwarden Secrets Manager integration |
Download a release from GitHub Releases, or build from source:
git clone https://github.com/jonwraymond/prismgate.git
cd prismgate
cargo install --path .The default config path is the platform config directory plus gatemini/config.yaml:
- macOS/Linux:
~/.config/gatemini/config.yaml - Windows:
%APPDATA%\\gatemini\\config.yaml
Minimal example:
log_level: info
daemon:
idle_timeout: 5m
backends:
exa:
command: npx
args: ["-y", "exa-mcp-server"]
env:
EXA_API_KEY: "${EXA_API_KEY}"
github:
transport: streamable-http
url: "https://api.githubcopilot.com/mcp/"
headers:
Authorization: "Bearer ${GITHUB_PAT_TOKEN}"For a fuller example covering secrets, CLI adapters, admin settings, and health tuning, see config/example.yaml.
Example Claude Code configuration:
{
"mcpServers": {
"gatemini": {
"command": "/path/to/gatemini",
"args": ["-c", "/path/to/config.yaml"]
}
}
}gatemini # Proxy mode (default)
gatemini --direct # Single-process direct mode, no daemon or socket
gatemini serve # Run the daemon in the foreground
gatemini status # Read PID/socket state
gatemini stop # Gracefully stop the daemon
gatemini restart # Stop, drain clients, let proxies reconnectThe daemon binds its socket early, before the heavier initialization path completes. That means proxies can connect while the daemon is still loading config, resolving secrets, restoring cache, and starting backends.
Proxy mode is not just a raw byte pipe. It also:
- acquires a flock lock to avoid duplicate daemon startup
- reconnects with backoff if the daemon disappears
- caches the MCP initialize request and initialized notification
- replays that cached handshake when reconnecting
Backend tools are not exposed as first-class MCP tools. Instead, Gatemini exposes a small discovery and execution surface:
| Meta-tool | Purpose |
|---|---|
search_tools |
Search live registry entries by task description |
list_tools_meta |
Page through registered tool names |
tool_info |
Inspect one tool in brief or full detail |
get_required_keys_for_tool |
Show required env keys for the owning backend |
call_tool_chain |
Execute JSON, simple TS, or full sandboxed TS |
register_manual |
Register a dynamic backend at runtime |
deregister_manual |
Remove a dynamic backend |
Resources and prompts round out the MCP surface:
- Static resources:
gatemini://overview,gatemini://backends,gatemini://tools,gatemini://recent - Resource templates:
gatemini://tool/{tool_name},gatemini://backend/{backend_name},gatemini://backend/{backend_name}/tools,gatemini://recent/{limit} - Prompts:
discover,find_tool,backend_status
Backend state exposed publicly is limited to:
StartingHealthyUnhealthyStopped
Circuit-breaker timing is tracked internally by the health checker and surfaced through those states rather than a separate public enum.
Current default health settings come from src/config.rs:
- interval:
30s - timeout:
5s - failure threshold:
3 - max restarts per window:
5 - restart window:
60s - restart backoff:
1sinitial,30smax - restart timeout:
30s - recovery multiplier:
3 - drain timeout:
10s
Config loading is intentionally simple and code-backed:
- Load
.envfiles once. - Read YAML.
- Expand environment variables with
shellexpand::env. - Deserialize config.
- Resolve
secretref:values. - Validate required fields and supported transport combinations.
.env files are loaded from:
~/.env- the standard Gatemini config directory, for example
~/.config/gatemini/.env - the config file's sibling directory
Supported secret modes:
- direct environment references such as
${EXA_API_KEY} secretref:bws:...with environment fallback when BWS is disabled- Bitwarden Secrets Manager when
secrets.providers.bws.enabled: true
The repo docs were rewritten against the current Rust implementation and diagrams:
- Docs index
- Architecture
- Codebase map
- Tool discovery
- Backend management
- Secrets and config
- Resources and prompts
- Token efficiency
- Telemetry strategy
- Sandbox
See CONTRIBUTING.md for development setup, docs build commands, and review expectations.
Licensed under the Apache License, Version 2.0.