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

@gongrzhe/mcp-proxy-server

v0.0.2

Published

MCP proxy server with multiple downstream server support and stateless architecture

Readme

MCP Proxy Server

A stateless HTTP proxy server for aggregating multiple Model Context Protocol (MCP) servers into a single endpoint. This allows AI clients to access tools and resources from multiple MCP servers through one unified interface.

Features

  • Stateless Architecture: Each request is handled independently without session management
  • Multiple MCP Server Support: Connect to and aggregate multiple downstream MCP servers
  • Tool Aggregation: All tools, prompts, and resources from downstream servers are exposed with prefixed names
  • Authorization Pass-through: Forwards Bearer tokens to downstream servers
  • Advanced Configuration: JSON configuration files with template variables and environment substitution
  • Tool Management: Enable/disable specific tools via configuration or runtime API
  • Health Monitoring: Real-time server health tracking with 30-second intervals
  • Auto-Reconnection: Automatic reconnection to failed servers every 60 seconds
  • MongoDB Logging: Comprehensive logging of tool calls with HTTP metadata analytics
  • Admin API: REST endpoints for runtime tool management and health monitoring
  • Header Template System: Dynamic header processing with variable substitution
  • Error Handling: Graceful error handling with detailed error responses

Quick Start

Installation

npm install

Build

npm run build

Configuration

Simple Configuration (URLs only)

Set the DOWNSTREAM_MCP_SERVERS environment variable with a comma-separated list of MCP server URLs:

export DOWNSTREAM_MCP_SERVERS="https://mcp.context7.com/mcp,https://mcp.deepwiki.com/mcp"

Advanced Configuration (JSON)

For advanced features like authentication, tool filtering, and header templates, use a JSON configuration file:

export DOWNSTREAM_MCP_SERVERS="./config/servers.json"

Example configuration file:

{
  "slack": {
    "url": "http://localhost:30003/mcp",
    "variables": {
      "slack_token": "xoxp-your-token-here",
      "workspace_id": "T1234567"
    },
    "headers": {
      "Authorization": "Bearer {{slack_token}}",
      "X-Workspace": "{{workspace_id}}",
      "X-Custom-Header": "proxy-${USER}"
    },
    "tools": {
      "enabled": ["channels_*", "users_list"],
      "disabled": ["admin_*", "files_delete"],
      "defaultEnabled": false
    }
  },
  "context7": {
    "url": "https://mcp.context7.com/mcp",
    "tools": {
      "disabled": ["dangerous_*"],
      "defaultEnabled": true
    }
  }
}

Template Variables

The proxy supports three types of variable substitution:

  1. Environment Variables: ${VAR_NAME} - Replaced with process.env.VAR_NAME
  2. Custom Variables: {{variable_name}} - Defined in the variables section
  3. Direct Replacements: String replacements using the replacements section

Tool Filtering

Control which tools are available from each server:

  • enabled: Array of tool names or patterns (wildcards supported with *)
  • disabled: Array of tool names or patterns to disable
  • defaultEnabled: Whether tools are enabled by default (default: true)

Filter Priority: disabled list > enabled list > defaultEnabled

Start Server

# Using compiled JavaScript (recommended)
npm run start:js

# Or using TypeScript directly
npm start

# With MongoDB logging
export MONGODB_URI="mongodb://localhost:27017/mcp_proxy"
npm run start:js

The server will start on port 30000 by default, or use the PORT environment variable.

Usage

List Available Tools

curl -X POST http://localhost:30000/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "id": "1", "method": "tools/list", "params": {}}'

Call a Tool

Tools are prefixed with their source server URL (with special characters replaced by underscores):

curl -X POST http://localhost:30000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0", 
    "id": "2", 
    "method": "tools/call", 
    "params": {
      "name": "https___mcp_deepwiki_com_mcp_read_wiki_structure",
      "arguments": {"repoName": "facebook/react"}
    }
  }'

With Authorization

