Agents
Agents (Claude Code, Codex, ...) running in T3 can queue and manage stage tasks. Three front ends share one set of operations, all over the REST API. No gating: agents get the same access as the web UI.
Front ends
- CLI:
stage task add|ls|show|edit|rm|start|stop|followup|dup|link|order|unlink|wait,schedule ...,sessions ls|search|show|questions(questions is read-only),projects ls,models ls,context. Human output by default,--jsonfor agents and scripts.stage helplists everything. - stdio MCP:
stage mcp. - HTTP MCP:
http://<host>:7380/mcp(streamable HTTP, stateless, served by the running app; no install). It calls the app's own/apion loopback. Cannot read local files, so noimagePaths.
Install and register
Install the binary on the T3 host and register it. The compose image does not install it; rerun after updates.
mise run install-cli # ~/.local/bin/stage (no args = server; subcommands = CLI)
stage setup mcp # claude mcp add --scope user + codex mcp add (stdio); --http registers /mcp instead
stage setup instructions # idempotent usage block in ~/.claude/CLAUDE.md and ~/.codex/AGENTS.mdSTAGE_URL (or --url) points the CLI and stdio MCP at the app. Default http://127.0.0.1:7380.
Caller context
T3 sets T3CODE_THREAD_ID in every provider process. The CLI and stdio MCP read it and the cwd; HTTP MCP tools take callerThreadId / cwd arguments instead (override; required for context over HTTP).
- Project: explicit
--project(id or exact title) > the calling session's project > the project whose root is the longest prefix of cwd. - Model: explicit (provider inferred from the model via the catalog) > pinned default > last used > T3 default, like the New task form.
- Provenance: tasks and schedules record the creating session (
originThreadId; spawned schedule tasks inherit it), shown as "Created by" on task detail and "by agent" on task rows.
Run after me
--after-me / afterMe starts the task when the calling session is settled in T3 (error without a calling session).
- A session owned by a task becomes a normal task link (
afterTaskId). - Any other session is a session link (
afterThreadId). Many tasks may wait on one session.
Rules: link rules.
Handoff
A linked task's launch prompt gets its predecessor's final reply, PRs, branch/worktree and thread id. Default on.
- Turn off with
--handoff=false/handoff: falseoncreate_task,update_taskorlink_task(CLItask add|link --handoff=false,task edit --handoff=true|false). Omitted keeps the task's value. get_taskreturnshandoffandcurrentHandoff.stage task showprintshandoff on|offfor linked tasks and the current attempt's record.
Block format: Handoff.
Predecessor base
--base predecessor --base-ref origin/main / base: "predecessor" starts a linked task's worktree from its predecessor's branch. --base-ref is the fallback.
create_task,create_schedule,update_task,update_scheduleandlink_tasktake optionalbase(ref|predecessor; CLItask add|edit --base).- On create it needs
baseRef(the fallback). Onupdate_task/link_taskwithoutbaseRefit keeps the task's current worktree (error for a root task). get_taskreturnscurrentLaunchBase.stage task showprintsworktree from #12's branch (fallback origin/main, branch -)and, once launched,base feat/api (from #12)orbase origin/main (fallback: <reason>).
Rules: Predecessor base.
Session batch
The tasks a session created, grouped into run-order chains (head first) and independent tasks.
get_session/stage sessions showreturn it (createdTasks) so a planning agent can check what it queued.get_taskreturnsbatch.order_tasks/stage task order ID ID...links several backlog tasks in order in one step.order_taskstakestaskIdsand returns{ "tasks": Task[] }.- In the web UI, session detail lists the batch ("Created tasks") and task detail shows it as a compact Batch panel.
Rules: Session batch.
MCP tools
| Area | Tools |
|---|---|
| Context | get_context, list_projects, list_models |
| Tasks | list_tasks, get_task, create_task, update_task, delete_task, start_task, stop_task, followup_task, duplicate_task, link_task, order_tasks, unlink_task, wait_task |
| Schedules | list_schedules, get_schedule, create_schedule, update_schedule, delete_schedule, run_schedule, preview_schedule |
| Sessions | list_sessions, search_sessions, get_session, get_session_questions |
- Results are the REST shapes; lists are compact rows. Errors are tool errors carrying the API
error. list_tasksandlist_sessionsrows carrylastWordPreview.get_taskandget_sessioncarry the reply excerpt inthread.lastWord(the CLI prints it as "last word"), pluspullRequestsandthread.recentRuns(the CLI prints aprsblock and arunsblock: newest 10,(10 of N runs);--jsonhas every stored run).get_session_questions/stage sessions questions IDread pending questions. Agents cannot answer them.search_sessions(stage sessions search QUERY [--project P] [--limit N]) wrapsGET /api/threads/searchand returns{ results: [{ t3ThreadId, title, match, snippet?, project?, state?, taskId?, lastWordPreview?, t3WebUrl? }], t3 }.imagePathsreads local files and uploads them (POST /api/uploads). CLI and stdio only; HTTP MCP rejects them.wait_taskpollsGET /api/tasks/:idevery 3s until the state is inuntil(defaultneeds_input done settled failed interrupted cancelled) ortimeoutSeconds(default 600, max 3600). CLItask waitexits 3 on timeout.
Examples
stage task add --title "Fix flaky test" --prompt "..." --effort high # backlog
stage task add --title "Deploy" --prompt-file deploy.md --after-me # runs when this session settles
echo "..." | stage task add --title "Refactor" --prompt - --base-ref origin/main --start
stage task ls --state backlog --json
stage task wait 42 --until done,settled --timeout 30m # exit 3 on timeout
stage task order 41 43 42 # 43 runs after 41, 42 after 43
stage sessions show "$T3CODE_THREAD_ID" # this session's batch
stage schedule add --title "Nightly deps" --prompt "..." --cron "0 2 * * *" --tz Asia/Kolkata
stage sessions search "token refresh" --project stage # titles, then message text via T3