Skip to main content

Context-saving MCP switchboard for AI agents - lazy-load tools, resources, and prompts only when needed

Project description

🔀 mcp-switch

Give your AI agent only the MCP capabilities it needs, right when it needs them.

PyPI License


Why?

When you connect MCP servers to your AI agent, every tool gets loaded at once - even the ones your agent doesn't need right now.

The more tools an agent sees, the slower and less accurate it gets. It's like giving someone a toolbox with 50 tools when they just need a screwdriver.

mcp-switch fixes this. Your agent starts with just 5 simple tools:

Tool What it does
list_namespaces "What tool groups are available?"
load_namespace "Give me the database tools"
unload_namespace "I'm done, put them away"
load_group "Give me all the dev tools at once"
unload_group "Put all the dev tools away"

When the agent needs database tools, it loads them. When it's done, it puts them back. Clean, fast, focused.

- You: "Fix the CSS on the navbar"
- Agent sees: 46 tools (database, GitHub, Slack, Docker, Kubernetes...)
- Agent: gets distracted, picks wrong tools, slower response

+ You: "Fix the CSS on the navbar"
+ Agent sees: 5 tools (list, load, unload, load_group, unload_group)
+ Agent: focuses entirely on your request, fast response

Setup

No Python install needed. Every setup below uses uvx which runs packages on-the-fly (like npx for Python).

Don't have uvx? Install uv first: curl -LsSf https://astral.sh/uv/install.sh | sh

Step 1: Create Your Config

Option A: Import from an existing client

# Auto-detect and import from Claude Desktop, Cursor, VS Code, or Windsurf
uvx mcp-switch init

# Or import from a specific config file
uvx mcp-switch init --from ~/.config/claude/claude_desktop_config.json

Option B: Write one manually

Create ~/.config/mcp-switch/config.yaml:

namespaces:
  # Proxy to a real MCP server (stdio - starts on demand)
  postgres:
    type: mcp
    command: "uvx mcp-server-postgres"
    args: ["--connection-string", "postgresql://localhost/mydb"]
    description: "Query and manage PostgreSQL databases"
    idle_ttl: 300  # Auto-unload after 5 min of inactivity

  # Connect to a remote/hosted MCP server (HTTP)
  supabase:
    type: http
    url: "https://mcp.supabase.com/mcp"
    headers:
      Authorization: "Bearer ${SUPABASE_TOKEN}"
    description: "Supabase database tools"

  # Wrap CLI commands as tools (no server needed)
  git:
    type: cli
    description: "Git version control"
    tools:
      git_status:
        command: "git status --porcelain"
        description: "Show working tree status"
      git_log:
        command: "git log --oneline -20"
        description: "Show recent commits"

# Groups: load/unload multiple namespaces at once
groups:
  dev:
    - git
    - postgres

Step 2: Verify It Works

# Check config is valid
uvx mcp-switch validate

# Check commands exist, env vars are set
uvx mcp-switch doctor

# Actually connect to each backend and list tools
uvx mcp-switch test

Step 3: Connect to Your Agent

Pick your agent and add one config block. That's the entire setup.

Claude Code
claude mcp add router -- uvx mcp-switch serve --config ~/.config/mcp-switch/config.yaml

Or add to .mcp.json:

{
  "mcpServers": {
    "router": {
      "command": "uvx",
      "args": ["mcp-switch", "serve", "--config", "~/.config/mcp-switch/config.yaml"]
    }
  }
}
Cursor

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "router": {
      "command": "uvx",
      "args": ["mcp-switch", "serve", "--config", "~/.config/mcp-switch/config.yaml"]
    }
  }
}
VS Code Copilot

Add to .vscode/mcp.json:

{
  "servers": {
    "router": {
      "command": "uvx",
      "args": ["mcp-switch", "serve", "--config", "~/.config/mcp-switch/config.yaml"]
    }
  }
}
Hermes

Add to ~/.hermes/config.yaml:

mcp_servers:
  router:
    command: uvx
    args: ["mcp-switch", "serve", "--config", "~/.config/mcp-switch/config.yaml"]

Or generate it: uvx mcp-switch export hermes

Claude Desktop / Windsurf / Codex / Cline / Amazon Q / Any MCP Client

The pattern is always the same. Point your client at:

  • Command: uvx
  • Args: ["mcp-switch", "serve", "--config", "~/.config/mcp-switch/config.yaml"]

mcp-switch speaks stdio MCP, which every compliant client supports.


Namespace Types

mcp - Local MCP Servers (stdio)

Starts a real MCP server as a subprocess. Lazy-started on first load, stopped on unload.

postgres:
  type: mcp
  command: "uvx mcp-server-postgres"
  args: ["--connection-string", "postgresql://localhost/mydb"]
  description: "Query and manage PostgreSQL databases"
  env:
    DB_PASSWORD: "${DB_PASSWORD}"
  idle_ttl: 300    # Auto-unload after 5 min
  pinned: true     # Never auto-evict

