Warmplane is the local control plane that keeps MCP sessions warm.
It runs multiple upstream MCP servers behind one local process, keeps those sessions persistent, and exposes a compact interaction surface for tools/resources/prompts. The goal is concrete and measurable: reduce startup latency, reduce payload size, and keep behavior deterministic.
Most agent stacks overpay in tokens and latency by eagerly surfacing large tool catalogs and detailed schemas that are never used.
Warmplane shifts that model to lazy, compact interaction:
- Discover compact indexes first.
- Fetch detail only when needed.
- Execute through normalized envelopes.
This improves:
- token efficiency
- time-to-first-useful-tool-call
- cross-client consistency
- observability and policy control
One runtime, three access modes:
- HTTP facade (
/v1/...) - CLI facade commands
- MCP facade server mode (
mcp-server) for MCP-native clients
All three modes share the same backend state, aliases, policy checks, and timeout behavior.
- list: compact capability index
- describe: on-demand detail for one capability
- call: normalized execution envelope
- list: compact resource index
- read: normalized read envelope
- list: compact prompt index
- get: normalized prompt rendering envelope
cargo install --path .cargo install warmplane is not available yet because the crate has not been published to crates.io.
Validate and lint configuration before startup:
warmplane validate-config --config mcp_servers.jsonExample success output:
{"ok":true,"config":"mcp_servers.json","servers":3}Create mcp_servers.json:
{
"port": 9090,
"toolTimeoutMs": 15000,
"capabilityAliases": {
"sqlite.read_query": "db.query"
},
"resourceAliases": {
"filesystem.file:///tmp/readme.txt": "fs.readme"
},
"promptAliases": {
"github.code_review": "prompt.code-review"
},
"policy": {
"allow": ["db.*", "fs.*", "prompt.*"],
"deny": ["fs.secret"],
"redactKeys": ["token", "api_key", "password"]
},
"mcpServers": {
"sqlite": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-sqlite", "./test.db"]
},
"remote_docs": {
"url": "https://mcp.example.com/mcp",
"protocolVersion": "2025-11-25",
"allowStateless": false,
"headers": {
"X-Tenant": "acme"
},
"auth": {
"type": "bearer",
"tokenEnv": "REMOTE_DOCS_MCP_TOKEN"
}
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
}
}Per mcpServers.<id>, transport selection is strict and inferred:
- stdio upstream: set
command(plus optionalargs,env) - HTTP/SSE upstream: set
url(plus optionalprotocolVersion,allowStateless,headers,auth) - exactly one of
commandorurlmust be set
No legacy config fallback is supported.
auth.type = "bearer":
{
"type": "bearer",
"tokenEnv": "MCP_TOKEN"
}auth.type = "basic":
{
"type": "basic",
"username": "svc-user",
"passwordEnv": "MCP_PASSWORD"
}For bearer/basic, exactly one direct secret (token/password) or env-backed secret (tokenEnv/passwordEnv) is required.
warmplane daemon --config mcp_servers.jsonEndpoints:
GET /v1/capabilitiesGET /v1/capabilities/:idPOST /v1/tools/callGET /v1/resourcesPOST /v1/resources/readGET /v1/promptsPOST /v1/prompts/get
warmplane mcp-server --config mcp_servers.jsonMCP clients can point directly to this process.
Synthetic lightweight tools exposed:
capabilities_listcapability_describecapability_callresources_listresource_readprompts_listprompt_get
Native MCP methods also supported:
- resources:
resources/list,resources/read - prompts:
prompts/list,prompts/get
# capabilities
warmplane list-capabilities
warmplane describe-capability db.query
warmplane call-capability db.query --params '{"query":"SELECT 1"}'
# resources
warmplane list-resources
warmplane read-resource fs.readme
# prompts
warmplane list-prompts
warmplane get-prompt prompt.code-review --arguments '{"code":"fn main() {}"}'{
"mcpServers": {
"fast-facade": {
"command": "warmplane",
"args": ["mcp-server", "--config", "mcp_servers.json"]
}
}
}Run an end-to-end stdio MCP smoke test:
./scripts/smoke_mcp_server.shIt validates:
- MCP
initialize tools/listincludes all synthetic lightweight facade toolsresources/listandprompts/listreturn valid responses
- Upstream MCP compatibility remains intact.
- Client-facing schemas are intentionally small and stable.
- Policy and aliasing are enforced consistently across modes.
- Timeout and error envelopes are normalized for deterministic orchestration.
- Runtime logs are structured JSON for auditability.
- OpenTelemetry trace export is supported via OTLP.
Warmplane emits structured JSON logs by default (tracing + tracing-subscriber).
Example controls:
RUST_LOG=info,warmplane=debugset verbosityWARMPLANE_OTEL_ENABLED=trueenable OpenTelemetry exportOTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4317set OTLP collector endpointWARMPLANE_OTEL_ENDPOINT=http://127.0.0.1:4317fallback OTLP endpoint ifOTEL_EXPORTER_OTLP_ENDPOINTis unsetWARMPLANE_SERVICE_NAME=warmplane-prodoverride service name
Operational notes:
- Logs include structured request/capability/resource/prompt fields for audit trails.
trace_idin execution envelopes can be correlated with logs and distributed traces.- When OTEL is enabled, traces are exported via OTLP gRPC and local structured logs remain active.
For detailed request/response contracts, see docs/spec.md.
Additional references:
- OpenAPI: openapi.yaml
- Config schema: config.schema.json
- Install/distribution: INSTALL.md
- Deployment runbook: DEPLOYMENT.md
- Observability: OBSERVABILITY.md