Debug WebMCP Tools with a Drop-in Devtools Panel
Short answer: @mcptrail/webmcp-devtools drops a panel into your page that intercepts every registerTool call, lists the tools it finds, auto-builds an input form from each tool’s inputSchema, invokes the tool when you submit, and renders the structured result. It’s one line — createWebMcpDevtools() — and it needs no agent and no configuration. You get to exercise your WebMCP tools by hand, the same way an agent would, and see exactly what comes back.
Debugging a WebMCP tool without a panel is guesswork. The handler runs only when an agent decides to call it, so to check your work you’d have to spin up a real agent, coax it into calling the right tool with the right arguments, and hope you can read what happened. This flips that around: a form you can fill in, a button you can click, and the result on screen. (If WebMCP itself is new to you, read What is WebMCP? first.)
The problem: WebMCP tools have no UI
Your WebMCP tools are invisible by design. They aren’t buttons on the page — they’re actions registered against navigator.modelContext, waiting for an agent to invoke them. That’s great in production and painful while you build.
Without tooling, debugging a tool means one of two bad options:
- Drive a real agent. Boot an agent in a flagged browser and prompt it until it happens to call the tool you’re working on — slow, flaky, and hard to reproduce.
- Scaffold throwaway UI. Hand-write a form and a button for each tool just to test it, then delete it before shipping.
Both waste time on something that should be free: seeing your tools, calling them with arguments you choose, and reading the result.
One line to get a panel
@mcptrail/webmcp-devtools (github.com/ElBartoTn/webmcp-devtools, MIT) installs a floating panel that discovers your tools automatically.
npm install @mcptrail/webmcp-devtools
import { createWebMcpDevtools } from "@mcptrail/webmcp-devtools";
// In dev only — mount the panel before your tools register
if (import.meta.env.DEV) {
createWebMcpDevtools();
}
That’s the whole setup. createWebMcpDevtools() wraps navigator.modelContext.registerTool so that every tool your app registers — now or later — shows up in the panel the moment it’s declared. No config object, no list of tools to maintain, no agent required.
Auto-built forms from inputSchema
The panel’s best trick: it reads each tool’s inputSchema and generates a matching input form for you. A string field becomes a text input, a number becomes a number input, a boolean becomes a checkbox, an enum becomes a select. Fill it in, hit invoke, and the panel calls the tool and shows the structured result underneath.
| From the schema | Rendered as |
|---|---|
type: "string" | Text input |
type: "number" | Number input |
type: "boolean" | Checkbox |
enum: [...] | Dropdown select |
required: [...] | Marked and enforced before invoke |
Because the form comes straight from the schema, it’s always in sync with what an agent would actually send. If the form looks wrong, your schema is wrong — which is itself a useful thing to catch early. You’re testing the real contract, not an approximation of it.
Pair it with highlight to see the effect
Invoking a tool tells you what it returned. It doesn’t tell you what it changed on the page — and WebMCP tools often have side effects: they mutate the DOM, update state, move things around. Pair the panel with @mcptrail/webmcp-highlight and you see both halves at once: the result in the panel, and a highlighted ring around whatever the call changed in the page.
import { createWebMcpDevtools } from "@mcptrail/webmcp-devtools";
import { createWebMcpHighlight } from "@mcptrail/webmcp-highlight";
if (import.meta.env.DEV) {
createWebMcpHighlight(); // outlines what each tool call changes
createWebMcpDevtools(); // the panel to trigger calls by hand
}
Now your debug loop is complete: pick a tool, fill its form, invoke, read the result, and watch the page change. See See what a WebMCP agent changed on your page for what the highlight overlay does in detail.
Fits any framework
The panel intercepts registerTool at the browser API level, so it doesn’t care how your tools got registered — plain script, React effect, Vue setup, Svelte. If it reaches navigator.modelContext, the panel sees it.
- React — mount
createWebMcpDevtools()once at app start; tools registered in effects appear as they mount. See Add WebMCP tools in React. - Any browser — combine with the polyfill so the panel works even where the native API isn’t available yet.
- Dev-only — gate the call behind a
DEVflag so it never ships to production.
FAQ
Do I need an agent running to use the panel?
No. The panel is the caller. It lists your registered tools, builds a form from each schema, and invokes the tool when you submit — playing the role an agent would, but driven by you. That’s what makes it useful during development, when no agent is in the loop yet and you just want to exercise a tool by hand.
How does it know what fields a tool needs?
It reads the tool’s inputSchema. Each property becomes a matching form field — text for strings, number inputs for numbers, checkboxes for booleans, selects for enums — and required fields are enforced before you can invoke. Because the form is generated from the same schema an agent reads, what you send by hand matches what an agent would send.
Will this end up in my production bundle?
Only if you let it. Gate createWebMcpDevtools() behind a dev flag like import.meta.env.DEV, and your bundler tree-shakes it out of production builds. The panel is a development tool; there’s no reason for it to ship, and the one-line guard keeps it out.
Explore features · Open MCP Trail
Related articles
- See what a WebMCP agent changed on your page — the highlight overlay that pairs with this panel.
- Use WebMCP on any browser with a polyfill — make the panel and your tools work where the native API isn’t yet.
- Add WebMCP tools in React — register tools from effects and see them appear in the panel.
- What is WebMCP? — the plain-English guide to the API these tools are built on.