middleware icon indicating copy to clipboard operation
middleware copied to clipboard

hono/mcp v0.2

Open MathurAditya724 opened this issue 6 months ago • 20 comments

Resolves #1259

  • [x] Updated the StreamableHTTPTransport class with tests
  • [x] Auth Support

MathurAditya724 avatar Jul 19 '25 08:07 MathurAditya724

🦋 Changeset detected

Latest commit: d6d059f5cc88e4ab8a239ca845f3fb050fafa2ef

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@hono/mcp Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

changeset-bot[bot] avatar Jul 19 '25 08:07 changeset-bot[bot]

Thank you for this amazing middleware contribution!

I've been using your implementation and found I needed the streamableHTTPTransport functionality for a project. Based on your excellent Draft PR, I've extracted and enhanced just the streamableHTTPTransport portion.

I've created a separate PR that focuses solely on the Transport implementation from #1318. If you find it useful, please feel free to incorporate these changes back into #1318.

As a suggestion, since the auth implementation appears to be ongoing, would it make sense to split the streamableHTTPTransport into a separate PR #1392 to move forward incrementally? This might help get the transport functionality merged sooner while auth work continues.

Thank you again for laying the groundwork with your original implementation!

himorishige avatar Aug 14 '25 14:08 himorishige

Thanks @himorishige, I just completed the auth changes. Need to write the tests but rest all seems good. (Thanks you for pushing me to complete it)

Are there any extra changes you have done in your PR? If yes then kindly create the PR for this branch instead of hono and I can review and merge it.

MathurAditya724 avatar Aug 15 '25 01:08 MathurAditya724

Hi @MathurAditya724

As requested, I’ve opened a dedicated PR against your branch: MathurAditya724/hono‑middleware #3. This PR extracts and enhances the StreamableHTTPTransport implementation from your draft PR #1318.

It adds MCP HTTP streaming transport support along with queue management, message size limits, backpressure handling and other improvements, while keeping your original architecture and test suite.

All tests are passing, so if you find these changes useful, please feel free to merge or cherry‑pick them into your auth PR when convenient.

If I’ve misunderstood the correct target or opened the PR in the wrong place, please let me know and I’ll fix it — apologies in advance.

Thank you again for your excellent groundwork on the transport and auth implementation.

himorishige avatar Aug 15 '25 07:08 himorishige

Codecov Report

:x: Patch coverage is 90.85174% with 58 lines in your changes missing coverage. Please review. :white_check_mark: Project coverage is 84.06%. Comparing base (41f2241) to head (d6d059f). :warning: Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
packages/mcp/src/streamable-http.ts 91.22% 19 Missing and 1 partial :warning:
packages/mcp/src/auth/helpers/revoke.ts 60.00% 6 Missing and 2 partials :warning:
packages/mcp/src/auth/helpers/authorize.ts 89.47% 6 Missing :warning:
packages/mcp/src/auth/helpers/token.ts 87.75% 6 Missing :warning:
packages/mcp/src/auth/providers/proxy-provider.ts 93.05% 5 Missing :warning:
packages/mcp/src/auth/middleware/bearerAuth.ts 0.00% 4 Missing :warning:
packages/mcp/src/auth/helpers/register.ts 90.90% 3 Missing :warning:
packages/mcp/src/auth/simpleAuth.ts 0.00% 3 Missing :warning:
packages/mcp/src/auth/router.ts 95.65% 2 Missing :warning:
packages/mcp/src/auth/middleware/client-auth.ts 96.77% 1 Missing :warning:
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1318      +/-   ##
==========================================
+ Coverage   83.68%   84.06%   +0.37%     
==========================================
  Files         106      118      +12     
  Lines        3414     3852     +438     
  Branches      900     1017     +117     
==========================================
+ Hits         2857     3238     +381     
- Misses        468      524      +56     
- Partials       89       90       +1     
Flag Coverage Δ
mcp 15.58% <90.85%> (+9.59%) :arrow_up:

Flags with carried forward coverage won't be shown. Click here to find out more.

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Aug 15 '25 22:08 codecov[bot]

I am thinking of updating the docs with more examples and also add things like config for different auth providers, making it easy to integrate them with @hono/mcp auth.

MathurAditya724 avatar Aug 26 '25 19:08 MathurAditya724

@yusukebe should we merge this and I'll add the examples later, or do you want me to add the examples first?

MathurAditya724 avatar Aug 26 '25 20:08 MathurAditya724

Hi @MathurAditya724 !

I think merging this first and adding the examples later is good. I'll review this later!

yusukebe avatar Aug 26 '25 20:08 yusukebe

@hono/ajv-validator

npm i https://pkg.pr.new/@hono/ajv-validator@1318
@hono/arktype-validator

