AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Mcp Bridge

mcp-aiwerk-mcp-bridge · by AIWerk

MCP Bridge — Multiplex your MCP servers into one interface. Works with Claude Desktop, Cursor, Windsurf, and any MCP client.

— No reviews yet
0 installs
42 views
0.0% view→install

Install

$ agentstack add mcp-aiwerk-mcp-bridge

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ● Environment & secrets Used
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-aiwerk-mcp-bridge)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
○ 4mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Mcp Bridge? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

@aiwerk/mcp-bridge

[](https://github.com/AIWerk/mcp-bridge/actions/workflows/ci.yml) [](https://www.npmjs.com/package/@aiwerk/mcp-bridge) [](https://opensource.org/licenses/MIT) [](#status)

Your AI, Connected to Everything. Multiplex multiple MCP servers into one interface. One config, one connection, all your tools.

🌐 aiwerkmcp.com — Learn more about the AIWerk MCP Platform

Works with Claude Code, Codex (OpenAI), Claude Desktop, Cursor, Windsurf, Cline, OpenClaw, or any MCP client.

Status

@aiwerk/mcp-bridge is actively developed as of 2026-05-03.

The primary use case is the local install path for the AIWerk catalog at aiwerkmcp.com. Some recipes (those marked localOnly: true, e.g. chrome-devtools) need a browser, display, USB device or user-specific local path that the hosted bridge cannot reach; this package is the recommended way to run them.

It also serves:

which embeds this library and ships its own recipe-install tooling.

  • Self-hosted / offline deployments where the hosted service is not an

option.

  • Library consumers that import McpRouter, transports and the OAuth2

token manager directly.

Active development tracks the Universal Recipe Spec v2 alongside the hosted bridge — new fields like localOnly, multiInstance, auth.options[] and envBinding are being ported, and the bundled servers/ directory is being kept in sync with the catalog. The install helper does not fetch recipes over HTTP — recipes come from the bundled servers/ directory only.

Why?

Most AI agents connect to MCP servers one-by-one. With 10+ servers, that's 10+ connections, 200+ tools in context, and thousands of wasted tokens.

MCP Bridge solves this:

  • Router mode: all servers behind one mcp meta-tool (~99% token reduction)
  • Intent routing: say what you need in plain language, the bridge finds the right tool
  • Schema compression: tool descriptions compressed ~57%, full schema on demand
  • Security layer: trust levels, tool deny/allow lists, result size limits
  • HTTP auth: bearer token, custom headers, OAuth2 Client Credentials, and OAuth2 Authorization Code + PKCE (interactive browser login)
  • Result caching: LRU cache with per-tool TTL overrides
  • Batch calls: parallel multi-tool execution via action=batch
  • Multi-server resolution: automatic tool disambiguation when multiple servers provide the same tool
  • Configurable retries: exponential backoff for transient errors
  • Graceful shutdown: clean process termination and connection cleanup
  • Direct mode: all tools registered individually with automatic prefixing
  • 3 transports: stdio, SSE, streamable-http
  • Bundled recipe examples: 14+ reference server recipes in servers/ — copy one as a starting point for your own config, or bring your own MCP server entirely
  • Zero config secrets in files: ${ENV_VAR} resolution from .env

Install

npm install -g @aiwerk/mcp-bridge

Quick Start

# 1. Initialize config and register with Claude Code
mcp-bridge init --register claude-code

# 2. Install a server from the catalog
mcp-bridge install todoist

# 3. Add your API key
echo "TODOIST_API_TOKEN=your-token" >> ~/.mcp-bridge/.env

# 4. Restart Claude Code — bridge is ready

Use with Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "bridge": {
      "command": "mcp-bridge",
      "args": []
    }
  }
}

Recipe Spec v2

Bundled servers now ship with recipe.json using Universal Recipe Spec v2.1 (15 servers with rich metadata: category, subcategory, origin, countries, audience, sideEffects). During install, MCP Bridge prefers recipe.json when present and falls back to legacy config.json (v1) for backwards compatibility.

  • Spec: [docs/universal-recipe-spec.md](docs/universal-recipe-spec.md)
  • Runtime compatibility: v1 and v2 are both supported
  • Existing v1-only servers continue to work unchanged

For third-party recipe authors:

  1. Author recipe.json per the spec above.
  2. Validate your recipe before publishing:
npx @aiwerk/mcp-bridge validate-recipe ./recipe.json

config.json (v1) remains supported, but recipe.json (v2) is the recommended format going forward.

Catalog Integration (v2.8.0+)

mcp-bridge now fetches recipes from catalog.aiwerk.ch instead of relying on bundled recipe files.

How it works

  1. First run: Automatically downloads the top 15 most popular recipes
  2. On-demand: When you install a server, it checks the catalog first
  3. Offline: Falls back to local cache if catalog is unreachable

API

import { CatalogClient, bootstrapCatalog, mergeRecipesIntoConfig } from '@aiwerk/mcp-bridge';

// Bootstrap: download top recipes
await bootstrapCatalog();

