HTTP API リファレンス

ccmux デーモンは、セッションの一覧表示、プロジェクト データの読み取り、リモート クライアントの構築のために HTTP および JSON API を公開します。このリファレンスでは、接続セットアップ、信頼モデル、エンドポイント、および応答タイプについて説明します。

ルートとタイプは ccmux source。古いデーモン バージョンでは、ここに記載されているすべてのエンドポイントがサポートされていない可能性があります。実行中のバージョンの正常性エンドポイントを確認してください。

輸送と到達可能性

同じルートが 2 つのトランスポートで提供されます。

トランスポート アドレス デフォルト
ローカル Unix ソケット ~/.local/state/ccmux/ccmuxd.sock (モード 0600) 常にオン
tailnet HTTP http://TAILNET-IPv4:PORT (ポートのデフォルト 7474) オフ

別のデバイスからデーモンにアクセスするには、 デーモン ホスト: 設定 daemon.listen_tailnet = true (オプション daemon.tailnet_port) で ~/.config/ccmux/config.toml し、ccmuxdを再起動します。バインドアドレスはホストの tailscale ip -4。 Tailscale が実行されていない場合、tailnet リスナーは静かに起動しません (Unix ソケットのみが提供されます)。

認証と信頼モデル — 最初にお読みください

HTTP API にはアプリケーションレベルの認証がありません。 ベアラー トークン、API キー、リクエストごとの署名、IP ホワイトリストがありません。信頼境界は Tailscale tailnet: デーモンにアクセスできる任意のホスト 100.x.x.x:7474 すべてのエンドポイントを呼び出すことができます - リスト/作成/強制終了/名前変更/キーの送信、 完全な対話型端末に接続します、メモ/会話/使用法を読みます。

これを保護します Tailscale ACL、アプリレベルの認証ではありません。デーモンのtailnet IP にルーティングできるものはすべて、完全に信頼できるものとして扱います。

リクエストごとに 2 つのエンドポイントが検証され、デバイスの信頼 + プッシュをブートストラップするためだけに検証されます。API を保護するためではありません。

エラーの形状

エラーは次のとおりです プレーンテキスト (text/plain): 単一行メッセージ、 ではありません JSON エンベロープ。チェックしてください ステータスコード、本文を人間のメッセージの文字列として読み取ります。成功した JSON 応答は次のとおりです。 application/json.

コード 意味
200 OK (JSON 本体)
204 OK、本文はありません (kill / send-keys / device register)
400 不正な入力/検証エラー
401 無効または期限切れのペアリング トークン (/v1/pair のみ)
404 見つかりません — またはこのデーモンはエンドポイントよりも古いものです
405 HTTP メソッドが間違っています
500 サーバー / tmux / スキャフォールドの障害
503 機能は利用できません (例: /v1/pair-token 付き listen_tailnet オフ)

API は次のように進化します。 追加 JSON フィールド (すべてのオプションのフィールドは omitempty) および 追加 ルート。治療する 404 エンドポイント全体で「このデーモンはその機能より古い」として表示され、正常に機能が低下します。

エンドポイントの概要

メソッド パス 応答
GET /v1/health HealthInfo
GET /v1/peers []PeerInfo
GET /v1/sessions []SessionState
POST /v1/sessions SessionState (作成または接続)
POST /v1/sessions/bare NewBareSessionResponse
POST /v1/sessions/NAME/kill 204
POST /v1/sessions/NAME/rename SessionState
POST /v1/sessions/NAME/send-keys 204
GET /v1/sessions/NAME/preview PreviewResponse
GET /v1/sessions/NAME/attach WebSocket (対話型 PTY)
GET /v1/projects []ProjectInfo
POST /v1/projects NewProjectResponse
GET /v1/conversations []Conversation
GET /v1/usage?window=… AgentUsage
GET /v1/notes?project=…[&file=…] []NoteEntry または NoteContent
GET /v1/notes/search?project=…&q=… []SearchHit
GET /v1/events SSE ストリーム SessionEvent
POST /v1/pair-token (Unix のみ) PairTokenResponse
POST /v1/pair PairResponse
POST /v1/devices 204
POST /v1/devices/test 204