http - Remote MCP Servers

Connects to hosted MCP servers via HTTP. Uses StreamableHTTP with automatic SSE fallback.

supabase:
  type: http
  url: "https://mcp.supabase.com/mcp"
  headers:
    Authorization: "Bearer ${SUPABASE_TOKEN}"
  description: "Supabase database tools"
  idle_ttl: 600

Works with Supabase, Neon, Cloudflare Workers, or any hosted MCP server.

cli - Shell Commands as Tools

Wraps shell commands as MCP tools. No server process needed.

git:
  type: cli
  description: "Git version control"
  tools:
    git_status:
      command: "git status --porcelain"
      description: "Show working tree status"
    git_diff:
      command: "git diff {file}"
      description: "Show changes for a specific file"
      parameters:
        file:
          type: string
          description: "File path to diff"
          required: true

Features

Groups

Load/unload multiple namespaces in one call:

groups:
  dev:
    - git
    - docker
    - system

Agent uses load_group("dev") instead of loading each one individually.

Idle TTL Auto-Unload

Automatically unloads namespaces after a period of inactivity:

postgres:
  type: mcp
  command: "uvx mcp-server-postgres"
  idle_ttl: 300  # 5 minutes

Timer resets on every tool call, resource read, or prompt fetch.

Pinned Namespaces & Load Caps

max_loaded_namespaces: 3  # Global cap

namespaces:
  github:
    type: mcp
    pinned: true  # Never auto-evicted when cap is reached

When the cap is hit, the least-recently-used unpinned namespace gets evicted.

Tools, Resources, and Prompts

mcp-switch proxies all three MCP capabilities. When a namespace is loaded, its tools, resources, and prompts all become available. When unloaded, they're all removed.

Export

Generate ready-to-paste config for any client:

uvx mcp-switch export claude-code
uvx mcp-switch export cursor
uvx mcp-switch export vscode
uvx mcp-switch export hermes    # YAML output
uvx mcp-switch export generic

Config Reference

Config Locations (checked in order)

  1. ./mcp-switch.yaml
  2. ./mcp-switch.yml
  3. ~/.config/mcp-switch/config.yaml
  4. ~/.mcp-switch.yaml

Or explicit: uvx mcp-switch serve --config /path/to/config.yaml

Environment Variables

Use ${VAR_NAME} syntax in config values. mcp-switch expands them at load time:

env:
  GITHUB_TOKEN: "${GITHUB_TOKEN}"
headers:
  Authorization: "Bearer ${SUPABASE_TOKEN}"

mcp-switch doctor will catch empty or missing env vars.


CLI Commands

Command What it does
mcp-switch serve Start the MCP server (stdio transport)
mcp-switch init Import existing MCP configs
mcp-switch validate Check config syntax
mcp-switch doctor Check commands, env vars, health
mcp-switch test [namespace] Connect to backends, list tools
mcp-switch status Show config summary
mcp-switch list List all namespaces
mcp-switch export <client> Generate client-specific config

Troubleshooting

"Command not found" for MCP backends

  • Make sure the MCP server package is installed: uvx mcp-server-postgres --help
  • Run mcp-switch doctor to catch missing executables

HTTP backend returns 401/403

  • Check your auth token is set: use ${ENV_VAR} syntax and export the variable
  • Run mcp-switch test <namespace> to verify connectivity

Env var expansion shows empty values

  • Use ${VAR_NAME} syntax (not $VAR_NAME)
  • mcp-switch doctor catches empty env expansions

Agent ignores or misuses mcp-switch tools

  • Make namespace description fields clear and specific
  • Keep namespace names short and descriptive

License

MIT - 2026 ZeroWaves - see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_switch-0.3.2.tar.gz (32.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_switch-0.3.2-py3-none-any.whl (31.6 kB view details)

Uploaded Python 3

File details

Details for the file mcp_switch-0.3.2.tar.gz.

File metadata

  • Download URL: mcp_switch-0.3.2.tar.gz
  • Upload date:
  • Size: 32.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_switch-0.3.2.tar.gz
Algorithm Hash digest
SHA256 49ad71cfd8b4c3f4d56f78efef05e7309c4909b7f5267476d9e4383ae25de3da
MD5 aa0717948325cc6bec0d196798c180d5
BLAKE2b-256 d8eff0c70053dcde066f8cbd689473947b58ffc6da143ea197c9cab1287699c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_switch-0.3.2.tar.gz:

Publisher: publish.yml on Zer0Wav3s/mcp-switch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_switch-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: mcp_switch-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 31.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_switch-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 508ed10c9d5173b4a61f25c204fce4591305b330bb6592c4c727dde74892961f
MD5 0f666b676a50599e071c6fca62158874
BLAKE2b-256 7d0b17f4270586fbdffe78a8fa3228873b219a7c4ae6153a8b2209f7316f9fdc

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_switch-0.3.2-py3-none-any.whl:

Publisher: publish.yml on Zer0Wav3s/mcp-switch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page