A manager server for MCP servers that handles process management and tool routing.
MCP Hub acts as a central coordinator for MCP servers and clients, providing two key interfaces:
This dual-interface approach means you can manage servers through the Hub's UI while MCP clients (Claude Desktop, Cline, etc.) only need to connect to one endpoint (localhost:37373/mcp
) to access all capabilities. Implements MCP 2025-03-26 specification.
Category | Feature | Support | Notes |
---|---|---|---|
Transport | |||
streamable-http | ✅ | Primary transport protocol for remote servers | |
SSE | ✅ | Fallback transport for remote servers | |
STDIO | ✅ | For running local servers | |
Authentication | |||
OAuth 2.0 | ✅ | With PKCE flow | |
Headers | ✅ | For API keys/tokens | |
Capabilities | |||
Tools | ✅ | List tools | |
🔔 Tool List Changed | ✅ | Real-time updates | |
Resources | ✅ | Full support | |
🔔 Resource List Changed | ✅ | Real-time updates | |
Resource Templates | ✅ | URI templates | |
Prompts | ✅ | Full support | |
🔔 Prompts List Changed | ✅ | Real-time updates | |
Roots | ❌ | Not supported | |
Sampling | ❌ | Not supported | |
Completion | ❌ | Not supported | |
Marketplace | |||
Server Discovery | ✅ | Browse available servers | |
Installation | ✅ | Auto configuration | |
Real-time | |||
Status Updates | ✅ | Server & connection state | |
Capability Updates | ✅ | Automatic refresh | |
Event Streaming to clients | ✅ | SSE-based | |
Auto Reconnection | ✅ | With backoff | |
Development | |||
Hot Reload | ✅ | Auto restart a MCP server on file changes with dev mode | |
Configuration | |||
${} Syntax | ✅ | Environment variables and command execution across all fields | |
VS Code Compatibility | ✅ | Support for servers key, ${env:} , ${input:} , predefined variables | |
JSON5 Support | ✅ | Comments and trailing commas in configuration files |
Configure all MCP clients with just one endpoint:
{
"mcpServers" : {
"Hub": {
"url" : "http://localhost:37373/mcp"
}
}
}
The Hub automatically:
filesystem__search
vs database__search
)Unified MCP Server Endpoint (/mcp):
Dynamic Server Management:
Unified REST API:
Real-time Events & Monitoring:
Client Connection Management:
Process Lifecycle Management:
Workspace Management:
The main management server that:
Connected services that:
npm install -g mcp-hub
Start the hub server:
mcp-hub --port 3000 --config path/to/config.json
# Or with multiple config files (merged in order)
mcp-hub --port 3000 --config ~/.config/mcphub/global.json --config ./.mcphub/project.json
Options:
--port Port to run the server on (required)
--config Path to config file(s). Can be specified multiple times. Merged in order. (required)
--watch Watch config file for changes, only updates affected servers (default: false)
--auto-shutdown Whether to automatically shutdown when no clients are connected (default: false)
--shutdown-delay Delay in milliseconds before shutting down when auto-shutdown is enabled (default: 0)
-h, --help Show help information
MCP Hub uses JSON configuration files to define managed servers with universal ${}
placeholder syntax for environment variables and command execution.
MCP Hub provides seamless compatibility with VS Code's .vscode/mcp.json
configuration format, enabling you to use the same configuration files across both VS Code and MCP Hub.
Both mcpServers
and servers
keys are supported:
{
"servers": {
"github": {
"url": "https://api.githubcopilot.com/mcp/"
},
"perplexity": {
"command": "npx",
"args": ["-y", "server-perplexity-ask"],
"env": {
"API_KEY": "${env:PERPLEXITY_API_KEY}"
}
}
}
}
MCP Hub supports VS Code-style variable substitution:
${env:VARIABLE_NAME}
or ${VARIABLE_NAME}
${workspaceFolder}
, ${userHome}
, ${pathSeparator}
${cmd: command args}
Supported Predefined Variables:
${workspaceFolder}
- Directory where mcp-hub is running${userHome}
- User's home directory${pathSeparator}
- OS path separator (/ or )${workspaceFolderBasename}
- Just the folder name${cwd}
- Alias for workspaceFolder${/}
- VS Code shorthand for pathSeparatorFor ${input:}
variables used in VS Code configs, use the MCP_HUB_ENV
environment variable:
# Set input variables globally
export MCP_HUB_ENV='{"input:api-key":"your-secret-key","input:database-url":"postgresql://..."}'
# Then use in config
{
"servers": {
"myserver": {
"env": {
"API_KEY": "${input:api-key}"
}
}
}
}
Existing .vscode/mcp.json
files work directly with MCP Hub. Simply point MCP Hub to your VS Code configuration:
mcp-hub --config .vscode/mcp.json --port 3000
MCP Hub supports loading multiple configuration files that are merged in order. This enables flexible configuration management:
~/.config/mcphub/global.json
)./.mcphub/project.json
)When multiple config files are specified, they are merged with later files overriding earlier ones:
# Global config is loaded first, then project config overrides
mcp-hub --port 3000 --config ~/.config/mcphub/global.json --config ./.mcphub/project.json
Merge Behavior:
mcpServers
sections are merged (server definitions from later files override earlier ones)${ENV_VAR}
or ${env:ENV_VAR}
- Resolves environment variables${cmd: command args}
- Executes commands and uses output${workspaceFolder}
- Directory where mcp-hub is running${userHome}
- User's home directory${pathSeparator}
- OS path separator${input:variable-id}
- Resolves from MCP_HUB_ENV (VS Code compatibility)null
or ""
- Falls back to process.env
{
"mcpServers": {
"local-server": {
"command": "${MCP_BINARY_PATH}/server",
"args": [
"--token", "${API_TOKEN}",
"--database", "${DB_URL}",
"--secret", "${cmd: op read op://vault/secret}"
],
"env": {
"API_TOKEN": "${cmd: aws ssm get-parameter --name /app/token --query Parameter.Value --output text}",
"DB_URL": "postgresql://user:${DB_PASSWORD}@localhost/myapp",
"DB_PASSWORD": "${cmd: op read op://vault/db/password}",
"FALLBACK_VAR": null
},
"dev": {
"enabled": true,
"watch": ["src/**/*.js", "**/*.json"],
"cwd": "/absolute/path/to/server/directory"
}
}
}
}
{
"mcpServers": {
"remote-server": {
"url": "https://${PRIVATE_DOMAIN}/mcp",
"headers": {
"Authorization": "Bearer ${cmd: op read op://vault/api/token}",
"X-Custom-Header": "${CUSTOM_VALUE}"
}
}
}
}
MCP Hub supports both STDIO servers and remote servers (streamable-http/SSE). The server type is automatically detected from the configuration. All fields support the universal ${}
placeholder syntax.
For running script-based MCP servers locally:
${VARIABLE}
and ${cmd: command}
)${VARIABLE}
and ${cmd: command}
placeholders)MCP_HUB_ENV
)MCP Hub will look for the environment variable MCP_HUB_ENV
(a JSON string) in its own process environment. If set, all key-value pairs from this variable will be injected into the environment of every managed MCP server (both stdio and remote). This is useful for passing secrets, tokens, or other shared configuration to all servers without repeating them in each server config.
env
fields always override values from MCP_HUB_ENV
.MCP_HUB_ENV='{"DBUS_SESSION_BUS_ADDRESS":"/run/user/1000/bus","MY_TOKEN":"abc"}' mcp-hub --port 3000 --config path/to/config.json
For connecting to remote MCP servers:
${VARIABLE}
and ${cmd: command}
placeholders)${VARIABLE}
and ${cmd: command}
placeholders)The server type is determined by:
command
fieldurl
fieldNote: A server configuration cannot mix STDIO and remote server fields.
${cmd: command args}
are executed first${VAR}
are resolved from env
object, then process.env
null
or ""
values fall back to process.env
coming...
Just add it to your NixOS flake.nix or home-manager:
inputs = {
mcp-hub.url = "github:ravitemer/mcp-hub";
...
}
To integrate mcp-hub to your NixOS/Home Manager configuration, add the following to your environment.systemPackages or home.packages respectively:
inputs.mcp-hub.packages."${system}".default
If you want to use mcphub.nvim without having mcp-hub server in your PATH you can link the server under the hood adding
the mcp-hub nix store path to the cmd
command in the plugin config like
Nixvim example:
{ mcphub-nvim, mcp-hub, ... }:
{
extraPlugins = [mcphub-nvim];
extraConfigLua = ''
require("mcphub").setup({
port = 3000,
config = vim.fn.expand("~/mcp-hub/mcp-servers.json"),
cmd = "${mcp-hub}/bin/mcp-hub"
})
'';
}
# where
{
# For nixpkgs (not available yet)
mcp-hub = pkgs.mcp-hub;
# For flakes
mcp-hub = inputs.mcp-hub.packages."${system}".default;
}
The ravitemer/mcphub.nvim plugin provides seamless integration with Neovim, allowing direct interaction with MCP Hub from your editor:
GET /api/health
The health endpoint provides comprehensive status information including:
Response:
{
"status": "ok",
"state": "ready",
"server_id": "mcp-hub",
"version": "4.1.1",
"activeClients": 2,
"timestamp": "2024-02-20T05:55:00.000Z",
"servers": [],
"connections": {
"totalConnections": 2,
"connections": [
{
"id": "client-uuid",
"state": "connected",
"connectedAt": "2024-02-20T05:50:00.000Z",
"lastEventAt": "2024-02-20T05:55:00.000Z"
}
]
},
"workspaces": {
"current": "40123",
"allActive": {
"40123": {
"cwd": "/path/to/project-a",
"config_files": ["/home/user/.config/mcphub/global.json", "/path/to/project-a/.mcphub/project.json"],
"pid": 12345,
"port": 40123,
"startTime": "2025-01-17T10:00:00.000Z",
"state": "active",
"activeConnections": 2,
"shutdownStartedAt": null,
"shutdownDelay": null
}
}
}
}
GET /api/servers
POST /api/servers/info
Content-Type: application/json
{
"server_name": "example-server"
}
POST /api/servers/refresh
Content-Type: application/json
{
"server_name": "example-server"
}
Response:
{
"status": "ok",
"server": {
"name": "example-server",
"capabilities": {
"tools": ["tool1", "tool2"],
"resources": ["resource1", "resource2"],
"resourceTemplates": []
}
},
"timestamp": "2024-02-20T05:55:00.000Z"
}
POST /api/refresh
Response:
{
"status": "ok",
"servers": [
{
"name": "example-server",
"capabilities": {
"tools": ["tool1", "tool2"],
"resources": ["resource1", "resource2"],
"resourceTemplates": []
}
}
],
"timestamp": "2024-02-20T05:55:00.000Z"
}
POST /api/servers/start
Content-Type: application/json
{
"server_name": "example-server"
}
Response:
{
"status": "ok",
"server": {
"name": "example-server",
"status": "connected",
"uptime": 123
},
"timestamp": "2024-02-20T05:55:00.000Z"
}
POST /api/servers/stop?disable=true|false
Content-Type: application/json
{
"server_name": "example-server"
}
The optional disable
query parameter can be set to true
to disable the server in the configuration.
Response:
{
"status": "ok",
"server": {
"name": "example-server",
"status": "disconnected",
"uptime": 0
},
"timestamp": "2024-02-20T05:55:00.000Z"
}
GET /api/workspaces
Response:
{
"workspaces": {
"40123": {
"cwd": "/path/to/project-a",
"config_files": ["/home/user/.config/mcphub/global.json", "/path/to/project-a/.mcphub/project.json"],
"pid": 12345,
"port": 40123,
"startTime": "2025-01-17T10:00:00.000Z",
"state": "active",
"activeConnections": 2,
"shutdownStartedAt": null,
"shutdownDelay": null
},
"40567": {
"cwd": "/path/to/project-b",
"config_files": ["/home/user/.config/mcphub/global.json"],
"pid": 54321,
"port": 40567,
"startTime": "2025-01-17T10:05:00.000Z",
"state": "shutting_down",
"activeConnections": 0,
"shutdownStartedAt": "2025-01-17T10:15:00.000Z",
"shutdownDelay": 600000
}
},
"timestamp": "2024-02-20T05:55:00.000Z"
}
GET /api/marketplace
Query Parameters:
search
: Filter by name, description, or tagscategory
: Filter by categorytags
: Filter by comma-separated tagssort
: Sort by "newest", "stars", or "name"Response:
{
"servers": [
{
"id": "example-server",
"name": "Example Server",
"description": "Description here",
"author": "example-author",
"url": "https://github.com/user/repo",
"category": "search",
"tags": ["search", "ai"],
"stars": 100,
"featured": true,
"verified": true,
"lastCommit": 1751257963,
"updatedAt": 1751265038
}
],
"timestamp": "2024-02-20T05:55:00.000Z"
}
POST /api/marketplace/details
Content-Type: application/json
{
"mcpId": "example-server"
}
Response:
{
"server": {
"id": "example-server",
"name": "Example Server",
"description": "Description here",
"author": "example-author",
"url": "https://github.com/user/repo",
"category": "search",
"tags": ["search", "ai"],
"installations": [],
"stars": 100,
"featured": true,
"verified": true,
"lastCommit": 1751257963,
"updatedAt": 1751265038
},
"readmeContent": "# Server Documentation...",
"timestamp": "2024-02-20T05:55:00.000Z"
}
POST /api/servers/tools
Content-Type: application/json
{
"server_name": "example-server",
"tool": "tool_name",
"arguments": {},
"request_options" : {}
}
POST /api/servers/resources
Content-Type: application/json
{
"server_name": "example-server",
"uri": "resource://uri",
"request_options" : {}
}
POST /api/servers/prompts
Content-Type: application/json
{
"server_name": "example-server",
"prompt": "prompt_name",
"arguments": {},
"request_options" : {}
}
Response:
{
"result": {
"messages": [
{
"role": "assistant",
"content": {
"type": "text",
"text": "Text response example"
}
},
{
"role": "assistant",
"content": {
"type": "image",
"data": "base64_encoded_image_data",
"mimeType": "image/png"
}
}
]
},
"timestamp": "2024-02-20T05:55:00.000Z"
}
POST /api/restart
Reloads the configuration file and restarts all MCP servers.
Response:
{
"status": "ok",
"timestamp": "2024-02-20T05:55:00.000Z"
}
MCP Hub implements a comprehensive real-time events system using Server-Sent Events (SSE) at /api/events
. This endpoint provides live updates about server status, configuration changes, capability updates, and more.
The hub server transitions through several states during its lifecycle:
State | Description |
---|---|
starting | Initial startup, loading configuration |
ready | Server is running and ready to handle requests |
restarting | Reloading configuration/reconnecting servers |
restarted | Configuration reload complete |
stopping | Graceful shutdown in progress |
stopped | Server has fully stopped |
error | Error state (includes error details) |
You can monitor these states through the /health
endpoint or SSE events.
MCP Hub emits several types of events:
{
"connections": 2,
"timestamp": "2024-02-20T05:55:00.000Z"
}
{
"state": "ready",
"server_id": "mcp-hub",
"version": "1.0.0",
"pid": 12345,
"port": 3000,
"timestamp": "2024-02-20T05:55:00.000Z"
}
{
"type": "info",
"message": "Server started",
"data": {},
"timestamp": "2024-02-20T05:55:00.000Z"
}
{
"type": "config_changed",
"newConfig": {},
"isSignificant": true,
"timestamp": "2024-02-20T05:55:00.000Z"
}
{
"type": "servers_updating",
"changes": {
"added": ["server1"],
"removed": [],
"modified": ["server2"],
"unchanged": ["server3"]
},
"timestamp": "2024-02-20T05:55:00.000Z"
}
{
"type": "servers_updated",
"changes": {
"added": ["server1"],
"removed": [],
"modified": ["server2"],
"unchanged": ["server3"]
},
"timestamp": "2024-02-20T05:55:00.000Z"
}
{
"type": "tool_list_changed",
"server": "example-server",
"tools": ["tool1", "tool2"],
"timestamp": "2024-02-20T05:55:00.000Z"
}
{
"type": "resource_list_changed",
"server": "example-server",
"resources": ["resource1", "resource2"],
"resourceTemplates": [],
"timestamp": "2024-02-20T05:55:00.000Z"
}
{
"type": "prompt_list_changed",
"server": "example-server",
"prompts": ["prompt1", "prompt2"],
"timestamp": "2024-02-20T05:55:00.000Z"
}
{
"type": "workspaces_updated",
"workspaces": {
"40123": {
"cwd": "/path/to/project-a",
"config_files": ["/home/user/.config/mcphub/global.json", "/path/to/project-a/.mcphub/project.json"],
"pid": 12345,
"port": 40123,
"startTime": "2025-01-17T10:00:00.000Z",
"state": "active",
"activeConnections": 2,
"shutdownStartedAt": null,
"shutdownDelay": null
}
},
"timestamp": "2024-02-20T05:55:00.000Z"
}
/health
endpointMCP Hub uses structured JSON logging for all events. Logs are written to both console and file following XDG Base Directory Specification:
$XDG_STATE_HOME/mcp-hub/logs/mcp-hub.log
(typically ~/.local/state/mcp-hub/logs/mcp-hub.log
)~/.mcp-hub/logs/mcp-hub.log
(for backward compatibility)Example log entry:
{
"type": "error",
"code": "TOOL_ERROR",
"message": "Failed to execute tool",
"data": {
"server": "example-server",
"tool": "example-tool",
"error": "Invalid parameters"
},
"timestamp": "2024-02-20T05:55:00.000Z"
}
Log levels include:
info
: Normal operational messageswarn
: Warning conditionsdebug
: Detailed debug information (includes configuration changes)error
: Error conditions (includes error code and stack trace)Logs are rotated daily and kept for 30 days by default.
MCP Hub maintains a global workspace cache to track active instances across different working directories with real-time lifecycle management:
$XDG_STATE_HOME/mcp-hub/workspaces.json
(typically ~/.local/state/mcp-hub/workspaces.json
){
"40123": {
"cwd": "/path/to/project-a",
"config_files": ["/home/user/.config/mcphub/global.json", "/path/to/project-a/.mcphub/project.json"],
"pid": 12345,
"port": 40123,
"startTime": "2025-01-17T10:00:00.000Z",
"state": "active",
"activeConnections": 2,
"shutdownStartedAt": null,
"shutdownDelay": null
},
"40567": {
"cwd": "/path/to/project-b",
"config_files": ["/home/user/.config/mcphub/global.json"],
"pid": 54321,
"port": 40567,
"startTime": "2025-01-17T10:05:00.000Z",
"state": "shutting_down",
"activeConnections": 0,
"shutdownStartedAt": "2025-01-17T10:15:00.000Z",
"shutdownDelay": 600000
}
}
MCP Hub implements a comprehensive error handling system with custom error classes for different types of errors:
Each error includes:
Example error structure:
{
"code": "CONNECTION_ERROR",
"message": "Failed to communicate with server",
"details": {
"server": "example-server",
"error": "connection timeout"
},
"timestamp": "2024-02-20T05:55:00.000Z"
}
sequenceDiagram
participant C as Client
participant H as Hub Server
participant M1 as MCP Server 1
participant M2 as MCP Server 2
Note over H: Server Start (state: starting)
activate H
Note over H: Config Loading
H->>H: Load & Validate Config
H->>H: Watch Config File
H->>H: Initialize SSE Manager
Note over H: Server Connections (state: ready)
H->>+M1: Connect
M1-->>-H: Connected + Capabilities
H->>+M2: Connect
M2-->>-H: Connected + Capabilities
H-->>C: hub_state (ready)
Note over C,H: Client Setup
C->>H: Connect to /api/events (SSE)
H-->>C: connection_opened
Note over C,H: Client Operations
C->>H: Execute Tool (HTTP)
H->>M1: Execute Tool
M1-->>H: Tool Result
H-->>C: HTTP Response
Note over H,C: Real-time Updates
H->>H: Detect Config Change
H-->>C: servers_updating (SSE)
H->>M1: Reconnect with New Config
M1-->>H: Updated Capabilities
H-->>C: servers_updated (SSE)
Note over H,C: Server Events
M2->>H: Tool List Changed
H-->>C: tool_list_changed (SSE)
Note over H: Shutdown Process
Note over C,H: Client Disconnects
H-->>C: hub_state (stopping) (SSE)
H->>M1: Disconnect
H->>M2: Disconnect
H-->>C: hub_state (stopped) (SSE)
deactivate H
The Hub Server coordinates communication between clients and MCP servers:
flowchart TB
A[Hub Server Start] --> B{Config Available?}
B -->|Yes| C[Load Server Configs]
B -->|No| D[Use Default Settings]
C --> E[Initialize Connections]
D --> E
E --> F{For Each MCP Server}
F -->|Enabled| G[Attempt Connection]
F -->|Disabled| H[Skip Server]
G --> I{Connection Status}
I -->|Success| J[Fetch Capabilities]
I -->|Failure| K[Log Error]
J --> L[Store Server Info]
K --> M[Mark Server Unavailable]
L --> N[Monitor Health]
M --> N
N --> O{Health Check}
O -->|Healthy| P[Update Capabilities]
O -->|Unhealthy| Q[Attempt Reconnect]
Q -->|Success| P
Q -->|Failure| R[Update Status]
P --> N
R --> N
The Hub Server actively manages MCP servers through:
sequenceDiagram
participant C as Client
participant H as Hub Server
participant M as MCP Server
Note over C,H: Tool Execution
C->>H: POST /api/servers/tools (HTTP)
H->>H: Validate Request & Server
alt Server Not Connected
H-->>C: 503 Server Unavailable (HTTP)
else Server Connected
H->>M: Execute Tool
alt Success
M-->>H: Tool Result
H-->>C: Result Response (HTTP)
else Error
M-->>H: Error Details
H-->>C: Error Response (HTTP)
H-->>C: log (SSE Event)
end
end
Note over C,H: Resource Access
C->>H: POST /api/servers/resources (HTTP)
H->>H: Validate URI & Template
alt Invalid Resource
H-->>C: 404 Not Found (HTTP)
else Server Not Connected
H-->>C: 503 Unavailable (HTTP)
else Valid Request
H->>M: Request Resource
alt Success
M-->>H: Resource Data
H-->>C: Resource Content (HTTP)
else Error
M-->>H: Error Details
H-->>C: Error Response (HTTP)
H-->>C: log (SSE Event)
end
end
Note over C,H: Prompt Execution
C->>H: POST /api/servers/prompts (HTTP)
H->>H: Validate Prompt & Args
alt Invalid Prompt
H-->>C: 404 Not Found (HTTP)
else Server Not Connected
H-->>C: 503 Unavailable (HTTP)
else Valid Request
H->>M: Execute Prompt
alt Success
M-->>H: Messages Array
H-->>C: Messages Response (HTTP)
else Error
M-->>H: Error Details
H-->>C: Error Response (HTTP)
H-->>C: log (SSE Event)
end
end
All client requests follow a standardized flow:
MCP Hub now uses the MCP Registry system for marketplace functionality. This provides:
The registry is updated regularly with new servers and improvements to existing entries.
Connect AI assistants to Limitless to access personal memory and lifelog data.
Access personal and team knowledge repositories, including documents and Slack discussions.
Interact with your local Obsidian vault using a REST API.
Query and search for issues in Linear, a project management tool.
A server for interacting with the Linear project management tool using the Linear API.
An intelligent task management system based on MCP, providing an efficient programming workflow framework for AI Agents with an optional web-based GUI.
An MCP server for integrating Todoist with Cursor AI. Requires a Todoist API token.
Interact with the Coda API to manage documents and pages, including creating, reading, updating, and deleting.
A spellchecker and grammar checker for developers, requiring a Hyperspell token for authentication.
Parses invoice data, uploads it to Google Sheets, and answers queries by fetching information from the sheet.