(パスが示されている場所 NAME それは tmux セッション名パスセグメントです。つまり、 /v1/sessions/{name}/kill.)

エンドポイントの詳細

セッション

対話型端末 — GET /v1/sessions/NAME/attach (Webソケット)

実際の WebSocket にブリッジされた WebSocket にアップグレードします。 tmux attach-session PTY 内: 真の対話型ターミナル (ライブ出力、入力、サイズ変更) それなし SSH/モッシュ。用途 coder/websocket フレーム。

初期 PTY サイズは 80x24 最初のサイズ変更まで。サーバーは 25 秒ごとに ping を送信し、期限は 10 秒です。ポンに応答するか、ティアダウンを期待します。 InsecureSkipVerify が設定されています(いいえ) Origin チェック)。ソケットのみを閉じる が切り離されます; tmux セッションは実行を続けます。ポーリングよりもこれを優先します /preview 対話型ビューの場合。

プロジェクト

会話、使用法、メモ

ライブアップデート — GET /v1/events (SSE)

text/event-stream。それぞれ data: フレームは JSON です SessionEvent; kindcreated / killed / state_change / needs_input。心拍数: : connected オープン時、 : ping 20 秒ごと (次で始まるコメント行) : は無視できます)。アン event: drops / data: N フレームは、N 個のイベントを見逃したため、再フェッチする必要があることを意味します /v1/sessions 再同期します。

健康と発見

ペアリングとプッシュ(モバイル)

ネイティブ プッシュ (APN/iOS、FCM/Android) と SSH キーのインストールのオプション フロー。 ssh/mosh 添付。 違います tailnet経由で読み取り/動作エンドポイントを使用する必要があります。

プッシュは 2 つの遷移で起動します: セッションの開始 needs_input、および active → idle (「エージェントは終了しました」)。プッシュのセッションIDは local/SESSIONNAME。 APN と FCM は、 デフォルトではオフ サーバー側の設定が必要です。 FCM ルーティングは存在しますが、Android 配信はまだ確立されていません。

タイプ

からコピーされました internal/daemon/protocol.go (JSON タグを持つ Go 構造体)。

type SessionState struct {
	Name        string    `json:"name"`
	Host        string    `json:"host"`         // "local" or a remote host name
	Project     string    `json:"project"`
	Path        string    `json:"path"`         // session working directory
	State       string    `json:"state"`        // active|idle|needs_input|error|unknown
	Attached    bool      `json:"attached"`
	Windows     int       `json:"windows"`
	Created     time.Time `json:"created"`
	LastChange  time.Time `json:"last_change"`
	PromptCount int       `json:"prompt_count"`
	Agent       string    `json:"agent,omitempty"`
}

type HealthInfo struct {
	OK        bool   `json:"ok"`
	Hostname  string `json:"hostname"`
	Version   string `json:"version"`
	Sessions  int    `json:"sessions"`
	SleepMode string `json:"sleep_mode"` // off|safe|dangerous|very_dangerous
}

type SessionEvent struct {
	At      time.Time    `json:"at"`
	Kind    string       `json:"kind"` // state_change|created|killed|needs_input
	Session SessionState `json:"session"`
}

type NewSessionRequest struct {
	Project  string `json:"project"`
	Path     string `json:"path"`     // defaults to PROJECTS_ROOT/PROJECT
	Continue bool   `json:"continue"` // start the agent with --continue
	Name     string `json:"name,omitempty"`
	Agent    string `json:"agent,omitempty"`
}

type NewBareSessionRequest struct {
	Name  string `json:"name,omitempty"`
	Path  string `json:"path,omitempty"`
	Agent string `json:"agent,omitempty"`
}
type NewBareSessionResponse struct {
	Session string `json:"session"`
	Path    string `json:"path"`
	Host    string `json:"host"`
}

type NewProjectRequest struct {
	Name  string `json:"name"`
	Agent string `json:"agent,omitempty"`
}
type NewProjectResponse struct {
	Session string `json:"session"`
	Path    string `json:"path"`
	Host    string `json:"host"`
}

