Cursor Agent CLI は、--print と組み合わせて使う --output-format オプションで複数の出力フォーマットに対応してるよ。プログラムで扱うための構造化フォーマット(jsonstream-json)に加えて、人間が読みやすい進行状況の表示向けのシンプルなテキストフォーマットもある。
デフォルトの --output-formatstream-json。このオプションが有効になるのは、--print で出力する場合、または出力が自動的に印字モードとみなされる場合(非 TTY の stdout やパイプされた stdin)だけだよ。

JSON 形式

json 出力形式は、実行が正常に完了したとき、1 行の JSON オブジェクト(末尾に改行付き)を出力する。デルタやツールイベントは出力されず、テキストは最終結果に集約される。 失敗時は、プロセスは非ゼロの終了コードで終了し、エラーメッセージを stderr に書き込む。失敗ケースでは、整形式の JSON オブジェクトは出力されない。

成功時のレスポンス

成功すると、CLI は次の構造の JSON オブジェクトを出力する:
{
  "type": "result",
  "subtype": "success",
  "is_error": false,
  "duration_ms": 1234,
  "duration_api_ms": 1234,
  "result": "<full assistant text>",
  "session_id": "<uuid>",
  "request_id": "<optional request id>"
}
FieldDescription
type終端結果では常に "result"
subtype成功した完了では常に "success"
is_error成功したレスポンスでは常に false
duration_ms総実行時間(ミリ秒)
duration_api_msAPI リクエスト時間(ミリ秒。現在は duration_ms と同一)
resultアシスタントの最終レスポンステキスト(すべてのテキストデルタを連結)
session_id一意のセッション識別子
request_id任意のリクエスト識別子(省略される場合がある)

ストリーム JSON 形式

stream-json の出力形式は、改行区切り JSON(NDJSON)を出力する。各行には、実行中のリアルタイムイベントを表す単一の JSON オブジェクトが入る。 ストリームは、成功時には終端の result イベントで終了する。失敗時は、プロセスが非ゼロの終了コードで終了し、終端イベントなしで早期にストリームが途切れる場合がある。エラーメッセージは stderr に書き出される。

イベントタイプ

システム初期化

各セッションの開始時に一度だけ出力される:
{
  "type": "system",
  "subtype": "init",
  "apiKeySource": "env|flag|login",
  "cwd": "/absolute/path",
  "session_id": "<uuid>",
  "model": "<model display name>",
  "permissionMode": "default"
}
今後、このイベントに toolsmcp_servers といったフィールドが追加される可能性がある。

ユーザーメッセージ

ユーザーの入力プロンプトを含む:
{
  "type": "user",
  "message": {
    "role": "user",
    "content": [{ "type": "text", "text": "<prompt>" }]
  },
  "session_id": "<uuid>"
}

アシスタントのテキストデルタ

アシスタントが応答を生成する間、複数回出力される。これらのイベントには差分のテキストチャンクが含まれる:
{
  "type": "assistant",
  "message": {
    "role": "assistant",
    "content": [{ "type": "text", "text": "<delta chunk>" }]
  },
  "session_id": "<uuid>"
}
完全なアシスタントの応答を再構成するには、message.content[].text の値を順番に連結する。

ツール呼び出しイベント

ツール呼び出しは、開始および完了イベントで追跡される: ツール呼び出し開始:
{
  "type": "tool_call",
  "subtype": "started",
  "call_id": "<string id>",
  "tool_call": {
    "readToolCall": {
      "args": { "path": "file.txt" }
    }
  },
  "session_id": "<uuid>"
}
ツール呼び出し完了:
{
  "type": "tool_call",
  "subtype": "completed",
  "call_id": "<string id>",
  "tool_call": {
    "readToolCall": {
      "args": { "path": "file.txt" },
      "result": {
        "success": {
          "content": "file contents...",
          "isEmpty": false,
          "exceededLimit": false,
          "totalLines": 54,
          "totalChars": 1254
        }
      }
    }
  },
  "session_id": "<uuid>"
}

ツール呼び出しタイプ

ファイル読み取りツール:
  • 開始: tool_call.readToolCall.args{ "path": "file.txt" } が入る
  • 完了: tool_call.readToolCall.result.success にファイルのメタデータと内容が入る
