{"slug": "i-turned-my-hono-api-into-an-mcp-server-by-changing-one-import", "title": "I turned my Hono API into an MCP server by changing one import", "summary": "Developer Serik Shaikamalov released hono-mcp-bridge, an open-source library that turns an existing Hono API into a Model Context Protocol server by swapping the zValidator import and calling mountMcp(app). The bridge reads each route's Zod validation schemas, converts them to JSON Schema with Zod 4's z.toJSONSchema, and exposes every endpoint as an MCP tool that routes through the app's normal validation, auth, logging and rate limiting. It supports include/exclude/method filtering and per-route hiding, and currently requires Zod v4 with no SSE support.", "body_md": "I have a travel-agency backend on [Hono](https://hono.dev): tours, bookings, payments. I wanted AI agents to use it too, so that a manager could tell Claude *\"find March tours under $2000 and book the first one for Ali Aliyev\"* and Claude would call the right endpoints itself.\n\nThe standard way to do that is [MCP](https://modelcontextprotocol.io): a server tells the agent which tools exist, what they do and which parameters they take, as JSON Schema.\n\nThe usual approach is to write that server next to your API and describe every endpoint a second time:\n\n```\nserver.registerTool('search_tours', {\n  description: 'Search tours',\n  inputSchema: { month: z.number(), maxPrice: z.number().optional() },\n}, async (args) => { /* call the same logic as GET /tours again */ })\n```\n\nBut my routes already have those schemas:\n\n```\napp.get('/tours',\n  zValidator('query', z.object({\n    month: z.coerce.number().min(1).max(12).describe('Departure month'),\n    maxPrice: z.coerce.number().optional(),\n  })),\n  (c) => c.json(searchTours(c.req.valid('query'))),\n)\n```\n\nMethod, path, parameters, types, even descriptions: everything an agent needs is already there. So I built [hono-mcp-bridge](https://github.com/serikshaikamalov/hono-mcp-bridge):\n\n``` js\n- import { zValidator } from '@hono/zod-validator'\n+ import { zValidator, mountMcp } from 'hono-mcp-bridge'\n\n+ mountMcp(app)   // POST /mcp: every route is now a tool\n```\n\n`zValidator`.`@hono/zod-validator` and attaches the schema to the returned middleware with a symbol. Same signature, same types, so `c.req.valid('query')` is still fully typed.`app.routes`.`{ method, path, handler }`. Group by route, read the schemas back, convert them with Zod 4's `z.toJSONSchema`. `GET /tours/:id` becomes `get_tours_by_id` with input `{ params, query, body }`.` Request` passed to `app.fetch()`. Validation, auth middleware (the `Authorization` and `Cookie` headers are forwarded), logging and rate limits all apply. If the agent sends bad input, it gets your zod 400 back as `isError: true`, reads it and retries.`@modelcontextprotocol/sdk` client to check compatibility.\n\n```\nclaude mcp add --transport http tours http://localhost:3000/mcp\n```\n\nFind March tours under $2000 and book the first one for Ali Aliyev, +77001234567\n\n```\n→ get_tours      {\"query\": {\"month\": 3, \"maxPrice\": 2000}}\n← {\"tours\":[{\"id\":1,\"title\":\"Umrah, 10 days\",\"price\":1890}]}\n→ post_bookings  {\"body\": {\"tourId\": 1, \"fullName\": \"Ali Aliyev\", \"phone\": \"+77001234567\"}}\n← {\"bookingId\":\"20aa50cd-...\", ...}\n```\n\nAgents act with the credentials of whoever connected them. Use `include`, `exclude` or `methods: ['GET']` to limit what is exposed, hide single routes with `describeTool({ hidden: true })`, and set `allowedOrigins` when serving on localhost. Your API still decides who can do what.\n\n`hono-mcp-server`: wrap each route in `registerTool()` with its own schema.`hono-gql-mcp`: one GraphQL tool derived from `@hono/zod-openapi`.`@hono/mcp`: transport only.` fastapi-mcp` does the same job for Python and FastAPI.\nNo SSE or server-initiated messages yet, zod v4 only. Next up: `@hono/zod-openapi`, Valibot and ArkType via Standard Schema, and `outputSchema`.\n\n```\nnpm i hono-mcp-bridge\n```\n\n**GitHub:** [https://github.com/serikshaikamalov/hono-mcp-bridge](https://github.com/serikshaikamalov/hono-mcp-bridge). Issues and PRs welcome. I'd love to hear how you handle permissions when exposing your API to agents.", "url": "https://wpnews.pro/news/i-turned-my-hono-api-into-an-mcp-server-by-changing-one-import", "canonical_source": "https://dev.to/serikshaikamalov/i-turned-my-hono-api-into-an-mcp-server-by-changing-one-import-3nkf", "published_at": "2026-10-19 16:37:46+00:00", "updated_at": "2026-10-19 16:44:42.030194+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "developer-tools", "ai-tools"], "entities": ["hono-mcp-bridge", "Hono", "Serik Shaikamalov", "Model Context Protocol", "Zod", "Claude", "fastapi-mcp"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/i-turned-my-hono-api-into-an-mcp-server-by-changing-one-import", "markdown": "https://wpnews.pro/news/i-turned-my-hono-api-into-an-mcp-server-by-changing-one-import.md", "text": "https://wpnews.pro/news/i-turned-my-hono-api-into-an-mcp-server-by-changing-one-import.txt", "jsonld": "https://wpnews.pro/news/i-turned-my-hono-api-into-an-mcp-server-by-changing-one-import.jsonld"}}