Skip to main content

Overview

This guide will have you running UMCP with multiple MCP providers in under 5 minutes.
1

Install UMCP

Install via npx (no installation needed) or npm:
npx github:grittyninja/umcp --help
Verify the installation by running npx github:grittyninja/umcp --help
2

Create Configuration File

Run UMCP once to auto-generate the configuration file:
npx github:grittyninja/umcp validate
This creates ~/.config/umcp/umcp.jsonc with detailed placeholder examples.
The config file is created automatically with example providers and comprehensive inline documentation.
3

Configure Your Providers

Edit ~/.config/umcp/umcp.jsonc to add your MCP providers:
~/.config/umcp/umcp.jsonc
{
  "$schema": "https://raw.githubusercontent.com/grittyninja/umcp/main/umcp.config.schema.json",

  "categories": {
    "web_search": {
      "providers": [
        {
          "name": "brave",
          "transport": "stdio",
          "command": "npx",
          "args": ["-y", "@modelcontextprotocol/server-brave-search"],
          "env": {
            "BRAVE_API_KEY": [
              "your_key_1",
              "your_key_2",
              "your_key_3"
            ]
          }
        },
        {
          "name": "tavily",
          "transport": "stdio",
          "command": "npx",
          "args": ["-y", "tavily-mcp"],
          "env": {
            "TAVILY_API_KEY": "your_tavily_key"
          }
        }
      ]
    },
    "project_mgmt": {
      "providers": [
        {
          "name": "linear",
          "transport": "streamable-http",
          "url": "https://linear-mcp.example.com/mcp"
        }
      ]
    }
  }
}
Replace placeholder API keys with your actual keys.
4

Validate Configuration

Verify your configuration is valid:
npx github:grittyninja/umcp validate
Expected output:
Config is valid: /Users/you/.config/umcp/umcp.jsonc
If validation fails, UMCP will output detailed error messages pointing to the exact issue.
5

Preview Tools (Dry Run)

See what tools UMCP will expose without actually connecting to providers:
npx github:grittyninja/umcp dry-run
Example output:
Discovered tools:
- web_search.brave.search → brave_search (from brave/search)
- web_search.tavily.search → tavily_search (from tavily/search)
- project_mgmt.linear.add_task → linear_create_issue (from linear/create_issue)

Total: 3 tools from 3 providers in 2 categories
Dry run discovers tools from all providers and shows how they’ll be namespaced, but doesn’t actually start the server.
6

Start UMCP Server

Launch UMCP with your preferred transport:
7

Connect from Your MCP Host

Configure your MCP host (like Claude Desktop) to use UMCP:
{
  "mcpServers": {
    "umcp": {
      "command": "npx",
      "args": [
        "-y",
        "github:grittyninja/umcp",
        "serve",
        "--transport",
        "stdio"
      ]
    }
  }
}
Restart your MCP host to apply changes.

Understanding Tool Namespacing

UMCP exposes all tools with a predictable three-segment namespace:
{category}.{provider}.{tool}

Category

The top-level grouping defined in your config (e.g., web_search, project_mgmt)

Provider

The specific MCP server within the category (e.g., brave, tavily, linear)

Tool

The actual tool name or alias (e.g., search, add_task)

Example Tool Names

Based on the configuration above:
web_search.brave.search
  ↓         ↓      ↓
category  provider tool
This namespacing eliminates conflicts when multiple providers offer tools with similar names.

Configuration Deep Dive

Let’s break down the key configuration concepts:
Categories are top-level groupings for related providers:
"categories": {
  "web_search": { /* ... */ },
  "project_mgmt": { /* ... */ },
  "databases": { /* ... */ }
}
Rules:
  • Must match [a-zA-Z0-9_-]+ (alphanumeric, underscores, hyphens)
  • At least one category required
  • Used as first segment in tool namespace
Providers are individual MCP servers within a category:
"providers": [
  {
    "name": "brave",
    "transport": "stdio",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-brave-search"]
  }
]
Required fields:
  • name: Provider identifier (must match [a-zA-Z0-9_-]+)
  • transport: "stdio", "sse", or "streamable-http"
  • command + args (for stdio)
  • url (for sse/streamable-http)
