Reference
Reference

mcpg (gateway)

beta
v0.0.1-beta.6

The MCPG gateway binary — run it, attach or embed a control plane (--enroll / --control-plane), MCPG_CONFIG, mcpg status, dev mode, --stdio.

mcpg — the gateway (and the hub CLI)

CLI reference

mcpg is the gateway server. Configuration comes from the MCPG_CONFIG env var (a path or path-separator-joined list of files) and/or the repeatable --config flag — the two layer together, later wins. See Configuration below.

InvocationWhat it does
mcpgRun the gateway, loading config from MCPG_CONFIG. Re-attaches to a paired control plane automatically (see below).
mcpg --config <source>Load a config layer (repeatable, later wins). A source is a local path, a file:// path, an https:// URL (fetched at boot), or inline base64:/data: YAML. Applied after any MCPG_CONFIG files.
mcpg --stdioRun the gateway forcing the stdio JSON-RPC transport (e.g. when spawned by an MCP client). Overrides gateway.server.transport.
mcpg --enroll <URL>Run attached to a control plane, enrolling with the given URL on first contact (minted by mcpg cp enroll new or the console). Sticky — see below.
mcpg --no-cpOne-off detached run despite a stored pairing (or a config attachment).
mcpg --control-plane (alias --cp)Run an embedded control plane in this process and auto-enroll over loopback — the all-in-one. --cp-<flag> passes through to the embedded server (--cp-bind-http → its --bind-http).
mcpg --tunnel [wss-url]Serve MCP by dialing an MCPG relay instead of binding a public port — a reverse tunnel. The optional value sets the relay endpoint (bare --tunnel uses the config's relay_url or the MCPG Cloud relay). Add --private (federation-only, no public URL), --tunnel-name <name>, --tunnel-mode <relay_terminated|e2ee>, --tunnel-relay <wss-url>. See reverse tunnels.
mcpg statusThis box: gateway (bind + health), agent pairing (endpoint, credentials, LKG hash), local control plane.
mcpg dev --plugin <path> [--plugin …] [--stdio]Local plugin-dev mode — load freshly-built plugin artifact(s) by path, layered onto your existing config.
mcpg <word> […]Front-door dispatch to the sibling mcpg-<word> binary: cp, cloud, admin, config, plugin.

Composition flags — attaching to / embedding a control plane

The rule across the CLI family: flags shape the gateway; subcommands run or operate everything else. The three flags conflict with each other (and --enroll errors against an explicit gateway.control_plane in config — config wins).

  • --enroll <URL> runs the agent in-process (the cp-attached build feature, on in release binaries) and enrolls. The agent gRPC endpoint defaults to the enrollment URL's host on :7844; --cp-grpc <URL> overrides. The pairing persists in MCPG_STATE_DIR (gateway-pairing.json + gateway-agent/ creds), so subsequent plain mcpg runs re-attach with the same instance identity — no re-enrollment.
  • --control-plane / --cp boots the CP in-process with mcpg cp serve --dev semantics (sqlite in the state dir, auth_mode=none) and auto-enrolls this gateway over loopback: one command, and the console at http://127.0.0.1:7843 already shows the gateway online. Deliberately not sticky — the CP only exists inside --cp runs. It shares the state-dir database with mcpg cp serve --dev, so graduating to split processes keeps all data. (Requires the embedded-cp build feature, on in release binaries.)
  • --no-cp detaches for one run.

Configuration (MCPG_CONFIG + --config)

Config comes from two ordered inputs that layer together, later wins: the MCPG_CONFIG env var (files only) and the repeatable --config flag.

MCPG_CONFIG is a single path or a path-separator-joined overlay list of files:

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 (';')

--config <source> adds layers after the MCPG_CONFIG files (repeat it; later wins). Unlike MCPG_CONFIG, a --config source is not path-split, so it can be more than a file path:

bash
mcpg --config base.yaml --config prod.yaml            # two files, prod wins
mcpg --config https://cfg.example.com/gateway.yaml    # fetched at boot (https)
mcpg --config base64:Z2F0ZXdheToge30K                 # inline base64 YAML
mcpg --config 'data:application/yaml;base64,Z2F0…'    # RFC 2397 data URI
Source formResolved as
path.yaml, /abs/path.yaml, file://…a local file (re-read on hot-reload)
https://host/cfg.yamlfetched at boot over TLS (10s timeout, 5 MiB cap)
http://host/cfg.yamlrefused unless MCPG_CONFIG_ALLOW_INSECURE_HTTP=1 (MITM risk)
base64:<b64> / data:…;base64,<b64>inline base64-decoded YAML

Remote and inline (https/base64/data) layers are held in memory and captured at boot — they are never written to disk, and a hot-reload reuses the boot snapshot rather than re-fetching. Only file layers hot-reload. Put secrets behind ${env.X} / cred:// references regardless of source.

Merge order: struct defaults → each YAML layer in order (MCPG_CONFIG files, then --config sources) → MCPG_* env vars last. Env overrides use __ (double underscore) as the nested-key separator; MCPG_CONFIG itself is the file entry point and is never treated as an override:

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

Each __ segment maps to one level of nesting, so the env var name mirrors the YAML path (gateway.server.bind_addressMCPG_GATEWAY__SERVER__BIND_ADDRESS).

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

mcpg dev — local plugin loop

Each --plugin <path> adds one plugin to the running gateway by path (no OCI, no packaging). The descriptor (plugin.yaml) is read from next to the artifact (or the crate root for target/release/…).

bash
mcpg plugin new --kind tool_gate --name my-gate        # scaffold (delegates to mcpg-plugin)
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-plugin

Where does the config come from in production? On Kubernetes the operator sets MCPG_CONFIG from MCPGGateway.spec.config; standalone, you author it with the config tooling.