ファイル書き込みツール:
  • 開始: tool_call.writeToolCall.args{ "path": "file.txt", "fileText": "content...", "toolCallId": "id" } が入る
  • 完了: tool_call.writeToolCall.result.success{ "path": "/absolute/path", "linesCreated": 19, "fileSize": 942 } が入る
その他のツール:
  • { "name": "tool_name", "arguments": "..." } を持つ tool_call.function 構造を使う場合がある

終端結果

正常終了時に出力される最終イベント:
{
  "type": "result",
  "subtype": "success",
  "duration_ms": 1234,
  "duration_api_ms": 1234,
  "is_error": false,
  "result": "<full assistant text>",
  "session_id": "<uuid>",
  "request_id": "<optional request id>"
}

シーケンス例

典型的なイベントフローを示す NDJSON の代表的なシーケンス:
{"type":"system","subtype":"init","apiKeySource":"login","cwd":"/Users/user/project","session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff","model":"Claude 4 Sonnet","permissionMode":"default"}
{"type":"user","message":{"role":"user","content":[{"type":"text","text":"README.md を読んで要約を作って"}]},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"了解"}]},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"README.md を読むね"}]},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"tool_call","subtype":"started","call_id":"toolu_vrtx_01NnjaR886UcE8whekg2MGJd","tool_call":{"readToolCall":{"args":{"path":"README.md"}}},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"tool_call","subtype":"completed","call_id":"toolu_vrtx_01NnjaR886UcE8whekg2MGJd","tool_call":{"readToolCall":{"args":{"path":"README.md"},"result":{"success":{"content":"# Project\n\nThis is a sample project...","isEmpty":false,"exceededLimit":false,"totalLines":54,"totalChars":1254}}}},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"それから要約を作るよ"}]},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"tool_call","subtype":"started","call_id":"toolu_vrtx_01Q3VHVnWFSKygaRPT7WDxrv","tool_call":{"writeToolCall":{"args":{"path":"summary.txt","fileText":"# README Summary\n\nThis project contains...","toolCallId":"toolu_vrtx_01Q3VHVnWFSKygaRPT7WDxrv"}}},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"tool_call","subtype":"completed","call_id":"toolu_vrtx_01Q3VHVnWFSKygaRPT7WDxrv","tool_call":{"writeToolCall":{"args":{"path":"summary.txt","fileText":"# README Summary\n\nThis project contains...","toolCallId":"toolu_vrtx_01Q3VHVnWFSKygaRPT7WDxrv"},"result":{"success":{"path":"/Users/user/project/summary.txt","linesCreated":19,"fileSize":942}}}},"session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff"}
{"type":"result","subtype":"success","duration_ms":5234,"duration_api_ms":5234,"is_error":false,"result":"README.md を読んで要約を作るね","session_id":"c6b62c6f-7ead-4fd6-9922-e952131177ff","request_id":"10e11780-df2f-45dc-a1ff-4540af32e9c0"}

テキスト形式

text 出力形式は、エージェントのアクションを簡潔で人間が読みやすいストリームとして提供する。詳細な JSON イベントの代わりに、エージェントがリアルタイムで何をしているかを短いテキストで記述して出力する。 この形式は、構造化データをパースするオーバーヘッドなしにエージェントの進捗を監視でき、ログ、デバッグ、シンプルな進捗トラッキングに最適。

出力例

Read file
Edited file
Ran terminal command
Created new file
各アクションは実行されるたびに新しい行で表示され、タスクにおけるエージェントの進捗を即時にフィードバックする。

実装メモ

  • 各イベントは改行 \n で終端された1行として送出される
  • thinking イベントはプリントモードでは抑制され、どちらの出力形式にも出力されない
  • フィールドの追加は後方互換性を保った形で随時行われる可能性がある(コンシューマーは未知のフィールドを無視すること)
  • ストリーム形式はリアルタイムに更新され、JSON 形式は完了を待ってから結果を出力する
  • 完全な応答を再構成するには、すべての assistant メッセージのデルタを連結する
  • ツール呼び出し ID は開始/完了イベントの相関付けに使用できる
  • セッション ID は単一のエージェント実行の全期間で一貫して維持される