Agent Experiences

Implementation Patterns

What to actually build, in rough priority order, as of August 2026.

In short

There are three ways to let an agent use your service, and they are not competitors. An MCP server exposes capabilities to agents running outside the browser. WebMCP exposes callable tools to an agent already inside the user’s browser session. A well-formed HTTP API underlies both and is often sufficient on its own. Underneath all three sit two unglamorous requirements: serve real HTML for anything you want read, and be able to verify which agent is calling you. Nothing on this page is exotic — most of it is API hygiene with the tolerances tightened.

MCP servers

The Model Context Protocol is the de facto standard for describing what a service can do in a form an agent can consume. It was donated to the Linux Foundation’s Agentic AI Foundation in December 2025, which moved it out of single-vendor governance — the reason it is reasonable to build on rather than wait out.

The protocol changed substantially in the 2026-07-28 revision, and if your mental model predates it, it is wrong in ways that matter for how you deploy:

  • The core is now stateless. The initialize handshake and protocol-level sessions were removed. A server no longer negotiates a connection lifecycle before it can be used, which means an MCP endpoint deploys like an ordinary HTTP service: any instance can serve any request, and you scale it horizontally without session affinity.
  • Tasks became an extension. Long-running work is no longer part of the mandatory core. If you need it, you adopt the extension deliberately — and you should still expose your own durable job state, since that is what survives protocol churn.
  • Roots, Sampling, and Logging were deprecated. Do not build new work on them. The direction of travel is a smaller core with capability surfaced through tools.

The practical consequence of statelessness is that your server should carry no per-connection memory. Authorize each call on its own token, keep any conversational context on the client side, and treat every tool invocation as independently replayable. If you were planning a design where the client establishes context once and then issues dependent calls, invert it.

What makes an MCP tool actually usable

  • Few, task-shaped tools beat many endpoint-shaped ones. A mechanical wrapper around forty REST routes produces a tool list the model has to reason through on every turn. Expose the handful of outcomes users actually ask for.
  • Descriptions are prompts. The tool description is read by a model deciding whether to call it. State what it does, when to use it, when not to, and what it costs or changes.
  • Constrain inputs in the schema. Enums, formats, and required fields prevent a whole class of failed calls before they are made.
  • Return results a model can use. Structured, compact, and free of pagination cruft the agent has to re-derive. If a result is truncated, say so in the payload.
  • Mark consequence. Make it unmistakable in the description which tools spend money, send communications, or delete things — clients use that to decide what to confirm with the user.

On distribution: the official MCP Registry was still in preview as of July 2026. List your server there when it stabilizes, but do not treat it as the discovery mechanism yet — in practice, agents find servers through the host application’s own directory and through your documentation. Publish install instructions where a developer will look, and keep the server URL stable.

WebMCP

WebMCP is a draft in the W3C Web Machine Learning Community Group, co-edited by Google and Microsoft. It was a headline item at Google I/O in May 2026 and ran as a Chrome origin trial across Chrome 149–156. The idea is straightforward: a page registers structured JavaScript tools that an in-browser agent can call directly, instead of the agent inferring intent from the DOM and driving the UI by simulated clicks.

That substitution is the value. DOM-driving is brittle — it breaks on redesigns, misreads dynamic components, and produces actions the site never intended to offer. A declared tool is an explicit contract: these are the operations this page supports, with these parameters. You get reliability, and you get control over what an agent can do on your surface.

Use WebMCP when

  • The agent is already in the user’s browser, in the user’s logged-in session.
  • Authorization is the session cookie the user already has — no separate credential exchange, no token to issue.
  • The capability is genuinely page-scoped: filter this table, apply this to the open form.
  • You are a client-heavy application where the useful state lives in the browser anyway.

Use an MCP server when

  • The agent runs outside a browser — a coding assistant, a backend workflow, a cron.
  • The work must continue when no tab is open.
  • You need your own authorization and audit trail rather than a borrowed session.
  • The capability is account-scoped rather than page-scoped.

Most services with both a web app and an API will eventually want both, over one shared authorization layer. Given origin-trial status, treat WebMCP as a progressive enhancement: build the capability behind a normal function, register it as a tool where the API exists, and lose nothing where it does not. The security caveat is real and is not solved by the protocol — a page can contain untrusted content, and an agent reading that content while holding the ability to call the page’s tools is the exact shape of the injection problem described in the case studies. Keep consequential operations behind explicit user confirmation regardless of how they were invoked.

Plain HTTP APIs

