Skip to main content
Glama

MCP Gateway

A service orchestration layer for the Model Context Protocol. Manages multiple MCP services through a single unified interface — spawn, supervise, and route tool calls across all your services.

Key Feature: Lazy Activate

By default, services activate in lazy mode — the process spawns and tool list is fetched, but zero tool schemas are injected into the LLM context. This means you can have hundreds of tools across dozens of services with no token overhead.

activate({name: "google-workspace"})     → 281 tools ready, 0 context tokens
tools({service: "google-workspace"})     → browse available tools
call({service: "...", tool: "...", args}) → call any tool directly

Related MCP server: SuperMCP Server

Features

  • Lazy activate — spawn services with 0 context tokens, browse with tools(), call with call()

  • Service orchestration — spawn, stop, restart child MCP services

  • On-demand tool browsingtools({service, filter}) returns tool descriptions as conversation text (not system prompt)

  • Direct routingcall() routes to child connections without needing schema registration

  • Environment variable expansion — use $VAR or ${VAR} in config for secrets

  • Dynamic management — add/remove services at runtime without restarting

  • Health monitoring — built-in ping/health checks

  • Any command — supports bun, node, npx, ssh, or any executable

Quick Start

# Install
bun install

# Create your config from the example
cp gateway.config.example.json gateway.config.json

# Edit gateway.config.json with your services
# Then start the gateway
bun run start

Configuration

gateway.config.json defines your services:

{
  "services": [
    {
      "name": "my-service",
      "command": "bun",
      "args": ["run", "/path/to/service/index.ts"],
      "env": { "API_KEY": "$MY_API_KEY" },
      "autoActivate": false
    }
  ]
}

Field

Required

Default

Description

name

yes

Unique service identifier

command

yes

Executable to run (bun, node, npx, ssh, ...)

args

no

[]

Command arguments

env

no

{}

Environment variables (supports $VAR expansion)

autoActivate

no

false

Start automatically on gateway launch

keepAlive

no

false

Always-on: respawn with exponential backoff on crash; never GC'd when idle

groups

no

Named tool subsets for full-mode activation, e.g. {"gmail": ["send", "search"]}

Environment Variables

Config values support $VAR and ${VAR} syntax, resolved from process.env at load time:

{
  "env": { "API_KEY": "$MY_SECRET_KEY" },
  "args": ["--config", "${HOME}/.config/my-service.json"]
}

This keeps secrets out of your config file. Pass them through your MCP client config (see below).

Built-in Tools

Once running, the gateway exposes these management tools:

Tool

Description

services

List all services with status, mode (lazy/full), tool count, uptime

activate

Start a service. Default lazy (0 context tokens). Set lazy=false for full schema registration

tools

List available tools for an active service. Supports filter for keyword search

deactivate

Stop a service and clean up

restart

Kill and respawn a service (preserves lazy/full mode)

health

Ping all active services

add

Register a new service dynamically (persists to config)

remove

Remove a service from config

call

Call any tool on any active service

Workflow

1. activate({name: "my-service"})                        → spawn process, 0 tokens
2. tools({service: "my-service"})                        → see all tools
3. tools({service: "my-service", filter: "search"})      → filter by keyword
4. call({service: "my-service", tool: "...", args: {}})   → call a tool
5. deactivate({name: "my-service"})                      → stop when done

Full Mode (optional)

If you want tool schemas injected into the LLM context (traditional MCP behavior):

activate({name: "my-service", lazy: false})              → register all schemas
activate({name: "my-service", lazy: false, groups: ["gmail", "drive"]})  → register specific groups

HTTP Daemon Mode (always-on, shared)

Set GATEWAY_HTTP_PORT to run the gateway as a long-lived Streamable HTTP daemon instead of per-client stdio:

GATEWAY_HTTP_PORT=8770 bun run start
  • Endpoint: http://127.0.0.1:8770/mcp (Streamable HTTP, Mcp-Session-Id per client)

  • Health: GET /health returns JSON with session count and per-service status/pid

  • Shared processes, isolated views: child services are spawned once and shared by every connected client; each session keeps its own tool registry, so one agent's full-mode activation never leaks into another's context

  • Session GC: sessions idle longer than the TTL are swept automatically (clients often exit without sending DELETE). Tune with GATEWAY_SESSION_TTL_MS (default 60 min) and GATEWAY_SESSION_SWEEP_MS (default 5 min)

  • Safe boot: GATEWAY_NO_AUTOACTIVATE=1 skips autoActivate services (e.g. when stateful singletons are already running elsewhere)

A systemd unit is provided in deploy/mcp-gateway.service.

Point Claude Code (or any MCP client) at the daemon:

{
  "mcpServers": {
    "gateway": { "type": "http", "url": "http://127.0.0.1:8770/mcp" }
  }
}

Using with Claude Code

Add to your Claude Code MCP config (~/.claude/config.json or project settings). API keys go in the env block — they're passed to the gateway process and expanded in gateway.config.json via $VAR syntax:

{
  "mcpServers": {
    "gateway": {
      "command": "bun",
      "args": ["run", "/path/to/mcp-gateway/src/index.ts"],
      "env": {
        "GEMINI_API_KEY": "your-gemini-key",
        "EXA_API_KEY": "your-exa-key"
      }
    }
  }
}

License

MIT

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jfikrat/mcp-gateway'

If you have feedback or need assistance with the MCP directory API, please join our Discord server