For AI agents: the complete documentation index is available at https://scriptedalchemy.github.io/agent-bundle/llms.txt, the full documentation bundle is available at https://scriptedalchemy.github.io/agent-bundle/llms-full.txt, and this page is available as Markdown at https://scriptedalchemy.github.io/agent-bundle/reference/dev-server-http.md.
Skip to main content
  • English
  • Development-server HTTP

    agent-bundle dev mounts these routes on its loopback foreground server for the Workbench. They are development protocols, not public deployment endpoints. Browser routes require the foreground session guard and enforce the Workbench origin policy described in Security. Unless noted otherwise, cursors are non-negative safe integers and responses are JSON.

    Route invocations

    MethodPathResponse
    POST/api/routes/invocations{ invocation: RouteInvocation }; with stream: true, 202 and { invocation: RunningRouteInvocation }
    GET/api/routes/invocations?limit=<1..200>{ invocations: RouteInvocationSummary[] }, newest first
    GET/api/routes/invocations/<id>{ invocation: RouteInvocation }
    GET/api/routes/invocations/<id>/streamServer-sent render, trace, truncated, and terminal final events
    POST/api/routes/invocations/<id>/cancel202 and the final { invocation: RouteInvocation }

    The POST body is a RouteInvocationRequest: routeId plus optional input, args, correlationId, caller requestId, and event fixture options. The foreground echoes the two identifiers on the invocation so the route workspace and trace can join the run. The completed envelope holds the input, provenance context, providers, render events, Agent Document, result, projections, diagnostics, and timings. Trace entries link to that full snapshot instead of duplicating it. Render events are the render-history window (at most 256 events and 2 MiB, always keeping the newest event and the newest document-bearing event, which alone may exceed 2 MiB) shared by the envelope, the item route, and the stream replay; when events were evicted the envelope carries retention with producedEvents, evictedEvents, evictedBytes, and retainedBytes, and the stream sends truncated once. The Agent Document, result, and outcome are never truncated by it. A cancelled invocation has status: "cancelled" and no outcome; cancelling an already-final invocation returns AB8256 (409).

    Host sessions

    Every route in this table requires the foreground session cookie or x-agent-bundle-session bearer value. Session ids match hs_[0-9a-z]{16}, JSON request bodies are strict, input is limited to 16 KiB of UTF-8 text, and terminal dimensions are integers from 1 through 500.

    MethodPathBody and response
    GET/api/sessions{ sessions: HostSession[], hosts: HostAvailability[] }
    POST/api/sessions{ host: "claude" | "codex", prompt?: string, cols, rows }; 201 with { session }
    GET/api/sessions/<id>{ session }
    GET/api/sessions/<id>/streamServer-sent state, output, and terminal end events
    POST/api/sessions/<id>/input{ data: string }; 204
    POST/api/sessions/<id>/resize{ cols, rows }; 204
    POST/api/sessions/<id>/terminate{}; 200 with { session }
    POST/api/sessions/<id>/restart{ cols, rows }; 201 with the replacement { session }
    DELETE/api/sessions/<id>204; a running session cannot be forgotten

    HostSession reports id, host, state, startedAt, optional terminal endedAt, exitCode, signal, pid, cols, rows, the optional seeded prompt, and optional restartOf and traceSessionId. Its authority contains the absolute projectRoot, adopted epochId, and host plugin install destination. HostAvailability contains host, launchable, and optional reason and resolved executable.

    The stream starts with a state frame, replays up to 256 KiB of retained output as one frame, then continues with live state and output. It sends a keep-alive comment every 15 seconds and closes after end. Each event has one JSON data: object:

    event: state
    data: { "session": HostSession }
    
    event: output
    data: { "data": "<base64 PTY bytes>" }
    
    event: end
    data: { "session": HostSession }

    Host-session failures use these diagnostics:

    CodeMeaning
    AB8260@lydell/node-pty is unavailable from the project and framework fallback.
    AB8261The body, path, query, dimensions, input, method state, or live-session delete is malformed.
    AB8262The session id is well formed but unknown.
    AB8263The executable is absent from PATH, no development install is attached to the adopted epoch, or spawning failed.
    AB8264Four sessions are already live.
    AB8265The host-session service is closed or unavailable.
    AB8266A hook receipt or proxy request supplied an invalid AGENT_BUNDLE_DEV_SESSION value.

    Development runtime runs

    POST /api/runtime/runs accepts a DevRuntimeInvocationRequest with surfaceId, target, input, and optional fixtureId and expectedGenerationId. GET /api/runtime/runs lists recent runs and GET /api/runtime/runs/<id> reads one run.

    MCP operations and correlation

    GET /api/mcp/launches?epochId=<epoch>&serverName=<server> lists the App launches eligible for one server on a published epoch: { launchId, targets } groups that share a launch identity, resolved from the artifact's declared projections with installed hosts consulted. The Workbench App workspace selects from this list rather than from the build's global targets.

    POST /api/mcp/sessions/<session-id>/apps accepts input without result to mount a preview for a call still in flight; the App then receives ui/notifications/tool-input only. POST /api/mcp/apps/<binding-id>/result with { result } or { cancelled } publishes that binding's single terminal notification (tool-result or tool-cancelled). It answers accepted: false for a binding already settled or created with a result, and 404 (AB8022) once the binding is closed.

    POST /api/mcp/sessions/<session-id>/operations keeps the existing operation union. A tools/call operation additionally accepts an optional top-level correlationId of at most 256 characters. The browser cannot supply _meta directly; the foreground copies this value to params._meta["agent-bundle/correlationId"] before sending the request.

    The MCP trace lifts the JSON-RPC id and method plus bounded host metadata. Request/response pairs share mcpRequestId and duration; tool calls and prompt reads link to their Application route with ?session=<session-id>. An operation that cannot resolve a route links to /advanced/protocol?session=<session-id>.

    Unified trace

    MethodPathTransport
    GET/api/trace?after=<sequence>TraceReplay JSON
    GET/api/trace/stream?after=<sequence>application/x-ndjson frames of TraceMessage

    Omitting after is equivalent to after=0. Replay has this shape:

    interface TraceReplay {
      readonly entries: readonly TraceEntry[];
      readonly gap?: TraceReplayGap;
      readonly latestSequence: number;
    }

    Each TraceEntry contains:

    interface TraceEntry {
      readonly id: string;
      readonly sequence: number;
      readonly occurredAt: string;
      readonly source:
        | 'invocation'
        | 'kernel'
        | 'mcp'
        | 'hook'
        | 'session'
        | 'log'
        | 'diagnostic';
      readonly kind: string;
      readonly summary: string;
      readonly correlation: TraceCorrelation;
      readonly status?: 'ok' | 'error' | 'running';
      readonly durationMs?: number;
      readonly details?: JsonValue;
      readonly href?: string;
    }

    TraceCorrelation can carry correlationId, conversationId, epochId, executionId, host, invocationId, mcpRequestId, mcpSessionId, requestId, routeId, and sessionId. Publishers fill only keys they know. details is a bounded, already-safe JSON projection; it is not a payload body.

    When the requested cursor predates retained history, replay returns a gap and the stream emits the same TraceReplayGap as one NDJSON frame:

    interface TraceReplayGap {
      readonly droppedCount: number;
      readonly firstAvailableSequence: number;
      readonly requestedAfterSequence: number;
      readonly type: 'trace.gap';
    }

    A malformed cursor returns 400, a cursor ahead of current history returns 409, and a closed or unavailable trace hub returns 503. These responses use the trace diagnostics registered in the generated diagnostics reference.

    Raw logs

    MethodPathTransport
    GET/api/logs/replay?after=<sequence>{ replay: DevLogReplay } JSON
    GET/api/logs/stream?after=<sequence>application/x-ndjson frames of DevLogMessage

    Raw logs remain a framework-diagnostics stream. Records expose only allowlisted context values and browser-safe text. A record carrying correlationId, invocationId, or mcpSessionId can link into /trace?correlation=<value>; uncorrelated records stay in Advanced → Raw logs.

    Host hook receipts

    MethodPathTransport
    POST/api/trace/receiptsOne EventTraceReceipt JSON body, at most 16 KiB; success is 204

    Generated hook processes post one bounded receipt to this foreground-only route. This is not a browser API: it rejects an Origin header and non-loopback peer, requires the receipt endpoint's random per-dev-server bearer token, and exposes no read or command operation. The Workbench cookie and session header do not authorize it. A receipt contains version 1, one EventTraceExecution, payload-free kernel events, their wall-clock start, host/session/request identity, and the resolved lineage axis. Native event bodies, tool input or output, rendered documents, environment values, credentials, filesystem paths, and error stacks are absent.

    For a host invocation, the wrapper finds .agent-bundle-dev.json beside its installed bundle, then reads the active endpoint from the named project's .agent-bundle/hook-receipts.json. A dev-server-spawned simulation receives the same loopback URL and token through the two internal receipt environment variables. The endpoint file is replaced with owner-only mode and removed when the server closes. Only an exact http://127.0.0.1:<port> or http://[::1]:<port> origin is accepted. The wrapper gives the post 750 ms and ignores transport failure, so Workbench observation can never change the hook result.

    See Trace for how receipt and kernel entries appear in the timeline.