npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vijaynkw/mcp-router

v1.0.0

Published

Smart MCP router — four modes (router, delegated, passthrough, smart) with support for Anthropic Claude, Ollama, Groq, and any OpenAI-compatible provider

Readme

mcp-router

Proxy all your MCP servers behind one smart router — choose how much AI you want.

Instead of exposing 50+ tools to your AI editor and hoping it picks the right one, mcp-router sits in front of all your MCP servers and gives you four modes to match your workflow and budget.


Modes at a glance

| Mode | Your editor sees | AI does | API key needed | |---|---|---|---| | router | 1 tool (route) | picks and executes | yes | | delegated | 2 tools (select + execute) | picks only — you review before execution | yes | | passthrough | all downstream tools directly | nothing | no | | smart | all tools + recommend | recommends only — editor executes | yes |


Why

AI editors connect to MCP servers to give agents superpowers — file access, GitHub, databases, Slack, etc. The problem: the more MCP servers you add, the more tools the agent sees. Five servers × ten tools each = 50 tools cluttering every prompt. The agent slows down, picks the wrong tool, or gets confused.

mcp-router solves this by standing between your editor and all your MCP servers, letting you control exactly how many tools the editor sees and how much AI is involved.


Requirements

  • Node.js >= 18
  • An AI provider (see Providers — Ollama is free and local)

Install

npm install -g mcp-router

Or run without installing:

npx mcp-router

Quick Start

1. Create mcp-router.config.json:

{
  "mode": "router",
  "mcpServers": {
    "filesystem": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/your/path"]
    },
    "github": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "ghp_your_token_here" }
    }
  },
  "claude": {
    "model": "claude-sonnet-4-6"
  }
}

2. Set your API key (skip if using Ollama):

export ANTHROPIC_API_KEY=sk-ant-...

3. Add to your editor (~/.windsurf/mcp_config.json, ~/.cursor/mcp.json, or claude_desktop_config.json):

{
  "mcpServers": {
    "router": {
      "command": "npx",
      "args": ["mcp-router"],
      "env": {
        "ANTHROPIC_API_KEY": "sk-ant-...",
        "MCP_ROUTER_CONFIG": "/absolute/path/to/mcp-router.config.json"
      }
    }
  }
}

Restart your editor — you'll see one route tool instead of all the individual tools.


Modes

router mode (default)

Your editor sees 1 tool: route(task). Describe what you want in plain English — the router picks the right downstream tool, executes it (chaining multiple calls if needed), and returns the result. You never need to know tool names.

Your editor ──── route("create a GitHub issue about X") ────► mcp-router
                                                                    │
                                                            AI picks + calls
                                                                    │
                                                        github__create_issue(...)
                                                                    │
Your editor ◄─────────────── result ────────────────────────────────┘

Config:

{
  "mode": "router",
  "mcpServers": { ... },
  "claude": { "model": "claude-sonnet-4-6", "maxTokens": 8192, "maxIterations": 5 }
}

Best for: Fully automated pipelines, single-user setups where you trust the AI to execute.


delegated mode

Your editor sees 2 tools: select(task) and execute(tool, args). The AI only classifies which tool to use — you (or your editor) review the selection and args before anything runs.

select("get my open GitHub issues")
        │
        AI reads names+descriptions only (no schemas — tiny payload)
        │
        returns { tool: "github__list_issues", schema: {...}, suggestedArgs: {...}, reason: "..." }
        │
[you review in Windsurf/Cursor]
        │
execute("github__list_issues", { state: "open" })
        │
        router proxies to GitHub MCP — no AI involved
        │
        result

Config:

{
  "mode": "delegated",
  "mcpServers": { ... },
  "claude": { "model": "claude-haiku-4-5-20251001", "maxTokens": 1024 }
}

Best for: Windsurf / Cursor users who want to review tool calls before execution. Most cost-efficient AI mode — Haiku with 1K tokens is sufficient.


passthrough mode

Your editor sees all downstream tools directly (no AI involved at all). The router acts as a multiplexer — it connects to all your MCP servers and exposes their tools under namespaced names (server__tool).

Your editor ──── filesystem__list_directory("/tmp") ────► mcp-router ──► filesystem MCP
Your editor ──── github__create_issue({...})         ────► mcp-router ──► github MCP

Config:

{
  "mode": "passthrough",
  "mcpServers": { ... }
}

No API key needed. The router handles connection management and tool namespacing — you still get unified access to all servers through one MCP connection.

Best for: Editors with good native tool selection, situations where you want full visibility and control over every call.


smart mode

Your editor sees all downstream tools (like passthrough) plus one extra recommend(task) tool. When you call recommend, the AI suggests which tool to use and what args — but the editor executes it directly using its own context.

recommend("search for TODO comments")
        │
        AI reads names+descriptions, returns { tool, args, reason }
        │
[editor calls the recommended tool directly]

Config:

{
  "mode": "smart",
  "mcpServers": { ... },
  "claude": { "model": "claude-haiku-4-5-20251001" }
}

Best for: Editors that handle tool execution well but benefit from AI-assisted discovery.