curl -X POST http://localhost:30000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer your-token-here" \
  -d '{"jsonrpc": "2.0", "id": "3", "method": "tools/call", "params": {...}}'

Tool Management

Runtime Tool Control

The proxy provides REST API endpoints for managing tool availability at runtime:

List All Tools and States

curl http://localhost:30000/admin/tools

Response includes all available tools with their enabled/disabled status and whether they're controlled by configuration or runtime state.

Enable a Tool

curl -X POST http://localhost:30000/admin/tools/http%3A%2F%2Flocalhost%3A30003%2Fmcp/tool_name/enable \
  -H "Content-Type: application/json" \
  -d '{"updatedBy": "admin"}'

Disable a Tool

curl -X POST http://localhost:30000/admin/tools/http%3A%2F%2Flocalhost%3A30003%2Fmcp/tool_name/disable \
  -H "Content-Type: application/json" \
  -d '{"updatedBy": "admin"}'

Remove Runtime State

curl -X DELETE http://localhost:30000/admin/tools/http%3A%2F%2Flocalhost%3A30003%2Fmcp/tool_name

Note: Server URLs in API paths must be URL-encoded.

Priority System

Tool availability is determined by this priority order:

  1. Runtime State (MongoDB) - Highest priority
  2. Configuration filtering - Middle priority
  3. Default enabled - Lowest priority

MongoDB Logging & Analytics

Setup

Set the MONGODB_URI environment variable to enable comprehensive logging:

export MONGODB_URI="mongodb://localhost:27017/mcp_proxy"

Features

  • Tool Call Logging: Every tool call with timing, parameters, and results
  • HTTP Metadata: Request/response headers, status codes, client IPs, User-Agent
  • Accept Header Tracking: Content negotiation patterns
  • Runtime Tool States: Persistent enable/disable states with audit trail
  • Performance Analytics: Duration, error rates, usage patterns

Analytics Scripts

Analyze your MCP proxy usage:

# View comprehensive analytics
MONGODB_URI="mongodb://localhost:27017/mcp_proxy" node scripts/analyze-tool-calls.js

# View detailed sample record
MONGODB_URI="mongodb://localhost:27017/mcp_proxy" node scripts/view-sample-record.js

Health Monitoring & Auto-Reconnection

Real-time Server Health Tracking

The proxy automatically monitors all downstream MCP servers with:

  • 30-second health checks via client.listTools()
  • Immediate disconnect detection (within 5 seconds)
  • Automatic reconnection every 60 seconds for failed servers
  • Persistent health history in MongoDB
  • Real-time status tracking with detailed metrics

Health Status API

View Server Health

# Get health status for all servers
curl http://localhost:30000/admin/health

# Get health status for specific server
curl "http://localhost:30000/admin/health?serverUrl=http://localhost:30003/mcp"

Response includes:

  • Current status (connected, disconnected, reconnecting, error)
  • Last connected/disconnected timestamps
  • Health check history
  • Reconnection attempt counts
  • Error messages

Manual Health Operations

# Perform immediate health check
curl -X POST http://localhost:30000/admin/health/http%3A%2F%2Flocalhost%3A30003%2Fmcp/check

# Force reconnection attempt  
curl -X POST http://localhost:30000/admin/health/http%3A%2F%2Flocalhost%3A30003%2Fmcp/reconnect

Health Monitoring Demo

Use the included demo script to monitor health status:

# Show current health status
node scripts/health-monitor-demo.js status

# Perform health check on specific server
node scripts/health-monitor-demo.js check "https://mcp.context7.com/mcp"

# Monitor health changes for 60 seconds
node scripts/health-monitor-demo.js monitor 60

# Attempt manual reconnection
node scripts/health-monitor-demo.js reconnect "http://localhost:30003/mcp"

Auto-Reconnection Behavior

When a server goes offline:

  1. Detection: Health check failure detected within 30 seconds
  2. Status Change: Server marked as disconnectederror
  3. Auto-Reconnection: Attempts every 60 seconds automatically
  4. Recovery: When server returns, immediate reconnection
  5. Logging: All events logged to MongoDB with timestamps

