この文書は、butler2 自身ではない別プロジェクトから Butler を Ubuntu 環境で利用するための実務手順をまとめる。
外部プロジェクト利用で Butler core に渡せるパスは次の 5 つ。
project_rootconfig_direnv_pathissue_template_dirsession_logs_dir未指定時は project_root 基準で次が既定値になる。
| 項目 | 既定値 |
|---|---|
project_root |
Butler 自身の repo root |
config_dir |
<project_root>/config |
env_path |
<project_root>/.env |
issue_template_dir |
<project_root>/.gitea/ISSUE_TEMPLATE |
session_logs_dir |
<project_root>/session_logs |
他プロジェクトで使うときは、原則としてこれらを対象プロジェクト側に向ける。
最低限必要なのは次のファイル群。
config/maid_registry.ymlconfig/intent_maid_routes.yml.envintent に応じて追加で次を置く。
.gitea/ISSUE_TEMPLATE/session_logs/implement の検証コマンドを使うなら config/verifier_allowlist.ymlButler は config を自 repo 固定で読まず、指定された対象プロジェクト側の設定を読む。
target-project/
├─ .env
├─ config/
│ ├─ maid_registry.yml
│ ├─ intent_maid_routes.yml
│ └─ verifier_allowlist.yml
├─ .gitea/
│ └─ ISSUE_TEMPLATE/
└─ session_logs/
butler2 をインストール済みなら、task contract JSON を渡して対象プロジェクトに対して実行できる。
butler2 task.json \
--project-root /path/to/target-project \
--config-dir /path/to/target-project/config \
--env-path /path/to/target-project/.env \
--issue-template-dir /path/to/target-project/.gitea/ISSUE_TEMPLATE \
--session-logs-dir /path/to/target-project/session_logs
すべて既定配置なら、最低限これでも動く。
butler2 task.json --project-root /path/to/target-project
from butler import Constraints, TaskContract, execute_task
task = TaskContract(
task_id="external-gitea-1",
intent="read_from_gitea",
target={"service": "gitea"},
constraints=Constraints(max_minutes=1),
success_criteria=["issue を読める"],
delegation_mode="known_only",
requested_by="external-client",
requested_at="2026-04-04T00:00:00Z",
payload={
"operation": "list_issues",
"owner": "team",
"repo": "sample",
},
)
result = execute_task(
task,
project_root="/path/to/target-project",
config_dir="/path/to/target-project/config",
env_path="/path/to/target-project/.env",
issue_template_dir="/path/to/target-project/.gitea/ISSUE_TEMPLATE",
session_logs_dir="/path/to/target-project/session_logs",
)
同じ対象プロジェクトに繰り返し向けるなら、毎回引数を渡さず環境変数でも固定できる。
export BUTLER_PROJECT_ROOT=/path/to/target-project
export BUTLER_CONFIG_DIR=/path/to/target-project/config
export BUTLER_ENV_PATH=/path/to/target-project/.env
export BUTLER_ISSUE_TEMPLATE_DIR=/path/to/target-project/.gitea/ISSUE_TEMPLATE
export BUTLER_SESSION_LOGS_DIR=/path/to/target-project/session_logs
この状態では butler2 task.json や uv run butler2-mcp が対象プロジェクト設定を既定として使う。
MCP facade は execute_task tool を 1 つ公開する stdio server。
起動例:
uv run butler2-mcp
tool 呼び出し時に対象プロジェクトのパスを渡す。
{
"task": {
"task_id": "mcp-session-log",
"intent": "session_log",
"target": { "service": "local" },
"constraints": { "max_minutes": 1 },
"success_criteria": ["ok"],
"delegation_mode": "known_only",
"requested_by": "external-client",
"requested_at": "2026-04-04T00:00:00Z",
"payload": {
"operation": "start_session",
"client": "codex",
"session_id": "sess-1",
"title": "External Session"
}
},
"project_root": "/path/to/target-project",
"config_dir": "/path/to/target-project/config",
"env_path": "/path/to/target-project/.env",
"session_logs_dir": "/path/to/target-project/session_logs"
}
MCP client 側で起動設定を固定したい場合は、環境変数を使うのがいちばん薄い。
例:
{
"mcpServers": {
"butler": {
"command": "uv",
"args": ["run", "butler2-mcp"],
"env": {
"BUTLER_PROJECT_ROOT": "/path/to/target-project",
"BUTLER_CONFIG_DIR": "/path/to/target-project/config",
"BUTLER_ENV_PATH": "/path/to/target-project/.env",
"BUTLER_ISSUE_TEMPLATE_DIR": "/path/to/target-project/.gitea/ISSUE_TEMPLATE",
"BUTLER_SESSION_LOGS_DIR": "/path/to/target-project/session_logs"
}
}
}
}
この方式なら、tool call 側では task だけ渡してもよい。
butler_version() で Butler 本体の version 文字列を確認することbutler_version_info() で Butler 本体の読み込み元を確認することmaid_registry.yml の entrypoint が現在の butler2 実装と一致していることintent_maid_routes.yml に対象 intent の route があること.env に必要な接続情報が入っていることimplement を使う場合、検証コマンドが verifier_allowlist.yml に許可されていること