Skip to main content

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.mod has a replace directive 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:

VariableDescription
GIG_BEARER_TOKENBearer token for authenticating MCP clients
GIG_MASTER_KEY32-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:

VariableDescription
GIG_DEMO_TOKENSeeds a demo credential for the echo server on startup
GIG_DEMO_ALLOWComma-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

ServiceRolePort
issuer-proxyalpine/socat sidecar that owns the gateway's network namespace and publishes its listener; also forwards localhost:8082 to the dev OIDC IdP8080:8080
gatewayThe 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
webNext.js dashboard3000: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:

VariableDescription
GIG_REGISTRY_INDEX_URLhttps:// or file:// location of the signed index.json
GIG_REGISTRY_PUBKEY32-byte ed25519 hex public key (the index trust root)
GIG_INSTALLComma-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.