npm i https://pkg.pr.new/@hono/arktype-validator@1318
@hono/auth-js

npm i https://pkg.pr.new/@hono/auth-js@1318
@hono/bun-compress

npm i https://pkg.pr.new/@hono/bun-compress@1318
@hono/bun-transpiler

npm i https://pkg.pr.new/@hono/bun-transpiler@1318
@hono/casbin

npm i https://pkg.pr.new/@hono/casbin@1318
@hono/class-validator

npm i https://pkg.pr.new/@hono/class-validator@1318
@hono/clerk-auth

npm i https://pkg.pr.new/@hono/clerk-auth@1318
@hono/cloudflare-access

npm i https://pkg.pr.new/@hono/cloudflare-access@1318
@hono/conform-validator

npm i https://pkg.pr.new/@hono/conform-validator@1318
@hono/effect-validator

npm i https://pkg.pr.new/@hono/effect-validator@1318
@hono/esbuild-transpiler

npm i https://pkg.pr.new/@hono/esbuild-transpiler@1318
@hono/eslint-config

npm i https://pkg.pr.new/@hono/eslint-config@1318
@hono/event-emitter

npm i https://pkg.pr.new/@hono/event-emitter@1318
@hono/firebase-auth

npm i https://pkg.pr.new/@hono/firebase-auth@1318
@hono/graphql-server

npm i https://pkg.pr.new/@hono/graphql-server@1318
@hono/hello

npm i https://pkg.pr.new/@hono/hello@1318
@hono/mcp

npm i https://pkg.pr.new/@hono/mcp@1318
@hono/medley-router

npm i https://pkg.pr.new/@hono/medley-router@1318
@hono/node-ws

npm i https://pkg.pr.new/@hono/node-ws@1318
@hono/oauth-providers

npm i https://pkg.pr.new/@hono/oauth-providers@1318
@hono/oidc-auth

npm i https://pkg.pr.new/@hono/oidc-auth@1318
@hono/otel

npm i https://pkg.pr.new/@hono/otel@1318
@hono/prometheus

npm i https://pkg.pr.new/@hono/prometheus@1318
@hono/qwik-city

npm i https://pkg.pr.new/@hono/qwik-city@1318
@hono/react-compat

npm i https://pkg.pr.new/@hono/react-compat@1318
@hono/react-renderer

npm i https://pkg.pr.new/@hono/react-renderer@1318
@hono/sentry

npm i https://pkg.pr.new/@hono/sentry@1318
@hono/session

npm i https://pkg.pr.new/@hono/session@1318
@hono/ssg-plugins-essential

npm i https://pkg.pr.new/@hono/ssg-plugins-essential@1318
@hono/standard-validator

npm i https://pkg.pr.new/@hono/standard-validator@1318
@hono/stytch-auth

npm i https://pkg.pr.new/@hono/stytch-auth@1318
@hono/swagger-editor

npm i https://pkg.pr.new/@hono/swagger-editor@1318
@hono/swagger-ui

npm i https://pkg.pr.new/@hono/swagger-ui@1318
@hono/trpc-server

npm i https://pkg.pr.new/@hono/trpc-server@1318
@hono/tsyringe

npm i https://pkg.pr.new/@hono/tsyringe@1318
@hono/typebox-validator

npm i https://pkg.pr.new/@hono/typebox-validator@1318
@hono/typia-validator

npm i https://pkg.pr.new/@hono/typia-validator@1318
@hono/ua-blocker

npm i https://pkg.pr.new/@hono/ua-blocker@1318
@hono/valibot-validator

npm i https://pkg.pr.new/@hono/valibot-validator@1318
@hono/zod-openapi

npm i https://pkg.pr.new/@hono/zod-openapi@1318
@hono/zod-validator

npm i https://pkg.pr.new/@hono/zod-validator@1318

commit: d6d059f

pkg-pr-new[bot] avatar Aug 30 '25 21:08 pkg-pr-new[bot]

Hi @MathurAditya724

I told you you didn't have to add examples first, but can you add them now? Sorry! I've tried the SSE feature of this branch, but it does not work as I expected. So, I would like to know an example.

yusukebe avatar Sep 02 '25 10:09 yusukebe

Yup already working on them, will ping you once completed

MathurAditya724 avatar Sep 02 '25 10:09 MathurAditya724

@MathurAditya724 Hi Aditya!

How is working on creating examples?

yusukebe avatar Sep 16 '25 07:09 yusukebe

Sorry for the delay on this, got busy with work. Will finish this by tomorrow

MathurAditya724 avatar Sep 16 '25 07:09 MathurAditya724

@MathurAditya724 No problem!

yusukebe avatar Sep 16 '25 08:09 yusukebe

Hey @MathurAditya724 !

Sorry for the delay on this, got busy with work. Will finish this by tomorrow

