ank MCP サーバー
CLI のすべての動詞をツールとして。シェルを持たないクライアントのために。Claude Code への追加は 1 行です:
claude mcp add ank -- ank mcp --repo /path/to/your/repo
ank mcp とは
ank mcp は、どのインストール方法でも置かれるひとつの実行ファイルの動詞です。別のファイルを取ってくる必要はありません。CLI がディスパッチするものが、そのままサーバーが提供するものです。同じバイナリだからです。
stdio 上で JSON-RPC を話し、クライアントがそれを起動します。つまり起動するのではなく、設定するものです。コマンド、その引数、そしてどのリポジトリを代弁するか。
クライアントを設定する
エントリは 3 つのクライアントすべてで同じ JSON です。変わるのは置くファイルだけです。
{
"mcpServers": {
"ank": {
"command": "ank",
"args": ["mcp", "--repo", "/path/to/your/repo"]
}
}
}置き場所
- Claude Code
- リポジトリのルートにある
.mcp.json。ツリーと一緒に移動し、clone した全員に届く形です。あるいは上のclaude mcp addの 1 行で、エントリを書いてもらえます。 - Claude Desktop
claude_desktop_config.json。macOS では~/Library/Application Support/Claude/、Windows では%APPDATA%\Claude\にあります。- Cursor
- リポジトリの隣の
.cursor/mcp.json、またはすべてのプロジェクトに効く~/.cursor/mcp.json。
コマンドは ank、mcp が最初の引数
0.6.0 までのリリースは、ank-mcp という 2 つ目の実行ファイルを置いていました。今はどのインストール方法も置かないので、まだそれを指している設定は command not found になります。変えるべきはその 1 行です。
--repo は必ず書く
クライアントはたまたまいるディレクトリでサーバーを起動し、--repo がなければサーバーはそのディレクトリを使います。この失敗はエラーになりません。誰も意図していない corpus を、あるいは何も代弁していないプロセスが、黙って動き続けるだけです。.ank/ のないパスは起動時に拒否され、人の目に届きます。
ank mcp --repo /tmp
error[1]: no .ank/ found from /tmp
-> ank init
動詞ひとつに、ツールひとつ
ツールは、バイナリがディスパッチに使い、ank help --json が記述するのと同じテーブルから生成されます。選び抜いたサブセットではありません。2 つの入口が、何が存在するかで食い違うことはありえません。
ank_contextank_claimank_showank_logank_doneank_releaseank_newank_reviewank_acceptank_readank_closeank_amendank_attestank_findank_statusank_graphank_scopeank_tuiank_mcpank_watchank_editank_checkank_migrateank_archiveank_configank_initank_skillsank_updateank_help
ank_<verb> という名前
ただの
contextでは、クライアントが読み込んでいる他のサーバーと衝突します。要約が説明に、フラグが入力スキーマになり、位置引数は文字列の配列argumentsとして渡ります。CLI の答えを、終了コードごと
呼び出しは
--jsonが返すドキュメントを、隣にexitCodeを添えて返します。拒否は CLI の拒否そのもので、ヒントも含めてisError付きの結果として返ります。JSON-RPC のエラーはリクエストが間違っていたこと、isErrorは corpus がノーと言ったことを意味します。CLI が取らない claim は取らない
claim はすべて、そのリポジトリの
refs/ank/claims/に同じ compare-and-swap で入ります。サーバーはクライアントの代わりに何も保持せず、ANK_AGENTが指定されていなければank-mcp/<version>として書き込みます。
--> {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"ank_show","arguments":{"arguments":["TASK-9999"]}}}
<-- {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"error[2]: entity not found: TASK-9999\n -> ank find TASK-9999"}],"isError":true,"exitCode":2,"stderr":"error[2]: entity not found: TASK-9999\n -> ank find TASK-9999"}}
複数のリポジトリを、ひとつのサーバーで
どのツールも省略可能な corpus 引数を取ります。ank status --json が "corpus" に出力するルートコミットで、パスではありません。各リポジトリを ank config --user corpora.<root> <path> で一度宣言すれば、クライアントの設定は一文字も変わりません。ひとつのサーバーが複数の corpus を扱えますが、その claim を混ぜることはありません。
ank_accept も他の動詞と同じくありますが、デフォルトブランチ以外では変わらず拒否します。意思決定の承認は、人間の行為のままです。
MCP か CLI か
どちらも同じ動詞に届き、同じドキュメントを返します。クライアントに何ができるかで選んでください。
エージェントにシェルがある
CLI を使います。npx skills add haksolot/ank でループを教える skills をエージェントに渡せば、他のコマンドと同じように ank を呼びます。
クライアントにシェルがない
ank mcp を使います。クライアントには同じ動詞がツールとして見え、各説明に拒否条件と終了コードが書かれているので、呼ぶ前に何が拒否されるかを読めます。
corpus を表示するものを作るなら、ポーリングするのは ank_status と ank_find です。ank_context と ank_show は claim を更新し、ank_check は古い ref を刈り込む、つまり書き込みます。
ank をインストール
コマンドは二つ。Linux、macOS、Windows に対応し、git 2.34 以降が必要です。
npm install -g @haksolot/ank
npx skills add haksolot/ank