# MCP・API 連携ガイド Pyunto Time Management は **MCP(Model Context Protocol)** に対応しています。 Claude Code・Claude Desktop・Codex CLI・Cursor といった AI クライアントに接続すると、 自然言語で次のようなことができます。 > 「今週、どのプロジェクトに何時間使った?」 > 「昨日の作業内容から日報を書いて」 > 「さっきの1時間半を Alpha プロジェクトの『設計』タスクに記録して」 - 日本語ガイド: [使い方ガイド](./guide.ja.md) - English: [MCP integration guide](./mcp.en.md) --- ## 1. できること(提供ツール) | ツール | 内容 | 必要なスコープ | |---|---|---| | `whoami` | 接続中のアカウント・キー名・権限・復号可否を返す | (なし) | | `list_projects` | プロジェクト一覧(id・名前・色・権限) | `projects:read` | | `list_tasks` | ガントのタスク/サブタスク一覧。日付での絞り込み可 | `projects:read` | | `list_time_blocks` | 指定期間の予定ブロック明細(開始・終了・メモ) | `blocks:read` | | `time_summary` | 指定期間の合計時間を**プロジェクト別/タスク別/日別**に集計 | `record:read` | | `log_time` | 作業時間を記録する(**書き込み**) | `blocks:write` | | `update_time_block` | 記録済みの時刻・メモ・タスク紐付けを**変更**する | `blocks:write` | | `delete_time_block` | 記録を**1件だけ削除**する | `blocks:delete` | | `list_deleted_time_blocks` | 削除済みで**まだ復元できる**ものの一覧 | `blocks:read` | | `restore_time_block` | 削除した記録を**元に戻す** | `blocks:write` | 期間指定は最大 92 日です。書き込み系のツールは実際のカレンダーを変更するため、 AI 側には「実行前にユーザに内容を確認する」よう指示しています。 > ⚠ **削除は14日以内なら復元できます。** 削除しても即座に消えるわけではなく、 > 14日間は `restore_time_block` で元に戻せます(添付ファイルも一緒に戻ります)。 > **14日を過ぎると完全に削除**され、以後は復元できません。 > `delete_time_block` のツール説明には、 > 「削除する前に、対象ブロックの日付・時刻・プロジェクト・タスク・メモを > ユーザに提示し、そのブロックについて明確な同意を得ること」「範囲でまとめて > 消さず、1件ずつ確認すること」を明記しています。範囲指定の一括削除は > **提供していません**(AI が範囲を誤ったときの被害が桁違いになるため)。 --- ## 2. 準備:API キーを発行する 1. にログイン 2. **設定 → アカウント → API キー** 3. 名前(例: `claude-code`)を入力し、**スコープ**を選びます 推奨スコープ: | 用途 | 選ぶスコープ | |---|---| | 読み取りだけ(日報生成・集計) | `projects:read` `blocks:read` `record:read` | | 記録・修正もさせる | 上記 + `blocks:write` | | 削除もさせる | 上記 + `blocks:delete`(**慎重に**。下記の注意を参照) | | プロジェクト名・タスク名・メモも読ませる(E2EE アカウント) | 上記 + `keys:read` | 4. 「作成」を押すと `ptm_…` で始まるキーが**一度だけ**表示されます。 その場でコピーして安全に保管してください。 --- ## 3. E2EE と名前の復号について Pyunto Time Management はエンドツーエンド暗号化されているため、 **サーバは名前やメモの中身を持っていません**。したがって MCP サーバも、 そのままでは以下のようになります。 | 項目 | 鍵なし | 鍵あり | |---|---|---| | 日付・時刻・所要時間・合計 | ✅ 読める | ✅ 読める | | プロジェクト名・タスク名・メモ | ❌ 空になる | ✅ 読める | 名前まで読ませたい場合は、API キーに `keys:read` を付けたうえで、 **アカウントのパスワードを MCP サーバに渡します**。 パスワードは**あなたの PC の中だけ**で使われます。サーバから受け取るのは 「パスワードで包まれた秘密鍵」であり、それをローカルで開くためだけに使われます。 パスワードがネットワークに送られることはありません。 パスワードを設定に書きたくない場合は、ファイルに保存してパスを渡せます (`PYUNTO_TM_PASSWORD_FILE`)。名前が不要なら、パスワードは設定不要です。 --- ## 4. インストール **事前にインストールする作業はありません。** MCP サーバは npm で公開されており、 各クライアントの設定に書いた `npx` コマンドから自動的に取得・実行されます。 必要なのは **Node.js 18 以上**だけです。 ### Node.js が入っているか確認する ターミナルを開いて `node -v` を実行します。 - **macOS**: アプリケーション → ユーティリティ → **ターミナル** - **Windows**: スタートメニューで「PowerShell」と入力して起動 ```bash node -v ``` - `v18.0.0` 以上が表示されれば準備完了です - `command not found` / `認識されていません` と出る場合は未インストールです。 から **LTS 版**のインストーラを入手して実行してください (画面の指示に従うだけです)。インストール後、**ターミナルを開き直してから** もう一度 `node -v` を確認します > **Claude Desktop をお使いの方へ。** インストーラ版(nodejs.org)を使うことを > 勧めます。Homebrew や nvm で入れた Node は、Claude Desktop からは見つからない > ことがあります(下の「6. Claude Desktop から使う」の注記を参照)。 MCP サーバのソースコードは公開されています。 - リポジトリ: (MIT ライセンス) - npm: `@pyunto/tm-mcp`(MCP サーバ)、`@pyunto/tm-sdk`(REST クライアント) パスワードを預ける相手なので、**中身を確認できることには意味があります**。 「パスワードは端末から出ない」という説明は、上記リポジトリの `mcp/src/index.ts` と `sdk/src/crypto.ts` で検証できます。 なお、Pyunto Time Management 本体(サーバ側)は非公開です。公開しているのは クライアント側、つまり公開 API を呼ぶ部分と、自分のデータを手元で復号する部分 だけです。
ソースからビルドして使う場合 ```bash git clone https://github.com/pyunto/tm-integrations cd tm-integrations && npm install && npm run build ``` 以降の設定では `npx -y @pyunto/tm-mcp` の代わりに、 `node /絶対パス/tm-integrations/mcp/dist/cli.js` を指定してください。
--- ## 5. Claude Code から使う プロジェクトのディレクトリで、次のコマンドを実行します。 ```bash claude mcp add pyunto-tm \ --env PYUNTO_TM_API_KEY=ptm_あなたのキー \ --env PYUNTO_TM_PASSWORD=あなたのパスワード \ -- npx -y @pyunto/tm-mcp ``` `--env PYUNTO_TM_PASSWORD=…` は名前の復号が不要なら省略できます。 全プロジェクトで使いたい場合は `--scope user` を付けてください。 設定ファイルを直接書く場合は `~/.claude.json`(または プロジェクトの `.mcp.json`)に次を追加します。 ```json { "mcpServers": { "pyunto-tm": { "command": "npx", "args": ["-y", "@pyunto/tm-mcp"], "env": { "PYUNTO_TM_API_KEY": "ptm_あなたのキー", "PYUNTO_TM_PASSWORD": "あなたのパスワード" } } } } ``` 接続を確認します。 ```bash claude mcp list # pyunto-tm が ✓ connected と表示される ``` Claude Code のセッション内では `/mcp` でも状態を確認できます。あとは普通に 話しかけてください。 ``` > 今週の作業時間をプロジェクト別に出して > 今日 14:00 から 15:30 まで Alpha の「設計」に記録して ``` --- ## 6. Claude Desktop から使う 設定ファイルを開きます。 - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json` - Windows: `%APPDATA%\Claude\claude_desktop_config.json` 上の「設定ファイルを直接書く場合」と同じ JSON を追加し、**Claude Desktop を 再起動**してください。入力欄のツールアイコンに `pyunto-tm` が現れます。 ### `npx` が見つからずサーバが起動しない場合 Claude Desktop はデスクトップアプリなので、**ターミナルとは別の(最小限の) PATH** で MCP サーバを起動します。ターミナルでは `npx` が使えるのに Claude Desktop からは「起動に失敗した」となる場合、これが原因です。 Homebrew(`/opt/homebrew/bin`)や nvm(`~/.nvm/…`)で入れた Node で起きます。 対処は、**`npx` の絶対パスを設定に書く**ことです。まずターミナルで場所を調べます。 ```bash which npx # 例: /usr/local/bin/npx, /opt/homebrew/bin/npx ``` その結果を `command` にそのまま書きます。 ```json { "mcpServers": { "pyunto-tm": { "command": "/opt/homebrew/bin/npx", "args": ["-y", "@pyunto/tm-mcp"], "env": { "PYUNTO_TM_API_KEY": "ptm_あなたのキー" } } } } ``` nvm をお使いの場合、`npx` はバージョン切り替え用の仕組みに依存しているため、 絶対パスを書いても動かないことがあります。その場合は の **LTS 版インストーラ**で Node を入れ直すのが 確実です(`/usr/local/bin` に入り、Claude Desktop からも見えます)。 --- ## 7. Codex CLI から使う `~/.codex/config.toml` に追記します。 ```toml [mcp_servers.pyunto_tm] command = "npx" args = ["-y", "@pyunto/tm-mcp"] env = { PYUNTO_TM_API_KEY = "ptm_あなたのキー", PYUNTO_TM_PASSWORD = "あなたのパスワード" } ``` コマンドラインからも追加できます。 ```bash codex mcp add pyunto-tm \ --env PYUNTO_TM_API_KEY=ptm_あなたのキー \ -- npx -y @pyunto/tm-mcp codex mcp list ``` > TOML のキー名にハイフンは使えないため、セクション名は `pyunto_tm` としています。 --- ## 8. その他のクライアント(Cursor など) MCP の stdio 方式に対応したクライアントであれば、共通の形で設定できます。 | 項目 | 値 | |---|---| | コマンド | `npx` | | 引数 | `-y` `@pyunto/tm-mcp` | | 環境変数 | `PYUNTO_TM_API_KEY`(必須)、`PYUNTO_TM_PASSWORD`(任意)、`PYUNTO_TM_BASE_URL`(自己ホスト時) | Cursor の場合は `.cursor/mcp.json` に、Claude Desktop と同じ形式で記述します。 --- ## 9. 環境変数の一覧 | 変数 | 必須 | 既定値 | 説明 | |---|---|---|---| | `PYUNTO_TM_API_KEY` | ✅ | — | `ptm_…` で始まる API キー | | `PYUNTO_TM_BASE_URL` | | `https://tm.pyunto.com` | 自己ホスト時のみ変更 | | `PYUNTO_TM_PASSWORD` | | (なし) | 名前・メモの復号用。ローカルでのみ使用 | | `PYUNTO_TM_PASSWORD_FILE` | | (なし) | パスワードを書いたファイルのパス(設定に平文で書きたくない場合) | --- ## 10. うまく動かないとき まず AI に **「whoami を実行して」**と頼んでください。接続先・キー名・ 付与されているスコープ・復号の可否が一度に分かります。 | 症状 | 原因と対処 | |---|---| | `the API key is missing, wrong or revoked` | `PYUNTO_TM_API_KEY` の誤り、または設定画面で失効済み。再発行してください | | `API key lacks scope 'blocks:write'` | キーの権限不足。必要なスコープを付けたキーを作り直します | | 名前が空で返る | E2EE のため。`keys:read` スコープ+`PYUNTO_TM_PASSWORD` を設定します | | `unlock failed` | パスワードが違うか、キーに `keys:read` がありません | | `rate limited` | 1キーあたり毎分240リクエストの上限です。少し待って再実行します | | クライアントに現れない | `node -v` が 18 以上か、`npx -y @pyunto/tm-mcp` を直接実行できるかを確認します。ターミナルでは動くのに Claude Desktop でだけ失敗する場合は PATH の問題です(「6. Claude Desktop」の注記を参照)。社内プロキシ等で npm レジストリに到達できない場合は「ソースからビルド」を使ってください | | `node` / `npx` が見つからない | Node.js が未インストールです。 の LTS 版インストーラを実行し、ターミナルを開き直してください | サーバ側のログは MCP クライアントのログに出ます(Claude Code なら `/mcp`、 Claude Desktop なら「MCP ログ」)。 --- ## 11. REST API を直接使う MCP を介さず、任意のプログラムから利用することもできます。 ```bash curl -H "Authorization: Bearer ptm_あなたのキー" \ "https://tm.pyunto.com/api/v1/service-record?date_from=2026-08-01&date_to=2026-08-31" ``` | エンドポイント | 内容 | スコープ | |---|---|---| | `GET /api/v1/me` | キーの情報 | — | | `GET /api/v1/projects` | プロジェクト一覧 | `projects:read` | | `GET /api/v1/tasks` | タスク一覧 | `projects:read` | | `GET /api/v1/blocks` | 予定ブロック(`date_from` / `date_to`) | `blocks:read` | | `POST /api/v1/blocks` | 予定ブロックの作成 | `blocks:write` | | `PATCH /api/v1/blocks/{id}` | 予定ブロックの変更 | `blocks:write` | | `DELETE /api/v1/blocks/{id}` | 予定ブロックの削除(1件・14日間は復元可) | `blocks:delete` | | `GET /api/v1/blocks/deleted` | 復元できる削除済みブロックの一覧 | `blocks:read` | | `POST /api/v1/blocks/{id}/restore` | 削除の取り消し | `blocks:write` | | `GET /api/v1/service-record` | 日別・プロジェクト別の集計 | `record:read` | | `GET /api/v1/keys` | パスワードで包まれた鍵素材 | `keys:read` | TypeScript から使う場合は、復号まで面倒を見る SDK が npm にあります (MIT ライセンス / ソースは上記リポジトリ)。 ```bash npm install @pyunto/tm-sdk ``` ```ts import { PyuntoTM } from "@pyunto/tm-sdk"; const tm = new PyuntoTM({ apiKey: process.env.PTM_KEY! }); await tm.unlock(process.env.PTM_PASSWORD!); // E2EE の名前を読む場合 const rows = await tm.serviceRecord("2026-08-01", "2026-08-31"); ``` --- ## 12. 安全のために - API キーはパスワードと同等に扱ってください。設定ファイルをリポジトリに コミットしないでください - 用途ごとにキーを分け、**必要最小限のスコープ**だけ付けてください。 読み取り専用の用途に `blocks:write` は不要です - 不要になったキーは、設定画面から**失効**させてください - `log_time` と `update_time_block` は実データに書き込みます。自動実行の前に 内容の確認を挟むことを推奨します - **`blocks:delete` は必要なときだけ付けてください。** `blocks:write` とは 別のスコープにしてあるのは、「記録させるだけ」のつもりで発行したキーが 削除権限まで持たないようにするためです。削除は14日間復元できますが、 それを過ぎると取り消せません --- *最終更新: 2026年8月 — このドキュメントは で公開されています。*