// Or use the client directly
const client = new CatalogClient();
const recipe = await client.resolve('todoist');
const results = await client.search('email');

Catalog & Auto-Merge Options

Two config options control catalog behavior:

| Option | Type | Default | Description | |--------|------|---------|-------------| | catalog | boolean | true | Whether bootstrapCatalog() fetches recipes from the remote catalog | | autoMerge | boolean | false | Whether mergeRecipesIntoConfig() auto-merges cached recipes into your config |

{
  "catalog": true,
  "autoMerge": true,
  "servers": { ... }
}
  • autoMerge defaults to false (opt-in) — cached recipes are not automatically added to your server list unless you explicitly enable it. This prevents servers without required credentials from being silently activated.
  • catalog defaults to true — recipe discovery from catalog.aiwerk.ch is enabled by default. Set to false to skip all remote fetching.

> Breaking change (v2.9.0): Previously, all cached recipes whose env vars were present were auto-merged. Now you must set "autoMerge": true to restore that behavior.

Multiple instances of the same server

Auto-discovery uses the recipe name as the config key (e.g., gohighlevel). If you need multiple instances of the same server with different credentials (e.g., two GoHighLevel subaccounts), configure them manually:

// config.json or openclaw.json
{
  "ghl-client-a": {
    "transport": "streamable-http",
    "url": "https://services.leadconnectorhq.com/mcp/",
    "headers": {
      "Authorization": "Bearer ${GHL_TOKEN_A}",
      "locationId": "${GHL_LOCATION_A}"
    }
  },
  "ghl-client-b": {
    "transport": "streamable-http",
    "url": "https://services.leadconnectorhq.com/mcp/",
    "headers": {
      "Authorization": "Bearer ${GHL_TOKEN_B}",
      "locationId": "${GHL_LOCATION_B}"
    }
  }
}

Use unique env var names (e.g., GHL_TOKEN_A instead of GHL_PIT_TOKEN) to prevent auto-discovery from adding a duplicate third entry. Manual config always takes priority over auto-discovered recipes.

> Note: The bundled servers/ directory is deprecated and will be removed in v3.0.0.

Use with Cursor / Windsurf

Add to your MCP config:

{
  "mcpServers": {
    "bridge": {
      "command": "mcp-bridge",
      "args": ["--config", "/path/to/config.json"]
    }
  }
}

Use with OpenClaw

Install as a plugin (handles everything automatically):

openclaw plugins install @aiwerk/openclaw-mcp-bridge

> ⚠️ Important: Always use the full scoped name @aiwerk/openclaw-mcp-bridge. The unscoped openclaw-mcp-bridge on npm is a different, unrelated package.

See @aiwerk/openclaw-mcp-bridge for details.

Configuration

Config: ~/.mcp-bridge/config.json | Secrets: ~/.mcp-bridge/.env

{
  "mode": "router",
  "servers": {
    "todoist": {
      "transport": "stdio",
      "command": "npx",
      "args": ["-y", "@doist/todoist-ai"],
      "env": { "TODOIST_API_KEY": "${TODOIST_API_TOKEN}" },
      "description": "Task management"
    },
    "github": {
      "transport": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" },
      "description": "GitHub repos, issues, PRs"
    },
    "notion": {
      "transport": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-notion"],
      "env": { "NOTION_API_KEY": "${NOTION_TOKEN}" },
      "description": "Notion pages and databases"
    }
  },
  "toolPrefix": true,
  "connectionTimeoutMs": 5000,
  "requestTimeoutMs": 60000,
  "maxBatchSize": 10,
  "schemaCompression": {
    "enabled": true,
    "maxDescriptionLength": 80
  }
}

Schema Compression

In router mode, tool descriptions from upstream servers can be verbose (100-300+ chars each). Schema compression truncates them to save tokens:

  • Enabled by default — descriptions capped at 80 characters
  • Cuts at sentence boundary when possible, otherwise word boundary
  • Use action=schema to retrieve the full uncompressed schema for any tool on demand
"schemaCompression": {
  "enabled": true,
  "maxDescriptionLength": 80
}

Token savings example: 30 Todoist tools: ~2800 tokens uncompressed -> ~1200 compressed (~57% reduction).

To get full details for a specific tool:

mcp(server="todoist", action="schema", tool="find-tasks")

Set "enabled": false to disable compression and return full descriptions.

Result Caching

Router mode can cache successful action=call tool results in memory using an LRU policy.

  • Disabled by default (resultCache.enabled: false)
  • No external dependencies (Map-based implementation)
  • Defaults: maxEntries: 100, defaultTtlMs: 300000 (5 minutes)
  • Cache key: server:tool:stableJson(params)
  • Per-tool TTL override via resultCache.cacheTtl (for example "todoist:find-tasks": 60000)
  • action=refresh clears the result cache
  • Error responses are never cached
"resultCache": {
  "enabled": true,
  "maxEntries": 100,
  "defaultTtlMs": 300000,
  "cacheTtl": { "todoist:find-tasks": 60000 }
}

Intent Routing

