---
title: Verify a WebMCP tool
description: Run a small board app. Check the tool result, visible change, invalid input, and cleanup.
sidebar:
  label: Verification example
---

Run a small board app with [`@nekuda/webmcp-sdk`](https://www.npmjs.com/package/@nekuda/webmcp-sdk) 0.7.1. Change its title with the form, then with a WebMCP tool.

This is a hand-written example. It shows SDK use and verification. It is not a claim about plugin-generated output.

## Tool plan

This is the approved scope for this example:

| Item | Scope |
| --- | --- |
| Tool | `rename_board` |
| Input | `title`: a nonblank string, up to 80 characters |
| Action | Call the same `renameBoard` function as the form |
| Result | Return the saved title and update the heading |
| Availability | This page, while the demo session is on |
| Cleanup | End the demo session to unregister the tool |
| Data | In this tab only. Reload to reset. |

The demo session is a local flag. It is not real sign-in or proof of access control. In an app, the server must check access for every protected action.

## Run it

Use Node.js 20 or later, npm, and Python 3. [Download the example](/verification-example.tar.gz) and extract it, or run:

```sh
curl -fLO https://docs.nekuda.ai/verification-example.tar.gz
tar -xzf verification-example.tar.gz
cd verification
npm ci
npm test
npm start
```

Open `http://127.0.0.1:4174`. Select **Start demo session**. Save a title with the form.

The form works in browsers without WebMCP. The page reports that no WebMCP surface is available. It adds no polyfill. SDK telemetry is off for this example.

## Before and after

The existing form calls one action:

```js
const { title } = board.renameBoard({ title: input.value });
```

The tool calls that same action. It adds no second write path:

```js
const renameTool = defineTool({
  stableKey: "board.rename",
  name: "rename_board",
  description: "Set the title of this demo board. Return the saved title.",
  inputSchema: {
    type: "object",
    properties: { title: { type: "string", minLength: 1, maxLength: 80 } },
    required: ["title"],
    additionalProperties: false,
  },
  annotations: { readOnlyHint: false },
  execute: renameBoard,
});
```

The shared action checks input before it changes the title. It rejects blank titles, extra fields, and calls after the demo session ends. The title is rendered as text.

Start and end registration with the session:

```js
registration = registerTools([renameTool], { telemetry: false });
await registration.ready;
// When the demo session ends:
registration.unregister();
```

The [example download](/verification-example.tar.gz) includes the full source and its local check.

## Check it in a browser

Use a browser with WebMCP enabled. With WebMCP Kit installed, ask your coding agent:

```text
/webmcp-kit:verify http://127.0.0.1:4174

This is a local demo. You may change its board title and start or end
its demo session. Test the steps below. Report observed results.
```

The verify skill uses the kit's test browser. See [Browser setup](/installation#browser-setup).

| Step | Expected result |
| --- | --- |
| Load the page. List tools. | `rename_board` is absent. |
| Start the demo session. List tools. | `rename_board` appears once. |
| Call it with `{"title":"Agent notes"}`. | The result contains `Agent notes`. The heading shows `Agent notes`. |
| Call it with `{"title":"   "}`. | The call fails. The heading stays `Agent notes`. |
| End the demo session. List tools again. | `rename_board` is absent. |
| Start the demo session again. List tools. | `rename_board` appears once. |

Record the browser version, date, returned result, and visible heading. Save a screenshot after the valid call. Report each step as passed, failed, or not run.

### Recorded result

All six steps passed on 6 October 2026 in the Codex browser, which reported Chrome 154.0.0.0, with SDK 0.7.1. The valid call returned `{"title":"Agent notes"}` and the heading showed `Agent notes`. The blank call failed without changing the heading. Ending and restarting the session removed and restored one tool.

## What the local check proves

`npm test` uses the published SDK and a stub of the browser API. It checks the shared action, registration, invalid input, cleanup, calls after the demo session ends, and the unsupported-browser fallback.

It does not launch a browser or prove native tool discovery. The browser steps above are a separate check. Do not report them as passed from `npm test` alone.
