lantern-grid
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@lantern-gridStart a Lantern Grid game and light all the lanterns"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-app-webmcp-demo
A small MCP App for testing hosts that support WebMCP inside MCP Apps.
The View is a little game, Lantern Grid. Instead of the host calling server tools to play it, the View
exposes its own tools with document.modelContext.registerTool(),
the direction discussed in
ext-apps#797 and prototyped in
ext-apps#798. The tool list changes while you
play, which makes it a useful probe for how a host handles tools that come and go.
The server has no dependencies and no SDK: one file of JSON-RPC over streamable HTTP. Node 20 or newer.
Play it
https://kenchris.github.io/mcp-app-webmcp-demo/
The same file is the MCP App View and a standalone web page, so it is also a plain WebMCP demo: open it in a
browser or extension that provides document.modelContext and the page registers its tools there, for any agent to
discover and call. Without WebMCP you can still play with the on-screen buttons or the arrow keys (Enter lights a
lantern); the page then says no tools are registered. ?polyfill=1 loads a minimal document.modelContext, enough
to try the tools from the console.
Related MCP server: opencode-webmcp
Use it as an MCP App
A web page cannot be an MCP server, so the MCP App needs the small server in this repo. Node 20+, no install step.
Launched by the host (stdio), for hosts with an mcpServers config (Claude Desktop, VS Code, Cursor, ...):
{
"mcpServers": {
"lantern-grid": {
"command": "npx",
"args": ["-y", "github:kenchris/mcp-app-webmcp-demo", "--stdio"]
}
}
}Over HTTP, for hosts that take a server URL (for example the OpenVINO Web Extension):
npx -y github:kenchris/mcp-app-webmcp-demo --port 8787 # MCP endpoint: http://127.0.0.1:8787/mcpHosts that need a public https endpoint (ChatGPT, for instance) need the server behind a tunnel.
Then ask the model: "Start a Lantern Grid game and light all the lanterns." It opens the view with start_game.
If the host supports WebMCP in MCP Apps, the model then plays with the tools the view registers. A host without that
support still shows the view, but the model does not see those tools, which is a result in itself.
From a checkout, node src/server.mjs --stdio or node src/server.mjs --port 8787 does the same.
Run it from a checkout
git clone https://github.com/kenchris/mcp-app-webmcp-demo
cd mcp-app-webmcp-demo
node src/server.mjs --port 8787 # MCP endpoint: http://127.0.0.1:8787/mcp
npm test # protocol checks for the serverThe same instructions are on the hosted page, in the "Use it as an MCP App" section.
Without a host
Open http://127.0.0.1:8787/view?polyfill=1 in a tab (or the hosted page above with ?polyfill=1). The variant adds
a minimal document.modelContext (src/dev-polyfill.js), so you can try the tools from the console:
const tools = await document.modelContext.getTools();
await document.modelContext.executeTool(tools.find(t => t.name === 'look'));Plain /view loads the View without a polyfill and shows a banner,
which is what a host that provides no WebMCP looks like.
How the game works
A grid with a few unlit lanterns. Walk onto each one and light it. When the last one is lit you win, and a
new game can be started with new_game.
start_game (server tool) ──▶ host opens ui://webmcp-demo/lanterns
│
View ◀─ ui/initialize ─▶ host
View registers look, count_lit, explode, then move
│
model ──▶ move / light_lantern / look ──▶ ViewWhat it exercises
Tool | Where | Why it is in the demo |
| server | Opens the View ( |
| server | A server tool with a purpose near the View's, to see how the model chooses between server and in-frame tools |
| View | Always there while playing. Read-only ( |
| View | Registered about 250 ms after start: late registration. Takes an enum argument |
| View | Registered only while standing on an unlit lantern, so the list changes after every move ( |
| View | Returns a bare number, not an object |
| View | Always throws: the error path |
| View | Appears only after you win, while |
Also covered: ui/initialize and ui/notifications/initialized, ui/update-model-context after every
state change, ui/notifications/size-changed, and a visible banner when the host provides no
document.modelContext.
Checklist for host implementers
The tools the View has registered at each moment:
Moment | Tools |
just after start |
|
standing on an unlit lantern | the above plus |
after lighting the last lantern |
|
after |
|
A host passes if:
the model sees each of these lists as it changes, without the user doing anything (the late
move, andlight_lanterncoming and going);a call reaches the View and its result comes back, including the bare number from
count_lit;the error from
explodearrives as a tool error and does not break the turn;tools that were unregistered disappear from the model's list, and nothing from a closed View lingers;
the View's tools do not collide with server tools such as
start_game.
window.__demo exposes state() and registeredTools(), so a browser test can compare the View's own idea
of its tools with what the host shows.
Notes
The hosted page carries a WebMCP origin trial token for
https://kenchris.github.io(Chrome 149+), so Chrome exposes native WebMCP there. It expires 2027-03-30; renew it and updatescripts/build-pages.mjs. The token is added by the build only, not tosrc/view.html.The hosted page is built by
npm run build:pages(copiessrc/view.htmltodocs/index.html, served frommaster/docs).The View is one self-contained HTML file with no external requests, so it works under a strict CSP.
It never polyfills
document.modelContextitself. If the host provides none, it shows a banner and registers nothing. Providing it is the host's job, as the proposal says.The MCP App handshake is hand-rolled in the View (about 30 lines of JSON-RPC over
postMessage), so there is nothing to build or bundle.The wire format between host and View for WebMCP tools is still a draft upstream and may change.
License
Copyright (C) 2026 Kenneth Rohde Christiansen. Apache-2.0, see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Build your own tools from chat: design, test and host them on a shareable MCP server URL.
Build, deploy, and operate hosted web apps on VibeKit (vibekit.bot) from any MCP client.
Hosted MCP runtime where your agent publishes its own tools by tool call and keeps working.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceExposes app-registered tools as an MCP server for OpenClaw, forwarding actual tool execution back to the app over a WebSocket bridge.-
- AlicenseNot gradedqualityCmaintenanceBridges OpenCode to Chromium's WebMCP API, exposing WebMCP tools from a webpage as standard MCP tools for any MCP client.18 npm1MIT
- AlicenseAqualityCmaintenanceMCP server that lets agents launch, drive, and read game instances over HTTP, with a dynamic toolset discovered from the running game.71MIT
- FlicenseNot gradedqualityBmaintenanceEnables MCP clients to discover and invoke WebMCP tools registered in pages open in Orca's embedded browser, without extensions or bridges.1-