
hatago-mcp-hub
io.github.himorishige/hatago-mcp-hub
Unified MCP Hub for managing multiple Model Context Protocol servers
Documentation
English | ๆฅๆฌ่ช
๐ฎ Hatago MCP Hub
Hatago (ๆ ็ฑ ) โ A relay point connecting modern AI tools with MCP servers.
Overview
Hatago MCP Hub is a lightweight hub that unifies access to multiple MCP (Model Context Protocol) servers from tools like Claude Code, Codex CLI, Cursor, Windsurf, and VS Code.
Documentation
- Docs index:
docs/README.md
- Canonical CLI & Hub guide:
packages/mcp-hub/README.md
- Public docs site (JA default): https://hatago.dev/ja/ โ English: https://hatago.dev/en/
Dev.to: Getting Started with Multi-MCP Using Hatago MCP Hub โ One Config to Connect Them All
โจ Features
๐ Performance (v0.0.14)
- 8.44x Faster Startup - 85.66ms โ 10.14ms
- 17% Smaller Package - 1.04MB โ 854KB
- Simplified Architecture - Direct server management without abstraction layers
๐ฏ Simple & Lightweight
- Zero Configuration Start (HTTP mode) -
npx @himorishige/hatago-mcp-hub serve --http
- Non-invasive to Existing Projects - Doesn't pollute your project directory
๐ Rich Connectivity
- Multi-Transport Support - STDIO / HTTP / SSE
- Remote MCP Proxy - Transparent connection to HTTP-based MCP servers
- NPX Server Integration - Dynamic management of npm package MCP servers
๐ฎ Additional Features
Configuration Updates
- Manual Restart Required - Configuration changes require server restart
- Alternative Solutions:
- Use process managers (PM2, nodemon) for auto-restart
- Example:
nodemon --exec "hatago serve --http" --watch hatago.config.json
- Or with PM2:
pm2 start "hatago serve" --watch hatago.config.json
- Dynamic Tool List Updates - Supports
notifications/tools/list_changed
notification
Progress Notification Forwarding
- Child Server Notification Forwarding - Transparent forwarding of
notifications/progress
- Long-running Operation Support - Real-time progress updates
- Local/Remote Support - Works with many MCP server types
Built-in Internal Resource
hatago://servers
- JSON snapshot of currently connected servers (id, status, type, tools, resources, prompts)
Enhanced Features
- Environment Variable Expansion - Claude Code compatible
${VAR}
and${VAR:-default}
syntax - Configuration Validation - Type-safe configuration with Zod schemas
- Tag-based Server Filtering - Group and filter servers using tags
- Configuration Inheritance - Extend base configurations with
extends
field for DRY principle
Minimal Hub Interface (IHub)
External packages (server/test-utils) use a thin IHub
interface to avoid tight coupling with the concrete class.
import type { IHub } from '@himorishige/hatago-hub';
import { createHub } from '@himorishige/hatago-hub/node';
const hub: IHub = createHub({
preloadedConfig: { data: { version: 1, mcpServers: {} } }
}) as IHub;
await hub.start();
hub.on('tool:called', (evt) => {
/* metrics, logs */
});
await hub.stop();
Extracted modules for thin hub:
- RPC handlers:
packages/hub/src/rpc/handlers.ts
- HTTP handler:
packages/hub/src/http/handler.ts
๐ Project Structure
packages/
โโโ mcp-hub/ # Main npm package (@himorishige/hatago-mcp-hub)
โโโ server/ # Server implementation (@himorishige/hatago-server)
โโโ hub/ # Hub core (@himorishige/hatago-hub)
โโโ core/ # Shared types (@himorishige/hatago-core)
โโโ runtime/ # Runtime components (@himorishige/hatago-runtime)
โโโ transport/ # Transport layer (@himorishige/hatago-transport)
โโโ cli/ # CLI tools (@himorishige/hatago-cli)
โโโ hub-management/ # Management components (@himorishige/hatago-hub-management)
โโโ test-fixtures/ # Test utilities
๐ฆ Installation
Quick Start (No Installation)
# Initialize configuration
npx @himorishige/hatago-mcp-hub init
# Start in STDIO mode (for Claude Code)
# NOTE: STDIO requires a config file path
npx @himorishige/hatago-mcp-hub serve --stdio --config ./hatago.config.json
# Or start in HTTP mode without a config (demo/dev)
npx @himorishige/hatago-mcp-hub serve --http
Global Installation
# Install globally
npm install -g @himorishige/hatago-mcp-hub
# Use with hatago command
hatago init
hatago serve
As Project Dependency
# Install as dependency
npm install @himorishige/hatago-mcp-hub
# Add to package.json scripts
{
"scripts": {
"mcp": "hatago serve"
}
}
๐ Usage
Claude Code, Codex CLI, Gemini CLI
STDIO Mode (Recommended)
Claude Code / Gemini CLI
Add to .mcp.json
:
{
"mcpServers": {
"hatago": {
"command": "npx",
"args": [
"@himorishige/hatago-mcp-hub",
"serve",
"--stdio",
"--config",
"./hatago.config.json"
]
}
}
}
Codex CLI
Add to ~/.codex/config.toml
:
[mcp_servers.hatago]
command = "npx"
args = ["-y", "@himorishige/hatago-mcp-hub", "serve", "--stdio", "--config", "./hatago.config.json"]
HTTP Mode
Claude Code / Gemini CLI
Add to .mcp.json
:
{
"mcpServers": {
"hatago": {
"url": "http://localhost:3535/mcp"
}
}
}
Codex CLI
Add to ~/.codex/config.toml
:
[mcp_servers.hatago]
command = "npx"
args = ["-y", "mcp-remote", "http://localhost:3535/mcp"]
MCP Inspector
For testing and debugging:
# Start in HTTP mode
hatago serve --http --port 3535
# Connect with MCP Inspector
# Endpoint: http://localhost:3535/mcp
Visit MCP Inspector
Metrics (opt-in)
Enable lightweight in-memory metrics and expose an HTTP endpoint:
HATAGO_METRICS=1 hatago serve --http --port 3535
# Then visit: http://localhost:3535/metrics
Notes:
- Metrics are disabled by default and add near-zero overhead when off.
- JSON logs are available when
HATAGO_LOG=json
(respectingHATAGO_LOG_LEVEL
).
โ๏ธ Configuration
Basic Configuration
Create hatago.config.json
:
{
"$schema": "https://raw.githubusercontent.com/himorishige/hatago-mcp-hub/main/schemas/config.schema.json",
"version": 1,
"logLevel": "info",
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
Remote Server Configuration
{
"mcpServers": {
"deepwiki": {
"url": "https://mcp.deepwiki.com/sse",
"type": "sse"
},
"custom-api": {
"url": "https://api.example.com/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer ${API_KEY}"
}
}
}
}
Configuration Strategies
Strategy 1: Tag-based Filtering
Group servers with tags in a single configuration file:
{
"mcpServers": {
"filesystem-dev": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
"tags": ["dev", "local"]
},
"github-prod": {
"url": "https://api.github.com/mcp",
"type": "http",
"tags": ["production", "github"]
},
"database": {
"command": "mcp-server-postgres",
"tags": ["dev", "production", "database"]
}
}
}
Start with specific tags:
# Only start servers tagged as "dev"
hatago serve --tags dev
# Start servers with either "dev" or "test" tags
hatago serve --tags dev,test
# Japanese tags are supported
hatago serve --tags ้็บ,ใในใ
Strategy 2: Configuration Inheritance
Split configurations by environment using the extends
field:
Base configuration (~/.hatago/base.config.json
):
{
"version": 1,
"logLevel": "info",
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
}
}
}
Work configuration (./work.config.json
):
{
"extends": "~/.hatago/base.config.json",
"logLevel": "debug",
"mcpServers": {
"github": {
"env": {
"GITHUB_TOKEN": "${WORK_GITHUB_TOKEN}",
"DEBUG": null
}
},
"internal-tools": {
"url": "https://internal.company.com/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer ${INTERNAL_TOKEN}"
}
}
}
}
Features:
- Inheritance: Child configs override parent values
- Multiple parents:
"extends": ["./base1.json", "./base2.json"]
- Path resolution: Supports
~
, relative, and absolute paths - Environment deletion: Use
null
to remove inherited env vars
Choosing a Strategy
Strategy | Tag-based | Inheritance-based |
---|---|---|
Files | Single config | Multiple configs |
Switch | --tags option | --config option |
Management | Centralized | Distributed |
Best for | Team sharing, Simple setups | Complex environments, Personal customization |
Environment Variable Expansion
Supports Claude Code compatible syntax:
${VAR}
- Expands to the value of VAR (error if undefined)${VAR:-default}
- Uses default value if VAR is undefined
๐ Commands
hatago init
Create configuration file with interactive setup:
hatago init # Interactive mode
hatago init --mode stdio # STDIO mode config
hatago init --mode http # HTTP mode config
hatago init --force # Overwrite existing
hatago serve
Start MCP Hub server:
hatago serve --stdio --config ./hatago.config.json # STDIO mode (default, requires config)
hatago serve --http # HTTP mode (config optional)
hatago serve --config custom.json # Custom config
hatago serve --verbose # Debug logging
hatago serve --tags dev,test # Filter servers by tags
hatago serve --env-file ./.env # Load variables from .env before start (repeatable)
hatago serve --env-override # Override existing env vars when using --env-file
Loading Environment Variables from Files
Use --env-file <path...>
to load variables before config parsing. This helps resolve ${VAR}
and ${VAR:-default}
placeholders without exporting variables globally.
- Format:
KEY=VALUE
,export KEY=VALUE
,#
comments, blank lines. - Quotes are stripped; supports escaped
\n
,\r
,\t
. - Paths: relative to CWD,
~/
expanded to home. - Precedence: files are applied in the given order; existing
process.env
keys are preserved unless--env-override
is provided.
โจ Performance Improvements (v0.0.14)
- 8.44x faster startup: 85.66ms โ 10.14ms
- 17% smaller package: 1.04MB โ 854KB (181KB reduction)
- Simplified architecture: Removed EnhancedHub and management layers
- Trade-off: Built-in config watching removed (use nodemon/PM2 instead)
๐ง Advanced Usage
Programmatic API
import { startServer } from '@himorishige/hatago-mcp-hub';
// Start server programmatically
await startServer({
mode: 'stdio',
config: './hatago.config.json',
logLevel: 'info'
});
Creating Custom Hub
import { createHub } from '@himorishige/hatago-mcp-hub';
const hub = createHub({
mcpServers: {
memory: {
command: 'npx',
args: ['@modelcontextprotocol/server-memory']
}
}
});
// Use hub directly in your application
const tools = await hub.listTools();
๐๏ธ Architecture
Client (Claude Code, etc.)
โ
Hatago Hub (Router + Registry)
โ
MCP Servers (Local, NPX, Remote)
Supported MCP Servers
Local Servers
- Any executable MCP server
- Python, Node.js, or binary servers
- Custom scripts with MCP protocol
NPX Servers
@modelcontextprotocol/server-filesystem
@modelcontextprotocol/server-github
@modelcontextprotocol/server-memory
- Any npm-published MCP server
Remote Servers
- DeepWiki MCP (
https://mcp.deepwiki.com/sse
) - Any HTTP-based MCP endpoint
- Custom API servers with MCP protocol
๐ Troubleshooting
Common Issues
-
"No onNotification handler set" warning
- Normal in HTTP mode with StreamableHTTP transport
- Hub handles notifications appropriately
-
Server connection failures
- Verify environment variables are set
- Check remote server URLs are accessible
- Use
--verbose
flag for detailed logs
-
Tool name collisions
- Hatago automatically prefixes with server ID
- Original names preserved in hub
Debug Mode
# Enable verbose logging
hatago serve --verbose
# Check server status
hatago status
๐ Documentation
๐ค Contributing
Contributions are welcome! Please see our GitHub repository for more information.
๐ License
MIT License
๐ Links
๐ Credits
Built with the Hono and the Model Context Protocol SDK by Anthropic.
@himorishige/hatago-mcp-hub
npm install @himorishige/hatago-mcp-hub