WebMCP tools
browsers with WebMCP
Each command becomes a tool with its JSON Schema and hints such as read-only or ask-first, and the list follows the page as commands come and go.
cart_add({ "sku": "V60-02", "qty": 2 })
Sutram gives your app one standard way to expose what it can do. Agents call your commands as WebMCP tools, from JavaScript in a headless browser, or by typing into a terminal-like console. People can use the same console.
Or press ` anywhere on this page.
You register commands once. Sutram exposes them four ways, with the same schema, checks, handler and exit codes behind each one.
browsers with WebMCP
Each command becomes a tool with its JSON Schema and hints such as read-only or ask-first, and the list follows the page as commands come and go.
cart_add({ "sku": "V60-02", "qty": 2 })
headless Chrome, Playwright, Puppeteer, browser agents
Sutram.tools() returns what a WebMCP agent would see, and Sutram.call() runs a tool. Consequential tools run only with { confirmed: true }.
await page.evaluate(() => Sutram.call("cart_add", { sku: "V60-02", qty: 2 }));
agents that type and read, and people
A terminal in the page: type a line, read text back. help, man and --json are built in. No screenshots, no hunting for buttons.
› cart add V60-02 --qty=2 Added 2 × V60 dripper, size 02.
ChatGPT or Claude, with no browser access
The assistant gets a prompt built from the page's commands and answers with command lines. A person pastes them into the console and pastes the output back. Try it below.
```sh cart add V60-02 2 cart status ```
This page registers a handful of commands with Sutram. Click one, or open the console and type. The shop's buttons, the console and agents all run the same commands, and each run shows up below. Have a headless browser? Open DevTools and try await Sutram.call("cart_status").
A command is a name, a JSON Schema for its input, and a function. Sutram turns it into a tool for agents and a command line that agents and people can type. Your handler never knows who called it.
Sutram.register({ name: "cart add", provider: "cart", description: "Add a product to the cart", input: { // JSON Schema type: "object", properties: { sku: { type: "string" }, qty: { type: "integer", minimum: 1, default: 1 }, }, required: ["sku"], }, positional: ["sku", "qty"], annotations: {}, // readOnly, consequential, … run: ({ sku, qty }) => cart.add(sku, qty), });
Typed into the console
› cart add V60-02 2 › cart add --sku=V60-02 --qty=2 › cart add -h › man cart add
Called as a tool
cart_add({ "sku": "V60-02", "qty": 2 }) // WebMCP
Sutram.call("cart_add", { sku: "V60-02", qty: 2 }) // JavaScript
// same schema, same checks, same handler
You write the commands. Sutram does the rest, the same way for every app on the page.
Agents call your app's own logic instead of reading pixels and guessing which button to click. Results come back as data.
Mark a command consequential. The console asks, WebMCP hosts get the hint, and Sutram.call() waits for confirmed: true.
Help, manual pages and a status of the whole page are generated from your definitions, so they always match what the page can do right now.
Commands run in the browser and call your own endpoints, so they can do exactly what the user could already do.
Return data. Agents and --json get it exactly as you returned it; people get tables and key: value lines.
ES modules, or one file from a CDN. A web component for the console. Works with any framework, or none.
No build step needed. Paste this into an HTML file and open it.
From the CDN, or install @d34dman/sutram from npm and import it.
<script type="module"> import Sutram from "https://cdn.jsdelivr.net/npm/@d34dman/sutram@0.3/dist/sutram.js"; </script>
Give it a name, an input schema and a function.
Sutram.register({
name: "hello world",
provider: "hello",
description: "Say hello",
input: { type: "object", properties: { who: { type: "string", default: "you" } } },
positional: ["who"],
annotations: { readOnly: true },
run: ({ who }) => ({ text: `Hello, ${who}.` }),
});
Sutram.mountConsole();Press ` and type hello world Ada. In a browser with WebMCP, agents get a hello_world tool. From a headless browser or DevTools:
await Sutram.call("hello_world", { who: "Ada" }); // → { code: 0, text: "Hello, Ada." }
The Drupal module exposes menus, pages and node forms as commands: nav go "Content types", form node-article-form set title …, form node-article-form save.