SDKsEdge MCP

Testing

Test your tools by hand and watch the whole surface through debug console logs — no agent required

Test your agent surface before any agent is connected — the browser is the inspector. Every tool can be called by hand from the console, Chrome's DevTools shows the surface natively, and debug mode narrates everything the toolkit does.

Call tools by hand

Every registered tool is callable from the DevTools console:

const tools = await document.modelContext.getTools();
const t = tools.find(x => x.name === 'cart.add');
await document.modelContext.executeTool(t, JSON.stringify({ productId: 'sku_123' }));

The real app should react — the cart drawer opens, the page navigates, the form submits. That's the whole point of the test: the agent will use exactly the same path, so if the app responds to your console call, it will respond to the agent.

Two wire-contract details when reading results by hand: getTools() returns each tool's inputSchema as a JSON string (parse before use), and executeTool resolves with a JSON string of the standard result envelope:

const text = JSON.parse(await document.modelContext.executeTool(t, JSON.stringify(args)))
  .content?.[0]?.text;

A good pass covers one tool per safety level you registered — a read, a reversible write, and (carefully) a destructiveHint tool — confirming for each that the returned content makes sense and the UI reacts.

Chrome DevTools

Chrome ships a dedicated WebMCP panel in DevTools: every registered tool is listed with its description and an invocation counter, every call is logged with its status, input, and output — and you can invoke tools manually with your own parameters, straight from the panel. This works because Edge MCP mirrors tools into the browser's native WebMCP registry.

Enabling the panel

The panel doesn't appear by default — WebMCP is an origin-trial feature (Chrome 149+), and for local development you enable it with flags:

  1. Open chrome://flags/#enable-webmcp-testing and set WebMCP for testing to Enabled.
  2. On the same page, search for WebMCP support in DevTools and set it to Enabled too.
  3. Relaunch Chrome.
  4. Open DevTools on your page → Application tab → WebMCP in the sidebar.

The flags are only needed for the DevTools panel. Edge MCP itself works without them in every browser — the polyfill provides document.modelContext regardless; the native mirror simply stays dormant until a native WebMCP surface exists.

The DevTools panel doesn't know about resources — they're a Napster extension. For those, use debug mode below.

Debug mode

Turn on the toolkit's flow logs and it narrates the entire surface with a colored [edge-mcp] prefix:

import { setDebug } from '@napster-corp/edge-mcp';
setDebug(true);

Or at runtime, straight from the console — no rebuild needed:

globalThis.__EDGE_MCP_DEBUG__ = true;

What you'll see, per event:

Log lineWhen
registered tool "…" / unregistered tool "…"Tool lifecycle
tool "…" called (locally | via native registry) — args:Every invocation, with its arguments
tool "…" responded: / tool "…" failed:Every result or error
registered resource "…"Resource lifecycle
resource "…" changed →Every push sent to consumers, with the value
resource "…" push suppressed (value unchanged)A push dropped because the value matched the last one sent

Logging is off by default, so the published integration stays quiet in production. Warnings about real problems (a failed native-registry mirror, a throwing resource getter) always print, debug on or off.

Testing resources

Resources only earn their place if they update on out-of-band changes — things the user does by hand. So test them that way:

  1. Enable debug mode.
  2. Use the site yourself: navigate, add something to the cart, type into the form — whatever your resources track.
  3. Watch for resource "…" changed → — each user action that should update state should log exactly once. Several echoes per action means your subscribe is wired to too broad a signal; none means either the subscription isn't firing, or the value didn't actually change — check for a push suppressed (value unchanged) line to tell those two apart.

You can also read a resource's current value directly:

await document.modelContext.readResource('state://cart');

Next steps

On this page