Quickstart
Bring up the Gig'MCP gateway with Docker Compose and connect an MCP client in a few minutes.
Prerequisites
- Docker with Docker Compose.
- A Linux host, or Docker Desktop on macOS. The sandbox runtime (bubblewrap, network namespaces, seccomp) is Linux-only; on a Mac everything runs inside the gateway's Linux container.
openssl(or any way to generate random hex) for the two required secrets.- A sibling checkout of the registry repo. The gateway's
go.modhas areplacedirective pointing at../gigmcp-registry/schema, and the compose file supplies that path as an additional build context — the Docker build fails without it.
1. Clone both repos
git clone https://github.com/gigmcp/gigmcp
git clone https://github.com/gigmcp/registry gigmcp-registry
cd gigmcp
The two checkouts must be siblings: docker-compose.yml references ../gigmcp-registry.
2. Start the stack
Two environment variables are required — the compose file refuses to start without them:
| Variable | Description |
|---|---|
GIG_BEARER_TOKEN | Bearer token for authenticating MCP clients |
GIG_MASTER_KEY | 32-byte hex master key for the credential vault (openssl rand -hex 32) |
GIG_BEARER_TOKEN=$(openssl rand -hex 24) \
GIG_MASTER_KEY=$(openssl rand -hex 32) \
docker compose up --build -d
You can also put both in a .env file next to docker-compose.yml instead of passing them inline.
Optionally, seed a demo credential for the bundled echo server:
| Variable | Description |
|---|---|
GIG_DEMO_TOKEN | Seeds a demo credential for the echo server on startup |
GIG_DEMO_ALLOW | Comma-separated allowed hosts for the demo credential (default: api.example.com) |
:::warning Save your master key
GIG_MASTER_KEY wraps every secret in the vault. If you lose it, stored credentials cannot be decrypted. Keep it somewhere safe.
:::
What comes up
| Service | Role | Port |
|---|---|---|
issuer-proxy | alpine/socat sidecar that owns the gateway's network namespace and publishes its listener; also forwards localhost:8082 to the dev OIDC IdP | 8080:8080 |
gateway | The Go gateway binary: MCP endpoint, sandbox supervisor, egress proxy, vault. Joins issuer-proxy's network namespace (network_mode: service:issuer-proxy), so port 8080 is published on the sidecar | — |
web | Next.js dashboard | 3000:3000 |
The gateway persists its data (SQLite database, extracted server binaries) in the gigmcp-data volume mounted at /data.
:::note Container privileges
The gateway container runs with cap_add: NET_ADMIN — needed to create a veth pair per sandbox and move one end into the sandbox's network namespace. No SYS_ADMIN or privileged mode is required. It also sets seccomp=unconfined, apparmor=unconfined, and systempaths=unconfined at the Docker layer so bubblewrap can create unprivileged user namespaces; an application-level seccomp-BPF filter inside each sandbox closes the namespace-escape vectors. See sandbox isolation for the full picture.
:::
3. Verify it's running
docker compose ps
docker compose logs -f gateway
All three services should be Up, and the gateway logs should show it listening and the echo server's sandbox spawning.
4. Connect an MCP client
Point Claude Code at the gateway with your bearer token:
claude mcp add --transport http gigmcp http://localhost:8080 \
--header "Authorization: Bearer <your token>"
You should see one tool, echo_echo, served by an MCP server running in an egress-isolated bubblewrap sandbox: private network namespace, no host filesystem, cleared environment, credential injected only at the proxy.
5. Install a server from the registry
The gateway installs servers at boot from a signed registry index. Set all three variables together — GIG_INSTALL refuses to work without the index URL and public key:
| Variable | Description |
|---|---|
GIG_REGISTRY_INDEX_URL | https:// or file:// location of the signed index.json |
GIG_REGISTRY_PUBKEY | 32-byte ed25519 hex public key (the index trust root) |
GIG_INSTALL | Comma-separated server refs to install at boot (auto-consented) |
The gateway verifies the index signature, pulls each server's OCI image pinned to its digest, verifies the content digest, extracts the entrypoint binary (today's installer handles static-binary images; node/python runtime-rootfs images are not yet installable), and spawns it under bubblewrap. See registry overview for how the trust chain works.
:::warning Registry status The public catalog tracks 221 planned manifests, but their image digests are currently placeholders — manifests with placeholder digests are not installable until registry CI has built the images and the digests are pinned. See the catalog. :::
Optional: local OIDC for the dashboard
The dashboard's control plane (/api) requires OIDC; without it, /api is disabled but the MCP endpoint keeps working. For development, the repo ships a local Zitadel IdP:
docker compose -f docker-compose.dev.yml up -d
Console: http://localhost:8082/ui/console (user admin, password Password1!). Bring the dev stack up before the main compose file, and never pass --remove-orphans to the main compose — both files share one compose project, and that flag would tear down the Zitadel containers. Then set the GIG_OIDC_* variables; see configuration and authentication.
Next steps
- Configuration — every environment variable, defaults, and validation rules.
- Deployment — running it for real.
- Profiles — per-profile MCP endpoints.