Claude working on a show from outside: known and in sync (protocol 1.15)
The owner's ask (2026-10-14): "When reelwright is connected the ai assistant needs to auto detect it and be synced obviously." Claude can reach a show without Studio's own chat:
- claude.ai's custom connector, or Claude Code, over the web service's MCP endpoint;
- Claude Code on this computer, which runs
reelwright mcp --show <dir>; - the plan bridge's Claude Code.
Studio said "Not connected" through all of it. The audit's gap list is in docs/audits/claude-setup-2026-10.md ("Claude from outside: detection and sync").
What a person sees
- The chat's header says it at once. "Claude is connected through claude.ai" (or "…through Claude Code", or "…through claude.ai and Claude Code") the moment Claude reaches the show, and it goes when Claude does. It is green, never "Not connected", and has no Check, which is for Studio's own chat. When Studio's chat is connected too, the line sits under how it is connected.
- The way in still offers Studio's own chat. The card's title says Claude is already connected from outside, then "To chat with it here in Studio too:".
- The rail says it under the show's status, in the same words.
- What Claude proposes arrives as it is made. A toast says "Claude, through claude.ai,
proposed: …" with Review, which opens the proposal. The change keeps which Claude it came
through (
via), and Studio names it wherever it says who a change is by:- the proposal's page: "Proposal · by Claude, through claude.ai · …";
- Next steps: "Proposed by Claude, through claude.ai";
- the set and the stage's banners: "Claude, through claude.ai, proposes: …". The review, the overview and the page in view update live, as they already did for any change (change.event, doc.event).
- Studio's own chat is not Claude from outside. When Studio's chat runs on the person's
Claude plan, its Claude Code reaches the show over MCP too. On the desktop it runs
reelwright mcp --studio-chat. On the web, the plan bridge's address sayschat=studio, and a runner's chat is one. Studio shows that chat's proposals in the chat, so the header, the rail and the toast say nothing of it, and its proposals are the showrunner's. - Nor is Studio's own work on the plan. Direct with Claude, memory and the looks run one
turn of the Claude Code here (
claude/plan-agent.ts), throughreelwright mcp --studio-work. Studio shows that work as it runs, so nothing says an AI is here. What it proposes still names Claude Code, which did it: its run is keyed by that name (plan-run.tscallerRun). - What Claude reads is what Studio has open.
studio_contextreads the place Studio last said (chat.focus).- That place goes when the Studio that said it leaves, not only when the daemon stops.
- Claude's reads come from the show's files and the change store at the moment it asks, so what the person changed in Studio is what Claude reads next.
How
- session.hello
agent. The web service's MCP link to a show's daemon names its client:agent: {client}, the MCP client's own name from its initialize ("claude-ai", "claude-code"), or else its connection's label. The daemon keeps it as an AI on that connection. The link still runs as the person it works for, so their role and key apply. It is never one of the people: session.people leaves it out. That also ends the hour in which collaborators saw a person "here" through their Claude's link after they had left. - Presence files.
reelwright mcpon this computer never meets Studio's daemon. Once its client says who it is, it writes.reelwright/studio/agents/<pid>.json(its client, pid, since, and when it last called a tool). It updates the file as it acts and takes it away when it stops. The daemon reads the folder every second. A file whose process is gone is not counted, and is removed. - session.agents (a notification). It lists each AI: id, client, the person it works for (on the service), since, and when it last acted. The daemon sends it to every connection when one comes, goes or acts, at most every quarter of a second and only when the list changed. A Studio that says hello hears the current list with its answer.
- ChangeSummary
via(a change set'sauthor.via, ChangeSet 1.2). The daemon runs an AI link's tools.call through it (runThrough).reelwright mcpruns its calls under its client's name. The change store writes it on the change set. - Studio's own chat (
agent.chat: true). The service's link for the plan bridge's sessions (?chat=studio) and a runner's chat says so in its hello. The daemon keeps that link out of session.people and session.agents, and runs its tools.call with novia.reelwright mcp --studio-chatwrites no presence file and names novia.--studio-workwrites none either, and names its client. - Additive and optional. A client that does not know 1.15 reads past
session.agentsandvia. 1.14 is capture-face-2's (perf-capture), below this one.
What came after
What such a Claude does, not only that it is there, shows in Studio's chat as it does it: what
it read, what it called and what came of it, each change it proposed as the chat's own card
(protocol 1.19, agent.event; docs/design/showrunner-connected.md). With the chat in sight the
toast is not said again.
Proof
- Core tests (
core/test/session-daemon.test.ts, "the AIs working on the show"):- an AI's link is listed apart from the people, with when it acted and when it goes, and what it proposes names it;
- a Studio that comes later hears the list;
reelwright mcp's file is heard, and a dead process's file is not counted;- a Studio's place goes when it leaves.
- Engine tests: the header and the rail say it, and the toast offers Review.
- A watch and a web check: a scripted MCP client (no model, no key) connects, reads,
proposes and leaves. Studio shows each step live, with no press: desktop over stdio
(
reelwright mcp), web over the service's MCP endpoint. - Mutations, one per guarantee.