Agent-Readable Web Standard (ARWS)

Agents that interact with web applications should not need to scrape HTML, click buttons, or reverse-engineer APIs. Web applications should be self-describing — exposing their capabilities in a machine-readable format that agents can discover, comprehend, and execute against without touching the GUI.

ARWS defines a four-layer pipeline for this. Each layer builds on the previous one. Together they turn any web application into a headless API that agents can use natively.


The Four Layers

graph TD
    L1["<b>Layer 1: Discovery</b><br/>/.well-known/llms.txt<br/><i>Where are the tools?</i>"] --> L2
    L2["<b>Layer 2: Schema</b><br/>OpenAPI 3.1+ / JSON Schema<br/><i>What do the tools accept?</i>"] --> L3
    L3["<b>Layer 3: Transport</b><br/>MCP Server<br/><i>How do I call them?</i>"] --> L4
    L4["<b>Layer 4: Safety</b><br/>OAuth scopes + HITL<br/><i>What am I allowed to do?</i>"]

Layer 1: Discovery

Agents need a deterministic entry point to index a site’s capabilities — the same way search crawlers use robots.txt.

Endpoint: Web servers host a manifest at /.well-known/llms.txt or /.well-known/agent-manifest.json.

Payload:

{
  "name": "Acme Store",
  "description": "E-commerce platform for electronics and accessories.",
  "auth": {
    "type": "oauth2",
    "token_url": "https://acme.com/oauth/token",
    "scopes": ["agent:read", "agent:draft_only"]
  },
  "tools": "https://acme.com/.well-known/openapi.json"
}

The manifest contains three things: a semantic summary of what the application does, authentication requirements, and a URI pointing to the tool definitions.


Layer 2: Tool Definition

Agents rely on strict typing and semantic context to generate valid payloads. Tool definitions use industry-standard schemas — not custom formats.

Specification: OpenAPI 3.1+ or native JSON Schema.

Semantic verbosity matters. LLMs need more context than human developers:

Anti-patternStandard
param: qparam: search_query — “The exact name or category of the product the user is looking for.”
param: type with no constraintsparam: product_type with enum: ["electronics", "accessories", "clothing"] and descriptions per value
response: dataresponse: search_results with per-field descriptions

Explicit enums with descriptions prevent the agent from hallucinating invalid parameter values. Every field that accepts a constrained set of values should declare them.


Layer 3: Transport

Without a standard transport, agents must learn a bespoke REST architecture for every website. MCP eliminates this.

sequenceDiagram
    participant A as Agent
    participant M as MCP Server
    participant App as Application Backend

    A->>M: tools/list
    M-->>A: [{name: "search_products", inputSchema: {...}}, ...]

    A->>M: tools/call {name: "search_products", arguments: {query: "USB-C cable"}}
    M->>App: Internal API call
    App-->>M: Product results
    M-->>A: {content: [{type: "text", text: "Found 12 results..."}]}

The MCP server wraps the application’s existing API. The agent never calls the backend directly — it calls the MCP server, which handles authentication, validation, error formatting, and response serialization. The agent gets a consistent interface regardless of the backend’s architecture.

What MCP standardizes:


Layer 4: Safety

Autonomous agents operate probabilistically. The API must strictly separate read operations from irreversible actions.

Tool Classification

ClassAccess LevelAuth RequiredExamples
Safe (read-only)Data gatheringMinimal or nonesearch_products, get_weather, list_orders
State-changing (write)MutationsAgent-scoped OAuth tokencreate_order, update_profile
Destructive (irreversible)Financial or deletionAgent-scoped OAuth + HITL approvaltransfer_funds, delete_account

Idempotency

All tools must be idempotent. If an agent fires the same request twice, the system state must not corrupt — no double charges, no duplicate records. Use idempotency keys for any state-changing operation.

Human-in-the-Loop

For high-risk state changes, the API responds with 202 Accepted and triggers an asynchronous approval flow:

sequenceDiagram
    participant A as Agent
    participant API as Application
    participant U as User (Phone/Email)

    A->>API: tools/call {name: "transfer_funds", arguments: {amount: 500, to: "vendor"}}
    API-->>A: 202 Accepted — "Pending human approval"

    API->>U: "Your agent requests: Transfer $500 to Vendor. Approve / Deny?"
    U-->>API: Approved

    API->>API: Execute transfer
    API-->>A: {status: "completed", transaction_id: "tx_892"}

The agent receives a pending status, not a rejection. It can continue other work while waiting for approval. This keeps the agent productive without granting unsupervised access to irreversible operations.


Implementation Stack

Discovery and Routing

ToolFunction
Next.js / Nuxt / AstroAuto-generate /.well-known/llms.txt at build time by scraping API routes
Express / FastAPI middlewareDetect agent User-Agent headers and route directly to the MCP server, bypassing HTML

Schema Generation

ToolFunction
Pydantic (Python).model_json_schema() converts typed models directly to JSON Schema
Zod (TypeScript).openapi() generates OpenAPI-compatible schemas from runtime validators
TypeSpec (Microsoft)Readable API definition language that compiles to OpenAPI with semantic verbosity built in

Protocol Integration

ToolFunction
MCP SDK (TypeScript, Python)Wrap existing APIs into an MCP-compliant server. Handles tool discovery, payload validation, and bidirectional communication

Authentication and Approval

ToolFunction
OAuth 2.0 with agent scopesAuth providers (Auth0, Clerk, WorkOS) issue agent-specific tokens with restricted scopes (agent:read, agent:draft_only)
Approval webhooksServices like Svix standardize outbound webhooks to prompt users: “Your agent requests [Action]. Approve / Deny?”

ARWS and MCP

ARWS and MCP are complementary, not competing:

MCP answers “how do agents call tools?” ARWS answers “how do websites become tools?”

A web application that implements all four ARWS layers is automatically compatible with any MCP client — Claude Code, OpenAI Codex, Gemini CLI, or any custom agent. The application becomes a tool that any agent can discover and use without custom integration.


Adoption Path

StepWhat to doEffort
1Add /.well-known/llms.txt with app description and API pointerMinutes
2Ensure API endpoints have OpenAPI 3.1 specs with semantic descriptionsHours (if specs exist), days (if not)
3Wrap the API in an MCP server using the SDKHours
4Add agent-scoped OAuth tokens and classify tools by risk levelDays
5Implement HITL approval webhooks for destructive operationsDays

Steps 1-3 make the application agent-accessible. Steps 4-5 make it agent-safe. Start with discovery and schema — those unlock value immediately.