{"_id":"@drmikecrowe/hatago-mcp-hub","_rev":"5-582bc99caebf3258e7b0c7396feceec4","name":"@drmikecrowe/hatago-mcp-hub","dist-tags":{"latest":"0.1.2"},"versions":{"0.0.17":{"name":"@drmikecrowe/hatago-mcp-hub","version":"0.0.17","keywords":["mcp","model-context-protocol","ai","claude","hatago","hub","server","npx"],"author":{"name":"@himorishige"},"license":"MIT","_id":"@drmikecrowe/hatago-mcp-hub@0.0.17","maintainers":[{"name":"drmikecrowe","email":"drmikecrowe@gmail.com"}],"homepage":"https://github.com/himorishige/hatago-mcp-hub#readme","bugs":{"url":"https://github.com/himorishige/hatago-mcp-hub/issues"},"bin":{"hatago":"dist/node/cli.js","hatago-mcp-hub":"dist/node/cli.js"},"dist":{"shasum":"e6400e0bb52244158da815434538067d17a8752f","tarball":"https://registry.npmjs.org/@drmikecrowe/hatago-mcp-hub/-/hatago-mcp-hub-0.0.17.tgz","fileCount":31,"integrity":"sha512-/hr+iU5Pb3lhCNxpP8ilIXeJTm+ZGOVB39CjZgtWCDxlpqCnPgdaPOZsMXpq9MO5lfltrgYKJUfyl/tzK0WPmQ==","signatures":[{"sig":"MEUCIFdg3TFRQ1aSBVPRR5EfnKUzSC5sb8znyyJmxZIpbCFlAiEAgPq1bIP9eDxbfW9M2V0I4oj7WXYuMUUS2OqhIhsNL7w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1067137},"main":"./dist/node/index.js","type":"module","types":"./dist/node/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"node":"./dist/node/cli.js","types":"./dist/node/cli.d.ts","default":"./dist/node/cli.js","workerd":"./dist/workers/index.js"},"./node":{"types":"./dist/node/index.d.ts","import":"./dist/node/index.js"},"./types":{"types":"./dist/types/index.d.ts"},"./browser":{"types":"./dist/browser/index.d.ts","import":"./dist/browser/index.js"},"./workers":{"types":"./dist/workers/index.d.ts","import":"./dist/workers/index.js"}},"gitHead":"bef485fd2b11f792400c3965b5c23eecd38becc2","mcpName":"io.github.himorishige/hatago-mcp-hub","scripts":{"dev":"tsdown --watch","lint":"eslint ./src","test":"vitest run","build":"tsdown","format":"prettier --write ./src","prepack":"node scripts/prepare-publish.js","postpack":"node scripts/restore-package.js","typecheck":"tsc --noEmit","serve:http":"node dist/node/cli.js serve --http --config ./hatago.config.json","test:forks":"vitest run --pool=forks","serve:stdio":"node dist/node/cli.js serve --stdio --config ./hatago.config.json","prepublishOnly":"pnpm build"},"_npmUser":{"name":"drmikecrowe","email":"drmikecrowe@gmail.com"},"repository":{"url":"git+https://github.com/himorishige/hatago-mcp-hub.git","type":"git"},"_npmVersion":"10.9.3","description":"Unified MCP Hub for managing multiple Model Context Protocol servers","directories":{},"sideEffects":false,"_nodeVersion":"22.18.0","dependencies":{"hono":"^4.9.4","commander":"^14.0.0","@modelcontextprotocol/sdk":"^1.17.4"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.14.2","vitest":"^2.1.9","typescript":"~5.7.2","@types/node":"^20.11.5","@himorishige/hatago-hub":"workspace:*","@himorishige/hatago-core":"workspace:*","@himorishige/hatago-server":"workspace:*","@himorishige/hatago-runtime":"workspace:*","@himorishige/hatago-transport":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/hatago-mcp-hub_0.0.17_1783771075530_0.7199343029542973","host":"s3://npm-registry-packages-npm-production"}},"0.0.18-test.2":{"name":"@drmikecrowe/hatago-mcp-hub","version":"0.0.18-test.2","keywords":["mcp","model-context-protocol","ai","claude","hatago","hub","server","npx"],"author":{"name":"@himorishige"},"license":"MIT","_id":"@drmikecrowe/hatago-mcp-hub@0.0.18-test.2","maintainers":[{"name":"drmikecrowe","email":"drmikecrowe@gmail.com"}],"homepage":"https://github.com/himorishige/hatago-mcp-hub#readme","bugs":{"url":"https://github.com/himorishige/hatago-mcp-hub/issues"},"bin":{"hatago":"dist/node/cli.js","hatago-mcp-hub":"dist/node/cli.js"},"dist":{"shasum":"bd71ef29135f81cdd712b35720816ad32e4bc06a","tarball":"https://registry.npmjs.org/@drmikecrowe/hatago-mcp-hub/-/hatago-mcp-hub-0.0.18-test.2.tgz","fileCount":38,"integrity":"sha512-s8R27QPZCZgUqm8PD66ZE/ajEy1L3dTndaPmlbtgdTeLdHH/vPxAW8WFW6YHVJC+1seRG6FUjXvGvcHW5gwyRg==","signatures":[{"sig":"MEUCIFQhUIE8e+qLh5JvWo+xHzPuYD/OTZT0PUnpybZu4X4eAiEAsceQ6XCaRhfc31z3riHunqg5X7aujGQ2mjUxmNh73Xk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1085949},"main":"./dist/node/index.js","type":"module","types":"./dist/node/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"node":"./dist/node/cli.js","types":"./dist/node/cli.d.ts","default":"./dist/node/cli.js","workerd":"./dist/workers/index.js"},"./node":{"types":"./dist/node/index.d.ts","import":"./dist/node/index.js"},"./types":{"types":"./dist/types/index.d.ts"},"./browser":{"types":"./dist/browser/index.d.ts","import":"./dist/browser/index.js"},"./workers":{"types":"./dist/workers/index.d.ts","import":"./dist/workers/index.js"}},"gitHead":"b156ea0aa0e3e24906d057af22e333d50d90a1f6","mcpName":"io.github.himorishige/hatago-mcp-hub","scripts":{"dev":"tsdown --watch","lint":"eslint ./src","test":"vitest run","build":"tsdown","format":"prettier --write ./src","prepack":"node scripts/prepare-publish.js","postpack":"node scripts/restore-package.js","typecheck":"tsc --noEmit","serve:http":"node dist/node/cli.js serve --http --config ./hatago.config.json","test:forks":"vitest run --pool=forks","serve:stdio":"node dist/node/cli.js serve --stdio --config ./hatago.config.json","prepublishOnly":"pnpm build"},"_npmUser":{"name":"drmikecrowe","email":"drmikecrowe@gmail.com"},"repository":{"url":"git+https://github.com/himorishige/hatago-mcp-hub.git","type":"git"},"_npmVersion":"10.9.3","description":"Unified MCP Hub for managing multiple Model Context Protocol servers","directories":{},"sideEffects":false,"_nodeVersion":"22.18.0","dependencies":{"hono":"^4.12.29","commander":"^14.0.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.14.2","vitest":"^2.1.9","typescript":"~5.7.3","@types/node":"^20.19.11","@himorishige/hatago-hub":"workspace:*","@himorishige/hatago-core":"workspace:*","@himorishige/hatago-server":"workspace:*","@himorishige/hatago-runtime":"workspace:*","@himorishige/hatago-transport":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/hatago-mcp-hub_0.0.18-test.2_1783955745849_0.03178412423824328","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@drmikecrowe/hatago-mcp-hub","version":"0.1.0","keywords":["mcp","model-context-protocol","ai","claude","hatago","hub","server","npx"],"author":{"name":"@himorishige"},"license":"MIT","_id":"@drmikecrowe/hatago-mcp-hub@0.1.0","maintainers":[{"name":"drmikecrowe","email":"drmikecrowe@gmail.com"}],"homepage":"https://github.com/drmikecrowe/hatago-mcp-hub#readme","bugs":{"url":"https://github.com/drmikecrowe/hatago-mcp-hub/issues"},"bin":{"hatago":"dist/node/cli.js","hatago-mcp-hub":"dist/node/cli.js"},"dist":{"shasum":"0780280fc3ed98878eff9835cd00950d1362e463","tarball":"https://registry.npmjs.org/@drmikecrowe/hatago-mcp-hub/-/hatago-mcp-hub-0.1.0.tgz","fileCount":39,"integrity":"sha512-9gRa++Xep7DYAJFctvJkNGg+KSo9kRpPnJX7LzzGrQ/jxiBRttml3swyniOUEPqjZAmSYkEWj+MZ0KrXERNgMA==","signatures":[{"sig":"MEUCIQC+EyglU91hKqeVKzpEPNNjR7JwGG7mNiPEoOsa4pJApQIgEgAg/+sILA6lCqtI6LLQ5zqdW42XFXWRRQItsZHeKsk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1137136},"main":"./dist/node/index.js","type":"module","types":"./dist/node/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"node":"./dist/node/cli.js","types":"./dist/node/cli.d.ts","default":"./dist/node/cli.js","workerd":"./dist/workers/index.js"},"./node":{"types":"./dist/node/index.d.ts","import":"./dist/node/index.js"},"./types":{"types":"./dist/types/index.d.ts"},"./browser":{"types":"./dist/browser/index.d.ts","import":"./dist/browser/index.js"},"./workers":{"types":"./dist/workers/index.d.ts","import":"./dist/workers/index.js"}},"gitHead":"077aeab2dd91c666c5d9368ada89c8bb0f311961","mcpName":"io.github.drmikecrowe/hatago-mcp-hub","scripts":{"dev":"tsdown --watch","lint":"eslint ./src","test":"vitest run","build":"tsdown","format":"prettier --write ./src","prepack":"node scripts/prepare-publish.js","postpack":"node scripts/restore-package.js","typecheck":"tsc --noEmit","serve:http":"node dist/node/cli.js serve --http --config ./hatago.config.json","test:forks":"vitest run --pool=forks","serve:stdio":"node dist/node/cli.js serve --stdio --config ./hatago.config.json","prepublishOnly":"pnpm build"},"_npmUser":{"name":"drmikecrowe","email":"drmikecrowe@gmail.com"},"repository":{"url":"git+https://github.com/drmikecrowe/hatago-mcp-hub.git","type":"git"},"_npmVersion":"10.9.3","description":"Unified MCP Hub for managing multiple Model Context Protocol servers","directories":{},"sideEffects":false,"_nodeVersion":"22.18.0","dependencies":{"hono":"^4.12.29","commander":"^14.0.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.14.2","vitest":"^2.1.9","typescript":"~5.7.3","@types/node":"^20.19.11","@himorishige/hatago-hub":"workspace:*","@himorishige/hatago-core":"workspace:*","@himorishige/hatago-server":"workspace:*","@himorishige/hatago-runtime":"workspace:*","@himorishige/hatago-transport":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/hatago-mcp-hub_0.1.0_1784114419719_0.2281816203893896","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@drmikecrowe/hatago-mcp-hub","version":"0.1.1","keywords":["mcp","model-context-protocol","ai","claude","hatago","hub","server","npx"],"author":{"name":"@himorishige"},"license":"MIT","_id":"@drmikecrowe/hatago-mcp-hub@0.1.1","maintainers":[{"name":"drmikecrowe","email":"drmikecrowe@gmail.com"}],"homepage":"https://github.com/drmikecrowe/hatago-mcp-hub#readme","bugs":{"url":"https://github.com/drmikecrowe/hatago-mcp-hub/issues"},"bin":{"hatago":"dist/node/cli.js","hatago-mcp-hub":"dist/node/cli.js"},"dist":{"shasum":"38d72f0378016dee3457eb1459ac204156e96c10","tarball":"https://registry.npmjs.org/@drmikecrowe/hatago-mcp-hub/-/hatago-mcp-hub-0.1.1.tgz","fileCount":39,"integrity":"sha512-iuLwTwoJnFu1Vq7b6RCIw6xDtvmULRdwsZnrr6mE+IaN23vp/QtJZ+syT0QevvYhuKw+hoO9J3Tz+zUZdvn4Kg==","signatures":[{"sig":"MEUCIBAyAMyiOmYg8sZqW3VEjAFNFRTIjBNdGtLeT300VhYCAiEA9XbtfbE3o0WnieIDs1vpAuX5ofALjArzARui3TKBBtU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1140203},"main":"./dist/node/index.js","type":"module","types":"./dist/node/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"node":"./dist/node/cli.js","types":"./dist/node/cli.d.ts","default":"./dist/node/cli.js","workerd":"./dist/workers/index.js"},"./node":{"types":"./dist/node/index.d.ts","import":"./dist/node/index.js"},"./types":{"types":"./dist/types/index.d.ts"},"./browser":{"types":"./dist/browser/index.d.ts","import":"./dist/browser/index.js"},"./workers":{"types":"./dist/workers/index.d.ts","import":"./dist/workers/index.js"}},"gitHead":"cfad1bfec1a2cd473f25a7eaaeb96ef407649700","mcpName":"io.github.drmikecrowe/hatago-mcp-hub","scripts":{"dev":"tsdown --watch","lint":"eslint ./src","test":"vitest run","build":"tsdown","format":"prettier --write ./src","prepack":"node scripts/prepare-publish.js","postpack":"node scripts/restore-package.js","typecheck":"tsc --noEmit","serve:http":"node dist/node/cli.js serve --http --config ./hatago.config.json","test:forks":"vitest run --pool=forks","serve:stdio":"node dist/node/cli.js serve --stdio --config ./hatago.config.json","prepublishOnly":"pnpm build"},"_npmUser":{"name":"drmikecrowe","email":"drmikecrowe@gmail.com"},"repository":{"url":"git+https://github.com/drmikecrowe/hatago-mcp-hub.git","type":"git"},"_npmVersion":"10.9.3","description":"Unified MCP Hub for managing multiple Model Context Protocol servers","directories":{},"sideEffects":false,"_nodeVersion":"22.18.0","dependencies":{"hono":"^4.12.29","commander":"^14.0.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.14.2","vitest":"^2.1.9","typescript":"~5.7.3","@types/node":"^20.19.11","@himorishige/hatago-hub":"workspace:*","@himorishige/hatago-core":"workspace:*","@himorishige/hatago-server":"workspace:*","@himorishige/hatago-runtime":"workspace:*","@himorishige/hatago-transport":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/hatago-mcp-hub_0.1.1_1784120394157_0.251632146340222","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@drmikecrowe/hatago-mcp-hub","mcpName":"io.github.drmikecrowe/hatago-mcp-hub","version":"0.1.2","description":"Unified MCP Hub for managing multiple Model Context Protocol servers","type":"module","main":"./dist/node/index.js","types":"./dist/node/index.d.ts","bin":{"hatago":"dist/node/cli.js","hatago-mcp-hub":"dist/node/cli.js"},"exports":{".":{"node":"./dist/node/cli.js","workerd":"./dist/workers/index.js","default":"./dist/node/cli.js","types":"./dist/node/cli.d.ts"},"./node":{"import":"./dist/node/index.js","types":"./dist/node/index.d.ts"},"./workers":{"import":"./dist/workers/index.js","types":"./dist/workers/index.d.ts"},"./browser":{"import":"./dist/browser/index.js","types":"./dist/browser/index.d.ts"},"./types":{"types":"./dist/types/index.d.ts"}},"sideEffects":false,"scripts":{"build":"tsdown","dev":"tsdown --watch","serve:http":"node dist/node/cli.js serve --http --config ./hatago.config.json","serve:stdio":"node dist/node/cli.js serve --stdio --config ./hatago.config.json","prepack":"node scripts/prepare-publish.js","postpack":"node scripts/restore-package.js","prepublishOnly":"pnpm build","test":"vitest run","test:forks":"vitest run --pool=forks","typecheck":"tsc --noEmit","format":"prettier --write ./src","lint":"eslint ./src"},"dependencies":{"@modelcontextprotocol/sdk":"^1.29.0","commander":"^14.0.0","hono":"^4.12.29"},"devDependencies":{"@himorishige/hatago-core":"workspace:*","@himorishige/hatago-hub":"workspace:*","@himorishige/hatago-runtime":"workspace:*","@himorishige/hatago-server":"workspace:*","@himorishige/hatago-transport":"workspace:*","@types/node":"^20.19.11","tsdown":"^0.14.2","typescript":"~5.7.3","vitest":"^2.1.9"},"engines":{"node":">=20.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"keywords":["mcp","model-context-protocol","ai","claude","hatago","hub","server","npx"],"author":{"name":"@himorishige"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/drmikecrowe/hatago-mcp-hub.git"},"bugs":{"url":"https://github.com/drmikecrowe/hatago-mcp-hub/issues"},"homepage":"https://github.com/drmikecrowe/hatago-mcp-hub#readme","_id":"@drmikecrowe/hatago-mcp-hub@0.1.2","gitHead":"9ebdf0f1eb9aa23c63e3a17a7bb12851240114f2","_nodeVersion":"22.18.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-YW7Xm+RkFC28vMiuP8L3FSAqlWN1yNbv9XOpbCK3g8BOC58EdbtNzLiw38W9inTWic2rMJh7rVsPod3W97aFjQ==","shasum":"2a242975a8ca5e385603c578f2d110fbfd6cc684","tarball":"https://registry.npmjs.org/@drmikecrowe/hatago-mcp-hub/-/hatago-mcp-hub-0.1.2.tgz","fileCount":39,"unpackedSize":1147888,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGAqTI0a3VOx5dge+RuSa4w5yGCi5pNNY9xIZxiCaWXJAiEAjM5Hd2v2ZsvYVo/ElqO263va7tlpyQ06wLjLmuLct4I="}]},"_npmUser":{"name":"drmikecrowe","email":"drmikecrowe@gmail.com"},"directories":{},"maintainers":[{"name":"drmikecrowe","email":"drmikecrowe@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/hatago-mcp-hub_0.1.2_1784120958326_0.38747027174080095"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-11T11:57:55.404Z","modified":"2026-07-15T13:09:18.635Z","0.0.17":"2026-07-11T11:57:55.721Z","0.0.18-test.2":"2026-07-13T15:15:46.008Z","0.1.0":"2026-07-15T11:20:19.859Z","0.1.1":"2026-07-15T12:59:54.315Z","0.1.2":"2026-07-15T13:09:18.550Z"},"bugs":{"url":"https://github.com/drmikecrowe/hatago-mcp-hub/issues"},"author":{"name":"@himorishige"},"license":"MIT","homepage":"https://github.com/drmikecrowe/hatago-mcp-hub#readme","keywords":["mcp","model-context-protocol","ai","claude","hatago","hub","server","npx"],"repository":{"type":"git","url":"git+https://github.com/drmikecrowe/hatago-mcp-hub.git"},"description":"Unified MCP Hub for managing multiple Model Context Protocol servers","maintainers":[{"name":"drmikecrowe","email":"drmikecrowe@gmail.com"}],"readme":"# @drmikecrowe/hatago-mcp-hub\n\n[![npm](https://img.shields.io/npm/v/@drmikecrowe/hatago-mcp-hub?logo=npm&color=cb0000)](https://www.npmjs.com/package/@drmikecrowe/hatago-mcp-hub)\n[![GitHub Release](https://img.shields.io/github/v/release/drmikecrowe/hatago-mcp-hub?display_name=tag&sort=semver)](https://github.com/drmikecrowe/hatago-mcp-hub/releases)\n\nUnified 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.\n\n> [!NOTE]\n> **This is a fork of [himorishige/hatago-mcp-hub](https://github.com/himorishige/hatago-mcp-hub)**, created by [Hiroshi Morishige (@himorishige)](https://github.com/himorishige). Full credit for Hatago's original design, architecture, and \"thin implementation\" philosophy belongs to the upstream project — this fork only layers optional customization features (server instructions, per-server skills, tool filtering/overrides) on top of it. If upstream adopts these (or equivalent) features, this fork will converge back to track upstream as the canonical source.\n\n## Customize Any MCP Server Without Touching It\n\nHatago lets you reshape what a connected MCP server exposes and how agents use it — purely at the hub layer, with zero changes to the upstream server:\n\n- **Per-server Skills (`skill://`)** — Drop a `skills` directory on a server and Hatago publishes each one as a `skill://<serverId>/<name>` resource, discoverable by any connecting agent. See [Per-Server Skills](#per-server-skills) below.\n- **Server Instructions** — Attach an `instructions` string (or file) to any server; Hatago aggregates them into `initialize.instructions` so agents get that guidance automatically at connect time. See [Server Instructions](#server-instructions) below.\n- **Tool Filtering & Overrides** — Choose exactly which upstream tools are exposed (`tools.include` / `exclude`) and rename or enrich their descriptions per server (`tools.overrides`). See [Per-Server Tool Filtering](#per-server-tool-filtering) below.\n\nAll three are optional and off by default — existing configs behave exactly as before.\n\n## Quick Start\n\n```bash\n# Initialize configuration\nnpx @drmikecrowe/hatago-mcp-hub init\n\n# Start server in STDIO mode (for Claude Code)\n# NOTE: STDIO mode requires a config file path\nnpx @drmikecrowe/hatago-mcp-hub serve --stdio --config ./hatago.config.json\n\n# Start server in HTTP mode (for development/debugging)\nnpx @drmikecrowe/hatago-mcp-hub serve --http --port 3535\n```\n\n## Installation\n\n### As a Command Line Tool (Recommended)\n\n```bash\n# Use directly with npx (no installation needed)\nnpx @drmikecrowe/hatago-mcp-hub init\n# STDIO requires config\nnpx @drmikecrowe/hatago-mcp-hub serve --stdio --config ./hatago.config.json\n# Or HTTP without config (for demo/dev)\nnpx @drmikecrowe/hatago-mcp-hub serve --http\n\n# Or install globally\nnpm install -g @drmikecrowe/hatago-mcp-hub\nhatago init\nhatago serve\n```\n\n### As a Project Dependency\n\n```bash\nnpm install @drmikecrowe/hatago-mcp-hub\n```\n\n## Commands\n\n### `hatago init`\n\nCreate a default configuration file with interactive mode selection:\n\n```bash\nhatago init                    # Interactive mode selection\nhatago init --mode stdio       # Create config for STDIO mode\nhatago init --mode http        # Create config for StreamableHTTP mode\nhatago init --force            # Overwrite existing config\n```\n\n### `hatago serve`\n\nStart the MCP Hub server:\n\n```bash\nhatago serve --stdio --config ./hatago.config.json  # STDIO mode (default, requires config)\nhatago serve --http                                 # HTTP mode (config optional)\nhatago serve --config custom.json  # Use custom config file\nhatago serve --verbose         # Enable debug logging\nhatago serve --env-file ./.env # Load variables from .env before start (can repeat)\nhatago serve --env-override    # Override existing process.env with values from env-file(s)\n```\n\n#### Environment Variables from Files\n\n`--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.\n\n- Supports lines like `KEY=VALUE`, `export KEY=VALUE`, comments starting with `#`, and empty lines.\n- Quotes are stripped from values; `\\n`, `\\r`, `\\t` escapes are expanded.\n- Relative paths are resolved from the current working directory; `~/` is expanded to the home directory.\n- By default, existing `process.env` keys are preserved. Use `--env-override` to overwrite.\n\nExamples:\n\n```bash\nhatago serve --http --env-file ./.env\nhatago serve --http --env-file ./base.env ./secrets.env\nhatago serve --http --env-file ./local.env --env-override\n```\n\n## Usage with MCP Clients\n\n> 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]\n\n### STDIO Mode\n\n#### Claude Code, Gemini CLI\n\nAdd to your `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"hatago\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"@drmikecrowe/hatago-mcp-hub\",\n        \"serve\",\n        \"--stdio\",\n        \"--config\",\n        \"./hatago.config.json\"\n      ]\n    }\n  }\n}\n```\n\n#### Codex CLI\n\nAdd to your `~/.codex/config.toml`:\n\n```toml\n[mcp_servers.hatago]\ncommand = \"npx\"\nargs = [\"-y\", \"@drmikecrowe/hatago-mcp-hub\", \"serve\", \"--stdio\", \"--config\", \"./hatago.config.json\"]\n```\n\n### HTTP Mode (StreamableHTTP transport)\n\n#### Claude Code, Gemini CLI\n\nAdd to your `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"hatago\": {\n      \"url\": \"http://localhost:3535/mcp\"\n    }\n  }\n}\n```\n\n#### Codex CLI\n\nAdd to your `~/.codex/config.toml`:\n\n```toml\n[mcp_servers.hatago]\ncommand = \"npx\"\nargs = [\"-y\", \"mcp-remote\", \"http://localhost:3535/mcp\"]\n```\n\nNote: Codex CLI connects via STDIO; use `mcp-remote` to bridge HTTP endpoints.\n\n### MCP Inspector\n\nStart in HTTP mode and connect:\n\n````bash\nhatago serve --http --port 3535\n\n# Connect MCP Inspector to:\n# - Endpoint: http://localhost:3535/mcp\n\n### Metrics (opt-in)\n\nEnable lightweight metrics and expose an endpoint (HTTP mode only):\n\n```bash\nHATAGO_METRICS=1 hatago serve --http --port 3535\n# Then visit: http://localhost:3535/metrics\n````\n\nJSON logs can be enabled with `HATAGO_LOG=json` (respects `HATAGO_LOG_LEVEL`).\n\n````\n\n## Configuration\n\n### Basic Configuration\n\nCreate a `hatago.config.json`:\n\n```json\n{\n  \"$schema\": \"https://raw.githubusercontent.com/drmikecrowe/hatago-mcp-hub/main/schemas/config.schema.json\",\n  \"version\": 1,\n  \"logLevel\": \"info\",\n  \"mcpServers\": {\n    \"filesystem\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/tmp\"]\n    },\n    \"github\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol/server-github\"],\n      \"env\": {\n        \"GITHUB_TOKEN\": \"${GITHUB_TOKEN}\"\n      }\n    }\n  }\n}\n````\n\n### Remote Server Configuration\n\n```json\n{\n  \"mcpServers\": {\n    \"deepwiki\": {\n      \"url\": \"https://mcp.deepwiki.com/sse\",\n      \"type\": \"sse\"\n    },\n    \"custom-api\": {\n      \"url\": \"https://api.example.com/mcp\",\n      \"type\": \"http\",\n      \"headers\": {\n        \"Authorization\": \"Bearer ${API_KEY}\"\n      }\n    }\n  }\n}\n```\n\n### Per-Server Tool Filtering\n\nSome MCP servers expose many tools, all of which land in your client's context. Use the optional `tools` field on any server to expose only the tools you actually use. Filtering is by the server's **original** tool name (before Hatago prefixing) and happens at registration, so hidden tools never enter context and are not invocable.\n\n```json\n{\n  \"$schema\": \"https://raw.githubusercontent.com/drmikecrowe/hatago-mcp-hub/main/schemas/config.schema.json\",\n  \"mcpServers\": {\n    \"atlassian\": {\n      \"url\": \"https://mcp.atlassian.com/v1/sse\",\n      \"type\": \"sse\",\n      \"tools\": {\n        \"include\": [\"getJiraIssue\", \"searchJiraIssues\", \"createJiraIssue\"]\n      }\n    },\n    \"github\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol/server-github\"],\n      \"tools\": {\n        \"exclude\": [\"delete_repository\"]\n      }\n    }\n  }\n}\n```\n\n- `include` — expose only these tools (allow-list). Omit to start from all tools.\n- `exclude` — hide these tools (deny-list).\n- If both are set, `exclude` is applied after `include`, so **exclude wins**.\n- Omitting `tools` entirely exposes all of the server's tools (unchanged default).\n\n### Per-Server Tool Overrides\n\nWhen you attach **two instances of the same server** (e.g. two Atlassian servers pointing at different Confluence instances), Hatago already keeps their tools from colliding by prefixing each with the server id (`serverId_toolName`). But the two instances still expose identical descriptions, so an LLM can't tell them apart. Use `tools.overrides` — keyed by the **original** tool name — to rename a tool and/or rewrite its description per instance:\n\n```json\n{\n  \"$schema\": \"https://raw.githubusercontent.com/drmikecrowe/hatago-mcp-hub/main/schemas/config.schema.json\",\n  \"mcpServers\": {\n    \"confluence-internal\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"mcp-atlassian\"],\n      \"tools\": {\n        \"overrides\": {\n          \"createConfluencePage\": {\n            \"name\": \"create_internal_page\",\n            \"description\": \"For the INTERNAL engineering Confluence. {description}\"\n          }\n        }\n      }\n    },\n    \"confluence-customer\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"mcp-atlassian\"],\n      \"tools\": {\n        \"overrides\": {\n          \"createConfluencePage\": {\n            \"name\": \"create_customer_page\",\n            \"description\": \"For the CUSTOMER-facing Confluence instance. {description}\"\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n- `name` — renames the exposed tool. The server-id prefix is still applied, so the result is `serverId_<name>` (e.g. `confluence_customer_create_customer_page`). Omit to keep the original name.\n- `description` — a **template**: the placeholder `{description}` expands to the tool's upstream description, letting you _augment_ it (`\"For the INTERNAL Confluence. {description}\"`). A string with no placeholder fully replaces the description. Omit to keep the upstream text unchanged.\n- Overrides are metadata only — the tool is still relayed to the underlying server under its original name.\n- Combine with `include` / `exclude`: filtering runs first, then overrides apply to whatever remains.\n\n### Per-Server Skills\n\nA **skill** is a markdown document that Hatago binds to one MCP server and exposes to connecting agents as a `skill://<serverId>/<name>` resource — discoverable via `resources/list` with no server call required. Use it for guidance on _how to use_ a particular server (a routing guide, a reference doc, worked examples).\n\nPoint a server's `skills` field at a directory:\n\n```json\n{\n  \"$schema\": \"https://raw.githubusercontent.com/drmikecrowe/hatago-mcp-hub/main/schemas/config.schema.json\",\n  \"mcpServers\": {\n    \"confluence-primary\": {\n      \"url\": \"https://example.atlassian.net/mcp\",\n      \"type\": \"sse\",\n      \"skills\": \"./skills/confluence-primary\"\n    }\n  }\n}\n```\n\nEach skill is either a flat `<dir>/<name>.md` file or a `<dir>/<name>/SKILL.md` directory (the Claude Code convention), with required YAML frontmatter:\n\n```markdown\n---\nname: kb-router\ndescription: Routes strategy questions to the primary knowledge base. Read first when unsure which Atlassian server to search.\n---\n\n# Knowledge Base Router\n\nFor anything about product strategy or the platform, search this server first...\n```\n\n- Skills are namespaced per server (`skill://confluence-primary/kb-router`), so two servers can reuse the same skill name without collision.\n- They share their server's lifecycle — registered on connect, removed on disconnect/disable/`--tags` filter-out.\n- The `skills` path must resolve **within** the config directory (symlinks are followed, so an external directory can be linked in).\n- See [docs/configuration.md](https://github.com/drmikecrowe/hatago-mcp-hub/blob/main/docs/configuration.md#local-skills) for the full contract.\n\n### Server Instructions\n\nA server `description` only helps an agent that reads the `hatago://servers` manifest. To **push** guidance to the agent at connect time instead, set the optional `instructions` field on any server — Hatago aggregates every active server's instructions into its own `initialize.instructions` (Claude Code loads this at session start, same as a system-prompt addition).\n\n```json\n{\n  \"$schema\": \"https://raw.githubusercontent.com/drmikecrowe/hatago-mcp-hub/main/schemas/config.schema.json\",\n  \"mcpServers\": {\n    \"confluence-primary\": {\n      \"url\": \"https://example.atlassian.net/mcp\",\n      \"type\": \"sse\",\n      \"instructions\": \"For product-strategy or platform questions, search this server first — see the kb-router skill for detailed routing rules.\",\n      \"skills\": \"./skills/confluence-primary\"\n    },\n    \"jira\": {\n      \"url\": \"https://example.atlassian.net/mcp\",\n      \"type\": \"sse\",\n      \"instructions\": { \"file\": \"./instructions/jira.md\" }\n    }\n  }\n}\n```\n\n- Accepts a literal string or a `{ \"file\": \"...\" }` reference, resolved against the config file's directory.\n- **Use it to redirect, not to duplicate.** Instructions share Claude Code's 2KB *aggregate* budget across every active server, while skills are only loaded when an agent reads them. Keep the instructions text itself to a one-line pointer, and put the actual detail in the skill.\n- **2KB aggregate budget, enforced.** Hatago fails startup with an error if the combined text exceeds that, rather than silently truncating.\n- A `{ file }` path must resolve **within** the config directory; out-of-tree paths are skipped with a warning.\n- See [docs/configuration.md](https://github.com/drmikecrowe/hatago-mcp-hub/blob/main/docs/configuration.md#server-instructions) for the full contract.\n\n### Putting It Together: Gating an OAuth-Only Remote Server\n\n`url`/`type: \"http\" | \"sse\"` only forwards a **static** `headers` map (bearer token, API key) — Hatago has no OAuth client (no dynamic client registration, no browser consent, no token cache). A remote MCP server that requires interactive OAuth, such as Atlassian's hosted MCP endpoint, can't be reached with a bare `url` entry. Bridge it instead by running [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) as a local process via `command`/`args`; it owns the OAuth handshake and token cache, and Hatago talks STDIO to it like any other local server:\n\n```json\n{\n  \"mcpServers\": {\n    \"confluence-internal\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"mcp-remote\",\n        \"https://mcp.atlassian.com/v1/mcp\",\n        \"--resource\",\n        \"https://your-org.atlassian.net\"\n      ],\n      \"tags\": [\"atlassian\", \"confluence\"],\n      \"description\": \"Internal engineering Confluence (your-org.atlassian.net) — team documentation, onboarding, architecture, and processes. Read-only. ALWAYS invoke the kb-router skill first — it maps intent to the exact right page without manual searching.\",\n      \"instructions\": \"When answering a question that internal documentation might cover, read the kb-router resource before calling any confluence-internal tool: ListMcpResourcesTool(server=\\\"confluence-internal\\\") → URI skill://confluence-internal/kb-router. Follow its instructions. Use confluence-internal search/fetch tools only when the router explicitly falls back to them.\",\n      \"skills\": \"./skills\",\n      \"tools\": {\n        \"include\": [\"fetch\", \"search\", \"getConfluencePage\", \"getConfluenceSpaces\", \"searchConfluenceUsingCql\"],\n        \"overrides\": {\n          \"search\": {\n            \"name\": \"searchInternal\",\n            \"description\": \"REQUIRED: Read the kb-router resource first: ListMcpResourcesTool(server=\\\"confluence-internal\\\"). Only use this tool as a fallback if the skill instructs it. {description}\"\n          },\n          \"fetch\": {\n            \"name\": \"fetchInternal\",\n            \"description\": \"Retrieves from the internal engineering Confluence instance. {description}\"\n          }\n        }\n      }\n    }\n  }\n}\n```\n\nWhat each field buys you, in the order an agent hits them: `command`/`args` (mcp-remote) is the only way in given the OAuth requirement; `description` is a passive routing hint read via `hatago://servers`; `instructions` is pushed into `initialize.instructions` at connect so the agent is told up front to check the router skill; `skills` holds the actual routing logic as a `skill://confluence-internal/kb-router` resource, pulled on demand instead of bloating the 2KB instructions budget; `tools.overrides` renames `search`/`fetch` and repeats the \"read the router first\" gate in the tool description itself — the last line of defense if earlier steps were skipped. See [docs/configuration.md](https://github.com/drmikecrowe/hatago-mcp-hub/blob/main/docs/configuration.md) for the full contract on `skills`, `instructions`, and `tools.overrides`.\n\n### Configuration Inheritance\n\nHatago supports configuration inheritance through the `extends` field:\n\n```json\n{\n  \"extends\": \"~/.hatago/base.config.json\",\n  \"mcpServers\": {\n    \"local-server\": {\n      \"command\": \"node\",\n      \"args\": [\"./server.js\"]\n    }\n  }\n}\n```\n\nFeatures:\n\n- Single or multiple parent configs: `\"extends\": [\"./base1.json\", \"./base2.json\"]`\n- Path resolution: Supports `~` for home directory, relative and absolute paths\n- Deep merging: Child values override parent values\n- Environment variable deletion: Use `null` to remove inherited env vars\n\nExample with env override:\n\n```json\n{\n  \"extends\": \"~/.hatago/global.json\",\n  \"mcpServers\": {\n    \"github\": {\n      \"env\": {\n        \"GITHUB_TOKEN\": \"${WORK_GITHUB_TOKEN}\",\n        \"DEBUG\": null\n      }\n    }\n  }\n}\n```\n\n### Environment Variables\n\nHatago supports Claude Code-compatible environment variable expansion:\n\n- `${VAR}` - Expands to the value of VAR (error if undefined)\n- `${VAR:-default}` - Uses default value if VAR is undefined\n\nExample:\n\n```json\n{\n  \"mcpServers\": {\n    \"api-server\": {\n      \"url\": \"${API_URL:-https://api.example.com}/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer ${API_KEY}\"\n      }\n    }\n  }\n}\n```\n\n## Features\n\n### 🎯 Core Features\n\n- **Unified Interface**: Single endpoint for multiple MCP servers\n- **Tool Name Management**: Automatic collision avoidance with prefixing\n- **Session Management**: Independent sessions for multiple AI clients\n- **Multi-Transport**: STDIO, HTTP, SSE support\n\n### 🔄 Dynamic Updates\n\n- **Configuration**: Requires restart (use nodemon/PM2 for auto-restart; see Operations in `docs/configuration.md`)\n- **Tool List Updates**: Dynamic tool registration with `notifications/tools/list_changed`\n- **Progress Notifications**: Real-time operation updates from child servers\n\n### 🧩 Built-in Internal Resource\n\n- `hatago://servers`: Returns a JSON snapshot of currently connected servers and their basic details.\n\n### 🚀 Developer Experience\n\n- **Zero Configuration (HTTP mode)**: Works out of the box without a config file\n- **Interactive Setup**: Guided configuration with `hatago init`\n- **NPX Ready**: No installation required for basic usage\n- **Multi-Runtime**: Supports Node.js and Cloudflare Workers (Bun/Deno: WIP)\n\n## Programmatic Usage\n\n### Node.js API\n\n```typescript\nimport { startServer } from '@drmikecrowe/hatago-mcp-hub';\n\n// Start server programmatically\nawait startServer({\n  mode: 'stdio',\n  config: './hatago.config.json',\n  logLevel: 'info'\n});\n```\n\n### Creating Custom Hub\n\n```typescript\nimport { createHub } from '@drmikecrowe/hatago-mcp-hub';\n\nconst hub = createHub({\n  mcpServers: {\n    memory: {\n      command: 'npx',\n      args: ['@modelcontextprotocol/server-memory']\n    }\n  }\n});\n\n// Use hub directly in your application\nconst tools = await hub.listTools();\n```\n\n## Architecture\n\nHatago uses a modular architecture with platform abstraction:\n\n```\nClient (Claude Code, etc.)\n    ↓\nHatago Hub (Router + Registry)\n    ↓\nMCP Servers (Local, NPX, Remote)\n```\n\n## Supported MCP Servers\n\n### Local Servers (via command)\n\n- Any executable MCP server\n- Python, Node.js, or binary servers\n- Custom scripts with MCP protocol\n\n### NPX Servers (via npx)\n\n- `@modelcontextprotocol/server-filesystem`\n- `@modelcontextprotocol/server-github`\n- `@modelcontextprotocol/server-memory`\n- Any npm-published MCP server\n\n### Remote Servers (via HTTP/SSE)\n\n- DeepWiki MCP (`https://mcp.deepwiki.com/sse`)\n- Any HTTP-based MCP endpoint\n- Custom API servers with MCP protocol\n\n## Troubleshooting\n\n### Common Issues\n\n1. **\"No onNotification handler set\" warning**\n   - This is normal in HTTP mode when using StreamableHTTP transport\n   - The hub automatically handles notifications appropriately\n\n2. **Server connection failures**\n   - Check environment variables are set correctly\n   - Verify remote server URLs are accessible\n   - Review logs with `--verbose` flag\n\n3. **Tool name collisions**\n   - Hatago automatically prefixes tools with server ID\n   - Original tool names are preserved in the hub\n\n### Debug Mode\n\nEnable verbose logging for troubleshooting:\n\n```bash\nhatago serve --verbose\n```\n\n## Version History\n\n- **v0.0.4** - Config inheritance, timeouts schema, security hardening, docs/tests updates\n- **v0.0.3** - Docs and examples update\n- **v0.0.2** - Tag-based server filtering with multi-language support\n- **v0.0.1** - Initial lightweight release with full MCP support\n\n## License\n\nMIT License\n\n## Contributing\n\nContributions are welcome! Please see our [GitHub repository](https://github.com/drmikecrowe/hatago-mcp-hub) for more information.\n\n## Links\n\n- [npm Package](https://www.npmjs.com/package/@drmikecrowe/hatago-mcp-hub)\n- [GitHub Repository](https://github.com/drmikecrowe/hatago-mcp-hub)\n- [MCP Protocol Specification](https://modelcontextprotocol.io/)\n","readmeFilename":"README.md"}