Instead of specifying the exact server and tool, describe what you need:

mcp(action="intent", intent="find my tasks for today")

The bridge uses vector embeddings to match your intent to the right server and tool automatically. Returns the best match with a confidence score and alternatives.

Embedding providers (configured via intentRouting.embedding):

| Provider | Config | Requires | |----------|--------|----------| | gemini (default for auto) | GEMINI_API_KEY in .env | Free tier available | | openai | OPENAI_API_KEY in .env | Paid API | | ollama | Local Ollama running | No API key | | keyword | Nothing | Offline fallback, less accurate |

"intentRouting": {
  "embedding": "auto",
  "minScore": 0.3
}
  • auto (default): tries gemini, openai, ollama, then keyword - in order of availability
  • minScore: minimum confidence to return a match (0-1, default: 0.3)
  • Index is built lazily on first action=intent call

Batch Calls

Run multiple tool calls in one round-trip with action="batch" (parallel execution):

{"action":"batch","calls":[{"server":"todoist","tool":"find-tasks","params":{"query":"today"}},{"server":"github","tool":"list_repos","params":{}}]}
{"action":"batch","results":[{"server":"todoist","tool":"find-tasks","result":{"tasks":[]}}, {"server":"github","tool":"list_repos","error":{"error":"mcp_error","message":"..."}}]}

Use maxBatchSize in config to cap requests (default: 10). Failed calls return per-slot error while successful calls still return result.

Security

Three layers of protection for tool results:

Trust Levels

Per-server control over how results are passed to the agent:

"servers": {
  "my-trusted-server": {
    "trust": "trusted"
  },
  "unknown-server": {
    "trust": "untrusted"
  },
  "sketchy-server": {
    "trust": "sanitize"
  }
}

| Level | Behavior | |-------|----------| | trusted (default) | Results pass through as-is | | untrusted | Results tagged with _trust: "untrusted" metadata | | sanitize | HTML tags stripped, known prompt injection patterns removed (best-effort — see note below) |

Tool Filter

Control which tools are visible and callable per server:

"servers": {
  "github": {
    "toolFilter": {
      "deny": ["delete_repository"],
      "allow": ["list_repos", "create_issue", "search_code"]
    }
  }
}
  • deny: block specific dangerous tools
  • allow: whitelist mode - only these tools are visible
  • If both: allowed tools minus denied ones
  • Applied in both tool listing and execution (defense in depth)
Max Result Size

Prevent oversized responses from consuming your context:

{
  "maxResultChars": 50000,
  "servers": {
    "verbose-server": {
      "maxResultChars": 10000
    }
  }
}
  • Global default + per-server override
  • Truncated results include _truncated: true and _originalLength

Adaptive Promotion

Frequently used tools can be automatically "promoted" to standalone tools alongside the mcp meta-tool. The promotion system tracks usage and reports which tools qualify — the host environment (e.g., OpenClaw plugin) decides how to register them.

"adaptivePromotion": {
  "enabled": true,
  "maxPromoted": 10,
  "minCalls": 3,
  "windowMs": 86400000,
  "decayMs": 172800000
}

| Option | Default | Description | |--------|---------|-------------| | enabled | false | Opt-in: must be explicitly enabled | | maxPromoted | 10 | Maximum number of tools to promote | | minCalls | 3 | Minimum calls within window to qualify | | windowMs | 86400000 (24h) | Time window for counting calls | | decayMs | 172800000 (48h) | Demote tools with no calls in this period |

Use action="promotions" to check current promotion state:

mcp(action="promotions")

Returns promoted tools (sorted by frequency) and full usage stats. All tracking is in-memory — promotion rebuilds naturally from usage after restart.

Modes

| Mode | Tools exposed | Best for | |------|--------------|----------| | router (default) | Single mcp meta-tool | 3+ servers, token-conscious agents | | direct | All tools individually | Clients with deferred/lazy tool loading (Claude Code), few servers |

Switch modes via CLI or config:

mcp-bridge init --mode direct    # all tools exposed individually
mcp-bridge init --mode router    # single mcp meta-tool (default)

Or set in ~/.mcp-bridge/config.json:

{ "mode": "direct" }

Router mode — the agent calls mcp(server="todoist", action="list") to discover, then mcp(server="todoist", tool="find-tasks", params={...}) to execute. Best when you have many servers and want minimal token usage.

Direct mode — all tools from all servers are registered individually as todoist_find_tasks, github_list_repos, etc. The bridge still provides unified config, catalog install, OAuth2, security, retries, and reconnection. Ideal for clients that support deferred/lazy tool loading, where tools are registered but not loaded into context until needed.

Multi-Server Tool Resolution

When action="call" is used without server=, mcp-bridge can resolve collisions automatically.

  • Tool exists on exactly one server → direct dispatch.
  • Tool exists on multiple servers + explicit server= → explicit target wins.
  • Tool exists on multiple servers + no server= → score each candidate:
  • base_priority: reverse config order (last=1.0, then 0.9, 0.8, floor 0.1)

…

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.