Perfetto UI: External agents via trace_processor as a conduit

Authors: @stevegolton

Status: Draft

Introduction

This doc covers exposing the assistant's tool/skill/context surface to external coding agents (Gemini CLI, Claude Code, Codex, Cursor, …) by turning trace_processor into an MCP conduit to the running UI.

This is the most speculative of the docs split out from RFC-0029, the top-level coordination doc - none of it is Phase 1, and it‘s the least settled part of the whole proposal. It’s written down mainly so the tool, skill and context contracts in the sibling docs don't have to change to accommodate it later; treat the specifics below as a candidate direction, not a committed design. The in-panel assistant (UX, agent loop, system prompt) lives in RFC-0032; the plumbing in RFC-0033; context injection in RFC-0034; the tools and skills this surface re-exposes in RFC-0035. The wider motivation is in RFC-0025.

External agents via trace_processor as a conduit

Most of the assistant work is about the in-panel assistant, but the same tool surface (see RFC-0035) should also be reachable by external coding agents (Gemini CLI, Claude Code, Codex, Cursor, etc.). MCP servers for data sources are common; what‘s less common - and what’s novel here - is an agent driving a running UI the user is watching. The value is twofold: meeting users in the harnesses they already pay for and trust, and - longer term - a scriptable DevTools-for-Perfetto automation surface that falls out of the same commands-with-schemas work.

None of this is Phase 1 work: the bridge and all external-harness support is punted to Phase 2 at the earliest (see Roadmap in RFC-0029); it‘s designed here so the tool and skill contracts don’t have to change to accommodate it later.

The cleanest path for the common Perfetto deployment is to reuse the existing trace_processor --httpd connection as the conduit: TP advertises an MCP server and bridges tool calls to the UI over the existing websocket connection, so calls round-trip out to the browser and back. No new transport, and it works in any browser (not gated on browser-extension features).

Parity with the in-panel assistant is not free, though: an external agent owns its own harness, so the channels we control in-panel degrade per channel:

  • Tool descriptions transfer for free - they travel with the MCP tool definitions, and the when-to-call guidance already lives there rather than in the system prompt.
  • System prompt becomes MCP instructions: we can‘t touch the external agent’s system prompt, but the MCP initialize handshake carries a server instructions field that well-behaved clients fold into context. A condensed application brief plus the payload-format conventions go there. Advisory and size-constrained, but workable.
  • Click-to-context inverts from push to pull: generically, there is no per-turn injection hook into someone else‘s harness, so the per-turn <ui_context> block (see RFC-0034) becomes a get_ui_context() tool returning exactly what the context providers would have emitted. The model has to decide to call it - steered via the server instructions (“call get_ui_context before answering questions about ‘this’”) - which is strictly worse: the user clicks a slice and the external agent doesn’t know unless it asks. Click-to-context largely does not survive the bare conduit - this gap is the main reason the embedded assistant exists.
  • read_docs / self-help transfers well - it's already pull-based, so external agents bootstrap the same way the in-panel model does.

Much of what the bare conduit loses could be clawed back by adding UI related tooling to our harness extension that we already build. Our Claude Code and Codex plugins for example, could be extended to push UI context per-turn (a prompt-submit hook that calls get_ui_context() and prepends the result), install our UI skills in native format, and carry the application brief - substantially narrowing the gap to the embedded assistant. But each extension is a bespoke integration to build, test, and maintain against someone else‘s moving harness, multiplied per harness, extra work on top of a conduit that is itself a Phase 2 item, so extensions land later still, if at all. The conduit’s generic posture (tools, MCP instructions, pull-based context) is the supported baseline.

WebMCP / navigator.modelContext is the browser-native standard this is heading toward, and we‘d register tools there too since that’s the direction of travel - but today it‘s an experimental draft API behind browser flags/origin trials, and reaching it from an external agent still needs a browser extension + local MCP shim, so it doesn’t really help us yet. The TP-conduit path is the pragmatic one for now; treat WebMCP as something to track, not depend on.

Migration from com.google.PerfettoMcp

PerfettoMcp already does a version of this - exposing the trace to an LLM - but in a more limited way. Rather than running two overlapping mechanisms, the plan is to fold its useful pieces into this design and deprecate PerfettoMcp once the assistant's tool surface covers what it did (a Phase 2 step, alongside the external agent conduit it overlaps with).