mcpg (gateway)
The MCPG gateway binary — run it, configure it via MCPG_CONFIG, force the stdio transport, and use the dev / plugin front-door subcommands.
mcpg is the gateway server. Its CLI surface is intentionally tiny and
config-driven: there is no --config flag — configuration comes from the
MCPG_CONFIG environment variable. The argument parser is hand-rolled (not a
clap-style parser), so it recognises only the flags and subcommands below and
has no --help / --version output of its own.
| Invocation | What it does |
|---|---|
mcpg | Run the gateway, loading config from MCPG_CONFIG. |
mcpg --stdio | Run the gateway forcing the stdio JSON-RPC transport (e.g. when spawned by an MCP client). Overrides gateway.server.transport. |
mcpg dev --plugin <path> [--plugin …] [--stdio] | Local plugin-dev mode — load freshly-built plugin artifact(s) by path, layered onto your existing config. |
mcpg plugin <cmd> […] | Delegate to the mcpg-plugins tool on $PATH (kubectl-style). See Plugins. |
--stdio is recognised anywhere on the command line; it flips the transport to
stdio after config load, regardless of what gateway.server.transport says.
Configuration (MCPG_CONFIG)
MCPG_CONFIG is a single path or a path-separator-joined overlay list
(later files win):
MCPG_CONFIG=config.yaml mcpg # single file
MCPG_CONFIG=base.yaml:production.yaml mcpg # Unix overlay (':' separator)
MCPG_CONFIG="base.yaml;prod.yaml" mcpg # Windows overlay (';')
Merge order: struct defaults → each YAML file in slice order → MCPG_* env
vars last. Files merge with later-wins semantics for any field they set.
MCPG_CONFIG itself is the file entry point and is never treated as a field
override.
Per-field env overrides use __ (double underscore) as the nested-key
separator, so the env var name mirrors the YAML path:
# Override gateway.server.bind_address without editing the file
MCPG_CONFIG=config.yaml MCPG_GATEWAY__SERVER__BIND_ADDRESS=0.0.0.0:8080 mcpg
Here gateway.server.bind_address becomes
MCPG_GATEWAY__SERVER__BIND_ADDRESS — one __ segment per level of nesting.
Transport modes are http (default — Axum HTTP/SSE on
gateway.server.bind_address, default 127.0.0.1:8787) and stdio (JSON-RPC
over stdin/stdout). The full set of keys lives in the
configuration reference.
mcpg dev — local plugin loop
mcpg dev synthesises a minimal config that adds your built artifact(s) as
plugins[] entries, layered on top of any existing MCPG_CONFIG. Each
--plugin <path> adds one plugin by path (no OCI, no packaging) — and at least
one --plugin is required. The descriptor (plugin.yaml) is read from next to
the artifact (<artifact>/../plugin.yaml), from a <artifact>.plugin.yaml
override, or from the crate root for target/release/… builds.
mcpg plugin new --kind tool_gate --name my-gate # scaffold (delegates to mcpg-plugins)
cd mcpg-plugin-tool-gate-my-gate && cargo build --release
mcpg dev --plugin target/release/libmcpg_plugin_tool_gate_my_gate.so
# Iterate against an MCP client over stdio:
mcpg dev --plugin ./libfoo.so --plugin ./libbar.so --stdio
Examples
MCPG_CONFIG=config.yaml mcpg # run the gateway (HTTP :8787)
MCPG_CONFIG=config.yaml mcpg --stdio # stdio transport
mcpg plugin list ./target/release # delegate to mcpg-plugins
Where config comes from in production
On Kubernetes the operator sets MCPG_CONFIG from MCPGGateway.spec.config,
so the gateway boots exactly as it would standalone. Self-hosted, you author
the config with the config tooling and validate
it before boot.