MCPG
Reference
Reference

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.

InvocationWhat it does
mcpgRun the gateway, loading config from MCPG_CONFIG.
mcpg --stdioRun 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):

bash
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:

bash
# 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.

bash
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

bash
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.