The connector only drove web pages. Add-on sidebar panels — Aegis's
wallet, Hermes's messenger, Pithos's storage panel, anything with
a sidebar-panel capability — were walled off: list_tabs skipped them
and webContents() refused anything that was not kind:"web".
Panels are now first-class tabs with a negative id, kind:"panel", and
an addon/panelId pair. Each open panel is listed next to the real
tabs; a closed one is still listed so a client can see what exists.
screenshot / snapshot / read_page_text / click / type / press_key /
paste_html / paste_text / wait_for / upload_file / evaluate all work
on them with the same TabDriver a web page uses. navigate /
activate_tab / close_tab refuse panels — the user owns panel
visibility, not the connector.
Approval is per add-on under a synthetic theseus-panel://<addon>
origin, so Aegis is approved once and every Aegis panel is reachable
from then on. The approval modal titles itself "Let Claude control
the Aegis panel?" when the origin is a panel origin, and the body
explains the panel is read, not the whole browser profile. Origin
pinning is skipped (the panel is served from the add-on scheme and
never navigates under us); password-field refusal and the action log
still apply, so a PIN input in a wallet panel is never typed into
and every call is in the connector's log.
The quick-link panel is one WebContentsView outside `tabs`, so the
connector could not see a web app opened in the sidebar, and the
signed-in session there (Telegram's channel account, for one) was out of
reach. tabControl.list() now ends with the panel as tab 0 while it holds a
web page, tagged with the app's name; webContents, navigate, close and
activate handle it (activate reopens the panel, close closes it). It runs
the same preload as a web tab and still needs the site approved, so it
hands out nothing a tab doesn't. Listed last so it is never picked as the
active tab when a tool call omits tab_id.
Home page splits into two self-contained panels so the left-column
links no longer scale with the Silent Mode cards. The slot grid is
narrower, the icons default closer to Windows desktop-shortcut size,
and each section carries its own subtle panel background and heading.
Claude connector hardening (the opt-in MCP add-on from 0.3.106):
- Pin the approved origin to the TabDriver on every Controller.use()
and re-check the tab's current URL before each CDP read / input
(isolated, snapshot, screenshot, clickAt, insertText, press,
setFiles, evaluate). A meta-refresh or soft-nav to an unapproved
origin between approval and the call now throws instead of leaking
content or steering input to the new site.
- Rotate the bearer token on every stop() so toggling the connector
off (toolbar chip, panel switch, deactivate) invalidates existing
credentials. Re-enabling issues a fresh token; the panel's install
strings update on the next start. Matches the mental model where
"off" means "the keys change" instead of "the server stops".
- click without a ref now resolves the element at (x, y) through
DOM.getNodeForLocation and refuses if it's a password / one-time-
code field. Previously only ref-based click ran isSecretField; raw
coordinates let focus land on a password field before FOCUS_GUARD
kicked in to block typing.
Claude sessions could not work inside the user's own profile: the desktop
app's browser lost synthetic pastes and typing in Medium's editor, and a
browser-wide --remote-debugging-port would hand every session to any local
process. The connector is a built-in extension, off until turned on in
Settings > Extensions, that serves MCP on 127.0.0.1 behind a per-install
token and drives one tab at a time through that tab's webContents.debugger.
- Host: a "tab-control" capability (built-in add-ons only) for listing,
opening, navigating, closing and focusing tabs, handing out web tabs'
webContents (never Settings, extension or home tabs), and a toolbar chip
plus tab outline while a client is connected; the chip's X stops it.
Built-in add-ons can ship "defaultEnabled": false.
- Tools: list_tabs, open_tab, navigate, activate_tab, close_tab, screenshot,
read_page_text, snapshot (accessibility tree with refs), click, type
(insertText + real Enter), press_key, paste_html / paste_text (system
clipboard + webContents.paste, clipboard restored), upload_file
(DOM.setFileInputFiles), wait_for, and evaluate behind its own switch.
- Safety: first use of each site asks the user; password and one-time-code
fields are refused; uploads only from folders the user added; requests
from web pages or foreign Host headers are refused; every action is
logged with a timestamp in the panel and actions.log.
- Claude Desktop runs stdio-shim.cjs through the Theseus executable in Node
mode.
- Tests: unit (protocol, auth, policy, shim) and an end-to-end run on a
throwaway profile that types, pastes HTML with a heading and a link, and
uploads a PNG on a local page.