Repository navigation
Run the tools in the browser via WebMCP - #32
Merged
Merged
Conversation
WebMCP lets a page register tools with the browser so an in-page agent can call them. These tools are pure functions over the bundled summaries, so there's no reason they need a local Node process: open-and-async.com can offer them to any visitor whose browser exposes a model context, with nothing to install. To share one set of tool definitions between stdio and the browser: - src/book.js holds the runtime-neutral helpers and a createBook() factory. data.js keeps its exports but is now just the Node loader for data/book.json.br. - registerContentTools takes the book as a parameter instead of importing data.js, so the tool modules never touch node: APIs. - src/browser.js (@open-and-async/mcp/browser) collects the same registrations and hands them to registerTool(). Each call is validated with the tool's own zod schema first, the way McpServer does for stdio, so defaults and min/max limits still apply. zod runs jitless there: its eval probe otherwise logs a CSP violation on strict-CSP pages. The page supplies the parsed book data rather than this module fetching it, because browsers can't decompress Brotli streams yet and where the data lives is the page's call. test/browser.test.js walks the browser import graph for node: imports and checks the WebMCP tool list matches the stdio server's. Adds an exports map (./browser, the data file, package.json) and bumps to 1.1.0 for the new entry point. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The data license only allows using book.json.br to operate this package. A generic "pass in the book data" snippet read like an invitation for any site to host it, so say the browser entry point exists for open-and-async.com. Also say that the data has to be decoded first: browsers can't decompress Brotli streams, which is why the site re-encodes it as gzip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
@open-and-async/mcp/browser, an entry point that registers the same 11 tools with a page's WebMCP model context. An agent in a WebMCP browser can then call them on open-and-async.com with nothing to install.Why
The tools are pure functions over the bundled summaries (template formatting, lookups, keyword ranking). Nothing about them needs a local Node process, so running them in the page is the cheapest way to reach people who will never run
npx. There's no server endpoint and nothing extra to deploy.How
src/book.jsholds the runtime-neutral helpers plus acreateBook()factory.src/data.jskeeps every export it had, but is now just the Node loader fordata/book.json.br.registerContentTools(server, data)takes the book as a parameter rather than importingdata.js, so the tool modules never touchnode:APIs.src/browser.jscollects the existingregisterToolcalls with a stand-in server (the same tricktest/helpers.jsalready uses) and passes them tomodelContext.registerTool():McpServerdoes for stdio, sosearch_principles'limitbounds and the optional fields behave the same.inputSchemacomes fromz.toJSONSchema(..., { io: "input" }).jitless: itsnew Functionprobe otherwise logs a CSP violation on pages without'unsafe-eval'.DecompressionStreamhas no'brotli'format), and where the data lives is the page's call. The site gzips the package's.brat build time.src/browser.d.tstypes the entry point. The newexportsmap lists./browser,./data/book.json.br, and./package.json. Nothing could import the package root before (nomain, no rootindex.js), andnpx/the bin aren't affected.manifest.jsontool list is unchanged.What WebMCP doesn't carry
Tools only. There's no channel for the server
instructions, resources, or prompts, so the once-per-session funnel line in tool output is the only attribution that reaches the agent. In the browser, each page load is one session.Verification
npm packtarball (so thefilesandexportsfilters apply): the site's build and CSP suites pass.npm test: 54 pass on Node 24 and Node 18. The newtest/browser.test.js:node:imports;--enable-experimental-web-platform-featuresexposes a native model context. Against a local build of the site, all 11 tools registered,triage_sync_vs_asyncexecuted, and there were no CSP violations once zod was jitless.For the owner: data license
The site serves a gzip re-encoding of
book.json.brat/webmcp/book.json.gzso the browser tools can read it.DATA-LICENSE.mdpermits use "solely as part of operating the@open-and-async/mcpsoftware", which this arguably is, but it's still a second hosted copy. As the licensor, you may want the license to name the site explicitly. The README now says the browser entry point exists for open-and-async.com and that the license doesn't cover other sites hosting the data.Releasing
The site PR depends on 1.1.0 being on npm. Publishing still goes through the tag and the
releaseapprovals. Nothing here tags or publishes.🤖 Generated with Claude Code