Adapter Runtime Patterns

These patterns come from real adapter work where a site's UI was not stable enough to support a DOM-first implementation.

Use them when a fallback adapter needs authenticated reads or writes that are driven by browser-side requests.

1. Prefer Real Request Interception Over Reconstructed Fetch

If the page already knows how to make the request, intercept that real request before trying to reconstruct it yourself.

Why:

Recommended order:

  1. intercept the real browser request
  2. inspect whether the intercepted response already contains the data you need
  3. only fall back to manual in-page replay if interception cannot expose the response body

2. route.fetch() Is Better Than DOM Guessing For Streamed Responses

For some sites, the request is normal HTTP but the response is streamed or chunked.

In this case:

Recommended pattern:

  1. intercept the real request with page.route
  2. skip preflight OPTIONS
  3. call route.fetch()
  4. read the response text
  5. parse the stream format
  6. route.fulfill({ response }) so the page still behaves normally

This lets the adapter observe the site's real response while preserving the page's normal execution path.

3. Treat Sessions As First-Class Tool Inputs

If the upstream product has a session or conversation concept, the adapter should expose it explicitly.

Do not rely on "whatever page is currently open" as the conversation source.

Recommended tool contract:

This makes agent behavior reproducible and avoids hidden context leaks between calls.

4. New Session Must Be Explicit, Not Implicit

If the tool should start a fresh session when no session id is supplied, make that an explicit browser action.

Example pattern:

  1. open the product landing route
  2. detect the current session id from the URL or page state
  3. click New Chat or equivalent
  4. wait until the previous session id disappears or changes
  5. only then send the new request

Do not assume that navigating to the same route automatically starts a new session.

5. Parse The Protocol, Not The Rendered Text

For assistant-like products, the DOM often exposes:

If the response stream contains structured events, parse those instead of reading visible text.

Look for fields such as:

Then build the final answer from the protocol itself.

6. Keep DOM As Fallback Only

DOM extraction is still useful, but only as a last resort.

Use DOM fallback when:

When falling back:

7. Validate Runtime Assumptions With Minimal Probes

When adapter behavior is ambiguous, write a tiny probe before rewriting production code.

Good probe targets:

These probes help separate:

8. Keep The Reusable Logic In Patterns, Not Site Constants

The reusable part is usually the execution pattern, not the exact endpoint name.

Examples of reusable adapter-library patterns:

Examples of site-specific details that should stay in the adapter:

When documenting or extracting shared helpers, keep this boundary explicit.

9. Prefer A Small Shared Utility Layer For Cross-Site Pieces

If several adapters need the same low-level mechanics, put them in a shared adapter utility package instead of copying them between site adapters.

Good candidates for that package:

Keep these out of the shared package:

Use the shared package for low-level mechanics, then keep matching, templating, and response interpretation inside the site adapter.

If you discover a reusable helper while building an adapter and it looks broadly useful, consider contributing it back to the webmcp-bridge repository as a focused PR.