Building Agent-Ready Web Apps

June 24, 202610 min read

For a long time, frontend engineering was mostly about presenting application capabilities to humans.

A user sees a button.
They click it.
We validate some state.
We call an API.
We render the result.

That model is still valid.

What is changing is that humans are no longer the only consumers of the interface.

AI agents increasingly need to understand what a product can do, which inputs an action accepts, when that action is available, and how it should be executed.

That creates a new frontend responsibility:

designing a machine-readable capability surface alongside the human-readable interface.

The Shift

A traditional UI asks:

What should the user see?

An agent-ready UI also needs to answer:

What capabilities are available here?

Today we might write:

<Button onClick={save}>
  Save
</Button>

The application knows exactly what this means.

The implementation knows which function runs.

The backend knows which operation is being performed.

But an external agent does not necessarily know any of that.

It may only see a button labeled "Save".

It still has to infer:

  • what is being saved
  • which inputs are required
  • what validation applies
  • whether the operation is available
  • whether submission requires user interaction
  • what result comes back

One possible response is to add an application-specific semantic abstraction:

<Action intent="save-document" />

That may be useful internally.

But it does not solve the more interesting interoperability problem:

how does the browser expose that capability to an agent in a structured way?

This is where WebMCP becomes relevant.

From UI Controls to Tool Contracts

WebMCP's Declarative API allows an existing HTML form to expose itself as an agent-callable tool.

For example:

<form
  toolname="saveDocument"
  tooldescription="Saves the current document as a draft."
>
  <label for="title">Title</label>

  <input
    id="title"
    name="title"
    required
    toolparamdescription="The title of the document."
  />

  <button type="submit">
    Save draft
  </button>
</form>

For a human, this is still a normal form.

For a compatible agent, it can also become a structured tool with:

  • a name
  • a description
  • parameters
  • required fields
  • submission behavior

That is the important architectural shift.

The frontend is not replacing UI with tools.

It is exposing selected UI capabilities through an explicit machine-readable contract.

Humans See UI. Agents See Capabilities.

That dual representation is what makes the declarative model interesting.

A human interacts with:

Title
[____________]

[Save draft]

An agent can reason about something closer to:

saveDocument({
  title: string
})

The application does not need two completely separate systems.

The visible interface can remain the primary product surface while also becoming discoverable to agents.

This matters because agents otherwise have to infer behavior from presentation structure.

They might inspect:

  • DOM elements
  • labels
  • accessibility metadata
  • visual state
  • button text

That can work, but it is indirect.

A tool contract is more explicit.

Instead of asking an agent to guess what a button does, the application can describe the capability directly.

This Is API Design

Once UI capabilities become callable by agents, tool design starts to look a lot like API design.

Consider these tool names:

handleAction
submitForm
performTask

They are technically valid names.

They are also poor interfaces.

Compare them with:

saveDocument
scheduleMeeting
createSupportRequest
assignTask

The same applies to descriptions.

This:

tooldescription="Does the thing."

is not useful.

This is:

tooldescription="Creates a support request for the current customer account."

Parameter descriptions matter for the same reason:

toolparamdescription="The urgency of the support request."

These descriptions are no longer implementation comments.

They are part of the contract an agent uses to understand the system.

That means frontend teams need to think about:

  • tool naming
  • capability boundaries
  • parameter semantics
  • required inputs
  • overlapping tools
  • tool availability
  • execution results

These are familiar API design concerns, but they are now appearing inside the frontend layer.

Tool Availability Should Follow Application State

Not every capability should be available all the time.

Consider a project management product.

When a task is open, an agent might have access to:

assignTask
changeTaskStatus
addComment

Once the task is archived, some of those capabilities may no longer make sense.

This creates an important rule:

Agent-visible capabilities should reflect the actual state and permissions of the application.

That does not require inventing a new frontend state model.

Traditional UI state still exists:

{
  selectedTab: "activity",
  modalOpen: false,
  isLoading: false
}

Application and workflow state still exists:

{
  taskStatus: "open",
  canAssign: true,
  canArchive: false
}

WebMCP adds another question:

Which of these capabilities should currently be exposed to an agent?

That is an additional boundary, not a replacement for normal frontend state.

Tool Calling Still Goes Through the Application

One of the useful properties of the declarative model is that agent execution can reuse normal application behavior.

For example:

form.addEventListener("submit", async (event) => {
  event.preventDefault();

  const result = await saveDocument();

  if (event.agentInvoked) {
    event.respondWith(Promise.resolve(result));
  }
});

The application still owns:

  • validation
  • authorization
  • business logic
  • API calls
  • error handling

The agent is not bypassing the application.

It is entering through an explicit tool boundary.

That is an important distinction.

WebMCP should not become a second business-logic layer.

The frontend should expose capabilities that already exist in the product and route them through the same rules humans use.