What's going on with this?

yusukebe avatar Oct 07 '25 01:10 yusukebe

@yusukebe it is ready, can you kindly review it.

I have added 2 new functions simpleMcpAuthRouter and mcpAuthRouter, for doing auth in MCP. I believe most devs will be using the simpleMcpAuthRouter, as that we can easily setup with a 3rd party auth provider like Stytch, Clerk, Auth0, etc. And the other one requires bit more config. I will be creating some videos for this, as we need to do some setup on the provider's side also or for custom, you need to write a lot of code 😅 . I think a video should be able to help here.

Other improvements -

  1. Added keepAlive.unref() as mentioned by @BYK in #1535
  2. Regarding test coverage, I have added all the tests which are in the official package so we can ignore that
  3. To keep things simple for others, I have exposed only a few function from @hono/mcp and if someone really wanna customize the implementation, they can import the middlewares and helpers from @hono/mcp/auth. Because of this the attw for @hono/mcp/auth in node10 is failing - image

But as I checked - https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/NoResolution.md#true-positive-node-10-doesnt-support-packagejson-exports, it seems alright as it's marked as true positive and this will only be affecting if we are importing from @hono/mcp/auth with node resolution. happy to merge both if this doesn't work for you.

Also It would be great if you can share some suggestions/opinions on https://github.com/honojs/hono/pull/4485 as I have to copy the bearerAuth middleware so that it's easy for others to verify the token and also comply with the MCP Specs for Auth.

Here is a complete example -

import {
  bearerAuth,
  StreamableHTTPTransport,
  simpleMcpAuthRouter,
} from "@hono/mcp";
import { Hono } from "hono";
import { cors } from "hono/cors";
import { validateStytchJWT } from "./auth";
import mcpServer from "./mcp";

const transport = new StreamableHTTPTransport();

const app = new Hono().use(
  cors({
    origin: (origin) => origin,
    credentials: true,
  }),
);

app.route(
  "/",
  simpleMcpAuthRouter({
    issuer: "[domain]", // Happy to send you a sample one on twitter
    resourceServerUrl: new URL("http://localhost:3000/mcp"),
  }),
);

app.all(
  "/mcp",
  bearerAuth({
    verifyToken: async (token, c) => {
      const verifyResult = await validateStytchJWT(token);

      c.set("result", verifyResult);

      return true;
    },
  }),
  async (c) => {
    if (!mcpServer.isConnected()) {
      // Connecting the MCP server to the transport
      await mcpServer.connect(transport);
    }

    return transport.handleRequest(c as any);
  },
);

export default app

MathurAditya724 avatar Oct 29 '25 09:10 MathurAditya724

Hi @MathurAditya724

How should I import validateStytchJWT? What is ./auth?

import { validateStytchJWT } from "./auth";

yusukebe avatar Oct 31 '25 08:10 yusukebe

This is just a function to verify your token, this depends on the dev how they wanna check this. Here is the sample I used -

let jwks: ReturnType<typeof createRemoteJWKSet> | null = null;

export async function validateStytchJWT(token: string) {
  if (!jwks) {
    jwks = createRemoteJWKSet(new URL(`${domain}/.well-known/jwks.json`));
  }

  return await jwtVerify(token, jwks, {
    algorithms: ["RS256"],
    audience: projectId,
    issuer: [domain],
    typ: "JWT",
  });
}

MathurAditya724 avatar Oct 31 '25 08:10 MathurAditya724

@MathurAditya724

Sorry. It's difficult for me to create a working example with your code. So, can you create a working GitHub project for the example? Making [domain] a variable. It's better for Cloudflare Workers.

yusukebe avatar Oct 31 '25 08:10 yusukebe

@yusukebe here is a working example - https://github.com/MathurAditya724/hono-mcp-examples/tree/main/examples/simple-auth-workers

You will need to link the hono/mcp package from this repo and place the URL I provided in the domain variable.

For the time being I removed the verification logic as this is different for each provider and this example is a generic one. If you use the official MCP Inspector, this will work

MathurAditya724 avatar Oct 31 '25 09:10 MathurAditya724

Hi @yusukebe, any update on this?

MathurAditya724 avatar Nov 19 '25 07:11 MathurAditya724

Completed the requested changes @yusukebe

MathurAditya724 avatar Nov 23 '25 15:11 MathurAditya724

@MathurAditya724

Thank you for the update! Looks good, but I left a nitpick comment.

yusukebe avatar Nov 24 '25 06:11 yusukebe

Done 🚀 @yusukebe

MathurAditya724 avatar Nov 24 '25 06:11 MathurAditya724

@MathurAditya724

Let's go with this. Thank you for the great work, Aditya!

yusukebe avatar Nov 24 '25 07:11 yusukebe