A specification for bringing AI capabilities to the web platform — with the user, not a vendor, in control.
AI is everywhere in the browser now. The list of "AI browsers" that shipped between October 2025 and February 2026 — ChatGPT Atlas, Comet, Dia, Copilot Mode in Edge, Gemini in Chrome — keeps growing. And yet, if you're a website that wants to offer AI features, you still have the same three bad options you had in 2024.
"Please enter your OpenAI API key to use this feature"
- Terrible user experience.
- Users don't know what keys to trust websites with.
- Keys can be leaked or stolen.
- No way to revoke access per-site.
Website → Their Server → AI Provider → Back to User
- Expensive infrastructure to maintain.
- All user data flows through the website's servers.
- Website becomes responsible for data custody.
- Users have no control over which AI is used.
Website embeds a chat widget from an AI company
- User data goes to yet another company.
- No integration with user's existing AI preferences.
- Fragmented experience across websites.
- No way to use local/private models.
"Tell your users to install Atlas / Comet / Dia / Edge / Chrome (with Gemini)"
- Users have to switch browsers to use your AI feature.
- The AI vendor is fixed — your users can't bring their own model.
- The agent free-roams the DOM, exposing your page (and the user's other tabs) to a documented prompt-injection surface (Comet → 1Password, Atlas omnibox injection).
- You don't get to integrate your own tools (WebMCP partially helps, but only on browsers that implement it).
- Your code path doesn't work in Firefox.
All four options share a fundamental problem: either the user loses control over their AI, or the developer does.
The W3C WebMCP draft (April 2026) and Chrome's Prompt API (stable in Chrome 138 extensions, origin trial for web) each solve a slice. WebMCP gives pages a standard way to declare tools an agent can call. The Prompt API gives pages on-device Gemini Nano. Neither defines the consumer side: how an arbitrary website asks for an AI capability, with what permission model, against what user-chosen model, on what browser. That's what this specification proposes.
What if AI worked like other browser capabilities?
| Capability | How It Works Today |
|---|---|
| Network | Websites call fetch(), browser handles the connection |
| Storage | Websites use localStorage, browser manages the data |
| Location | Websites request geolocation, user grants permission |
| AI | ??? |
The Web Agent API proposes that AI should work the same way:
// Website requests AI capability — developer chooses the integration style
const session = await window.ai.createTextSession();
const response = await session.prompt("Summarize this article");The developer chooses what to build:
- Which tools to integrate (search, files, your own custom tools)
- How much autonomy the AI gets (manual tool calls vs. autonomous
agent.run()) - Which provider/model to request (or defer to the user's default)
- What page tools to expose via
navigator.modelContext
The developer doesn't need to manage:
- API keys or authentication
- Model hosting or infrastructure
- Per-user billing or quotas
The developer chooses the architecture. The user controls the backend through their browser.
- Install an implementation (like Harbor)
- Configure your AI (local Ollama, cloud provider, etc.)
- Grant permissions when websites request AI access
The user experience looks like:
┌────────────────────────────────────────────────┐
│ example.com wants to: │
│ │
│ 🤖 Generate text using AI │
│ 🔧 Use the following tools: │
│ ☑ brave-search/search │
│ ☑ memory/save │
│ │
│ "To help you research this topic" │
│ │
│ ○ Allow once ● Always allow │
│ │
│ [ Deny ] [ Allow ] │
└────────────────────────────────────────────────┘
You write against two standard JavaScript APIs. You choose the model. You choose the tools. The API gives you the building blocks; every integration decision is yours.
window.ai — Text generation. Choose a provider, or let the user's default handle it.
// Use the user's default model
const session = await window.ai.createTextSession({
systemPrompt: "You are a helpful assistant."
});
// Or pick a specific provider/model
const session = await window.ai.createTextSession({
provider: "ollama",
model: "llama3"
});window.agent — Tools and autonomous capabilities. Choose which MCP servers and tools to integrate.
// Choose your tools: request only the scopes you need
await window.agent.requestPermissions({
scopes: ['model:tools', 'mcp:tools.list', 'mcp:tools.call'],
tools: ['brave-search/search', 'memory/save'], // pick exactly which tools
reason: 'Research assistant needs search access'
});
// Run an autonomous agent — yields typed events.
// (Requires the `toolCalling` feature flag in the Web Agents API sidebar.)
for await (const event of window.agent.run({
task: 'Find recent news about AI safety'
})) {
if (event.type === 'thinking') console.log(event.content);
if (event.type === 'tool_call') console.log('→', event.tool, event.args);
if (event.type === 'final') console.log('Done:', event.output);
}navigator.modelContext — Register your own tools (W3C WebMCP). Choose what capabilities your page provides to the AI.
navigator.modelContext.addTool({
name: 'search_products',
description: 'Search the product catalog',
handler: async (args) => searchCatalog(args.query),
});The Web Agent API uses MCP (Model Context Protocol) for tool extensibility. There is no walled garden — any MCP server works, and developers choose which ones to integrate.
Developer chooses tools → User installs MCP servers → Browser connects them → Website uses them
The MCP ecosystem is open. Pick the servers that fit your use case:
- Brave Search — Web search
- GitHub — Manage repos, issues, PRs
- File system — Read/write local files
- Memory — Persistent user memory
- Database — Query databases
- Your own — Build a custom MCP server for your domain
Developers select which tools their app uses. Users control which tools they allow.
Developers are not locked into any model, provider, or tool ecosystem:
- Choose your LLM — Ollama, llamafile, OpenAI, Anthropic, or any provider the user has configured. Specify one explicitly or use the default.
- Choose your MCP servers — Brave Search, GitHub, filesystem, databases, or build your own. Pick the tools that fit your application.
- Choose your integration style — Call tools manually with
agent.tools.call(), let the LLM drive withagent.run(), or register page tools vianavigator.modelContext. Mix and match. - Choose your scope — Request only the permissions your app needs. Nothing more.
Every AI operation requires explicit user permission:
| Scope | What It Allows |
|---|---|
model:prompt |
Basic text generation |
model:tools |
AI with autonomous tool use |
mcp:tools.list |
List available tools |
mcp:tools.call |
Execute tools |
browser:activeTab.read |
Read page content |
Permissions are scoped per-origin. example.com permissions don't affect other.com.
Users can run entirely local AI (Ollama, llamafile) — data never leaves their machine.
The window.ai surface is designed to work with Chrome's built-in AI:
// Same code works with Chrome AI or Web Agent API implementations
const session = await window.ai.languageModel.create({
systemPrompt: "Be helpful."
});Any MCP server can be connected. The ecosystem is open — not gated by an app store or approval process.
// Writing assistant
const session = await window.ai.createTextSession();
const improved = await session.prompt(`Improve: ${selectedText}`);// Agent that can search and synthesize
for await (const event of window.agent.run({
task: 'Research quantum computing breakthroughs in 2025',
maxToolCalls: 10
})) {
// Streams tool calls and final answer
}// Summarize current tab
const page = await window.agent.browser.activeTab.readability();
const summary = await session.prompt(`Summarize: ${page.text}`);// Website provides tools, user brings their AI
await window.agent.mcp.register({
url: 'https://shop.example/mcp',
name: 'Acme Shop',
tools: ['search_products', 'add_to_cart']
});
await window.agent.chat.open(); // Opens user's AI chatbot| Document | Description |
|---|---|
| Full Explainer | Complete specification with Web IDL |
| Security & Privacy | Threat model and mitigations |
| Examples | Working code examples |
| Implementation | Platform | Status |
|---|---|---|
| Harbor | Firefox, Chrome | Working implementation |
Chrome is building AI capabilities directly into the browser. The Web Agent API:
- Uses a compatible
window.aisurface - Extends it with tools and agent capabilities via
window.agent - Works as a polyfill until native support exists
MCP is the protocol for tool extensibility. The Web Agent API uses MCP to:
- Connect to tool servers (file system, GitHub, search, etc.)
- Provide a standardized way to extend AI capabilities
- Enable an open ecosystem of tools
Chrome's Prompt API is great for basic text generation. The Web Agent API extends it with:
- Tool calling via MCP
- Autonomous agent tasks
- User control over AI providers
- Works in Firefox and other browsers
You could, but then:
- Every user needs API keys
- Every website manages its own AI infrastructure
- No unified permission model
- No way to use local/private models
- Fragmented experience
See Security & Privacy for the full threat model. Key protections:
- All operations require user consent
- Permissions are scoped per-origin
- Tool access is granular (users can allow specific tools)
- Rate limiting prevents abuse
Websites receive the AI's responses (they made the request), but:
- They don't see your API keys or configuration
- They can't access other websites' permissions
- You control which AI backend is used
- Local models mean data never leaves your machine
Try it: Install Harbor and run the demos
Build with it: Developer Guide
Read the spec: Full Explainer
Using an AI coding assistant? Point it to docs/LLMS.txt — a compact reference designed for AI tools to quickly build with the API.
This specification is a draft proposal. Feedback welcome via GitHub Issues.