内容
English summary: akaire is a dependency-free local review loop for attaching browser-based sticky-note comments to static HTML reports or live development servers. AI coding agents can read and act on those comments through the CLI or the stdio MCP server, while all feedback stays in a local JSON file.
# akaire(赤入れ)
[](https://github.com/RyosukeArima/akaire/actions/workflows/ci.yml) [](https://github.com/RyosukeArima/akaire/releases)
ローカルの HTML レポートや稼働中の dev サーバーに、ブラウザ上でクリックして付箋コメントを付け、AI エージェント(Claude Code、Codex など、CLI/MCP を問わず)がそれを読んで修正対応するためのレビューループツールです。
言語について: ブラウザ UI と人間向けメッセージは日本語です。エージェント・機械向けの出力(`--help`、MCP ツール説明、エラー、machine-readable 行)は英語に統一しています。
## 特徴
- Python 標準ライブラリだけで動く、依存ゼロの単一ファイル
- 静的 HTML を配信する `serve` と、dev サーバーを透過する `proxy`
- SPA 対応。要素に追従するバッジ、モーダル文脈、route 横断のコメント一覧
- CLI と stdio MCP の両方で AI エージェントと連携
- コメントをローカルの JSON ファイルに保存
## インストール
Python 3.9 以降を推奨します(3.7/3.8 でも動作する可能性はありますが未検証で、起動時に警告を表示します。CI は 3.9〜3.14 で検証しています)。依存パッケージはありません。
git clone してリンクを張る方法(更新が `git pull` だけで済むため推奨):
```sh
git clone https://github.com/RyosukeArima/akaire.git
mkdir -p ~/.local/bin
ln -s "$PWD/akaire/akaire" ~/.local/bin/akaire
akaire --version
```
単一ファイルだけ取得する方法:
```sh
mkdir -p ~/.local/bin
curl -o ~/.local/bin/akaire https://raw.githubusercontent.com/RyosukeArima/akaire/main/akaire
chmod +x ~/.local/bin/akaire
akaire --version
```
`akaire: command not found` になる場合は、`~/.local/bin` が PATH に入っていません。次を実行してシェルを開き直してください(bash の場合は `~/.bashrc`):
```sh
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
```
PATH を変更したくない場合は、リンクを張らずに `python3 /path/to/akaire serve ...` と直接実行しても動きます(`python3` コマンドが必要です)。
macOS と Linux をサポートします。Windows はネイティブでは未検証です(コード上はファイルロックを `msvcrt` にフォールバックし、`0600` 権限は実質無効になります。シェバン実行ができないため `python akaire serve ...` のように起動してください)。Windows では WSL2 での利用を推奨します。
## クイックスタート
静的 HTML をレビューする場合:
```sh
akaire serve ./report.html --feedback-json ./report.feedback.json
```
稼働中の dev サーバーをレビューする場合:
```sh
akaire proxy http://127.0.0.1:3000 --feedback-json ./app.feedback.json
```
ブラウザで「+ コメント追加」を押し、対象要素をクリックして付箋コメントを保存します。保存先を明確にし、AI エージェントへ同じパスを渡せるよう、`--feedback-json` の指定を推奨します。
`--feedback-json` を省略した場合の既定は、`serve` は **HTML と同じディレクトリ**の `<名前>.feedback.json`、`proxy` は**カレントディレクトリ**の `akaire-proxy.feedback.json` で、モードによって場所が異なります。また、feedback JSON をリポジトリにコミットしたくない場合は、プロジェクトの `.gitignore` に `*.feedback.json` を追加してください。
## AI エージェント連携
### エージェントへの頼み方(コピペ例)
コメントを付けたら、エージェントには例えば次のように頼みます:
```
./report.feedback.json の open コメントを akaire で読んで対応してください。
直したことを検証してから reply → resolve までお願いします。
```
MCP 登録済みで常駐対応させたい場合:
```
akaire の watch_comments で新しいコメントを待ち、来たら対応して reply → resolve してください。
```
### 起動情報の機械読み取り(ready 行)
`serve` / `proxy` は起動時、人間向けメッセージに続けて機械可読な JSON を1行 stdout に出力します:
```
{"akaire": "ready", "mode": "serve", "url": "http://localhost:7777/", "port": 7777, "feedback_json": "/abs/path/report.feedback.json"}
```
`--port` 未指定でポートが自動選択された場合も、この行の `port` / `url` は実際の値です。エージェントがバックグラウンドで起動する場合はこの行をパースしてください(`proxy` では `"target"` キーが加わります)。`--port` は 0–65535 の範囲で検証され、範囲外を指定すると起動時にエラーで終了します。`--port 0` は OS に空きポートを選ばせ、この場合も ready 行の `port` / `url` には実際に使われたポートが出力されます。
### CLI
```sh
akaire list ./report.feedback.json --status open
akaire reply ./report.feedback.json c_abcd1234 "修正しました。確認してください。" --author codex
akaire resolve ./report.feedback.json c_abcd1234
akaire reopen ./report.feedback.json c_abcd1234
akaire export ./report.feedback.json --status all
```
`list` はコメント一覧、`reply` は返信追加、`resolve` は解決、`reopen` は再オープン、`export` は Markdown 出力に使います。`reply` の `--author` は返信を書いたエージェント名(`claude` / `codex` / `cursor` など。省略時は `agent`)を記録します。`author` は「英数字で始まり、英数字・`.`・`_`・`-` のみを含む32文字以内の文字列」のみ有効で、それ以外は `agent` にフォールバックします。さらに、CLI(`--author`)や MCP(`reply_comment` の `author`)からエージェントが `user` を明示的に指定しても、人間へのなりすましを防ぐため強制的に `agent` に矯正されます。ブラウザ UI からの人間のコメント・返信のみ常に `user` として保存されます。
### MCP を使わなくても shell から使える
MCP サーバーを立てられない/立てたくないエージェントでも、`akaire list / reply / resolve / reopen` を shell から直接呼び出せばレビューループに参加できます。MCP は便利な選択肢の一つであって必須ではありません。
```sh
akaire list ./report.feedback.json --status open
akaire reply ./report.feedback.json c_abcd1234 "対応しました" --author codex
```
### MCP(stdio)
Claude Code への登録例:
```sh
claude mcp add akaire -- /absolute/path/to/akaire mcp /absolute/path/to/report.feedback.json
```
Codex CLI への登録例(`~/.codex/config.toml`):
```toml
[mcp_servers.akaire]
command = "/absolute/path/to/akaire"
args = ["mcp", "/absolute/path/to/report.feedback.json"]
```
利用できる主なツールは次のとおりです。
- `read_comments`: コメントを読む
- `reply_comment`: コメントへ返信する(`author` 省略時は `agent`。エージェント名を渡せます)
- `resolve_comment`: コメントを解決済みにする
- `reopen_comment`: コメントを再オープンする
- `watch_comments`: 新しいユーザーコメントと返信を待つ
`watch_comments` は待機中に発生した複数イベントをまとめて返します。timeout になった場合は、継続監視のため再度呼び出してください。
### reply → resolve の規律はツール自身が教える
akaire が提供するのはコメントの読み書きの道具だけで、「読んだら直して返信・解決する」というワークフローを強制する仕組みはありません。とはいえ、各プロジェクトの `AGENTS.md` / `CLAUDE.md` を書き換えてもらうのは利用者に負担を強いるため、**akaire自身が「見れば分かる」形で規律を教えます**。プロジェクト側の設定を追加しなくても、以下のどちらかに触れれば自然に伝わります:
- `akaire --help` / `akaire reply --help` / `akaire resolve --help`: 「reply してから resolve する。reply なしの resolve はしない」という注意書きをコマンド末尾に表示
- MCP `tools/list`: `reply_comment` / `resolve_comment` / `watch_comments` のツール説明文自体に、検証してから reply → resolve する順序と、resolve 単独禁止の注意を埋め込み済み
これによりCLI/MCPどちらの経路でakaireに触れても、エージェントは既存の `AGENTS.md` を書き換えられていなくても規律を認識できます。プロジェクト固有の追加ルール(コミットハッシュを reply に含める、部分対応時の扱いなど)を明文化したい場合のみ、プロジェクト側の `AGENTS.md` / `CLAUDE.md` に追記してください。
## セキュリティモデル
akaire は認証機構を持たないローカルツールで、トラストバウンダリは同一ホストです。
- 既定では `127.0.0.1` に bind します。`--bind 0.0.0.0` を指定すると、同一ネットワーク上の利用者にコメントの読み書きを許し、`proxy` では上流にも到達できるようになるため、起動時に警告を表示します。
- `proxy --allow-remote` はプライベートネットワークだけでなく、パブリックホストへの到達も許可します。
- `serve` は対象 HTML の親ディレクトリ配下を配信します。dotfile を含むパスと、`.env`、`.pem`、`.key`、`.p12`、`.pfx`、および拡張子なしの SSH 秘密鍵ファイル名(`id_rsa`、`id_dsa`、`id_ecdsa`、`id_ed25519`)は 404 で遮断しますが、機密情報を含むディレクトリでの利用は推奨しません。
- 自動終了に使う session API は、同一ホストの任意プロセスから呼び出せる設計です。
- SSRF 対策として、上流ホストの DNS 解決結果を検証して IP をピン留めし、プロキシ自身はリダイレクトを追従しません。
- XSS 対策として、コメントなどの表示には `textContent` を使用します。
- CSRF 対策として、レビュー API の `POST`、`PATCH`、`DELETE` には `Origin` ヘッダーを必須とします。
## 制約・非対応
- iframe 内部の document にある要素にはコメントできません。
- OS の信頼ストアで検証できない自己署名証明書を使う HTTPS 上流には接続できません。正規に検証できる証明書は利用できます。
- Shadow DOM 内部の要素は選択できません。
- `Accept-Encoding: identity` を無視して圧縮 HTML を返す上流にはレビュー UI を注入せず、stderr に警告します。
- chunked リクエストボディには対応しません。リクエストボディには `Content-Length` が必要です。
- 通常の HTTP 応答は HTTP/1.0 で、HTTP/1.1 keep-alive には対応しません。WebSocket は専用経路で中継します。
- コメント本文の編集は `watch_comments` のイベント対象になりません。
- テキスト入力中を除き、`]` キーをサイドバーの開閉に使用します。
- HashRouter(`#/path` 形式)の SPA では、route の一致判定がハッシュ部分を除いた pathname + クエリのみで行われるため、ハッシュ側だけが変わるページ遷移は別 route として区別されません。ハッシュ違いの別画面でも同じコメントが表示され続ける、または off-route 扱いにならない場合があります。
## 環境変数
| 変数 | 用途 | 既定値 |
| --- | --- | --- |
| `AKAIRE_NO_BROWSER` | `1` の場合、起動時にブラウザを開かない(`--no-browser` フラグと同等) | 未設定 |
| `AKAIRE_DEFAULT_PORT` | `--port` 未指定時に自動選択を試みる起点ポート(使用中なら +1 ずつ最大50個先まで空きポートを探す) | `7777` |
| `AKAIRE_SHUTDOWN_GRACE_SECONDS` | 最後の session 終了後に自動終了するまでの猶予秒数 | `10` |
| `AKAIRE_IDLE_TIMEOUT_SECONDS` | session がない状態、または heartbeat が途絶えた状態のタイムアウト秒数 | `300` |
| `AKAIRE_HEARTBEAT_SWEEP_SECONDS` | session の失効を確認する間隔(秒) | `15` |
環境変数の値が不正・範囲外・空文字の場合は、stderr に警告を出したうえで既定値にフォールバックします(プロセスは停止しません)。有効範囲は `AKAIRE_DEFAULT_PORT` が 1–65535、秒数系(`AKAIRE_SHUTDOWN_GRACE_SECONDS` / `AKAIRE_IDLE_TIMEOUT_SECONDS` / `AKAIRE_HEARTBEAT_SWEEP_SECONDS`)が非負の有限数です。
ブラウザを開かずに起動した場合(`--no-browser` / `AKAIRE_NO_BROWSER=1`)、ブラウザセッションが一度も張られないと `AKAIRE_IDLE_TIMEOUT_SECONDS`(既定300秒)で自動終了します。エージェント用に長時間立てておく場合は `--no-auto-shutdown` を併用してください。
## フィードバック
不具合報告・要望は [GitHub Issues](https://github.com/RyosukeArima/akaire/issues) へお寄せください。
## ライセンス
[MIT License](./LICENSE)