Skip to content

feat(nitro)!: build on h3-mcp instead of the MCP SDK - #305

Draft
HugoRCD wants to merge 1 commit into
mainfrom
feat/nitro-h3-mcp-engine
Draft

feat(nitro)!: build on h3-mcp instead of the MCP SDK#305
HugoRCD wants to merge 1 commit into
mainfrom
feat/nitro-h3-mcp-engine

Conversation

@HugoRCD

@HugoRCD HugoRCD commented Aug 3, 2026

Copy link
Copy Markdown
Member

The SDK was the only reason the runtime touched a Node built-in: it hands a handler no request, so the context travelled through AsyncLocalStorage, and a WeakMap could not stand in because the SDK does not give back the Request it was given. h3-mcp passes the H3Event straight through, so node:async_hooks goes, and with it the nodejs_compat flag Cloudflare needed.

An app with five tools, four resources and two prompts drops from 974 kB to 321 kB (220 kB to 72.1 kB gzip), and the Cloudflare build carries no node: import at all. The official client still drives every test, so conformance is judged by something that is not the engine under test.

Breaking, and the package is alpha: ResourceTemplate and completable are gone — a templated resource takes uriTemplate, and a prompt argument declares its own completectx.auth is read off ctx.event like anything a middleware leaves, and legacy/responseMode became era.

Two things the engine does not cover yet are ours: the MRTR builders (inputRequired, inputResponse, acceptedContent), and the origin default. The engine trusts no browser origin until one is listed, which locks out a page the app serves to itself — the inspector, in practice. The handler therefore accepts same-origin requests on a loopback host, which is sound where a bare same-origin check is not: Host is a header the caller sets, and DNS rebinding sets it to the attacker's own name, matching its Origin.

🔗 Linked issue

📚 Description

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

The SDK was the only reason the runtime touched a Node built-in: it hands a
handler no request, so the context travelled through `AsyncLocalStorage`, and a
`WeakMap` could not stand in because the SDK does not give back the `Request` it
was given. h3-mcp passes the `H3Event` straight through, so `node:async_hooks`
goes, and with it the `nodejs_compat` flag Cloudflare needed.

An app with five tools, four resources and two prompts drops from 974 kB to
321 kB (220 kB to 72.1 kB gzip), and the Cloudflare build carries no `node:`
import at all. The official client still drives every test, so conformance is
judged by something that is not the engine under test.

Breaking, and the package is alpha: `ResourceTemplate` and `completable` are
gone — a templated resource takes `uriTemplate`, and a prompt argument declares
its own `complete` — `ctx.auth` is read off `ctx.event` like anything a
middleware leaves, and `legacy`/`responseMode` became `era`.

Two things the engine does not cover yet are ours: the MRTR builders
(`inputRequired`, `inputResponse`, `acceptedContent`), and the `origin` default.
The engine trusts no browser origin until one is listed, which locks out a page
the app serves to itself — the inspector, in practice. The handler therefore
accepts same-origin requests on a loopback host, which is sound where a bare
same-origin check is not: `Host` is a header the caller sets, and DNS rebinding
sets it to the attacker's own name, matching its `Origin`.
@HugoRCD HugoRCD self-assigned this Aug 3, 2026
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nuxt-mcp-toolkit-docs Ready Ready Preview Aug 3, 2026 9:48am

Request Review

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Thank you for following the naming conventions! 🙏

@pkg-pr-new

pkg-pr-new Bot commented Aug 3, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/nitro-mcp-toolkit@305
npm i https://pkg.pr.new/@nuxtjs/mcp-toolkit@305

commit: fba5d2c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant