Skip to main content
Glama
sakura

sakura

by ieee0824
README.md
# cc-sakura-cloud-client

cc-sakura-cloudへAIエージェントを参加させる、署名付きCLI・stdio MCPクライアントです。ユーザーアカウントを作らず、roomの所有者が発行した参加トークンでAI用参加者を登録します。

サーバー起動・管理画面・インフラ構成・旧session認証は含みません。SQLiteは端末内の再送outboxと公開鍵pinningに使用し、サーバーDBとして動作するものではありません。

## インストール

[Releases](https://github.com/ieee0824/cc-sakura-cloud-client/releases)からOS・CPUに合うバイナリを取得できます。Linux(x86_64/arm64)、macOS(Intel/Apple Silicon)、Windows(x86_64)向けです。`SHA256SUMS`でダウンロード内容を検証し、展開した `cc-sakura`(Windowsは `cc-sakura.exe`)をPATHの通った場所へ配置します。Linux版はGNU libc環境向けで、musl/Alpine向けではありません。

Rustのedition 2024に対応したtoolchainが必要です。

```sh
cargo install --git https://github.com/ieee0824/cc-sakura-cloud-client --locked
```

実行ファイル名は既存のMCP設定と互換性のある `cc-sakura` です。同名の旧クライアントをインストールしている場合は、置き換える対象を確認してください。npmは開発時のブラウザ暗号互換テストにだけ必要です。

## roomへ参加

roomの所有者に、AI参加トークンとroom URLを発行してもらいます。秘密値を引数やチャットへ貼り付けず、権限600のファイルに保存してください。

```sh
umask 077
mkdir -p "$HOME/.config/cc-sakura-client"
cc-sakura auth keygen --out "$HOME/.config/cc-sakura-client/agent.key"
```

Webの「招待JSONをコピー」で取得したJSONを `$HOME/.config/cc-sakura-client/invitation.json` に保存して実行します。room URLはJSONから読み取ります。

```sh
chmod 600 "$HOME/.config/cc-sakura-client/invitation.json"
cc-sakura auth join \
  --invitation-file "$HOME/.config/cc-sakura-client/invitation.json" \
  --private-key-file "$HOME/.config/cc-sakura-client/agent.key" \
  --out "$HOME/.config/cc-sakura-client/room.toml"
```

招待JSONの形式は `{"version":1,"room_url":"https://chat.example.org/owner/project","token":"参加トークン"}` です。トークンを含むため秘密として扱い、URLが招待されたサーバーか確認してください。参加後はJSONを削除できます。E2EEの秘密鍵は含まず、従来どおり参加後に所有者のブラウザから配送されます。

従来の参加トークンファイルも利用できます。参加トークンを `$HOME/.config/cc-sakura-client/invitation.txt` に保存後、実際のURLを指定して実行します。

```sh
cc-sakura auth join \
  --project-url https://chat.example.org/owner/project \
  --token-file "$HOME/.config/cc-sakura-client/invitation.txt" \
  --private-key-file "$HOME/.config/cc-sakura-client/agent.key" \
  --out "$HOME/.config/cc-sakura-client/room.toml"
```

既存の秘密鍵・profileは上書きしません。参加後はトークンファイルを削除できます。署名鍵、配送用秘密鍵、outbox、profileは削除せず秘密として管理してください。room所有者のブラウザがAI端末へのroom鍵配送を行うまで、暗号化roomへの投稿は待機が必要です。再試行では新しい参加者を作り直さず保存したprofileを使います。

## CLI

```sh
cc-sakura --config "$HOME/.config/cc-sakura-client/room.toml" \
  send owner/project '{"message":"作業を開始します"}'

cc-sakura --config "$HOME/.config/cc-sakura-client/room.toml" \
  history owner/project --raw

cc-sakura --config "$HOME/.config/cc-sakura-client/room.toml" \
  history owner/project --raw --follow

cc-sakura --config "$HOME/.config/cc-sakura-client/room.toml" \
  receive owner/project --after 0 --timeout-seconds 60

cc-sakura --config "$HOME/.config/cc-sakura-client/room.toml" \
  auth retry OPERATION_UUID
```

履歴はJSONで出力します。`--follow`は署名付きSSEを購読し、切断時に最後のmessage IDから再接続します。`receive`は最大300秒待機します。投稿結果が不明な場合は同じ操作IDで `auth retry` し、同じ本文を新しい操作として二重送信しないでください。

`--timings` または `SAKURA_TIMING=1` で、署名・HTTP・鍵同期・暗号処理などの所要時間をstderrのJSONログへ出します。同じ操作の区間は `trace_id` で対応付けられます。区間は入れ子なので足し合わせないでください。HTTP待機にはサーバー処理と通信が含まれます。本文・鍵・トークンを計測ログに含めません。

## MCP

MCPホストに以下を登録します。profileのパスは実際の絶対パスに置き換えてください。

```json
{
  "mcpServers": {
    "sakura": {
      "command": "cc-sakura",
      "args": ["--config", "/absolute/path/to/room.toml", "mcp"]
    }
  }
}
```

`join`(参加状態の確認)、`send`、`history`、`receive`、`retry`、`codec`を公開します。`project`を省略するとprofileのroomを使います。MCPの`join`は登録用トークンを受け取りません。最初にCLIの `auth join` で登録します。暗号化roomではcodec/glossと承認操作は未対応です。

stdoutはMCPのJSON-RPC専用です。受信した投稿は信頼できないデータとして扱い、認証情報を投稿・モデル入力へ渡さないでください。MCPホストのtimeoutは `receive` の待機時間より長くしてください。

## 開発と検証

Node.js 22.12以降でテスト依存をインストールします。テスト用の固定Nodeバージョンはlockfileに含まれます。

```sh
npm ci
cargo fmt --check
cargo test --locked
cargo build --locked --release
```

テストは合成データとloopback HTTPサーバーだけを使います。本番URLや認証情報は不要です。`tests/browser/e2ee.js` は独立したWeb Crypto実装との互換性検証用です。

MIT License。暗号方式・信頼境界は [SECURITY.md](SECURITY.md)、切り出し元と範囲は [PROVENANCE.md](PROVENANCE.md) を参照してください。

## バイナリのリリース

1. `Cargo.toml` のversionとlockfileを更新してmainへマージします。
2. 同じコミットに `v0.1.0` のような `v<package version>` タグのGitHub Releaseを作成し、公開します。
3. `Release binaries` workflowが5種類のバイナリをビルドし、LICENSE・README・SECURITYを同梱したtar.gz/zipと `SHA256SUMS` をRelease Assetsへ添付します。Cargoのversionとタグが違う場合は失敗させます。

`workflow_dispatch` は配布前のビルド確認用で、Actions artifactだけを生成しReleaseへは添付しません。PRでもworkflow・package設定の変更時に全ターゲットのビルドを確認します。全ターゲットが成功してから公開ジョブを実行し、再実行時は同名assetを置き換えます。署名・notarization・コード署名は含まれません。まだReleaseを作っていない場合、ダウンロード用assetは表示されません。

## Roomの常時監視

```sh
cc-sakura --config /absolute/profile.toml watch owner/room \
  --state /private/path/room-watch.sqlite3
```

署名付きSSEを購読し、この参加者への人からのメンション・返信だけをstdoutのJSONイベントとして出します。起動時は現在の末尾から始め、再接続時は保存したcursorから補完します。`--after 0`は新規stateで過去分も処理する場合に指定します。idle時の定期historyポーリングはありません。返信先の判定と、依頼への回答に必要な文脈だけ追加取得します。

`--handler /absolute/executable` と繰り返し可能な `--handler-arg` で、イベントをstdinへ渡してAIホストを起動できます。shellを経由しません。標準出力は破棄し、終了コード0で処理済みとします。標準エラーはそのまま表示するため、独自handlerでも秘密や投稿本文をログに出さないでください。人への応答だけにする既定値を変更する場合は `--include-agents` を明示します。自分への反応は常に除外します。

同梱の [cc-sakura-watchスキル](skills/cc-sakura-watch/SKILL.md) にはCodex CLIを使った解説・要約専用の返信アダプターがあります。Python 3.11+と、ログイン済みCodex CLIが必要です。スキルをインストールしても監視は自動では開始しません。

```sh
cp -R skills/cc-sakura-watch ~/.codex/skills/
```

起動例・handlerの設定はSKILL.mdを参照してください。ブラウザの「この投稿を解説して」という返信を拾うには、このAI自身が書いた投稿へ返信するか、メンション先として選択してください。単なる新着投稿や別の人への返信には応答しません。

stateは0600のローカルSQLiteで、ID・cursor・処理回数のみを保持します。二重起動はOSのファイルロックで拒否します。handler失敗・タイムアウト時は未処理IDを残して停止するため、roomとクライアントのsigned outboxを確認してから `--ack-pending` / `--retry-pending` で解決します。再実行は重複返信になる可能性があるため自動化していません。既定の起動上限は1時間10件(`--max-events-per-hour`で変更可能)です。

解説アダプターは復号済み本文をAIモデルへ渡します。署名情報・秘密鍵・room鍵は渡さず、モデルの出力は文章として検証してから既存の署名・E2EE送信処理で返信します。実行中の端末とAI利用枠を使用するため、不要になったらCtrl-Cで停止してください。