npm package: @himorishige/hatago-mcp-hub
Description: Unified MCP Hub for managing multiple Model Context Protocol servers
Author: @himorishige
Latest version: 0.0.16

# @himorishige/hatago-mcp-hub

[![npm](https://img.shields.io/npm/v/@himorishige/hatago-mcp-hub?logo=npm&color=cb0000)](https://www.npmjs.com/package/@himorishige/hatago-mcp-hub)
[![GitHub Release](https://img.shields.io/github/v/release/himorishige/hatago-mcp-hub?display_name=tag&sort=semver)](https://github.com/himorishige/hatago-mcp-hub/releases)

Unified MCP (Model Context Protocol) Hub for managing multiple MCP servers. Works with Claude Code, Codex CLI, Cursor, Windsurf, VS Code and other MCP-compatible tools.

## Quick Start

```bash
# Initialize configuration
npx @himorishige/hatago-mcp-hub init

# Start server in STDIO mode (for Claude Code)
# NOTE: STDIO mode requires a config file path
npx @himorishige/hatago-mcp-hub serve --stdio --config ./hatago.config.json

# Start server in HTTP mode (for development/debugging)
npx @himorishige/hatago-mcp-hub serve --http --port 3535
```

## Installation

### As a Command Line Tool (Recommended)

```bash
# Use directly with npx (no installation needed)
npx @himorishige/hatago-mcp-hub init
# STDIO requires config
npx @himorishige/hatago-mcp-hub serve --stdio --config ./hatago.config.json
# Or HTTP without config (for demo/dev)
npx @himorishige/hatago-mcp-hub serve --http

# Or install globally
npm install -g @himorishige/hatago-mcp-hub
hatago init
hatago serve
```

### As a Project Dependency

```bash
npm install @himorishige/hatago-mcp-hub
```

## Commands

### `hatago init`

Create a default configuration file with interactive mode selection:

```bash
hatago init                    # Interactive mode selection
hatago init --mode stdio       # Create config for STDIO mode
hatago init --mode http        # Create config for StreamableHTTP mode
hatago init --force            # Overwrite existing config
```

### `hatago serve`

Start the MCP Hub server:

```bash
hatago serve --stdio --config ./hatago.config.json  # STDIO mode (default, requires config)
hatago serve --http                                 # HTTP mode (config optional)
hatago serve --config custom.json  # Use custom config file
hatago serve --verbose         # Enable debug logging
hatago serve --env-file ./.env # Load variables from .env before start (can repeat)
hatago serve --env-override    # Override existing process.env with values from env-file(s)
```

#### Environment Variables from Files

`--env-file <path...>` loads environment variables from one or more files before configuration is parsed. This allows `${VAR}` and `${VAR:-default}` placeholders in `hatago.config.json` to resolve without exporting variables manually.

- Supports lines like `KEY=VALUE`, `export KEY=VALUE`, comments starting with `#`, and empty lines.
- Quotes are stripped from values; `\n`, `\r`, `\t` escapes are expanded.
- Relative paths are resolved from the current working directory; `~/` is expanded to the home directory.
- By default, existing `process.env` keys are preserved. Use `--env-override` to overwrite.

Examples:

```bash
hatago serve --http --env-file ./.env
hatago serve --http --env-file ./base.env ./secrets.env
hatago serve --http --env-file ./local.env --env-override
```

## Usage with MCP Clients

> Terminology: In this document, "HTTP mode" refers to the MCP SDK's StreamableHTTP transport. We mention "StreamableHTTP" only once here for clarity; elsewhere we say "HTTP mode". [ISA]

### STDIO Mode

#### Claude Code, Gemini CLI

Add to your `.mcp.json`:

```json
{
  "mcpServers": {
    "hatago": {
      "command": "npx",
      "args": [
        "@himorishige/hatago-mcp-hub",
        "serve",
        "--stdio",
        "--config",
        "./hatago.config.json"
      ]
    }
  }
}
```

#### Codex CLI

Add to your `~/.codex/config.toml`:

```toml
[mcp_servers.hatago]
command = "npx"
args = ["-y", "@himorishige/hatago-mcp-hub", "serve", "--stdio", "--config", "./hatago.config.json"]
```

### HTTP Mode (StreamableHTTP transport)

#### Claude Code, Gemini CLI

Add to your `.mcp.json`:

```json
{
  "mcpServers": {
    "hatago": {
      "url": "http://localhost:3535/mcp"
    }
  }
}
```

#### Codex CLI

Add to your `~/.codex/config.toml`:

```toml
[mcp_servers.hatago]
command = "npx"
args = ["-y", "mcp-remote", "http://localhost:3535/mcp"]
```

Note: Codex CLI connects via STDIO; use `mcp-remote` to bridge HTTP endpoints.

### MCP Inspector

Start in HTTP mode and connect:

````bash
hatago serve --http --port 3535

# Connect MCP Inspector to:
# - Endpoint: http://localhost:3535/mcp

### Metrics (opt-in)

Enable lightweight metrics and expose an endpoint (HTTP mode only):

```bash
HATAGO_METRICS=1 hatago serve --http --port 3535
# Then visit: http://localhost:3535/metrics
````

JSON logs can be enabled with `HATAGO_LOG=json` (respects `HATAGO_LOG_LEVEL`).

````

## Configuration

### Basic Configuration

Create a `hatago.config.json`:

```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

```json
{
  "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 Inheritance

Hatago supports configuration inheritance through the `extends` field:

```json
{
  "extends": "~/.hatago/base.config.json",
  "mcpServers": {
    "local-server": {
      "command": "node",
      "args": ["./server.js"]
    }
  }
}
```

Features:

- Single or multiple parent configs: `"extends": ["./base1.json", "./base2.json"]`
- Path resolution: Supports `~` for home directory, relative and absolute paths
- Deep merging: Child values override parent values
- Environment variable deletion: Use `null` to remove inherited env vars

Example with env override:

```json
{
  "extends": "~/.hatago/global.json",
  "mcpServers": {
    "github": {
      "env": {
        "GITHUB_TOKEN": "${WORK_GITHUB_TOKEN}",
        "DEBUG": null
      }
    }
  }
}
```

### Environment Variables

Hatago supports Claude Code-compatible environment variable expansion:

- `${VAR}` - Expands to the value of VAR (error if undefined)
- `${VAR:-default}` - Uses default value if VAR is undefined

Example:

```json
{
  "mcpServers": {
    "api-server": {
      "url": "${API_URL:-https://api.example.com}/mcp",
      "headers": {
        "Authorization": "Bearer ${API_KEY}"
      }
    }
  }
}
```

## Features

### 🎯 Core Features

- **Unified Interface**: Single endpoint for multiple MCP servers
- **Tool Name Management**: Automatic collision avoidance with prefixing
- **Session Management**: Independent sessions for multiple AI clients
- **Multi-Transport**: STDIO, HTTP, SSE support

### 🔄 Dynamic Updates

- **Configuration**: Requires restart (use nodemon/PM2 for auto-restart; see Operations in `docs/configuration.md`)
- **Tool List Updates**: Dynamic tool registration with `notifications/tools/list_changed`
- **Progress Notifications**: Real-time operation updates from child servers

### 🧩 Built-in Internal Resource

- `hatago://servers`: Returns a JSON snapshot of currently connected servers and their basic details.

### 🚀 Developer Experience

- **Zero Configuration (HTTP mode)**: Works out of the box without a config file
- **Interactive Setup**: Guided configuration with `hatago init`
- **NPX Ready**: No installation required for basic usage
- **Multi-Runtime**: Supports Node.js and Cloudflare Workers (Bun/Deno: WIP)

## Programmatic Usage

### Node.js API

```typescript
import { startServer } from '@himorishige/hatago-mcp-hub';

// Start server programmatically
await startServer({
  mode: 'stdio',
  config: './hatago.config.json',
  logLevel: 'info'
});
```

### Creating Custom Hub

```typescript
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

Hatago uses a modular architecture with platform abstraction:

```
Client (Claude Code, etc.)
    ↓
Hatago Hub (Router + Registry)
    ↓
MCP Servers (Local, NPX, Remote)
```

## Supported MCP Servers

### Local Servers (via command)

- Any executable MCP server
- Python, Node.js, or binary servers
- Custom scripts with MCP protocol

### NPX Servers (via npx)

- `@modelcontextprotocol/server-filesystem`
- `@modelcontextprotocol/server-github`
- `@modelcontextprotocol/server-memory`
- Any npm-published MCP server

### Remote Servers (via HTTP/SSE)

- DeepWiki MCP (`https://mcp.deepwiki.com/sse`)
- Any HTTP-based MCP endpoint
- Custom API servers with MCP protocol

## Troubleshooting

### Common Issues

1. **"No onNotification handler set" warning**
   - This is normal in HTTP mode when using StreamableHTTP transport
   - The hub automatically handles notifications appropriately

2. **Server connection failures**
   - Check environment variables are set correctly
   - Verify remote server URLs are accessible
   - Review logs with `--verbose` flag

3. **Tool name collisions**
   - Hatago automatically prefixes tools with server ID
   - Original tool names are preserved in the hub

### Debug Mode

Enable verbose logging for troubleshooting:

```bash
hatago serve --verbose
```

## Version History

- **v0.0.4** - Config inheritance, timeouts schema, security hardening, docs/tests updates
- **v0.0.3** - Docs and examples update
- **v0.0.2** - Tag-based server filtering with multi-language support
- **v0.0.1** - Initial lightweight release with full MCP support

## License

MIT License

## Contributing

Contributions are welcome! Please see our [GitHub repository](https://github.com/himorishige/hatago-mcp-hub) for more information.

## Links

- [npm Package](https://www.npmjs.com/package/@himorishige/hatago-mcp-hub)
- [GitHub Repository](https://github.com/himorishige/hatago-mcp-hub)
- [MCP Protocol Specification](https://modelcontextprotocol.io/)