# oRPC-to-WebMCP Bridge

The AI in the browser uses your app, not just reads it.

One package that hands a web app's own features to the AI assistant running in the browser. Built in the open as a working reference for WebMCP, the draft browser API for AI tools.

## Tags

Next.js, oRPC, WebMCP, TypeScript, Zod, shadcn/ui

![Task manager demo exposing its API as browser-native AI tools](https://lxbpjvrr41.ufs.sh/f/6KZjuRTQYJxHUj0kiKQh4PdzHWOxTYaqE2v1eBI3wC8rkgDb)

## At a glance

- **Role:** Author
- **Scope:** Bridge package plus a task manager demo
- **Runs on:** document.modelContext, native or polyfilled
- **Status:** Open source on GitHub

Nothing in the app's own code mentions WebMCP. The API is written as ordinary oRPC procedures with Zod schemas, and one hook does the rest.

WebMCP is a draft, and it moves. This was built in February 2026 against `navigator.modelContext`; the May 27, 2026 draft moved tools to `document.modelContext`, and the bridge moved with it in August 2026. What follows matches the repo today, checked against the spec's 28 July 2026 publication.

### 1. Define oRPC procedures

Type-safe procedures with oRPC and Zod. Standard API work.

### 2. The bridge registers tools

`orpc-webmcp` walks the router and registers every procedure as a tool through `document.modelContext`.

### 3. The agent calls them

An agent that speaks WebMCP calls them like any other tool. No shipping agent does yet — they still read the DOM.

### 4. Calls run server-side

Arguments validate against the same Zod schema, execute through oRPC, and the result goes back to the agent.

## The bridge package

The monorepo splits in two: `apps/web/` is the Next.js app with the UI, server actions and oRPC route handler, and `packages/orpc-webmcp/` is the bridge itself: core logic plus React hooks.

The bridge introspects the oRPC router at runtime, converts each Zod schema to JSON Schema for the tool description, registers the procedure via `document.modelContext`, then handles invocation, validation and response marshalling. A single hook makes any oRPC app WebMCP-compatible.

The task manager gets six tools out of that: `tasks.list` with an optional status filter, `tasks.get`, `tasks.create`, `tasks.update`, `tasks.delete` and `tasks.search`. No tool definition is written by hand.

## Run it yourself

The app loads the WebMCP polyfill, so the tools register in any Chromium browser. No shipping agent picks them up yet, so call them by hand.

1. `git clone https://github.com/Mark-Life/webMCP-example && cd webMCP-example && bun install && bun dev`
2. Open `http://localhost:3000`: the console prints `[WebMCP] Registered 6/6 tools from router`
3. `const tools = await document.modelContext.getTools()` lists them
4. `await document.modelContext.executeTool(tools.find((t) => t.name === "tasks.create"), JSON.stringify({ title: "Buy milk" }))` creates one, and the list on the page updates as it runs

`executeTool` takes the descriptor rather than the name, and its arguments as a JSON string. The [Model Context Tool Inspector](https://github.com/beaufortfrancois/model-context-tool-inspector) extension does the same job with a UI.

On Chrome 150+, enabling WebMCP for testing in `chrome://flags` hands the page to the native implementation and the polyfill stands down. Edge 147 ships it without a flag, and Chrome has it slated to be on by default in 157. Only the polyfill path has been tested.

## Stack

Next.js 16 and React 19 on the front with Tailwind and shadcn/ui, oRPC and Zod for the API, Turborepo and Bun to build it.

## Links

- Project page: https://andrey-markin.com/projects/webmcp-example
- All projects: https://andrey-markin.com/projects.md
- GitHub: https://github.com/Mark-Life/webMCP-example
- Contact: https://andrey-markin.com/#contact
