vibium internals
Companion to the CLI version — same
underlying daemon and browser layer, one extra process and a full model reasoning turn
added on top. Traced from this project's own journey_mcp.py harness
(2026-08-04): direct transcript parsing of real agent-driven runs, not documentation.
The path, one tool call
sequenceDiagram
participant A as Claude agent (LLM)
participant M as vibium MCP server
(long-lived for the session)
participant D as vibium daemon
participant X as Chrome for Testing
participant P as Page (live site)
Note over A: reasons about what to do next —
a real model inference call
A->>M: mcp__vibium__browser_click
(JSON-RPC over stdio)
activate M
Note over M: NOT spawned per call —
one process for the whole agent session
M->>D: connect via Unix socket
(same socket the CLI uses)
activate D
alt no browser session yet
D->>X: spawn Chrome, fresh temp
--user-data-dir profile
activate X
end
D->>X: forward command over BiDi
(WebSocket)
X->>P: dispatch the actual action
(click / eval / navigate)
P-->>X: DOM state / JS return value
X-->>D: BiDi response
D-->>M: Unix socket response
deactivate D
M-->>A: JSON-RPC tool_result
deactivate M
Note over A: reads the result, decides the
next tool call — repeats per step
Stage by stage
Before every tool call the model decides what to do next: a genuine inference call
to the Anthropic API. This is the step with no equivalent at all in the CLI path — a
scripted vibium click has no "decide what to click" step, it's already
decided.
Unlike the CLI, where every command is a fresh OS process, vibium mcp
is launched once (as a child process of claude -p, per this project's
harness config) and stays alive for every tool call the agent makes during that
session — confirmed by the same server handling all 8+ tool calls in a single run's
transcript.
Confirmed live parsing real transcripts: calls show up as
mcp__vibium__browser_navigate, mcp__vibium__browser_click,
etc. — not the bare browser_navigate the MCP spec examples show. A
transcript parser that matches on the bare name silently finds nothing — this is
exactly the bug this project's own journey_mcp.py hit and fixed first.
Same Unix socket, same daemon PID, same BiDi transport to the same kind of Chrome-for-Testing process with its own fresh temp profile — see the CLI diagram. The MCP layer sits entirely above this, translating agent tool calls into the same commands the CLI issues directly.
A tool_result's content is [{"type":"text","text":"..."}],
not a plain string — JSON-encoding the whole block instead of extracting the text
was the second bug this session's harness hit before results parsed correctly.
Navigate, dismiss, fill, click, fill, click — each is its own reasoning-then-tool-call round trip. That accumulation, not any single slow step, is why an MCP-driven run reaches the same real submit click roughly 17.5–30.1 seconds after load (hardened, n=70), against the CLI arm's 4.4–5.0 seconds for the identical sequence.
What this costs, measured
None of this is CLI/BiDi overhead — the daemon-and-browser layer underneath costs the
MCP arm the same 170–250ms per actual browser action as the CLI. The gap is entirely the
reasoning layer sitting on top of it. See
references/timing-methodology.md's explicit scope note: the two arms measure
different kinds of time and shouldn't be netted against each other.