MongoDB Health Data

Health monitoring data is stored in the server_health collection:

{
  serverUrl: "http://localhost:30003/mcp",
  status: "connected",
  lastConnected: "2025-08-16T15:30:00.000Z",
  lastDisconnected: "2025-08-16T15:25:00.000Z", 
  lastHealthCheck: "2025-08-16T15:31:00.000Z",
  reconnectAttempts: 0,
  errorMessage: null
}

Example Use Cases

1. Multi-Service Integration

# Configuration for integrating Slack, GitHub, and documentation services
export DOWNSTREAM_MCP_SERVERS='{
  "slack": {
    "url": "http://localhost:30003/mcp",
    "headers": {"Authorization": "Bearer ${SLACK_TOKEN}"},
    "tools": {"enabled": ["channels_*", "users_*"], "defaultEnabled": false}
  },
  "github": {
    "url": "http://localhost:30002/mcp", 
    "headers": {"Authorization": "token ${GITHUB_TOKEN}"},
    "tools": {"disabled": ["delete_*", "admin_*"]}
  },
  "docs": {
    "url": "https://mcp.context7.com/mcp"
  }
}'

2. Development vs Production Tool Control

# Enable all tools in development
export DOWNSTREAM_MCP_SERVERS='{"dev": {"url": "http://localhost:30001/mcp"}}'

# Restrict tools in production
export DOWNSTREAM_MCP_SERVERS='{
  "prod": {
    "url": "http://production-server/mcp",
    "tools": {"enabled": ["read_*", "list_*"], "defaultEnabled": false}
  }
}'

3. Runtime Tool Management Workflow

# 1. Check current tool states
curl http://localhost:30000/admin/tools

# 2. Temporarily disable a problematic tool
curl -X POST http://localhost:30000/admin/tools/server/problematic_tool/disable \
  -H "Content-Type: application/json" -d '{"updatedBy": "ops-team"}'

# 3. Re-enable after fix
curl -X POST http://localhost:30000/admin/tools/server/problematic_tool/enable \
  -H "Content-Type: application/json" -d '{"updatedBy": "ops-team"}'

# 4. Remove runtime override (revert to config)
curl -X DELETE http://localhost:30000/admin/tools/server/problematic_tool

4. Production Health Monitoring Workflow

# Monitor all servers continuously
node scripts/health-monitor-demo.js monitor 300  # 5 minutes

# Set up alerts for server failures
while true; do
  offline_servers=$(curl -s http://localhost:30000/admin/health | \
    jq -r '.data.currentStatuses[] | select(.status != "connected") | .serverUrl')
  
  if [ ! -z "$offline_servers" ]; then
    echo "ALERT: Servers offline: $offline_servers"
    # Send notification (email, Slack, etc.)
  fi
  
  sleep 60
done

# Manual recovery of failed server
curl -X POST http://localhost:30000/admin/health/http%3A%2F%2Ffailed-server%2Fmcp/reconnect

# Check historical health data
MONGODB_URI="mongodb://localhost:27017/mcp_proxy" node -e "
const { MongoClient } = require('mongodb');
(async () => {
  const client = new MongoClient('mongodb://localhost:27017/mcp_proxy');
  await client.connect();
  const collection = client.db('mcp_proxy').collection('server_health');
  
  // Get servers with high failure rates
  const healthStats = await collection.aggregate([
    { \$group: { 
        _id: '\$serverUrl', 
        totalReconnects: { \$sum: '\$reconnectAttempts' },
        avgReconnects: { \$avg: '\$reconnectAttempts' }
      }
    },
    { \$sort: { totalReconnects: -1 } }
  ]).toArray();
  
  console.log('Server Health Statistics:', healthStats);
  await client.close();
})();
"

How It Works

Tool Name Mapping

The proxy server transforms tool names from downstream servers by prefixing them with the server URL:

  • Original tool: read_wiki_structure
  • From server: https://mcp.deepwiki.com/mcp
  • Proxied name: https___mcp_deepwiki_com_mcp_read_wiki_structure

