You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A live coding run is opaque over MCP, and the data it needs is already being written
Owner's ask, recorded by their own agent as feedback fd60c895-bc18-4ee3-b4f1-de9b351ad4f7
(2026-08-15 02:19, instance bd43f4de-ef35-4051-bdec-43f8571414a1, status:"open") and repeated
directly to me on 2026-08-15:
expose a live, per-step trace of a loop run to the owner — each iteration's tool calls with
arguments and results, and streaming or incremental output — through the same MCP surface that
starts the run. agent_trace exists for chat turns; loop runs need the equivalent, queryable
while the run is still in flight, not just after it ends.
What an external MCP client can see today, while a run is running
Tool
What it gives
Gap
coding_loop_status / check_instance_loop
status, iteration, lastProgressAt, detail (only once finished)
No steps, no tool calls, no output
coding_session_capture
last pane text + runState
A rolling terminal buffer, not a record; needs the session id
agent_trace source:"coding"
act.consequential rows, and errors only via lib/coding-failure.ts:341 on a classified failure
Nothing per-step; a run that stalls writes nothing
instance_activity
chat-session events only
Feedback: "shows nothing at all from loop runs, so during a run it looks idle even though work is happening"
Measured consequence in #580: a run whose engine died at step 1 reported running for 4.35 hours,
and the only place the truth existed was the pane.
The data is already recorded — it just has no MCP reader
coding_timeline (migration 0023, append-only, seq-ordered) is written during the run. workers/api/src/routes/coding.ts:416 is explicit:
/** Persist a system/status message to the coding timeline (loop events, errors). */
There is an API route — GET /:instanceId/coding/sessions/:sessionId/timeline
(routes/coding.ts:430) — backed by loadTimeline in lib/coding-timeline.ts.
$ grep -rl 'coding_timeline' workers/mcp/src/
(no matches)
Thirteen coding tools on the MCP surface and none of them reads it. This is the same absence #527 names for the finished-run case. #527 and this issue are one tool apart: a seq-cursored reader answers both, because "audit a finished run" and "watch a running one" differ
only in whether you keep asking.
Design
One tool, cursor-paged the way instance_messages now is after #566:
Payload-size constraint, learned the hard way today
#569 measured list_instance_tools at 66,042 B in production — over the 64 KiB wire limit — after
a guard passed at ~54 KB, because jsonText pretty-printed after the assertion. #578 is open
on the same tool 433 B over on its opt-in path. A timeline reader is unbounded by nature, so:
limit must have a real default and the response must be measured on the deployed tool, not
on the API body.
Terminal snapshots are the bulk. Consider returning them by reference or truncated-with-a-count
rather than inline, and state the decision.
Acceptance criteria
An MCP client can read a coding run's per-step record while the run is in flight, without
knowing a session id in advance.
Inferred: that coding_timeline contains enough per-step detail to satisfy the ask —
it demonstrably carries loop events and errors, but whether it holds each tool call with
arguments and results was not confirmed. That is the first thing to establish: if it does not,
this issue grows a write-side half and should say so rather than shipping a reader over a record
that lacks what was asked for.
A live coding run is opaque over MCP, and the data it needs is already being written
Owner's ask, recorded by their own agent as feedback
fd60c895-bc18-4ee3-b4f1-de9b351ad4f7(2026-08-15 02:19, instance
bd43f4de-ef35-4051-bdec-43f8571414a1,status:"open") and repeateddirectly to me on 2026-08-15:
What an external MCP client can see today, while a run is running
coding_loop_status/check_instance_loopstatus,iteration,lastProgressAt,detail(only once finished)coding_session_capturerunStateagent_trace source:"coding"act.consequentialrows, and errors only vialib/coding-failure.ts:341on a classified failureinstance_activityMeasured consequence in #580: a run whose engine died at step 1 reported
runningfor 4.35 hours,and the only place the truth existed was the pane.
The data is already recorded — it just has no MCP reader
coding_timeline(migration 0023, append-only,seq-ordered) is written during the run.workers/api/src/routes/coding.ts:416is explicit:There is an API route —
GET /:instanceId/coding/sessions/:sessionId/timeline(
routes/coding.ts:430) — backed byloadTimelineinlib/coding-timeline.ts.Thirteen coding tools on the MCP surface and none of them reads it. This is the same absence
#527 names for the finished-run case. #527 and this issue are one tool apart: a
seq-cursored reader answers both, because "audit a finished run" and "watch a running one" differonly in whether you keep asking.
Design
One tool, cursor-paged the way
instance_messagesnow is after #566:since_seqmakes it a live feed. Poll with the lastnextSeq; get only what is new. Nostreaming transport needed, and it is the same shape Notify proactively when an agent run finishes (webhook / event feed) - investigation #579 Phase 2 proposes for run completion —
build one cursor convention, not two.
session_idoptional → newest active session, so a caller that only has an instance id canstill watch.
runStateso a caller learns "no new events AND idle" (dead) apart from "no newevents AND working" (a long step). That distinction is the actual question in A run whose engine died at step 1 reported 'running' for 4.35 hours with a fresh lastProgressAt, and wrote nothing to the trace #580 and cannot be
answered by an event list alone.
Payload-size constraint, learned the hard way today
#569 measured
list_instance_toolsat 66,042 B in production — over the 64 KiB wire limit — aftera guard passed at ~54 KB, because
jsonTextpretty-printed after the assertion. #578 is openon the same tool 433 B over on its opt-in path. A timeline reader is unbounded by nature, so:
limitmust have a real default and the response must be measured on the deployed tool, noton the API body.
rather than inline, and state the decision.
Acceptance criteria
knowing a session id in advance.
since_seqreturns only newer events; repeated polling with the returned cursor neverre-delivers or skips. A test drives two overlapping pages and asserts disjointness, as
instance_messagesreturnsnextCursorandhasMore: trueand has no cursor input — every message older than the first page is unreachable over MCP #566'sfix does.
is long.
the denominator stated per ADR 0002.
second one.
error rather than silence.
Verified vs inferred
grep -rl coding_timeline workers/mcp/src/;routes/coding.ts:416and:430;coding-failure.ts:341as the sole coding-trace writer;A finished coding run is unauditable over MCP — 13 coding tools, none reads coding_timeline, and coding_session_capture answers an ended session with an empty pane #527's open state and title; the four tools' current payloads, called live 2026-08-15; the
list_instance_toolsdocuments 2 of the 4tiervalues it returns, and its default response is 117 KB — enough to exceed a host's limit on one instance #569production measurement.
coding_timelinecontains enough per-step detail to satisfy the ask —it demonstrably carries loop events and errors, but whether it holds each tool call with
arguments and results was not confirmed. That is the first thing to establish: if it does not,
this issue grows a write-side half and should say so rather than shipping a reader over a record
that lacks what was asked for.