Making Web Apps AI-Ready with WebMCP: Capabilities Beyond Traditional Technologies
1. From User Interfaces to AI Interfaces
Web applications have traditionally been designed around two primary interfaces.
The first is the user interface:
User
│
▼
UI
│
▼
Application
Users interact with buttons, forms, menus, and other visual elements to perform actions.
The second is the developer interface:
Developer
│
▼
API
│
▼
Application
Developers interact with APIs and services to work with the application programmatically.
AI agents introduce another interaction model:
AI Agent
│
▼
Application Capabilities
Instead of navigating the interface to perform an action, an agent can work with capabilities that the application explicitly exposes.
Consider a simple theme system:
Application
│
├── Dark
├── Light
├── Emerald
├── Indigo
└── Rose
A user can change the theme through the UI:
Settings
↓
Theme
↓
Emerald
An AI agent could represent the same operation as a structured action:
toggle_theme({
theme: "emerald",
});
This is the basic idea behind making a web application accessible to AI agents.
WebMCP provides a web platform approach for exposing application functionality as structured tools that agents can interact with.
To understand where WebMCP fits, it helps to start with a normal web application and gradually introduce this capability.
2. Start With a Normal Web App
Consider a theme system where the current theme is maintained as application state:
type ThemeMode =
| "dark"
| "light"
| "emerald"
| "indigo"
| "rose";
interface AppState {
theme: ThemeMode;
lastAction?: string;
}
A traditional UI can update the state directly:
setAppState((state) => ({
...state,
theme: "emerald",
lastAction: "Switched theme to emerald",
}));
The interaction looks like:
User
│
▼
Theme Button
│
▼
Application State
The important part is that the actual capability is not the button itself.
The capability is:
Change the application theme
The button is simply one interface for accessing that capability.
We can therefore separate the interface from the underlying application capability:
UI
│
├── Dark
├── Light
└── Emerald
Application Capability
│
└── Change Theme
This separation becomes useful when another interface, such as an AI agent, needs to perform the same operation.
3. Turn the Capability Into a Tool
Once the application capability has been separated from the UI, it can be represented as a structured tool:
toggle_theme
The tool accepts a theme as input:
{
"theme": "emerald"
}
The application can then validate the requested theme and update its state.
A simple dispatcher can handle the operation:
const THEME_CYCLE: ThemeMode[] = [
"dark",
"light",
"emerald",
"indigo",
"rose",
];
export function dispatchTool(
toolName: string,
args: Record<string, unknown>,
currentState: AppState
) {
if (toolName !== "toggle_theme") {
return {
result: {
success: false,
error: `Unknown tool: "${toolName}"`,
},
newState: currentState,
};
}
const requestedTheme =
(args.theme as string)?.toLowerCase();
const nextTheme =
requestedTheme &&
THEME_CYCLE.includes(
requestedTheme as ThemeMode
)
? requestedTheme as ThemeMode
: currentState.theme === "dark"
? "light"
: "dark";
const newState: AppState = {
theme: nextTheme,
lastAction: `Switched theme to ${nextTheme}`,
};
return {
result: {
success: true,
data: {
theme: nextTheme,
},
actionSummary:
`Theme switched to ${nextTheme}`,
},
newState,
};
}
The architecture now becomes:
Application
│
┌───────┴───────┐
│ │
UI Tool
│ │
▼ ▼
Theme Controls toggle_theme
│ │
└───────┬───────┘
▼
Application State
The capability is now independent from the UI.
This is an important distinction.
The AI agent does not need to understand how the theme selector is implemented. It only needs to understand that the application provides a capability called toggle_theme.
4. Let the AI Choose the Tool
Once the capability has been defined as a tool, an AI model can decide when that tool should be used.
In the example application, the available tools are passed to Gemini:
const data = await callGemini({
apiKey,
model,
prompt,
tools: WEBMCP_TOOLS,
systemInstruction: SYSTEM_INSTRUCTION,
});
The system instruction describes how the tool should be used:
const SYSTEM_INSTRUCTION = `
You are an AI assistant controlling
the application theme.
When the user asks to change, switch,
or toggle the theme, call the
"toggle_theme" tool.
`;
The user can then provide a natural-language request:
Make the theme emerald.
The model can map that request to:
toggle_theme
with:
{
"theme": "emerald"
}
The application then executes the tool and updates its state.
The overall flow becomes:
User
│
│ "Make the theme emerald"
▼
AI Model
│
│ selects tool
▼
toggle_theme
│
▼
Application Logic
│
▼
Theme = emerald
The responsibilities are intentionally separated:
AI
│
└── Determines the requested action
Application
│
├── Validates the input
├── Applies business rules
└── Executes the operation
The model is responsible for interpreting intent.
The application remains responsible for execution.
This distinction becomes increasingly important as the operations become more meaningful than changing a theme.
5. Where Does WebMCP Fit?
The previous example demonstrates the general agent-to-tool pattern using Gemini, a Next.js API route, and a tool dispatcher.
It is important, however, to distinguish this approach from the browser-level WebMCP API.
Native WebMCP allows a web application to register tools through the browser's model context:
await document.modelContext.registerTool({
name: "toggle_theme",
description:
"Change the application's visual theme.",
inputSchema: {
type: "object",
properties: {
theme: {
type: "string",
enum: [
"dark",
"light",
"emerald",
"indigo",
"rose",
],
},
},
required: ["theme"],
},
execute: async ({ theme }) => {
changeTheme(theme);
return `Theme switched to ${theme}`;
},
});
The important difference is where the capability is exposed.
The application itself declares what it can do.
The resulting architecture looks like:
AI Agent
│
▼
Browser
│
▼
Web Application
│
▼
WebMCP Tool
│
▼
Application Logic
Compare that with the custom tool-calling example:
Custom Tool-Calling Example
AI
│
▼
Next.js API
│
▼
Gemini
│
▼
Tool Dispatcher
│
▼
Application State
With native WebMCP:
Native WebMCP
AI Agent
│
▼
Browser
│
▼
document.modelContext
│
▼
Registered Tool
│
▼
Application Logic
The first approach is useful for understanding and implementing agent-driven application capabilities.
WebMCP provides a browser-level mechanism for exposing those capabilities directly from a web application.
6. Why Is This Different From Browser Automation?
Traditional browser automation operates through the interface.
For example:
Find Settings
↓
Open Theme Menu
↓
Find Emerald
↓
Click Emerald
The agent has to understand the structure of the interface before performing the operation.
With a structured tool, the operation can instead be represented directly:
toggle_theme({
theme: "emerald",
});
The difference can be illustrated as:
Browser Automation
Agent
│
▼
UI
│
├── Find element
├── Click
├── Wait
└── Click again
Compared with:
WebMCP
Agent
│
▼
Structured Tool
│
▼
Application Capability
The application is providing a higher-level interface to the agent.
This does not eliminate browser automation.
Some interactions will still require direct UI manipulation.
WebMCP instead provides another option for capabilities that the application can explicitly expose as structured actions.
7. Keep AI Away From Application Rules
Defining tools does not mean that the AI should become responsible for application logic.
Consider the previous example:
AI
│
│ "Set theme to emerald"
▼
Application
│
├── Validate theme
├── Check application rules
└── Apply change
The AI provides the intent and arguments.
The application remains responsible for deciding whether the operation is valid.
This becomes more important for business operations such as:
add_to_cart
book_appointment
cancel_order
update_profile
A useful architecture is:
AI Agent
│
└── Intent + Arguments
│
▼
Application
│
┌───┼───┐
│ │ │
Validation
│
Authorization
│
▼
Execution
The exact business rules should remain inside the application rather than being moved into prompts or model behavior.
The AI decides which capability to request.
The application decides whether and how that capability is executed.
8. Tool Design Matters
Once an application starts exposing capabilities, tool design becomes important.
A tool should represent a clear application operation.
For example:
manage_application()
provides very little information about what the agent can actually do.
Smaller tools provide clearer boundaries:
toggle_theme()
add_to_cart()
remove_from_cart()
get_order_status()
update_profile()
A useful tool generally contains:
Clear name
+
Clear description
+
Structured input
+
Predictable behavior
For example:
{
name: "toggle_theme",
description:
"Change the application's visual theme.",
inputSchema: {
type: "object",
properties: {
theme: {
type: "string",
enum: [
"dark",
"light",
"emerald",
"indigo",
"rose",
],
},
},
required: ["theme"],
},
}
The number of available tools also matters.
Exposing every possible operation at the same time can increase the context available to the model and make tool selection more difficult.
A page can instead expose capabilities relevant to its current context.
For example, a checkout page might expose:
Checkout
│
├── get_cart
├── update_quantity
└── place_order
While an account section might expose:
Account
│
├── get_profile
└── update_profile
The goal is not to expose everything.
The goal is to expose the capabilities that are meaningful for the current application context.
9. WebMCP and MCP
WebMCP and MCP operate at different boundaries.
A traditional MCP architecture can look like:
AI Application
│
▼
MCP Client
│
▼
MCP Server
│
├── APIs
├── Databases
└── External Services
WebMCP moves the tool boundary closer to the web application:
AI Agent
│
▼
Browser
│
▼
Web Application
│
▼
WebMCP Tools
│
└── Application Capabilities
MCP is intended as a general protocol for connecting AI applications with tools and external resources.
WebMCP focuses on exposing capabilities from web applications through the browser.
These approaches can also coexist:
AI Agent
│
┌────────┴────────┐
│ │
WebMCP Tools MCP Tools
│ │
▼ ▼
Web Application Backend Services
This means an application does not necessarily have to choose between the two.
WebMCP can expose capabilities that belong naturally to the web application, while MCP can connect the AI system to backend services and external resources.
More information about MCP is available in the Model Context Protocol documentation.
10. The Bigger Shift
The broader idea behind WebMCP is not simply another API.
It introduces another interface for interacting with an application.
Traditionally:
Human
│
▼
UI
│
▼
Application
Developers interact through APIs:
Developer
│
▼
API
│
▼
Application
Agents can interact through tools:
AI Agent
│
▼
Tools
│
▼
Application
The three interfaces can exist around the same system:
Application
/ | \
/ | \
▼ ▼ ▼
Human Developer Agent
│ │ │
▼ ▼ ▼
UI API Tools
The goal is not to replace the user interface.
It is to provide a structured interface for agents alongside the interfaces already used by humans and developers.
This leads to a simple architectural principle:
Design application capabilities independently from the interface used to access them.
Once those capabilities are well defined, they can be exposed through a UI, an API, an agent tool, or multiple interfaces at the same time.
11. Where Does WebMCP Stand?
WebMCP is an evolving web platform technology, so its API surface and browser support are still developing.
For that reason, it is useful to separate two ideas:
WebMCP API
│
└── Browser-level implementation
and:
Application Capability Design
│
└── Longer-term architecture
Even if the browser API continues to evolve, the underlying concept remains useful:
Application Capability
│
▼
Structured Tool
│
▼
AI Agent
The important architectural question is therefore not only:
How can an AI use my application?
It is also:
What capabilities should my application explicitly expose to an AI agent?
That shift in thinking is where WebMCP becomes interesting.