type ProjectInfo struct {
	Name      string    `json:"name"`
	Host      string    `json:"host"`
	Path      string    `json:"path"` // absolute on the daemon host
	HasGit    bool      `json:"has_git"`
	HasCM     bool      `json:"has_cm"`
	HasAgents bool      `json:"has_agents,omitempty"`
	HasDocs   bool      `json:"has_docs"`
	Agent     string    `json:"agent,omitempty"`
	Modified  time.Time `json:"modified"`
}

type PeerInfo struct {
	Hostname   string `json:"hostname"`
	Addr       string `json:"addr"` // tailnet IPv4
	OS         string `json:"os"`
	Online     bool   `json:"online"`
	RunsCCMuxd bool   `json:"runs_ccmuxd"`
	Port       *int   `json:"port,omitempty"`
}

type Conversation struct {
	ID       string    `json:"id"` // agent UUID (its --resume id)
	Agent    string    `json:"agent"`
	Project  string    `json:"project,omitempty"`
	Path     string    `json:"path,omitempty"`
	Preview  string    `json:"preview,omitempty"`
	Modified time.Time `json:"modified"`
}

type AgentUsage struct {
	Claude      UsageSummary `json:"claude"`
	Codex       UsageSummary `json:"codex"`
	Antigravity UsageSummary `json:"antigravity"`
}
type UsageSummary struct {
	HasData       bool    `json:"has_data"`
	WindowSeconds int     `json:"window_seconds"`
	Prompts       int     `json:"prompts"`
	InputTokens   int     `json:"input_tokens"`
	OutputTokens  int     `json:"output_tokens"`
	EstimatedCost float64 `json:"estimated_cost"` // USD
}

type NoteEntry struct {
	Rel      string    `json:"rel"`
	Dir      string    `json:"dir"`
	Display  string    `json:"display"`
	Modified time.Time `json:"modified"`
}
type NoteContent struct {
	Rel     string `json:"rel"`
	Content string `json:"content"`
}
type SearchHit struct {
	Rel     string `json:"rel"`
	LineNum int    `json:"line_num"`
	Snippet string `json:"snippet"`
}

type PreviewResponse struct {
	Lines   int    `json:"lines"`
	Content string `json:"content"`
}

type RenameRequest   struct{ Name string `json:"name"` }
type SendKeysRequest struct{ Keys string `json:"keys"` }

type PairRequest struct {
	Token       string `json:"token"`
	PublicKey   string `json:"public_key"`
	DeviceToken string `json:"device_token,omitempty"`
	APNsEnv     string `json:"apns_env,omitempty"` // development|production
}
type PairResponse      struct{ Hostname string `json:"hostname"`; Version string `json:"version"` }
type PairTokenResponse struct{ Token string `json:"token"`; URL string `json:"url"` }
type RegisterDeviceRequest struct {
	Token     string `json:"token"`
	Env       string `json:"env,omitempty"` // apns: development|production; fcm: empty
	PublicKey string `json:"public_key"`
	Provider  string `json:"provider,omitempty"` // apns (default) | fcm
}
// POST /v1/devices/test body is { "public_key": "..." }

クライアント側をミラーリングするための検証ルール

# Health (over the tailnet)
curl -s http://100.75.64.20:7474/v1/health | jq

# List sessions
curl -s http://100.75.64.20:7474/v1/sessions | jq

# Type a reply into a session and press Enter
curl -s -X POST http://100.75.64.20:7474/v1/sessions/c-auth/send-keys \
  -H 'content-type: application/json' \
  -d '{"keys":"yes, ship it\n"}'

# Peek at the last 40 lines of a pane
curl -s 'http://100.75.64.20:7474/v1/sessions/c-auth/preview?lines=40' | jq -r .content

# Subscribe to live events
curl -sN http://100.75.64.20:7474/v1/events

Go 参照クライアント internal/daemon/client.go は正規のコンシューマであり、メソッド→エンドポイントの便利なマップです。

ccmux の改善にご協力ください

不具合、わかりにくい説明、不自然な翻訳を見つけましたか?小さな改善も歓迎します。Issue やプルリクエストでお知らせください。


エラーまたは古いものを見つけましたか? GitHub でこのページを編集します.