Providers

mcp-router works with Anthropic Claude (paid) or any OpenAI-compatible endpoint (Ollama, Groq, LM Studio, OpenRouter). Configure via the provider block.

Anthropic Claude (default)

{
  "claude": {
    "model": "claude-sonnet-4-6",
    "maxTokens": 8192,
    "maxIterations": 5
  }
}

Requires ANTHROPIC_API_KEY env var. Available models: claude-sonnet-4-6, claude-haiku-4-5-20251001, claude-opus-4-7.

Ollama — free, runs locally

ollama serve
ollama pull llama3.1:8b
{
  "provider": {
    "type": "openai-compatible",
    "baseUrl": "http://localhost:11434/v1",
    "model": "llama3.1:8b",
    "apiKey": "ollama"
  }
}

No API key env var needed. Any model with tool-calling support works for router mode (llama3.1, mistral, qwen2.5). Any model works for delegated and smart modes.

Groq — free tier, fast cloud inference

Get a free API key at console.groq.com.

{
  "provider": {
    "type": "openai-compatible",
    "baseUrl": "https://api.groq.com/openai/v1",
    "model": "llama-3.1-8b-instant",
    "apiKey": "gsk_your_key_here"
  }
}

LM Studio / OpenRouter

Same pattern — set baseUrl to your endpoint and model to the model name.

provider fields

| Field | Required | Description | |---|---|---| | type | yes | "openai-compatible" | | baseUrl | yes | Base URL of the OpenAI-compatible API | | model | yes | Model name (provider-specific) | | apiKey | no | API key — optional for local endpoints like Ollama | | maxTokens | no | Max tokens per response (default: 8192 for router, 1024 for delegated/smart) | | maxIterations | no | Max agentic iterations in router mode (default: 5) |


Configuration reference

mcp-router.config.json

| Field | Type | Default | Description | |---|---|---|---| | mcpServers | object | required | Map of named downstream MCP servers | | mode | string | "router" | router, delegated, passthrough, or smart | | provider | object | — | AI provider config (Ollama, Groq, etc.) — overrides claude block | | claude | object | — | Anthropic provider config | | claude.model | string | claude-sonnet-4-6 | Claude model | | claude.maxTokens | number | 8192 | Max tokens per response | | claude.maxIterations | number | 5 | Max tool calls chained per request (router mode) |

Server types

stdio — spawns a local process (most MCP servers):

{
  "type": "stdio",
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"],
  "env": { "EXTRA_VAR": "value" }
}

sse — connects to a remote SSE endpoint:

{
  "type": "sse",
  "url": "http://localhost:3001/sse",
  "headers": { "Authorization": "Bearer token" }
}

Environment variables

| Variable | Default | Description | |---|---|---| | ANTHROPIC_API_KEY | — | Required when using Anthropic provider | | MCP_ROUTER_CONFIG | ./mcp-router.config.json | Path to config file | | TRANSPORT | stdio | stdio or http | | PORT | 3000 | HTTP port (when TRANSPORT=http) | | HOST | 127.0.0.1 | HTTP bind address (when TRANSPORT=http) | | MCP_ROUTER_TOKEN | — | Bearer token to protect HTTP endpoints |


HTTP Mode

Run as an HTTP server instead of stdio — useful for remote or multi-client setups:

TRANSPORT=http PORT=3000 ANTHROPIC_API_KEY=sk-ant-... npx mcp-router
  • MCP endpoint: POST http://127.0.0.1:3000/mcp
  • Health check: GET http://127.0.0.1:3000/health
{ "status": "ok", "tools": 14, "servers": ["filesystem", "github"] }

Cost

| Mode | AI calls per request | Cheapest model | Approx cost | |---|---|---|---| | router | 1 + 1 per chained tool call | Haiku / Llama 3.1 8B | ~$0.0005–0.015 | | delegated | 1 (classification only) | Haiku / Llama 3.1 8B | ~$0.0001–0.0003 | | smart | 1 (recommendation only) | Haiku / Llama 3.1 8B | ~$0.0001–0.0003 | | passthrough | 0 | — | free |

Using Ollama or Groq's free tier makes all AI modes effectively free.


Security Considerations

Config file

Never commit mcp-router.config.json — it may contain API keys and tokens. It is listed in .gitignore. Use mcp-router.config.example.json as a template.

HTTP mode

  • Always set MCP_ROUTER_TOKEN when running HTTP mode:

    MCP_ROUTER_TOKEN=your-secret TRANSPORT=http npx mcp-router

    All requests must include Authorization: Bearer your-secret.

  • Never bind to 0.0.0.0 without authentication. The default HOST=127.0.0.1 is safe for local use.

  • For internet-facing deployments, put the router behind a reverse proxy (nginx, Caddy) that handles TLS.

Stdio mode

Only accepts connections from the local editor process — no network exposure. Safest for personal use.


Development

git clone https://github.com/vijaynw/mcp-router
cd mcp-router
npm install
npm run build   # compile to dist/
npm start       # run compiled output

License

MIT © Vijaynw