Skip to content

Quick Start

  • Docker and Docker Compose installed
  • A PostgreSQL database (or use the bundled one)

Terminal window
curl -O https://raw.githubusercontent.com/gatesuite/mcpgate/main/docker-compose.yml

Generate a strong admin key:

Terminal window
export ADMIN_API_KEY=$(python3 -c "import secrets; print(secrets.token_hex(32))")
echo "Save this somewhere safe: $ADMIN_API_KEY"

Create a .env file:

Terminal window
cat > .env << EOF
DATABASE_URL=postgresql+asyncpg://mcpgate:mcpgate@postgres:5432/mcpgate
ADMIN_API_KEY=$ADMIN_API_KEY
KEY_PREFIX=mcp_sk_
EOF

Terminal window
docker compose up -d

Check it’s healthy:

Terminal window
curl http://localhost:8000/health
# {"status": "ok", "service": "mcpgate"}

The ADMIN_API_KEY is your master credential — your backend uses it to manage keys on behalf of your users.

Terminal window
curl -X POST http://localhost:8000/api/v1/keys \
-H "Authorization: Bearer $ADMIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_123",
"name": "Claude Desktop",
"scopes": {"read": true, "write": true}
}'

Response:

{
"id": "a1b2c3d4-...",
"key": "mcp_sk_3f8a1c2e9b4d7f6a_4a7b2c9e1d3f8a5b...",
"prefix": "mcp_sk_3f8a1c2e9b4d7f6a_...5b",
"user_id": "user_123",
"name": "Claude Desktop",
"created_at": "2026-04-16T10:00:00Z"
}

Your MCP server calls this on every incoming request:

Terminal window
curl -X POST http://localhost:8000/api/v1/verify \
-H "Content-Type: application/json" \
-d '{"key": "mcp_sk_3f8a1c2e9b4d7f6a_4a7b2c9e1d3f8a5b..."}'

Response when valid:

{
"valid": true,
"user_id": "user_123",
"scopes": {"read": true, "write": true},
"error": null
}

Response when invalid:

{
"valid": false,
"user_id": null,
"scopes": null,
"error": "Invalid API key"
}

List all keys for a user:

Terminal window
curl http://localhost:8000/api/v1/keys/user_123 \
-H "Authorization: Bearer $ADMIN_API_KEY"

Revoke a key by its ID:

Terminal window
curl -X DELETE http://localhost:8000/api/v1/keys/a1b2c3d4-... \
-H "Authorization: Bearer $ADMIN_API_KEY"

The root docker-compose.yml defaults to latest. For production, pin to a specific release:

Terminal window
MCPGATE_VERSION=1.2.3 docker compose up -d

Or set it in your .env:

MCPGATE_VERSION=1.2.3