役割: 新しく Butler を使う Brain 向けの入口ガイド
対象読者: Butler を呼び出す側の Brain(Codex / Claude Code / 後継モデル)
この文書は、butler2 の内部実装をまだ深く知らない Brain が、
Butler の目的と使いどころを短時間で理解し、
安全に最初の task を流せるようにするための利用ガイドである。
設計原則そのものは マスタードキュメント と
黒執事アーキテクチャ v2 が正本であり、
本書は「新しい Brain が何をどう使い始めるか」に絞って案内する。
Butler の最上位目的は、Brain を低レベル作業の反復から切り離し、
判断、設計、会話に集中させることである。
Butler は単なる model 呼び出し器ではない。
task contract を受け取り、適切な Maid を選び、実行を監督し、証跡つきで結果を返す執事長として振る舞う。
簡単に言うと、Brain は「何を達成したいか」を渡し、
Butler は「どう進めて、どう確かめるか」を受け持つ。
現在の butler2 は Butler core を中心に持ち、その上に
Python API、CLI、MCP facade を載せる構成である。
つまり、MCP は Butler の入口のひとつであり、本体ではない。
次のような task は Butler に向いている。
逆に、次のような task は Brain がそのまま処理してよい。
迷った時は、「Brain が再試行ループを抱えるかどうか」で考えると判断しやすい。
最も薄く、テストしやすい入口である。
ローカルコードから直接 Butler core を呼ぶ時に使う。
from butler import Constraints, TaskContract, execute_task
task = TaskContract(
intent="read_from_gitea",
target={"service": "gitea"},
constraints=Constraints(max_minutes=1),
success_criteria=["issue を読める"],
delegation_mode="known_only",
requested_by="brain",
requested_at="2026-04-04T00:00:00Z",
payload={"operation": "list_issues", "owner": "team", "repo": "sample"},
)
result = execute_task(task, project_root="/path/to/project")
人手で試したい時や、外部ツールからプロセス実行したい時の入口である。
butler2 task.json --project-root /path/to/project
別の Brain から MCP tool として Butler を呼びたい時の入口である。
現在は stdio server として execute_task と inspect_runtime_config を公開している。
uv run butler2-mcp
MCP facade は薄い変換層であり、実際の routing、supervision、verification は Butler core が担当する。
接続時には短い instructions が返り、次の resource も読める。
butler://usage-guidebutler://runtime-defaults新しい接続では、まず butler://usage-guide を読み、次に inspect_runtime_config で実効パスを確認してから、軽い execute_task を流すのが安全である。
ユーザーが「確定して」「公開して」「反映して」と依頼した場合は、まず work_observe() で状態を確認し、必要に応じて work_record() を促したうえで work_publish() を実行する。
agy を使う capability は、Brain の事前知識に依存せず capability 側で agy_auth_status() 相当の前置チェックを必ず行い、認証が必要なら need_input と通常端末での実行案内を返す。Brain から agy_auth_status() を個別に呼ぶのは補助的な事前確認として扱う。
agy 認証が必要な時の役割分担Antigravity CLI(agy)を使う capability では、OAuth 認証そのものを Butler や Brain が裏で完了させることはできない。
特に、Brain が見ている hidden PTY / バックグラウンド端末に認証 URL が出ても、ユーザーの見える通常ターミナルやブラウザには自動で出ない。そのため、Brain は agy -p ... を裏で起動して認証を進めようとしてはいけない。
役割分担は次のとおり。
agy の実行ログを観測し、認証要求を検知したら process tree を停止して auth_required と理由(例: access_token_expired)を返す。OAuth URL / state / token / email は evidence に残さない(redaction 済み)。need_input として解釈し、ユーザーに通常端末での操作を案内するユーザーに案内するコマンドは次を基本形とする。
agy -p 'Reply with exactly OK.' --print-timeout 5m
案内時は、少なくとも次を明記する。
agy_auth_status() や capability 実行前の precheck は token file の readiness hint に過ぎない。agy は OS keyring(D-Bus Secret Service)経由でも認証できるため、token file が無い/読めない(auth_status: unknown や keyring_unavailable)だけでは実行を止めない。
agy_auth_status() が ok / unknown を返す: precheck では止めず、実行レベルの arbiter に最終判定を委ねる。agy 未インストール等の確実な失敗のみ precheck でブロックする(failed)。auth_required → need_input を返す。したがって、keyring 認証済みのユーザーが token file を持たない構成でも review は実行できる。逆に、token file があっても(refresh token 失効など)認証可否は実行時にしか確定しない。
run_review(route: agy_review)も上記の役割分担に従う。未認証時は need_input と通常端末向け手順が返り、認証後に同じ run_review を再実行すれば先へ進める。route を従来の gemini_cli_review へ戻す場合は config/intent_maid_routes.yml の intent: review の maid_id を変更するだけでよい(コード変更不要)。
agy の課金・credits 運用方針(#74 Phase F1)agy(Antigravity CLI)は Google AI Pro のアカウント認証(OS keyring / OAuth)だけで利用し、API 従量課金は使わない。運用方針は次のとおり(2026-06-24 ユーザー承認)。
pending / backoff として返し、連打しない。run_toolless は実行直前に sanitize_agy_env で GEMINI_API_KEY / GOOGLE_API_KEY / GOOGLE_APPLICATION_CREDENTIALS / GOOGLE_GENAI_USE_VERTEXAI / GOOGLE_CLOUD_* 等の API/Vertex 認証 env を agy へ渡さない(OAuth 経路の GOOGLE_GENAI_USE_GCA は維持)。Antigravity の Overages は「baseline 消費後に保有 AI credits を使うか」という運用設定であり、Gemini API / Vertex AI の API 課金とは別物である点に注意する。
agy への切替は config / env を戻すだけでロールバックでき、コード変更や再デプロイは不要。agy の回答を既存データへ不可逆反映することはしない。
config/intent_maid_routes.yml の intent: review の maid_id を agy_review から従来の gemini_cli_review へ戻す(§5.4 参照)。legacy maid は registry に enabled で残してあり、config だけで切り戻せる。BUTLER_WIKI_SUMMARY_BACKEND で backend を切り替える。
agy(既定 / production): agy tool-less backend で要約を生成する。unavailable(rollback): agy runner を一切呼ばず、skipped(reason=backend_unavailable)を返す明示的な安全停止。要約なしのまま Wiki sync は継続する。agy 未インストール環境でも安全に切り戻せる。unavailable の安全停止としている。未知の backend 値は起動時に ValueError で弾く。Butler 本体の repo と、実際に task を適用したいプロジェクトは別でよい。
その場合は、対象プロジェクトの文脈を Butler に明示する。
主な指定項目:
project_rootconfig_direnv_pathissue_template_dirsession_logs_dir最小では project_root だけで足りることもあるが、
capability が .env や config/ を参照する場合は明示した方が安全である。
Butler MCP の tool が見えていることと、対象プロジェクトで Butler の実用機能が使えることは別である。
最低限、次の 2 段階に分けて確認する。
butler_version() や inspect_runtime_config(project_root) が成功するissue_list()、issue_create()、work_observe() など、目的の capability が対象プロジェクトで成功する前者だけで「Butler が使える」と判断しない。Gitea issue 管理、Wiki 同期、Maid 実行などは追加の環境変数やプロジェクト側ファイルを必要とする。
すでに Butler が使えているプロジェクトがある場合は、そのプロジェクトの構成を参照する。
確認するもの:
.env の有無と、Butler が必要とするキー名.gitea/ISSUE_TEMPLATE/ の有無session_logs/ の有無git remote -v で解決される Gitea repoinspect_runtime_config(project_root) の diagnostic_only に出る実効パス.env の値そのもの、特に token は表示・転記しない。比較する時はキー名だけを見る。
まず対象プロジェクトで次を呼ぶ。
inspect_runtime_config(project_root="/path/to/project")
見る場所:
for_brain.project_rootfor_brain.available_capabilitiesdiagnostic_only.env_path.existsdiagnostic_only.issue_template_dir.existsdiagnostic_only.session_logs_dir.existsenv_path.exists=false の場合、Gitea 連携や Wiki 同期など、.env を読む capability は失敗する可能性が高い。
.env を用意するGitea issue を使うには、対象プロジェクトの .env または Butler プロセスの環境変数に次が必要である。
GITEA_URL=https://gitea.example.com
GITEA_TOKEN_DEFAULT=...
token は次の順に探索される。
GITEA_TOKEN_<CLIENT>GITEA_TOKEN_DEFAULTGITEA_TOKEN_AI通常は GITEA_TOKEN_DEFAULT か GITEA_TOKEN_AI を使うのが扱いやすい。
注意:
.env は .gitignore に入れる.env には GITEA_URL だけで足りることがあるGITEA_URL がないと Environment variable GITEA_URL is not set で失敗するNo Gitea token is configured で失敗するissue_create() を使うプロジェクトには、次のディレクトリを用意する。
.gitea/ISSUE_TEMPLATE/
最低限、既存の正常稼働プロジェクトから次のようなテンプレートを移植するとよい。
bug.mdfeature.mddesign.mdテンプレートには、Butler が issue の状態を扱いやすいように次の見出しを入れておく。
## 現在の状態(なぜOpenか)
## 次にすること(Next Action)
## ブロック要因
この 3 見出しがあると、後続の issue_read()、issue_comment()、work_start()、handover 系の運用に繋げやすい。
issue_create(label_names=[...]) で指定できるのは、対象 Gitea repo に既に存在する label だけである。
.gitea/ISSUE_TEMPLATE/*.md の front matter に labels: を書いていても、repo 側に label が未作成なら label_not_found で失敗する。
確認するもの:
.gitea/ISSUE_TEMPLATE/*.md の labels: に書かれている label 名典型例:
labels: 機能
labels: バグ
labels: "種別: 設計待ち"
label_not_found が出た場合は、issue 本文や template だけでなく、Gitea repo の label 設定を確認する。
Butler MCP の issue tool は既存 label を issue に付けることはできるが、label 自体の作成は現時点では専用 tool として公開されていない場合がある。その場合は Gitea Web UI または Gitea API で label を作成してから再実行する。
他プロジェクトの label を確認するときは、Butler の作業セッションがどの project_root / repo を向いているかに注意する。別プロジェクトで work_session_start(project_root=...) した後は、そのまま issue 系 tool が別 repo を向く可能性があるため、対象プロジェクトで再度 work_session_start(project_root=...) してから確認する。
Gitea repo の has_projects: true(Project unit が UI 上有効)は、API から Project を操作できることを意味しない。API path が swagger 上に公開されていない Gitea では Project ボード作成・Issue の Project 追加を自動化できず、UI での手動作成が必要になる(issue #80 / docs/検討用/80_Gitea_Project_API対応実装案.md)。
複数の探索、試作、方針転換、やり直しを Project ボードに依存せず追跡する場合は、Butler の Track Ledger を使う。親 Issue の初期化、子 track の開始・記録・完了、Issue 間 relation、整合性確認までの手順は Track Ledger 運用マニュアル を参照する。
handover や session 系を使う場合は、次のディレクトリが対象プロジェクトにあるか確認する。
session_logs/
存在しない場合でも capability 側で作成されることはあるが、inspect_runtime_config() で存在を確認しておくと切り分けがしやすい。
設定後、対象プロジェクトでまず読み取り系を試す。
work_session_start(project_root="/path/to/project")
issue_list(state="open", limit=3)
work_observe()
work_session_start() の返値に含まれる brain_id は、Butler 上で handover の照合に使う現在の Brain ID の正本である。Handover の client / target_brain には自己呼称や推測した名前ではなく、この brain_id または handover_list_brains() に出る値を使う。
特に handover_accept() では、明示的な理由がなければ client を省略する。client を明示すると session.brain_id を override するため、指定する場合は必ず work_session_start() の返値か handover_list_brains() で確認した値を使う。
ここまで成功して初めて、対象プロジェクトで Butler の実用機能が使える状態と判断する。
issue 起票が目的なら、いきなり長い本文を投げず、まず短い本文で issue_create() を確認する。
本文には最低限、次を含める。
## 現在の状態(なぜOpenか)
疎通確認用。
## 次にすること(Next Action)
作成できることを確認する。
## ブロック要因
なし
成功したら、実際の issue 本文を起票する。
| 症状 | 意味 | 対応 |
|---|---|---|
butler_version() は成功するが issue_create() が失敗する |
MCP 接続はできているが Gitea 設定が不足している | .env と token を確認する |
Environment variable GITEA_URL is not set |
GITEA_URL が見えていない |
対象プロジェクト .env または Butler 起動環境に追加する |
No Gitea token is configured |
token が見えていない | GITEA_TOKEN_DEFAULT または GITEA_TOKEN_AI を設定する |
issue_template_dir.exists=false |
issue template がない | .gitea/ISSUE_TEMPLATE/ を作る |
label_not_found |
指定した label が対象 Gitea repo に存在しない | repo 側で label を作成するか、既存 label 名に合わせる |
resolved_repo が想定と違う |
git remote から repo 解決がずれている | git remote -v を確認する |
対象プロジェクトで次がすべて満たされていれば、「Butler を使える状態」と判断してよい。
inspect_runtime_config(project_root) で env_path と issue_template_dir が期待どおりwork_session_start(project_root) が成功するissue_list() が成功するissue_create() が成功するwork_observe() が対象プロジェクトの状態を返す最初は副作用の小さい task から始める。
read_from_gitea の読み取り系session_log の読み取りや開始wiki の読み取り系implement は強力だが、最初の疎通確認には重い。
まずは軽い capability で Butler 自体が呼べることを確認し、そのあとで小さな implement task に進むのが安全である。
implement を使う時の注意implement は Maid を起動し、監督し、検証まで含めて返す長時間 task になりやすい。
MCP 経由でも動くが、次の点は理解して使う。
GOOSE_COMMAND と OPENROUTER_API_KEY(または接続先の API キー)gemini CLI で Google ログイン済みであること、GOOGLE_GENAI_USE_GCA=true / GEMINI_CLI_TRUST_WORKSPACE=true を設定要するに、MCP 化しても implement の本体監督は失われていないが、
UI から見える進捗表示はまだ簡素である。
implement とレビューの境界implement は、レビュー判断そのものを Butler に丸投げするための入口ではない。
Butler / Maid が担うのは、実装、差分確認、変更ファイル列挙、機械的チェック、レビュー用の根拠収集までである。
次は Brain の責務として残す。
したがって Brain は「レビューして」と抽象的に渡すのではなく、
「この差分の変更ファイルを列挙する」「この観点で機械的チェックを行う」「根拠付きの観測事項を出す」のように、
観測可能な下請け task に分解して Butler を使うのがよい。
Gemini CLI Maid は execution_profile: gemini_cli_trial を run_implement に指定した時だけ起動する(研究枠)。
指定なしの場合は通常の Goose route に流れる。
認証の準備(事前に一度だけ):
gemini # 対話モードで Google アカウントにログイン
ログイン後、以下の環境変数が必要:
GOOGLE_GENAI_USE_GCA=true
GEMINI_CLI_TRUST_WORKSPACE=true
利用枠(Google AI Pro):
切り戻し方法:
run_implement から execution_profile 引数を外すだけで Goose route に戻るconfig/maid_registry.yml の gemini_cli_implement.enabled を false にして MCP を再起動するButler は docs/**/*.md を Wiki.js へ同期する機能を持つ。
接続設定は .env の WIKIJS_URL と WIKIJS_TOKEN から読む。
work_publish() を呼んだとき、push 対象のコミットに docs/ ファイルが含まれていれば
自動的に Wiki.js へ同期が走る。
data.wiki_sync で確認できる(triggered / created_pages / updated_pages / failed_pages)push を伴わずに docs を wiki に反映したい時は wiki_sync() を使う。
wiki_sync() — docs/**/*.md を全件同期する
wiki_sync(dry_run=true) — 書き込まず、対象ページ一覧だけ返す
典型的な使いどころ:
repo の docs/ より下の相対パスが wiki path にそのまま対応する。
docs/README.md → <repo_slug>
docs/capabilities/wiki/仕様書.md → <repo_slug>/capabilities/wiki/仕様書
ファイル名にスペースが含まれる場合は - に置換される。
project_root と設定ファイルの場所を確認するimplement は最後に小さく試すこの順序を守ると、環境不足と task 設計不足を切り分けやすい。
Butler を使う Brain は以下の3つのルールに従うこと。
これらは Butler サーバー側(MCP Instructions)でも明示されているが、
Brain が「なぜそうするか」を理解して守ることが前提である。
git コマンドを直接実行しない。Butler の作業記録ツールを使う。
| やりたいこと | 使うツール |
|---|---|
| 状態確認 | work_observe() |
| 差分確認 | work_diff() |
| 履歴確認 | work_history() |
| コミット | work_record(message) |
| プッシュ | work_publish() |
| 上記以外の git 操作 | work_vcs(args) |
理由: raw git では作業記録・issue 紐付け・Wiki 同期が漏れる。Butler 経由で完結させる。
python / pip / python3 コマンドを直接使わず、uv 経由で実行する。
uv run python script.py # スクリプト実行
uv run pytest # テスト実行
uv run ruff check . # linter 実行
uv add <package> # パッケージ追加
uv pip install <package> # pip install 相当
理由: グローバル環境を汚さず、仮想環境と lockfile を一貫して管理するため。
調査・検討の途中経過を issue_comment() で記録する。
最終結果だけを残すのではなく、途中の判断・根拠・方針変更も残す。
記録するタイミングの例:
理由: 後から読む Brain やユーザーが「なぜその実装になったか」を追跡できるようにするため。
handover でのコンテキスト引き継ぎ品質も上がる。