Confirmation Is a Product Decision

Not every tool should execute the same way.

There is a meaningful difference between:

searchOrders

and:

cancelOrder

or between:

findAvailableTimes

and:

scheduleMeeting

A low-risk action may be appropriate for automatic execution.

A destructive or high-impact action may need a visible confirmation step.

WebMCP's declarative model allows the form itself to remain part of this interaction.

An agent can populate a form while the human still performs the final submission.

For appropriate cases, automatic submission can be enabled.

That creates a useful spectrum:

Agent discovers tool
        ↓
Agent fills inputs
        ↓
User reviews
        ↓
User submits

or:

Agent discovers tool
        ↓
Agent invokes tool
        ↓
Application executes
        ↓
Result returns

The important engineering question is not:

Can the agent do this?

It is:

Under what conditions should the agent be allowed to do this automatically?

That decision belongs to product policy, permissions, and application design.

WebMCP gives us a mechanism to expose the capability.

It does not replace those controls.

Tool Execution Needs Visible Feedback

Agent invocation should not make the interface opaque.

If an agent activates a tool, the user should still be able to understand what is happening.

The application may need to show:

  • which capability is active
  • which values were provided
  • whether the operation is waiting for confirmation
  • whether it succeeded
  • whether it failed
  • whether it was cancelled

WebMCP exposes lifecycle hooks that make this possible.

For example:

window.addEventListener("toolactivated", ({ toolName }) => {
  console.log(`${toolName} activated`);
});

window.addEventListener("toolcancel", ({ toolName }) => {
  console.log(`${toolName} cancelled`);
});

The frontend can use these events when the product needs visible feedback around agent activity.

The point is not to create a new "agent state management" framework.

The point is simply that agent invocation becomes another application event the UI may need to represent.

WebMCP Does Not Replace Application Architecture

This is an important boundary.

WebMCP does not solve:

  • authorization
  • permissions
  • business rules
  • transaction design
  • workflow orchestration
  • risk classification
  • policy engines
  • backend validation

Those systems still belong where they belong.

WebMCP provides a browser-facing mechanism for exposing tools.

A useful architecture still looks like:

Human or Agent
      ↓
Frontend capability
      ↓
Application logic
      ↓
Backend API
      ↓
Domain rules

The tool contract should expose the application.

It should not duplicate it.

Declarative Tools and Internal Components Are Different Layers

This is why I would not frame the future as:

<Action intent="save-document" />

versus:

<form toolname="saveDocument">

These abstractions solve different problems.

An internal component abstraction may help your own codebase model behavior:

<SaveDocumentAction />

A WebMCP tool contract helps an external agent understand that behavior.

You can have both.

For example:

<SaveDocumentForm />

could render:

<form
  toolname="saveDocument"
  tooldescription="Saves the current document as a draft."
>

The component architecture is internal.

The tool contract is external.

That separation is useful.

Generative UI Is a Separate Concern

Generative UI and WebMCP can work together, but they should not be treated as the same idea.

Generative UI asks:

What interface should be assembled for this task?

WebMCP asks:

Which capabilities on this page can an agent understand and invoke?

Those can compose.

For example, an AI system might generate an incident-review interface containing:

Incident summary
Risk table
Escalation form

The escalation form could expose:

<form
  toolname="escalateIncident"
  tooldescription="Escalates an incident to the on-call response team."
>

But that composition is an architectural choice.

WebMCP itself does not provide a generative UI system.

It simply gives generated or static UI a way to expose structured tools.

That distinction matters.

The Frontend Gets a Second Consumer

The most useful way to think about this is not that frontend engineering is becoming completely different.

It is that frontend now has another consumer.

Traditionally, we design an interaction contract for humans:

labels
controls
validation
feedback
navigation

Agent-ready interfaces add another contract:

tool names
descriptions
schemas
availability
execution results

Both contracts can sit on top of the same product capability.

That is where frontend engineering becomes more interesting.

Not because buttons disappear.

Not because every interface becomes generated.

Not because the frontend suddenly becomes an orchestration engine.

But because the application now has to communicate its capabilities clearly to both humans and machines.

The Takeaway

The future of frontend is not just more components.

It is also not necessarily a new universal layer of "intent components".

A more concrete change is happening:

frontend applications are beginning to expose selected capabilities as structured tools.

With WebMCP, an interface can remain normal HTML for humans while also describing to an agent:

what this capability is
what inputs it accepts
when it is available
how it is submitted
what result it produces

That creates a new engineering boundary.

Frontend engineers will increasingly need to think not only about:

How should the user interact with this?

but also:

How should an agent understand and invoke this safely?

That is not a replacement for frontend engineering.

It is an extension of it.

And if this direction continues, one of the most valuable frontend skills will be designing interfaces that are both human-readable and machine-readable without creating two separate products.