butler-mcp
v0.1.6
Published
MCP server for Butler: Google Drive/Sheets task management and butler config
Readme
butler-mcp
MCP server for Butler: Google Drive / Google Sheets 連携でタスク台帳と執事設定を扱う。
Cursor 等の MCP クライアントから npx butler-mcp で起動する。
セットアップ
依存のインストール
npm install必須
- driveRootId … Butler 用ルートフォルダの Google Drive フォルダ ID(必須)
- spreadsheetId … 省略可。省略時は Drive 内で名前
"Tasks"のスプレッドシートを検索し、なければ自動作成 - credentialsPath … サービスアカウント JSON のパス(任意。未指定時は環境変数
GOOGLE_APPLICATION_CREDENTIALSを参照)
設定ファイル(任意)
npx butler-mcp --config ./butler.config.jsonJSON 例:
{ "driveRootId": "...", "credentialsPath": "/path/to/key.json" }(spreadsheetId は任意)
Google Drive / Sheets の認証(サービスアカウント)
butler-mcp は サービスアカウント で Google API にアクセスする。手順は次のとおり。
1. Google Cloud でプロジェクトを作る
- Google Cloud Console にログイン
- 画面上部のプロジェクト選択 → 新しいプロジェクト で作成(例:
butler-mcp)
2. API を有効にする
- API とサービス → ライブラリ
- Google Drive API を検索 → 有効にする
- 同様に Google Sheets API を検索 → 有効にする
3. サービスアカウントとキーを作る
- API とサービス → 認証情報 → 認証情報を作成 → サービスアカウント
- 名前(例:
butler-mcp)を入れて 作成 - ロールは省略で OK → 完了
- 一覧で作ったサービスアカウントをクリック → キー タブ
- 鍵を追加 → 新しい鍵を作成 → JSON を選んで 作成
- ダウンロードされた JSON ファイルを安全な場所に保存(例:
~/butler-service-account.json)
この JSON が 秘密鍵。Git にコミットしたり公開しないこと。
4. Drive のフォルダをサービスアカウントに共有する
サービスアカウントは「別の Google アカウント」なので、あなたの Drive のフォルダを共有しないとアクセスできない。
- Google Drive で Butler 用のルートフォルダ(例:
Butler)を作成 - フォルダを右クリック → 共有
- ユーザーやグループを追加 に、サービスアカウントの メールアドレス を入力
(JSON 内のclient_emailの値。例:[email protected]) - 権限を 編集者 にして 送信
- フォルダの URL から フォルダ ID を取得
例:https://drive.google.com/drive/folders/1ABC...xyz→1ABC...xyzがdriveRootId
5. butler-mcp に渡す
- 環境変数:
GOOGLE_APPLICATION_CREDENTIALS=/path/to/サービスアカウント.json - または args:
--credentialsPathに上記 JSON の絶対パスを指定(MCP 設定で渡す)
これで Drive / Sheets への認証が通る。
このリポジトリで googleCloudKey.json を使う場合
キーをリポジトリ直下の googleCloudKey.json に置いた場合の例(パスは環境に合わせて書き換えてね):
ターミナルで起動する場合
# リポジトリルート(TAISHO)で
export GOOGLE_APPLICATION_CREDENTIALS="$(pwd)/googleCloudKey.json"
cd butler-mcp && npx butler-mcp --driveRootId "あなたのDriveルートフォルダID"Cursor の MCP 設定(args で渡す)
googleCloudKey.json をリポジトリルートに置いているとき、--credentialsPath に 絶対パス を指定する:
"args": [
"butler-mcp",
"--driveRootId",
"あなたのDriveルートフォルダID",
"--credentialsPath",
"/Users/charu/Library/CloudStorage/Dropbox/mac_setting/work/private/TAISHO/googleCloudKey.json"
]※ googleCloudKey.json は .gitignore に入れてあるので Git にはコミットされない。
Cursor など MCP クライアントでの設定
args に キーと値を並べて 渡す(フラットな羅列):
{
"mcpServers": {
"butler-mcp": {
"command": "npx",
"args": [
"butler-mcp",
"--driveRootId",
"YOUR_DRIVE_ROOT_FOLDER_ID",
"--credentialsPath",
"/absolute/path/to/service-account.json"
]
}
}
}- --driveRootId … Butler 用 Drive ルートフォルダ ID(必須)
- --spreadsheetId … タスク台帳のスプレッドシート ID(任意。省略時は Drive 内で
"Tasks"を検索 or 作成) - --credentialsPath … 秘密鍵(サービスアカウント JSON)の絶対パス(任意。未指定時は環境変数
GOOGLE_APPLICATION_CREDENTIALS)
設定ファイルでまとめて渡す場合:
"args": ["butler-mcp", "--config", "/absolute/path/to/butler.config.json"]ビルド・実行
npm run build
npm start
# または
npx butler-mcp提供ツール(MCP)
- sheets.queryTasks … タスク一覧を条件付きで取得(status はカンマ区切り or JSON 配列文字列、due_date_before, priority, limit)
- sheets.addTask … タスク 1 件追加(title 必須)。成功時に監査ログへ追記
- sheets.updateTask … タスク更新(id, dryRun, patch)。patch は JSON 文字列(例:
{"status":"Done"})。dryRun=true で diff のみ返却。 - drive.search … Butler ルート配下のファイル検索(query オプション)
- drive.readFile … fileId または path(例:
config/persona.yml)でファイル内容取得 - drive.writeFile … path, content, mode(create|replace|append)で書き込み。成功時に監査ログへ追記
- drive.getConfigBundle … persona / policies / templates を Drive から取得(執事名は persona.name)
- drive.updateConfig … target=persona|policies, patch(JSON 文字列), dryRun 必須で設定更新。適用時に監査ログへ追記
- drive.guideInitialSetup … 執事の初期設定ナビ。config が無いときに質問を返し、回答を name / tone / wip_limit で渡して繰り返し呼ぶと、最後に Drive に config/persona.yml と config/policies.yml を作成する
監査ログは Butler/history/audit-log.ndjson に NDJSON で追記される。
テスト
npm test(スコープガード・Diff・Persona/Policies スキーマ検証の単体テスト)
トラブルシューティング
- Agent モードでツールが呼べない場合の原因と対処: docs/トラブルシューティング.md
仕様・設計
- 要件・設計・タスク: リポジトリルートの
.spec-workflow/specs/butler-mcp/を参照 - 開発は TDD(テスト先行)。スコープガード・Diff は単体テストあり
