@out-of-the-blue-ai/otb-mcp
v1.4.3
Published
Out of the Blue AI's Model Context Protocol (MCP) Gateway - A middleware server to interface with MCP-compatible AI models like Anthropic's Claude.
Readme
MCP Gateway Server
A gateway/proxy server for the Model Context Protocol (MCP) that aggregates and routes requests to multiple MCP backend servers, providing a unified interface for MCP clients.
Installation
Install via npm
npm install -g @out-of-the-blue-ai/otb-mcpQuick Start
Global Installation Setup
Install the package globally:
npm install -g @out-of-the-blue-ai/otb-mcpConfigure Claude Desktop: Edit your Claude Desktop config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{ "mcpServers": { "otb-mcp": { "command": "npx", "args": ["@out-of-the-blue-ai/otb-mcp"], "env": { "API_KEY": "<JWT API Key, obtained from the platform>" } } } }- macOS:
Local Development Setup
If you want to develop or modify the gateway:
# Clone the repository
git clone https://github.com/Out-of-the-Blue-AI/otb-mcp.git
cd otb-mcpConfigure your backend MCP servers in
gateway-config.json(see Configuration section below)Add to Claude Desktop config:
{ "mcpServers": { "local-otb-mcp": { "command": "node", "args": ["<Path to the otb-mcp repo>/dist/index.js"], "env": { "API_KEY": "<JWT API Key, obtained from the platform>" } } } }Install dependencies and build
npm install && npm run buildThat's it! Restart Claude Desktop and all your backend MCP server tools will be available with prefixed names.
Overview
The MCP Gateway Server acts as a middleware layer that:
- Consolidates multiple MCP servers into a single entry point
- Routes tool calls and resource requests to appropriate backend servers
- Aggregates capabilities (tools and resources) from all connected servers
- Prevents naming conflicts through automatic prefixing and URI transformation
This is particularly useful when you want to connect Claude Desktop (or other MCP clients) to multiple MCP servers without having to configure each one individually.
Why Use This?
Problem: Claude Desktop requires you to configure each MCP server individually, which becomes unwieldy with many servers.
Solution: Configure all your MCP servers in gateway-config.json once, then connect Claude to just the gateway. The gateway handles:
- ✅ Connecting to all backend servers
- ✅ Prefixing tool names to avoid conflicts (
db1__query,db2__query) - ✅ Routing requests to the correct backend server
- ✅ Aggregating resources with namespace isolation
How It Works
Architecture
┌─────────────────────────────────────────────────────┐
│ Client (e.g., Claude Desktop) │
└────────────────────┬────────────────────────────────┘
│ stdio
┌────────────────────▼────────────────────────────────┐
│ MCP Gateway Server │
│ ┌──────────────────────────────────────────────┐ │
│ │ Handles: │ │
│ │ - ListTools → aggregate from all servers │ │
│ │ - CallTool → route to correct server │ │
│ │ - ListResources → aggregate from all │ │
│ │ - ReadResource → route to correct server │ │
│ └──────────────────────────────────────────────┘ │
└─────────────┬──────────┬──────────┬────────────────┘
│ │ │
│ stdio │ stdio │ stdio
┌─────────────▼───┐ ┌───▼──────┐ ┌▼────────────────┐
│ MCP Server 1 │ │ MCP │ │ MCP Server 3 │
│ (e.g., DB) │ │ Server 2 │ │ (e.g., Files) │
└─────────────────┘ └──────────┘ └─────────────────┘Request Flow
When listing tools:
- Client requests all available tools
- Gateway queries each connected MCP server for their tools
- Gateway prefixes tool names:
servername__toolname - Gateway adds descriptive prefix to descriptions:
[servername] description - Returns aggregated tool list to client
When calling a tool:
- Client calls
servername__toolname - Gateway parses the server name from the prefix
- Gateway routes the call to the appropriate server with the original tool name
- Returns the server's response to the client
When listing resources:
- Client requests all available resources
- Gateway queries each connected MCP server for their resources
- Gateway transforms URIs:
servername://original-uri - Gateway prefixes resource names:
[servername] name - Returns aggregated resource list to client
When reading a resource:
- Client requests
servername://original-uri - Gateway parses the server name from the URI scheme
- Gateway routes the request to the appropriate server with the original URI
- Returns the server's response to the client
Features
- Multi-Server Support: Connect to unlimited MCP backend servers
- Automatic Namespace Isolation: Prevents naming conflicts through prefixing
- Built-in Gateway Tools:
gateway_statustool shows status of all connected serversget_tenant_contexttool retrieves authorized tenants and context for the current user (requires API_KEY)
- Smart Environment Detection: Automatically uses production API endpoints when installed via npm, development endpoints when running locally
- Environment Variable Support: Pass custom environment variables to each server
- Graceful Cleanup: Proper shutdown handling for all child processes
- Error Resilience: Continues operating even if individual servers fail
- TypeScript: Fully typed with comprehensive type safety
Configuration for Local Development
If you're developing locally and want to connect to additional MCP servers, you can configure them in gateway-config.json:
{
"servers": [
{
"name": "filesystem",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/directory"],
"env": {}
},
{
"name": "postgres",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"],
"env": {
"PGPASSWORD": "your-password"
}
}
]
}Configuration Fields
| Field | Required | Description | Example |
|-------|----------|-------------|---------|
| name | ✅ Yes | Unique identifier for the server. Used as prefix for tools/resources. | "postgres-db" |
| command | ✅ Yes | Command to execute | "npx", "node", "python" |
| args | ⚪ Optional | Array of command-line arguments | ["-y", "@modelcontextprotocol/server-postgres", "postgresql://..."] |
| env | ✅ Yes | Environment variables to pass to the server | {"API_KEY": "eY2A..."} |
How Tool/Resource Naming Works
When you configure a server with name myserver:
- Tools →
myserver__toolname(e.g.,myserver__query) - Resources →
myserver://uri(e.g.,myserver://file.txt) - Descriptions →
[myserver] original description
This prevents naming conflicts when multiple servers have tools with the same name.
Note: For production use, the recommended approach is to install via npm as shown in the Quick Start section above.
Usage Examples
Example 1: Multiple Databases
Connect to multiple PostgreSQL databases through one gateway:
{
"servers": [
{
"name": "production-db",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/production"],
"env": {"PGPASSWORD": "prod-password"}
},
{
"name": "analytics-db",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/analytics"],
"env": {"PGPASSWORD": "analytics-password"}
}
]
}Available tools in Claude:
production-db__query- Query production databaseanalytics-db__query- Query analytics database
Example 2: Mix Different Server Types
Combine filesystem, database, and custom tools:
{
"servers": [
{
"name": "docs",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/docs"]
},
{
"name": "database",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"]
},
{
"name": "custom-tools",
"command": "node",
"args": ["/path/to/your/custom-mcp-server.js"]
}
]
}Example 3: Custom MCP Servers
If you have custom MCP servers:
{
"servers": [
{
"name": "bigquery",
"command": "/usr/local/bin/bigquery-mcp",
"args": ["--stdio"],
"env": {
"BIGQUERY_PROJECT": "my-project-id",
"GOOGLE_APPLICATION_CREDENTIALS": "/path/to/credentials.json"
}
}
]
}Checking Server Status
Use the built-in gateway_status tool in Claude Desktop to see which servers are connected:
[
{
"name": "production-db",
"ready": true,
"tools": 1,
"resources": 0
},
{
"name": "docs",
"ready": true,
"tools": 5,
"resources": 123
}
]Using the Tenant Context Tool
The gateway includes a built-in get_tenant_context tool that retrieves authorized tenants and context for the current user.
Smart Environment Detection
- When installed via npm: Automatically uses production API (
https://app.outoftheblue.ai) - When running locally: Uses QA/development API (
https://qa.app.outoftheblue.ai) - No configuration needed - the environment is detected automatically
Configuration
The API key is already configured in the main setup (see Quick Start section above). The tool uses the same API_KEY environment variable.
Usage
In Claude Desktop, simply call the get_tenant_context tool to retrieve your authorized tenants list with metadata like timezone and currency.
Note: The API key should be the JWT token you obtain from the Out of the Blue platform.
Development & Testing
Test the gateway directly:
npm start
# The gateway will load and connect to all backend servers
# Check stderr for connection statusDevelopment mode with auto-reload:
npm run dev
# Automatically rebuilds and restarts when you modify src/index.tsProject Structure
otb-mcp/
├── src/
│ ├── index.ts # Main gateway server implementation
│ └── config/
│ └── gateway-config.json # Default server configuration
├── dist/ # Compiled JavaScript (generated)
├── gateway-config.example.json # Example configuration
├── package.json # Project metadata and dependencies
├── tsconfig.json # TypeScript compiler configuration
└── README.md # This fileTechnical Details
Implementation Highlights
Gateway Pattern: Acts as a single entry point (proxy) that routes requests to multiple backend services.
Namespace Isolation:
- Tools:
${serverName}__${toolName} - Resources:
${serverName}://${originalUri}
Lazy Loading: Servers are initialized asynchronously during startup. The gateway continues operating even if some servers fail to initialize.
Process Management: Each backend MCP server runs as a child process. The gateway manages their lifecycle and ensures proper cleanup on shutdown (SIGINT/SIGTERM).
Transport: Uses StdioServerTransport for client communication and StdioClientTransport for backend server connections.
Smart Environment Detection: Automatically determines the correct API endpoints based on installation method:
- When installed via npm (path contains
node_modules): Uses production endpoints - When running from source (local development): Uses QA/development endpoints
Key Classes and Interfaces
MCPGatewayServer (Main class in src/index.ts):
- Initializes and manages multiple MCP client connections
- Routes requests based on tool/resource naming
- Aggregates capabilities from all servers
MCPServer (Interface):
{
name: string; // Server identifier
client: Client; // MCP SDK client instance
transport: StdioClientTransport;
ready: boolean; // Connection status
tools: Tool[]; // Cached tool list
resources: Resource[]; // Cached resource list
}GatewayConfig (Interface):
{
servers: {
name: string;
command: string;
args?: string[];
env?: Record<string, string>;
}[];
}Troubleshooting
Common Issues & Solutions
❌ "Failed to load config" Error
Symptom: Error: ENOENT: no such file or directory, open '/gateway-config.json'
Solution: This error typically occurs during local development. The gateway comes with a default configuration for Out of the Blue services. If you need custom backend servers, create a gateway-config.json file:
# Create basic config
cat > gateway-config.json << 'EOF'
{
"servers": []
}
EOF❌ Claude Desktop Can't Find Gateway
Symptom: Gateway doesn't appear in Claude Desktop
Solutions:
- ✅ Use absolute path in Claude Desktop config (not relative)
- ✅ Run
npm run buildto compile TypeScript - ✅ Restart Claude Desktop after config changes
- ✅ Check logs:
~/Library/Logs/Claude/mcp-server-gateway.log
❌ Tools Not Appearing with Prefixes
Symptom: Claude sees backend servers directly instead of through gateway
Solution: Make sure Claude Desktop config only has the gateway, not individual backend servers:
{
"mcpServers": {
"gateway": {
"command": "node",
"args": ["/path/to/mcp-gateway/dist/index.js"]
}
// ❌ Don't add individual backend servers here
// ✅ Add them to gateway-config.json instead
}
}❌ Backend Server Won't Connect
Symptom: Failed to start server X
Debug steps:
# 1. Test the command directly
npx -y @modelcontextprotocol/server-postgres postgresql://localhost/mydb
# 2. Check environment variables are correct
# 3. Verify network connectivity (for database servers)
# 4. Check logs with: npm start 2>&1 | grep "ERROR"❌ Port Already in Use
Symptom: Error: listen EADDRINUSE: address already in use
Solution: Some MCP servers try to bind to ports. Check what's using the port:
lsof -i :PORT_NUMBER
kill PID_NUMBER # if safe to killGetting Help
Check server status:
# In Claude Desktop, use the gateway_status tool
# It shows which servers are connected and their tool/resource countsView logs:
# macOS
tail -f ~/Library/Logs/Claude/mcp-server-gateway.log
# Or run directly to see output
npm start 2>&1 | tee debug.logCommon requirements:
- ✅ MCP SDK version: 0.5.0+
- ✅ Node.js version: 18.0.0+
- ✅ Valid JSON in gateway-config.json
- ✅ Absolute paths in Claude Desktop config
FAQ
Q: Can I use this with Claude Code or other MCP clients? A: Yes! The gateway works with any MCP client that supports stdio transport (Claude Desktop, Claude Code, etc.).
Q: How many backend servers can I connect? A: Unlimited! The gateway can handle as many backend servers as you configure.
Q: What happens if a backend server fails? A: The gateway continues operating with the remaining servers. Failed servers are logged to stderr.
Q: Can backend servers have tools with the same name? A: Yes! The gateway automatically prefixes tool names with the server name to prevent conflicts.
Q: Do I need to restart the gateway when changing backend server configs?
A: Yes. Edit gateway-config.json, rebuild if needed (npm run build), then restart Claude Desktop.
Q: Can I mix different types of MCP servers? A: Absolutely! Mix PostgreSQL, filesystem, custom tools, APIs, etc. - any MCP-compatible server works.
Q: How do I know which tools came from which server?
A: Tool names are prefixed (e.g., postgres-db__query) and descriptions include [servername] prefix.
Q: What if a server doesn't support resources? A: No problem! The gateway handles this gracefully. Servers can have tools only, resources only, or both.
Q: How does the environment detection work for API endpoints?
A: The gateway automatically detects if it's running from an npm installation (path contains node_modules) or from source code, and uses the appropriate API endpoints accordingly.
Q: What is the get_tenant_context tool?
A: It's a built-in tool that retrieves authorized tenants and their context (timezone, currency, etc.) for the current user. It requires an API_KEY to be configured.
Dependencies
Production:
@modelcontextprotocol/sdk(^0.5.0) - Official MCP SDK
Development:
typescript(^5.0.0) - TypeScript compiler@types/node(^20.0.0) - Node.js type definitions
Programmatic Usage
You can also use this package programmatically in your Node.js applications:
import { MCPGatewayServer, GatewayConfig } from '@out-of-the-blue-ai/otb-mcp';
const config = {
servers: [
{
name: "my-server",
command: "my-mcp-server",
args: ["--arg1", "value1"]
}
]
};
const gateway = new MCPGatewayServer();
await gateway.run();Publishing
To publish a new version:
# Update version
npm version patch # or minor/major
# Build and publish
npm publishDevelopment
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make your changes
- Build and test:
npm run build - Submit a pull request
Scripts
npm run build- Build the TypeScript codenpm run clean- Remove built filesnpm run dev- Development mode with hot reloadnpm start- Start the gateway servernpm run lint- Run linter (when configured)
Package Information
This package provides both:
- CLI Tool: Install globally with
npm install -g @out-of-the-blue-ai/otb-mcpand usemcp-gatewaycommand - Library: Import types and classes for programmatic usage in your Node.js applications
Package Contents
- Pre-built JavaScript and TypeScript declaration files
- Gateway configuration template
- CLI binary for global installation
- Full source code and documentation
License
MIT
First-Time Setup
# 1. Clone the repository
git clone <your-repo-url>
cd mcp-gateway-server
# 2. Install dependencies
npm install
# 3. Copy example config and customize it
cp gateway-config.example.json gateway-config.json
# Edit gateway-config.json with your backend servers
# 4. Build the project
npm run build
# 5. Test it works
npm startMaking Changes
# 1. Create a feature branch
git checkout -b feature/your-feature-name
# 2. Make your changes to src/index.ts
# 3. Build and test
npm run build
npm start # Test manually
# 4. Commit your changes
git add src/
git commit -m "Description of your changes"
# 5. Push and create PR
git push origin feature/your-feature-nameImportant Notes
⚠️ Never commit gateway-config.json - It contains passwords and sensitive data!
- ✅ DO commit:
gateway-config.example.json(sanitized examples) - ❌ DON'T commit:
gateway-config.json(real credentials)
Contributing
Contributions are welcome! Please ensure:
- TypeScript code compiles without errors (
npm run build) - Code follows existing patterns and style
- All features are documented in README
- No sensitive data committed (check with
git diffbefore committing) - Test with real MCP servers before submitting PR