Request Flow

  1. Client sends MCP request to proxy server
  2. Proxy server creates a fresh MCP server instance (stateless)
  3. For tool calls, proxy parses the prefixed tool name to identify the target server
  4. Health check: Proxy verifies server status before forwarding request
  5. Request is forwarded to the appropriate downstream MCP server
  6. Response is returned to the client
  7. Background: Health monitoring continues every 30 seconds

Architecture

┌─────────────┐    HTTP POST    ┌─────────────────┐    MCP Client    ┌────────────────┐
│   AI Client │ ──────────────► │   MCP Proxy     │ ──────────────► │ MCP Server 1   │
│             │                 │    Server       │                 │ (Context7)     │
└─────────────┘                 │                 │ ──────────────► ┌────────────────┐
                                │  (Stateless)    │                 │ MCP Server 2   │
                                └─────────────────┘                 │ (DeepWiki)     │
                                                                    └────────────────┘

Environment Variables

  • DOWNSTREAM_MCP_SERVERS: Comma-separated list of downstream MCP server URLs or path to JSON config file
  • PORT: Server port (default: 30000)
  • MONGODB_URI: MongoDB connection string for logging and tool state management (optional)
  • USER: User identifier for template substitution (optional)

API Endpoints

MCP Protocol Endpoints

  • POST /mcp: Main MCP endpoint for all requests
  • GET /mcp: Returns 405 Method Not Allowed (stateless mode)
  • DELETE /mcp: Returns 405 Method Not Allowed (stateless mode)

Admin API Endpoints

Tool Management

  • GET /admin/tools: List all tools and their enabled/disabled states
  • POST /admin/tools/:serverUrl/:toolName/enable: Enable a specific tool at runtime
  • POST /admin/tools/:serverUrl/:toolName/disable: Disable a specific tool at runtime
  • DELETE /admin/tools/:serverUrl/:toolName: Remove runtime state for a tool (reverts to config)

Health Monitoring

  • GET /admin/health: View health status of all servers
  • GET /admin/health?serverUrl=<url>: View health status of specific server
  • POST /admin/health/:serverUrl/check: Perform immediate health check on server
  • POST /admin/health/:serverUrl/reconnect: Force reconnection attempt to server

Development

Scripts

  • npm start: Start with TypeScript (ts-node)
  • npm run build: Compile TypeScript to JavaScript
  • npm run start:js: Start compiled JavaScript version
  • npm test: Run tests (not implemented)

Project Structure

mcp-proxy-server/
├── src/
│   └── index.ts          # Main server implementation
├── config/               # Configuration examples
│   ├── servers-template-examples.json
│   ├── servers-with-tool-filtering.json
│   └── servers-local-only.json
├── scripts/              # Analytics and utilities
│   ├── analyze-tool-calls.js
│   ├── view-sample-record.js
│   └── health-monitor-demo.js
├── dist/                 # Compiled JavaScript (after build)
├── package.json
├── tsconfig.json
└── README.md

Example Downstream Servers

  • Context7: https://mcp.context7.com/mcp - Library documentation and code examples
  • DeepWiki: https://mcp.deepwiki.com/mcp - GitHub repository documentation

Error Handling

The server provides detailed error responses:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32603,
    "message": "Internal server error"
  },
  "id": null
}

Common errors:

  • No client found for tool: <tool_name> - Tool name doesn't match any connected server
  • Tool '<tool_name>' is disabled on server '<server_url>' - Tool is disabled via configuration or runtime state
  • Arguments are required - Missing arguments in tool call
  • Connection errors to downstream servers
  • Client must accept both application/json and text/event-stream - Missing Accept header

Limitations

  • Stateless Only: No session management or persistent connections
  • HTTP Transport: Only supports HTTP-based MCP servers
  • URL Encoding: Server URLs in admin API paths must be URL-encoded
  • MongoDB Dependency: Tool management and logging features require MongoDB

License

ISC

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request