sutram docs
All pages

Why commands

Without Sutram, an agent that wants to use a web app has two options.

  • Read the page. Take screenshots or an accessibility snapshot, work out what is on the page, find the right elements, click and type, and read the page again to see whether it worked. It is slow, it costs tokens on every step, and it breaks when the layout changes. A headless browser and the user's own browser behave differently, so the experience is not the same either.
  • Call an API built for agents. Someone writes a tool, with a schema, for every action. That is work for every form and every page, and it usually means a new way into the server, with its own login.

Sutram is the third option: a standard interface on the page itself. Any part of the app (a form, the navigation, an editor, a module) hooks in the same way, by registering commands. Agents find them with help, run them one at a time or in one batch, and correct what goes wrong:

form fields node-article-form
form set node-article-form title "Pour-over, step by step"
form set node-article-form field_tags "coffee, v60"
form set node-article-form status false
form submit node-article-form

Each command has a JSON Schema for its input, and agents with WebMCP get it as a tool. So an agent can also send everything in one go first, and fix single values after.

In the user's session

Commands run in the browser, as the logged-in user. A person can log in, then let an agent take over: it can do exactly what the person could already do, and nothing more. There is no new API, no extra login and no service account. Access checks stay on the server, where they are today.

The same everywhere

The same commands answer the same way whether the agent drives a headless browser, uses WebMCP in the person's browser, runs JavaScript in the page, or types into the console. Nothing depends on screen size, layout or how the page looks.

Precise edits

form set <form> title "Foo" changes one field and nothing else. With one schema for the whole form, the agent writes every field, including the ones it did not mean to touch, and one wrong value fails or overwrites all of it.

For an existing article with a long body, that matters more: changing the title should not mean reading the body and sending it back.

Forms that change as you fill them

Real forms are not fixed. Pick "billing" and the form asks for an invoice number. Tick "call me back" and it wants a phone number. Drupal has conditional fields, AJAX widgets, paragraphs and multi-step forms.

A schema written up front cannot describe fields that do not exist yet. With commands the agent answers, and the result says what appeared:

› form set request topic billing
topic set. The form now also asks for: invoice, amount.

The forms example does exactly this. The coffee shop on the home page does it at small scale: the checkout command exists only once the cart has something in it.

Errors the agent can act on

When a command fails, the message names the command and what is wrong:

› form set node-article-form status draft
form set: status is a yes/no field. Use true or false.

The agent fixes that one line and carries on. The fields it already set stay set. With one schema, a rejected call means nothing was applied, and the agent sends the whole object again.

Exit codes say what kind of failure it was: 2 for input that did not fit, 127 for a command that does not exist (with "did you mean"), 1 for a command that ran and failed, 130 for one that was not allowed to run. See Results and exit codes.

Control, and a person in the loop

  • Read first. status shows what every part of the page reports. Commands marked read-only change nothing.
  • Ask before what matters. Annotations mark what is consequential, and the page's policy decides who has to agree. See Annotations and the policy.
  • Save on purpose. Changes go into the page's working copy. submit sends them; discard throws them away. Nothing is saved as a side effect. See Drafts and saving.
  • Readable by people. Every agent call is a command line a person can read, repeat, paste into a bug report, or type themselves.

What it costs in tokens

Claude Code, driving a real browser on the Drupal demo, ran two tasks once with Sutram and once without it, on the same set-up. Building a Canvas page took half the task tokens (228k instead of 453k) and 21 calls instead of 28; editing an article took 11 calls instead of 14. One run each, so a direction, not a benchmark; the method and all numbers are in Measurements.

Where the saving comes from, estimated from captured outputs on Drupal's "Create Article" form with one wrong value (bytes ÷ 4, Sutram 0.3 and 0.4, no agent run):

  • Reading the page: a browser agent reads about 3,300 tokens of accessibility snapshot (about 81,000 as HTML, about 1,600 per screenshot). With Sutram, the agent reads about 650 tokens of help and field list, or about 1,200 through the full WebMCP tool list.
  • Correcting one wrong value: 17 to 44 tokens with Sutram. Without it, about 3,300: the browser agent gets no error message, so it reads the page again to find out what happened.
  • Hidden fields: four of the form's fields sit behind toggles. Sutram's field list shows them; a browser agent has to find them and click them open.

A schema written by hand for this one form would read even less, but someone has to write it for every form, and it resends every value after one mistake.

Why not just WebMCP?

WebMCP is how a page hands tools to an agent. It does not say which tools a page has, how they are named, or how many parts of an app share one page. Sutram is that layer, and WebMCP is one of the ways out of it.

  • Many providers, one page. On a Drupal page a dozen modules may each want to expose something. With plain WebMCP each registers its own tools, with its own names. With Sutram they share one registry and one command grammar.
  • People see what agents see. WebMCP tools are invisible to people. Every Sutram command is also a line in the console, so a person can type exactly what the agent would call and watch what it runs.
  • Few tools, stable list. form set <form> … is the tool form_set for every form, not one tool per form. Commands look up their target when they run, so the tool list stays put while content comes and goes.
  • What WebMCP leaves out. Discovery (help, man, status), errors that name the fix, changes to poll (events) and app-defined formats.
  • Works before WebMCP does. Browser agents and tests call the same commands through Sutram.call() today.

Sutram registers its tools through WebMCP's own registerTool() and never reads or changes the page's HTML. It does not replace Playwright or browser agents: they drive the browser, and Sutram gives them commands to call instead of buttons to click.

When one tool is enough

For one app with a few fixed actions, a plain WebMCP tool with a schema is fine. That is exactly what each Sutram command is through WebMCP. Sutram earns its place when several parts of an app share a page, or when people should use the same commands as the agent.

Next

This page as MarkdownEdit on GitHub