MCP server that bridges Claude Code, OpenCode, GitHub Copilot CLI and other MCP clients to a Chrome tab. Per-tool permissions, multi-agent mode (multiple MCP clients sharing one bridge), persistent UI map across sessions.
Five tools with complete JSON schemas and detailed descriptions. Naming follows verb_noun pattern (recall, save, record_use, forget, rename_app). Descriptions are comprehensive (100-300+ chars), explaining WHAT, WHEN, and dependencies. All parameters have types and descriptions. However, output schemas are not documented, LLMs cannot see what recall() or save() return. Error handling is absent: no guidance on retryability, user-fixable vs fatal errors, or recovery paths. No tool annotations (readOnlyHint, destructiveHint) despite clear risk levels (READ_ONLY, WRITE, DESTRUCTIVE). Parameter descriptions are strong but lack format constraints (e.g., origin format, url_pattern regex). Overall solid definitions hampered by missing output documentation and error guidance.
Permanently delete an entry (entry_id) or a whole app and all its entries (app_id). Use when a refactor or app change makes the saved knowledge actively wrong.
Recall what is already known about a browser app/route from the local map DB. Call this first when you arrive at a tab so you can reuse known selectors, flows and gotchas instead of rediscovering them. Pass origin (scheme://host:port). Optionally pass app_key to disambiguate when multiple apps share an origin, and url to filter entries down to a specific pathname. Response includes `flows`: named browser.flow-replayable recipes saved for the app (`{ name, description, steps, use_count }`, not filtered by url) — adapt any placeholder text in `steps` (e.g. `type text "<QUERY>"`) to the real value before replaying with browser.flow.
Mark an entry as freshly verified or freshly failed after you used it. ok=true updates verified_at and clears failed_at; ok=false updates failed_at. Always call this after using an entry from recall so the map stays honest about what works today.
Rename an app_key. Useful when the heuristic from the document title picked a poor name (e.g. typos like "FLIGHT MANAGMENT" → "flight-management").
Persist something learned about a browser app. Three entry kinds are supported: "selector" (a CSS selector tied to a purpose), "flow" (a free-form note about a multi-step path), and "gotcha" (a free-form note). Saving auto-creates the app row if needed (app_key is derived from title when not provided). Upsert on (app, url_pattern, kind, purpose). Marks verified_at = now and clears failed_at. Never save selectors or flows you have not just successfully executed. Optionally pass `flows`: an array of NAMED, REPLAYABLE flow recipes (`{ name, description?, steps }`) — `steps` must follow the EXACT browser.flow step grammar and is validated with the same rules browser.flow itself enforces. Upserts on (app, name); saving an existing name replaces its steps/description. Distinct from the "flow" entry kind above: that is a free-form note, this is a structured, browser.flow-replayable recipe returned by browser.map.recall.
Output schemas not documented. LLMs cannot see what recall() returns (flows array structure, entry fields) or what save() confirms. Forces agents to guess field names for downstream calls.
No error handling guidance. Tools lack recovery hints: 'entry_id not found, call recall() to list valid IDs' or 'origin format invalid, use scheme://host:port'. Agents cannot self-correct on failures.
Tool annotations missing. browser.map.forget is DESTRUCTIVE and browser.map.save is WRITE, but no destructiveHint or idempotentHint declared. Agents cannot reason about side effects or retry safety.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | 2026-07-28+ | v2 |
Parameter format constraints missing. 'origin' accepts 'scheme://host:port' but no regex or format hint. 'url_pattern' accepts pathname but no examples of parametric routes. LLMs may pass invalid formats.
browser.map.save 'payload' parameter is polymorphic (selector|flow|gotcha) but union type not explicit in schema. Agents must infer correct structure from 'kind' enum. Should use oneOf with discriminator.