Quickstart
Boot a working MCPG gateway in under five minutes — generate a validated dev config, check it, run the gateway, and curl /health.
This gets you from nothing to a running gateway answering health checks in under five minutes. No external services, no auth — a single-node dev config on loopback.
Just want to click around? The control-plane server has a one-command dev wedge:
mcpg cp serve --devboots the control plane + an embedded dashboard onhttp://127.0.0.1:7843(gRPC on:7844) with loopbackauth_mode=none, and stores its state (sqlite db) in~/.mcpg. That gives you the fleet dashboard, not a serving gateway — to expose MCP tools you still run a gateway, which is exactly what the rest of this page walks through.
You'll use three commands that ship in the mcpg crate:
mcpg config init— scaffold a validated starter config from a templatemcpg config check— validate a config before bootingmcpg— the gateway itself
First, get the binaries. Build from source, grab the release tarball, or use the Docker image — see Install. The commands below assume
mcpg,mcpg config init, andmcpg config checkare on yourPATH. From a source checkout, prefix each withcargo run -q -p mcpg --bin <name> --.
1. Generate a dev config
The dev-single-node template is built for a laptop: a mock tool that answers
from config alone and an http tool that calls a real endpoint, stderr JSON
logs, audit on, and anonymous identity (fine on loopback).
mcpg config init --template dev-single-node --output dev.yaml
✓ Wrote dev.yaml (dev-single-node).
Validate: mcpg config check dev.yaml
Boot: MCPG_CONFIG=dev.yaml mcpg
Run mcpg config init --list to see all templates (dev-single-node,
production-single-redis, production-redis-cluster, production-nats-cluster,
air-gapped, multi-tenant).
The generated dev.yaml is small and readable. The shape is the real schema —
note the top-level keys gateway, cluster, plugins, mcp, and
observability:
gateway:
server:
bind_address: "127.0.0.1:8787"
mcp_path: "/mcp"
health_path: "/health"
allowed_origins: []
cluster:
kind: single_node
plugins:
- id: dev.mcpg.backend.mock
class: backend
source:
oci: "ghcr.io/mcpg-dev/source-code/plugins/backend-mock:0.0.1-alpha.10"
- id: dev.mcpg.backend.http
class: backend
source:
oci: "ghcr.io/mcpg-dev/source-code/plugins/backend-http:0.0.1-alpha.10"
mcp:
capabilities:
tools:
- name: dev.mock.echo
description: Echo a JSON value back as the tool result.
governance:
minimum_trust: unauthenticated
backend:
kind: mock
response: { ok: true, source: "dev-single-node" }
- name: dev.http.get
description: Fetch a URL and return the response body.
governance:
minimum_trust: unauthenticated
backend:
kind: http
url: "https://example.com/"
method: GET
observability:
logs:
level: info
sinks:
- kind: stderr
config: { format: json }
Every backend is a plugin, including mock — nothing is linked into the binary.
The plugins: block is what makes kind: mock and kind: http resolvable; drop
it and the bindings have no implementation to bind to. The gateway pulls each
reference at boot, so the first run needs registry access.
2. Validate it
The gateway rejects unknown fields at boot, so validate before you run. This catches typos and stale keys up front.
mcpg config check dev.yaml
✓ dev.yaml: valid (2 bindings, 2 plugins, audit on, observability on)
Exit code 0 and valid means you're good to boot.
3. Boot the gateway
The gateway reads its config path from the MCPG_CONFIG environment variable:
MCPG_CONFIG=dev.yaml mcpg
It binds to 127.0.0.1:8787, pulls the two backend plugins, loads both tools,
and starts logging to stderr in JSON. Leave it running and open a second
terminal.
4. Check it's alive
curl http://127.0.0.1:8787/health
{"status":"ok","service":"mcpg","version":"1.0.0-rc.17"}
A 200 with "status":"ok" means the gateway is up and serving.
The MCP endpoint at
/mcpspeaks the streamable-HTTP transport, which requires the full session lifecycle (initialize→notifications/initialized→ your calls, all carrying themcp-session-idheader the server returns and anaccept: application/json, text/event-streamheader). A rawcurloftools/listwill be rejected withmissing mcp-session-id header— use a real MCP client to drive it (next step).
5. Point a client at it
Any MCP client connects at http://127.0.0.1:8787/mcp and handles the lifecycle for you:
- Claude Desktop / Cursor / Continue — add an MCP server with
url: http://127.0.0.1:8787/mcp. You'll seedev.mock.echoanddev.http.getin its tool list — proof both bindings wired up end-to-end. - MCP Inspector (
npx @modelcontextprotocol/inspector) — connect to the same URL to browse tools/prompts/resources interactively.
What's next
dev.http.get already calls a real endpoint. To go further, declare the plugin
for the backend you need and add a binding against it:
- Configuration reference — every key, including
MCPG's 32 backend plugins (
http,sql,openapi, the LLM backends, and more). - Identity guide — wire up OIDC, mTLS, SPIFFE, or API keys before you leave loopback.
- Policy guide — authorize tool calls with Cedar, OPA, or Casbin.
- Kubernetes install — take it to production with the operator and a Helm chart.