Skip to content

feat(agent): list connected browser tabs and route client tool calls per tab - #413

Open
antfubot wants to merge 1 commit into
mainfrom
feat/mcp-list-client-tabs
Open

antfubot wants to merge 1 commit into
mainfrom
feat/mcp-list-client-tabs

Conversation

@antfubot

Copy link
Copy Markdown
Collaborator

Closes #394. MVP of the plan discussed there.

What changes

With several tabs of the same app open, the MCP surface behaved as if there were one client: devframe connect lists instances per port, and in-page tools (from #376) were silently owned by whichever tab synced last.

  • Ports the feat: eagerly expose in-page tools to browser agents #376 bridge onto 0.10 (@devframes/agentic era): agent-flagged in-page channel functions register in a per-document browser-agent registry and sync to the node over the page's RPC connection; the node exposes them as MCP tools and relays calls back. Not yet on main, so it lands here as the foundation.
  • Each tab reports itself with its manifest: a per-tab id (the in-page channel's existing sessionStorage-backed instance id, so it survives reloads), URL, title, visible, focused. Re-synced on connect, tool changes, and focus/blur/visibilitychange.
  • devframe:agent:list-clients (wire devframe_agent_list-clients): built-in tool listing the connected tabs and the tool ids each exposes. Appears once a tab is connected, so a devframe with no agent surface of its own doesn't flip MCP auto-mount.
  • Per-tab routing: tools/list stays deduped (one entry per tool id). Forwarded tools take a reserved client_id argument; an unknown id fails with the new DF0081 listing the live ids. Without client_id, the call goes to the most recently focused visible tab, falling back to the last-synced one — which is what medula's vendored patch approximated with "last sync wins".
  • devframe connect: list-instances nests mcp.clients per instance (fetched in the same MCP session it already opens to list tools); call-tool passes client_id through.
  • Docs: guide section, DF0080 (the feat: eagerly expose in-page tools to browser agents #376 jsonSerializable guard, renumbered since DF0078 is taken on main) and DF0081 pages.

Verification

  • Unit tests for the routing rules (focus → visible → last synced, client_id targeting/stripping, missing id, no re-publish on focus-only re-sync).
  • Integration test over a live dev server + real MCP client: two WS tabs, tools/list dedup + injected client_id schema, list-clients output, addressed/unaddressed/missing-id calls, focus follow.
  • pnpm lint && pnpm knip && pnpm test && pnpm typecheck && pnpm build green (knip's remaining items are the pre-existing unbuilt-starter hints).

Known limits (MVP)

  • A duplicated tab copies sessionStorage, so two tabs can briefly share an id; targeting then picks the better-ranked one.
  • A tab with several RPC connections (host page + dock iframes) lists once per connection.
  • URL/title lag briefly after an SPA navigation until the next focus/visibility/tool event.

Supersedes the in-page-tools part of #376 (ported and extended here).


This PR was created with the help of an agent.

…per tab

Forward agent-flagged in-page channel functions to the node MCP endpoint
(ports the bridge from #376 onto 0.10), and make each connected browser
tab visible and addressable: a built-in devframe:agent:list-clients tool,
a reserved client_id argument on forwarded tools, and focus-aware default
routing so an unaddressed call follows the tab the user looked at last.
devframe connect nests the tab list under mcp.clients per instance.

Closes #394
@coldtea-pr-lens

coldtea-pr-lens Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

◈ PR Lens

🟢 +4 new · 🟠 ~6 changed · 🔴 -0 removed · 2 flows · 14 files · commit fc6a624


Architecture

Architecture diagram for devframes/devframe at fc6a624

10 components touched across 3 lanes.

Play the interactive walkthrough


Inside the changed components — 2 views

Component view — Browser Agent Bridge

In-tab registry and RPC sync bridge forwarding page functions to Devframe

Architecture view of Component view — Browser Agent Bridge in devframes/devframe

Component view — Client Agent Manager

Node session manager tracking tabs, focus state, and routing tool calls

Architecture view of Component view — Client Agent Manager in devframes/devframe

Data flow

Data flow diagram for devframes/devframe at fc6a624

Syncing browser tools to node MCP · Calling a forwarded tool from an agent

Follow each request, response and payload


The other flows — 1 sequence

Calling a forwarded tool from an agent

Sequence diagram of Calling a forwarded tool from an agent in devframes/devframe

View

  • Architecture lens
  • Data flow lens
  • Expand every detail

Tip

Click the link under each diagram to open it on a canvas you can zoom, pan and step through

🪧 More tips
  • Run npx skills add coldteadotai/pr-lens, then tell your coding agent: "Diagram the change you just made with PR Lens and attach it to the pull request."
  • Run npx @coldtea/pr-lens-cli analyze --base origin/main on a branch, then npx @coldtea/pr-lens-cli render .pr-lens/graph.json. Same lenses, your own model key, before the pull request exists
  • Untick Architecture lens or Data flow lens under View to hide a diagram, or tick Expand every detail to open every section. The comment redraws in a few seconds
  • The diagrams are links. Click one to open it on the canvas, then press W or click play to walk through the change
  • Open a diagram on the canvas, then press W or click play to walk through the change one step at a time
  • The CLI's render reads .github/pr-lens.yml and applies your renames, exclusions and lane pins at draw time
  • Set github.comment.collapsed: true in .github/pr-lens.yml to fold the comment behind one View architecture and data flow row. Drawing still runs as before
  • Set github.draw: on-demand in .github/pr-lens.yml and PR Lens stops drawing pull requests on its own. Comment @pr-lens draw on a pull request when you want that one drawn
  • Add .github/workflows/pr-lens.yml with coldteadotai/pr-lens/packages/action@v0 and your model provider's key as its api-key to run PR Lens from your own CI. Any /chat/completions endpoint works
  • Push a commit and the drawing stays, with a note that it is out of date. Tick Redraw in the note to draw the new head
  • Switch GitHub to dark mode and the diagrams follow. The moving dots are this pull request's data in motion

Thanks for using PR Lens! It's built by Coldtea, free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

@vercel

vercel Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
devframe Ready Ready Preview Sep 30, 2026 8:19am UTC

This branch was successfully deployed

1 active deployment
Preview — fc6a6244 Deployed Sep 30, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP: list every connected browser tab and route client tool calls per tab

1 participant