Environment variables can be single values or arrays for round-robin rotation:
"env": {
  // Single value
  "TAVILY_API_KEY": "single-key",
  
  // Round-robin rotation
  "BRAVE_API_KEY": [
    "key_1",
    "key_2",
    "key_3"
  ]
}
Arrays rotate on each invocation. State is in-memory and resets on process restart.
Control which tools are exposed and create aliases:
"tools": [
  {
    "upstream": "create_issue",  // Original tool name
    "alias": "add_task",          // Exposed as this
    "enabled": true               // Optional, defaults to true
  }
]
If tools is omitted, UMCP auto-discovers and exposes all upstream tools.
If an upstream tool name contains dots or other invalid characters, you must provide an explicit alias.
UMCP supports three upstream transport types:stdio (default):
{
  "transport": "stdio",
  "command": "npx",
  "args": ["-y", "some-mcp-server"]
}
sse (Server-Sent Events):
{
  "transport": "sse",
  "url": "https://mcp.example.com/events"
}
streamable-http:
{
  "transport": "streamable-http",
  "url": "https://mcp.example.com/api"
}

Common Patterns

Multiple Search Providers with Load Balancing

{
  "categories": {
    "web_search": {
      "providers": [
        {
          "name": "brave",
          "transport": "stdio",
          "command": "npx",
          "args": ["-y", "@modelcontextprotocol/server-brave-search"],
          "env": {
            "BRAVE_API_KEY": [
              "team_key_1",
              "team_key_2",
              "team_key_3",
              "team_key_4"
            ]
          }
        },
        {
          "name": "tavily",
          "transport": "stdio",
          "command": "npx",
          "args": ["-y", "tavily-mcp"],
          "env": {
            "TAVILY_API_KEY": [
              "backup_key_1",
              "backup_key_2"
            ]
          }
        }
      ]
    }
  }
}
Now you have:
  • web_search.brave.search (rotates through 4 keys)
  • web_search.tavily.search (rotates through 2 keys)

Mixed Transport Providers

{
  "categories": {
    "tools": {
      "providers": [
        {
          "name": "local_db",
          "transport": "stdio",
          "command": "node",
          "args": ["/path/to/local/db-server.js"]
        },
        {
          "name": "remote_api",
          "transport": "streamable-http",
          "url": "https://api.example.com/mcp"
        },
        {
          "name": "sse_service",
          "transport": "sse",
          "url": "https://sse.example.com/stream"
        }
      ]
    }
  }
}

Tool Aliasing for Clean Names

{
  "categories": {
    "database": {
      "providers": [
        {
          "name": "postgres",
          "transport": "stdio",
          "command": "mcp-postgres",
          "tools": [
            {
              "upstream": "pg_query_v2",
              "alias": "query"
            },
            {
              "upstream": "pg_insert_v2",
              "alias": "insert"
            },
            {
              "upstream": "pg_update_v2",
              "alias": "update"
            }
          ]
        }
      ]
    }
  }
}
Exposes clean names:
  • database.postgres.query
  • database.postgres.insert
  • database.postgres.update

CLI Commands Reference

npx github:grittyninja/umcp serve --transport stdio

Default Values

--config
string
default:"~/.config/umcp/umcp.jsonc"
Path to UMCP configuration file
--transport
string
default:"stdio"
Transport type: stdio or http
--host
string
default:"127.0.0.1"
HTTP server host (only for --transport http)
--port
number
default:8787
HTTP server port (only for --transport http)
--path
string
default:"/mcp"
HTTP endpoint path (only for --transport http)

Troubleshooting

Run validation to see detailed error messages:
npx github:grittyninja/umcp validate
Common issues:
  • Invalid characters in category/provider names (must be [a-zA-Z0-9_-]+)
  • Missing required fields (name, transport, command/url)
  • Duplicate provider names within a category
  • Empty arrays or objects
Check the structured logs for connection errors:
{"level":"error","event":"provider.error","provider":"brave","message":"..."}
Common causes:
  • Invalid API keys in env
  • Incorrect command or args for stdio providers
  • Unreachable URL for HTTP/SSE providers
  • Missing npm packages (try npx -y to auto-install)
UMCP automatically handles npm cache issues by using a fallback cache at ~/.cache/umcp/npm.To force the fallback cache for a specific provider:
{
  "name": "brave",
  "env": {
    "NPM_CONFIG_CACHE": "/Users/you/.cache/umcp/npm",
    "BRAVE_API_KEY": "..."
  }
}
Use dry-run to see what tools would be discovered:
npx github:grittyninja/umcp dry-run
If tools are missing:
  • Check that the provider is connecting successfully
  • Verify tools mapping if you’re using explicit tool lists
  • Ensure enabled: true for tool mappings (or omit the field)

Next Steps

Configuration Guide

Deep dive into all configuration options

CLI Reference

Complete command-line interface documentation

Examples

Real-world configuration examples

Troubleshooting

Common issues and solutions

Build docs developers (and LLMs) love