Hono
Set up the xmcp Hono adapter with automatic initialization and a stateless Fetch handler.
For the complete documentation index, see llms.txt. Markdown variants of every page are available by appending .md to the URL.The Hono adapter lets your existing application serve MCP requests. It generates an ESM module with xmcpHandler(request, options?), returning a standard Response. Initial supported deployment targets are Node.js and Cloudflare Workers.
Automatic setup
Run this inside an existing TypeScript Hono project:
The initializer generates a Hono router at src/routes/mcp.ts. Import it into your server and mount it with app.route("/mcp", mcp). It leaves your application entry point intact. --route-path src/api changes the generated file to src/api/mcp.ts; it does not change where you mount the router.
Initialization creates xmcp configuration and sample handlers, installs the packages, and prepends xmcp commands to your existing build and development scripts. Relative imports preserve your application's aliases and TypeScript configuration. Existing .ts and .js MCP route files cause a clear conflict error before configuration changes. Use --skip-route to keep your route and wire the handler yourself; --skip-tools, --skip-prompts, and --skip-resources omit those samples.
Workers mode is inferred when wrangler or @cloudflare/vite-plugin is installed. Use --cf to select it explicitly. The initializer preserves your host framework and deployment configuration. If multiple deployment adapters are installed, check the generated scripts and remove --cf for a Node deployment.
Manual setup
Set paths.prompts or paths.resources to directories to discover those handlers. Each uses the same exports as other xmcp transports. Create tools following the runnable Hono example.
Run pnpm exec xmcp build before importing the generated adapter:
Mount the router in your existing Hono app, before any catch-all route:
You can also register the handler directly with app.all("/mcp", (c) => xmcpHandler(c.req.raw)). Adjust the relative adapter import for the file containing that registration.
Import the adapter only from server code. Do not include it in browser components. Adjust relative imports if you move the route.
Development and build order
Build the adapter first, then run the xmcp watcher alongside your host development server:
The xmcp watcher updates discovery when tools, prompts, or resources are added or removed. The host processes their TypeScript and framework imports. Keep .xmcp/ ignored by Git. Run xmcp before your application's production build and retain the host's type checking; skipTypeCheck only disables xmcp's separate check.
For Node, use @hono/node-server to serve app.fetch and bundle the application, including .xmcp/adapter, with your existing build tool. The example uses esbuild for production and tsx for development. Node’s watcher follows the generated adapter inside the hidden .xmcp directory. tsx watch ignores hidden directories, so use node --watch --import tsx to pick up discovery changes. An app without existing host scripts must add its own server command after the xmcp commands.
Cloudflare Workers
Keep the Hono Worker entry and Wrangler configuration from Hono's Workers setup. Add nodejs_compat to compatibility_flags for request context storage. Run xmcp build --cf before Wrangler bundles your app:
Workers builds emit .xmcp/adapter/index.js with the Workers-compatible runtime. xmcp does not emit a standalone Worker or rewrite Wrangler configuration in adapter mode. Tools and their dependencies must also be compatible with Workers.
Authentication and CORS
Authenticate with Hono middleware. After verifying credentials, pass the verified information into the handler:
The variables above come from your application's credential verification. Reject unauthorized requests before calling the adapter. Passing authInfo forwards it to MCP handlers as extra.authInfo; it does not verify credentials itself.
Configure browser CORS and OPTIONS responses in Hono middleware, before invoking xmcp. Include the MCP headers required by your clients. Preserve the returned streaming response; do not parse and reserialize it. Avoid consuming the original request body before passing it to xmcp.
Stateless request metadata
Each request gets a fresh MCP server with isolated request context. Initialization does not create a persistent session. Repeat authentication and client metadata on each request: modern clients use protocol metadata, while older clients can send x-mcp-client-name and x-mcp-client-version headers.
The SDK handles protocol validation, malformed JSON, and unsupported methods. Registering GET and DELETE forwards them to the transport; it does not enable persistent sessions.
