Skip to content
All posts
Design6 min read

WebMCP and the editor as a tool surface

Agents already drive Elah from a one-file guide and a JSON render spec. WebMCP would let them drive an open editor in the browser. What the timeline already gets right for that, and where this stands: planned, with no date.

Status first, because this post is about a direction and it would be easy to read it as an announcement. WebMCP support for Elah is planned. Nothing in this repository implements it today, there is no beta, and we have no date to give you. Everything below the status line is about why we think the engine is shaped well for it, and what we would expose when we build it.

Agents already use Elah

It is worth being concrete about the part that is real. Coding agents use Elah now, through two doors, and both were designed for a reader that gets one shot.

The first is a single file, docs/ai/ELAH_FOR_AI_AGENTS.md. It is a complete integration guide for building a custom editor UI on @elah/editor, written so that nothing in it requires reading another file or having the repository checked out. That matters for the tools that generate an app in a hosted sandbox with no repo access. It also contains the unglamorous section that earns its keep, the common mistakes: the three stylesheets people forget, the bundler setup, the places a first attempt goes wrong.

The second is the headless one. npx @elah/cli serve starts an HTTP render server that accepts a JSON build spec: times in seconds, assets by name, no engine bookkeeping. If the spec is wrong, the error is addressed by path, in the form clips[2].duration must be …, and the server answers with a 422. A generating model can read that, fix clips[2], and try again. The point of the format is that the failure message names the field the model wrote.

Both doors share an assumption: the agent produces text, and the engine turns text into a video. What they do not give an agent is a way to work inside an editor a person already has open. That is the gap WebMCP is aimed at.

What WebMCP is

WebMCP is a proposal in the W3C Web Machine Learning Community Group, put forward by Google and Microsoft. The idea is that a web page can tell the browser, and through it any agent, what it can do. A page registers tools with document.modelContext.registerTool(), a name that replaced navigator.modelContext around August 2026, and each tool describes its arguments with JSON Schema. An agent that visits the page discovers those tools, instead of having to guess at buttons by reading the DOM or looking at screenshots.

Support is early and uneven, and we will state what we verified rather than what we hope. Chrome shipped it in Canary 146 and ran an origin trial from Chrome 149. ChatGPT's desktop browser and Codex can discover WebMCP tools on a page, and Claude Code reaches them through an MCP bridge. Firefox and Safari are engaged but have not committed. The specification itself has already been renamed once, so treat any code written against it today as provisional.

illustration-only.ts
// Illustrates the WebMCP standard. This is NOT an elah API, and nothing in
// this repository calls it. The exact shape is still moving.
document.modelContext.registerTool({
  name: 'get_weather',
  description: 'Look up the current weather for a city',
  inputSchema: {
    type: 'object',
    properties: { city: { type: 'string' } },
    required: ['city'],
  },
  async execute({ city }) {
    return { content: [{ type: 'text', text: 'Sunny in ' + city }] }
  },
})

What a timeline exposes well

A tool surface is only as good as the thing behind it. Handing an agent a poorly shaped model, one where meaning is implicit and every action half-works, produces an agent that fails in interesting ways. A timeline engine happens to have three properties that suit an agent unusually well, all of which exist because of decisions we made for other reasons.

The first is integer frames. Every position and duration in the model is a whole number of frames, so when an agent says frame 240 there is exactly one thing it can mean. There is no rounding to argue about, no question of whether 8.0 seconds and 8.0000003 seconds are the same instant, and the half-open interval rule settles which clip owns a seam. An agent that reasons in seconds has to be taught our rounding. An agent that reasons in frames just has to count.

The second is one mutation funnel. Every project edit goes through TimelineEngine; the stores that the interface reads are mirrors, never written to. For a person that is an architecture rule. For an agent it is a guarantee: whatever an agent does, it does through the same methods a human drag does, which means it is validated the same way, it lands in the same history, and it shows up in the interface because the interface is listening to the same engine. There is no second, privileged path for an agent to use or to break.

The third is batching. engine.batch(recipe, description) groups several mutations into a single undo entry. A multi-step edit that an agent plans as a unit becomes a unit for the person too.

batch.ts
// Several steps, one undo entry.
engine.batch(() => {
  engine.setClipSpeed(clip.id, clip.trackId, 2)
  engine.updateClip(clip.id, clip.trackId, { cornerRadius: 0.1 })
}, 'Tighten the intro')

Put those together and you get the property that makes an agent tolerable to work beside: when it does something you did not want, you press undo once and it is gone. An agent that edits your project is only usable if its mistakes are cheap, and the history model was already built to make mistakes cheap.

What we plan to expose

This section is intent, not a specification, and the names will change. The surface we have in mind is deliberately small, because a long list of tools is a long list of ways for a model to pick the wrong one.

  • Describe the project: read the current tracks, clips and their frame positions, so an agent starts from what is on the timeline and not from a guess.
  • Apply edits: change the project through the engine, as a batch, so the result is one step the person can undo.
  • Export: render the result to a file, with the same pipeline a person would use.

Describing before editing is the part we care most about. An agent that cannot see the timeline will invent one, and a plausible invention is worse than an error. Reading first, then proposing, then applying as one undoable step is the loop we would want even if no standard existed.

Status

To repeat what we said at the top, without softening it. WebMCP support is planned. It is not shipped and it is not in beta. There is no date, and this post is not one. What exists today is the single-file guide for agents building on the SDK and npx @elah/cli serve for agents rendering from a spec. If you are building something that would benefit from the open-editor version, open an issue on GitHub and tell us what you would want an agent to be able to do, and in what order. That is more useful to us than a date would be to you.

Expose the model you already trust your own interface with. If an agent needs a second, looser path, the first one was not good enough.

Building something with browser-native video?

Try the SDK, read the docs, or join the conversation.