For a great many services this is still the right answer, and it is the substrate the other two run on. Models have absorbed an enormous amount of REST convention, which means a conventional API is already close to agent-usable. The gap is almost always in the parts developers tolerate and agents cannot.

  • Predictable resources. Consistent naming, consistent nesting, consistent identifier formats. An agent generalizes from one endpoint to the next; irregularity costs it failed calls.
  • Real status codes. Distinguish “not found” from “not permitted” from “malformed” from “conflict.” A 200 carrying an error body forces the agent to parse prose to learn it failed.
  • Machine-readable errors. A structured body — RFC 9457application/problem+json is a good default — with a stable code, the offending field, and an explicit retryability signal.
  • Honest pagination. Cursors and an explicit indication of whether more exists. An agent that cannot tell it received a partial list will confidently report a partial answer.
  • Rate-limit headers that say when to retry. A 429 alone tells the agent to back off by an amount it will invent. Return the reset time.
  • An OpenAPI description agents can fetch. Generated from the implementation, served at a stable URL, no authentication required to read it.

A response that gives an agent everything it needs to behave:

HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
RateLimit: limit=100, remaining=0, reset=42
Retry-After: 42

{
  "type": "https://api.example.com/errors/rate-limited",
  "title": "Rate limit exceeded",
  "status": 429,
  "detail": "100 requests per minute for this token.",
  "retryable": true,
  "retry_after_seconds": 42
}

The agent now knows it failed, why, that waiting will fix it, and exactly how long to wait. Compare that with a bare 429 and an empty body, which produces either an immediate retry storm or an unnecessary abandonment. Idempotency keys on writes complete the picture — see the delegation cycle.

Rendering and access

The least sophisticated item on this page is the one most likely to be your actual problem: most AI fetchers do not execute JavaScript. A page whose content assembles client-side is, to a large share of automated readers, an empty shell. This applies to product pages, pricing, documentation, and support articles alike.

  • Server-render anything you want read. In a modern framework this is a rendering-mode decision, not a rewrite.
  • Test by fetching your own URLs without a JavaScript engine and reading what comes back. If the substance is missing, so is your presence in answers.
  • Keep the meaningful content in the initial response rather than behind interaction — tabs, accordions, and infinite scroll all hide content from a single-fetch reader.
  • Offer a clean text or markdown representation of documentation where you can. It is cheap and it removes all ambiguity about what your docs say.
  • Do not gate ordinary public content behind interstitials or challenges. That is the same policy mistake as blanket bot blocking, expressed in the rendering layer.

Bot verification

Every policy that treats agents differently depends on knowing which agent is calling. A user-agent string is a claim, not evidence — anyone can send one.

Web Bot Auth is the emerging answer. The IETF chartered the WEBBOTAUTH working group in 2026; there is no RFC yet, so this is a moving target. The mechanism composes existing pieces rather than inventing new ones: an agent signs its requests using RFC 9421 HTTP Message Signatures, and publishes a key directory the receiving service can check the signature against. The result is cryptographic proof of which operator sent a request, rather than an unverifiable header. Despite the unfinished standardization it is already deployed in production at Cloudflare, Vercel, Shopify, and AWS — which is why it is worth understanding now even though the specification will change.

The older mechanisms still work and still matter: the major crawler operators publish IP ranges you can allow-list, and forward-confirmed reverse DNS remains a reliable check for the ones that support it. Both are worth implementing today; neither is exclusive with signature verification.

Frame verification as a benefit, not a gate. An agent that identifies itself verifiably should get higher limits, better data, or access to capabilities unidentified traffic does not receive. Identification spreads when it buys something. And remember what it cannot do: an agentic browser operating in a user’s own session presents as an ordinary browser, so verification tells you about declared automation and is silent on the rest.

A sensible order of work

  1. Server-render your public content and confirm it is readable without JavaScript.
  2. Fix errors, status codes, pagination, and rate-limit headers on the API you already have.
  3. Publish a generated OpenAPI description at a stable, unauthenticated URL.
  4. Add idempotency keys to every write.
  5. Instrument logs so you can segment agent traffic by operator and purpose.
  6. Ship an MCP server covering your handful of highest-value tasks.
  7. Add verification — IP ranges and reverse DNS now, signatures as they stabilize.
  8. Register WebMCP tools on the pages where an in-browser agent would be doing real work.

Steps one through five deliver most of the value and none of them depend on a standard that might change. That is deliberate: the protocol layer is still moving, and the fundamentals are not.

Stay Updated

Analysis of AI search, crawler policy and agent standards — sent when there is something worth reading, roughly twice a month. Unsubscribe anytime.

We store your email address only to send you this newsletter. See our privacy policy.