Skip to main content
Glama
README.md
# Task API MCP

[English](README.en.md)

既存REST APIをAIクライアントから利用するための、ローカル実行可能なPythonサンプルです。FastAPIで作られたタスク管理APIを正規の入り口として残し、stdio MCPサーバーは `create_task` ToolとHTTPの間を変換する薄いアダプターとして動作します。

> このリポジトリは学習・ローカル検証用です。認証、複数プロセス対応、冪等性など、実運用で必要になる機能は意図的に含めていません。

最終更新: 2026-07-15

## できること

- `POST /tasks` でタスクを作成し、`data/tasks.json` へ保存する
- `GET /tasks` と `GET /tasks/{task_id}` でタスクを確認する
- MCPの `create_task` Toolから同じREST APIを呼び出す
- 入力エラー、一時障害、想定外レスポンスを安全なMCPエラーへ変換する
- 実サーバーを使わず、API・HTTP・MCP各層を自動テストする

## アーキテクチャ

```mermaid
flowchart LR
    User[ユーザー] -->|自然言語| AI[AIクライアント]
    AI -->|MCP / stdio| MCP[task_mcp]
    MCP -->|HTTP POST /tasks| API[task_api]
    API --> JSON[(data/tasks.json)]
```

| コンポーネント | 責務 |
|---|---|
| AIクライアント | 自然言語をTool引数へ変換する |
| `task_mcp` | Tool Schemaを公開し、MCPとHTTPを変換する |
| `task_api` | 入力・業務ルールを検証し、タスクを作成する |
| `data/tasks.json` | ローカル環境でタスクを永続化する |

MCPサーバーはJSONファイルを直接変更しません。保存処理と過去日付の禁止はREST API側にだけ実装されています。

## クイックスタート

### 必要なもの

- Python 3.10以上
- [uv](https://docs.astral.sh/uv/getting-started/installation/)
- Node.js 18以上(MCP Inspectorを使う場合のみ)
- Codex CLI(Codexから試す場合のみ)

### 1. 依存関係をインストールする

リポジトリをcloneしたディレクトリで実行します。

```bash
cd task-api-mcp
uv sync --dev
```

`uv.lock` が含まれているため、記事と同じ `mcp[cli]==1.28.1` を含む検証済みの依存関係がインストールされます。

### 2. REST APIを起動する

```bash
uv run task-api
```

開発中に自動リロードを使う場合は、代わりに次を実行します。

```bash
uv run uvicorn task_api.app:app --reload --port 8000
```

APIは `http://localhost:8000` で起動します。Swagger UIは [http://localhost:8000/docs](http://localhost:8000/docs) です。

### 3. タスクを作成する

別のターミナルで実行します。

```bash
curl -X POST http://localhost:8000/tasks \
  -H "Content-Type: application/json" \
  -d '{
    "title": "MCPの記事を公開する",
    "description": "図とコードを最終確認する",
    "priority": "high"
  }'
```

`201 Created` と、次のようなタスクが返れば成功です。

```json
{
  "id": "b48b8da3-f80b-40e3-a78d-8d70b11e58c4",
  "title": "MCPの記事を公開する",
  "description": "図とコードを最終確認する",
  "priority": "high",
  "due_date": null,
  "status": "todo",
  "created_at": "2026-07-15T21:30:00+09:00"
}
```

作成結果は `data/tasks.json` に保存されます。

## MCP Inspectorで試す

REST APIを起動したまま、別のターミナルで実行します。

```bash
TASK_API_BASE_URL=http://localhost:8000 \
npx -y @modelcontextprotocol/inspector \
uv run python -m task_mcp.server
```

Inspectorで次を確認できます。

1. `Tools` から `create_task` を選ぶ
2. `title` が必須であることを確認する
3. `priority` が `low` / `medium` / `high` のenumであることを確認する
4. `due_date` に今日以降の日付を入力して実行する

## Codex CLIへ登録する

リポジトリのルートで次を実行します。

```bash
codex mcp add task-manager \
  --env TASK_API_BASE_URL=http://localhost:8000 \
  --env TASK_API_TIMEOUT_SECONDS=10 \
  -- uv run python -m task_mcp.server
```

登録結果を確認します。

```bash
codex mcp list
```

その後、Codexへ次のように依頼できます。

```text
明日までに「MCPの記事を公開する」というタスクを作成してください。
優先度はhighにしてください。
```

Codexの設定方法は[公式MCPドキュメント](https://developers.openai.com/codex/mcp)も参照してください。

## REST APIリファレンス

ベースURL: `http://localhost:8000`

認証: なし(ローカルデモのみ)

| メソッド | パス | 成功時 | 説明 |
|---|---|---:|---|
| `POST` | `/tasks` | `201` | タスクを作成する |
| `GET` | `/tasks` | `200` | 全タスクを作成順で返す |
| `GET` | `/tasks/{task_id}` | `200` | IDでタスクを1件取得する |

### `POST /tasks` の入力

| フィールド | 型 | 必須 | デフォルト | 制約 |
|---|---|---:|---|---|
| `title` | string | はい | — | 空白除去後1〜100文字 |
| `description` | string / null | いいえ | `null` | 最大1000文字 |
| `priority` | string | いいえ | `medium` | `low`, `medium`, `high` |
| `due_date` | string / null | いいえ | `null` | `YYYY-MM-DD`、今日以降 |

未知のフィールドは受け付けません。時刻は保存しないため、「明日の17時」の17時部分は `due_date` には入りません。

### 主なエラー

| 状態 | HTTP | MCPでの扱い |
|---|---:|---|
| 必須・型・文字数・enum・日付形式の不正 | `422` | 通常はTool Schemaで先に検出 |
| 過去の `due_date` | `422` | 修正可能な `ToolError` |
| 存在しないタスク | `404` | `GET` APIのみ |
| JSON保存障害 | `500` | 一時的な利用不能 |
| APIタイムアウト・接続失敗 | — | 一時的な利用不能 |
| 不正JSON・未知のHTTP状態 | — | 詳細を隠した想定外エラー |

## 設定

| 環境変数 | デフォルト | 使用箇所 | 説明 |
|---|---|---|---|
| `TASK_API_BASE_URL` | `http://localhost:8000` | MCP | 接続先REST API |
| `TASK_API_TIMEOUT_SECONDS` | `10` | MCP | HTTPタイムアウト秒数。0より大きい数値 |
| `TASK_API_DATA_FILE` | `data/tasks.json` | REST API | JSON保存先 |

`.env.example` を使う場合、uvへ明示的に渡します。

```bash
cp .env.example .env
uv run --env-file .env task-api
```

MCPサーバーにも同じ方法を使えます。

```bash
uv run --env-file .env task-mcp
```

## プロジェクト構成

```text
task-api-mcp/
├── data/tasks.json              # ローカルのタスクデータ
├── docs/plans/                  # 設計判断
├── src/
│   ├── task_api/
│   │   ├── app.py               # FastAPIのルートと起動処理
│   │   ├── models.py            # REST APIの入出力モデル
│   │   └── repository.py        # JSON永続化
│   └── task_mcp/
│       ├── api_client.py        # 非同期REST APIクライアント
│       ├── errors.py            # HTTP結果の意味的なエラー分類
│       ├── models.py            # MCP境界の構造化モデル
│       └── server.py            # create_task Toolとstdio起動処理
├── tests/                       # API、HTTP、MCPのテスト
├── .env.example                 # 環境変数の例
├── pyproject.toml               # パッケージと依存関係
└── uv.lock                      # 解決済み依存関係
```

## テスト

```bash
uv run pytest
```

テストでは一時ディレクトリと `httpx.MockTransport` を使うため、起動中のAPIや既存の `data/tasks.json` は変更しません。

## トラブルシューティング

### `Address already in use` と表示される

ポート8000を使用中のプロセスを停止するか、別ポートでAPIを起動し、MCP側のURLも合わせます。

```bash
uv run uvicorn task_api.app:app --port 8001
TASK_API_BASE_URL=http://localhost:8001 uv run task-mcp
```

### MCPから `temporarily unavailable` が返る

REST APIが起動していることと、`TASK_API_BASE_URL` が正しいことを確認してください。コンテナ内から接続する場合、`localhost` はコンテナ自身を指します。

### `due_date must be today or later` が返る

`due_date` をAPIが動作している環境の今日以降へ変更してください。

### `Task storage is unavailable` が返る

`TASK_API_DATA_FILE` の親ディレクトリへ書き込めることと、既存ファイルがJSON配列であることを確認してください。デモデータを破棄してよければ、API停止後に `data/tasks.json` を削除できます。次回作成時に再生成されます。

## 実運用へ進む前に

- JSONファイルをトランザクションと複数プロセスに対応したデータベースへ置き換える
- API認証情報をTool引数ではなく、環境変数またはシークレットストアから取得する
- REST API側へ冪等性キー、重複検出、監査ログ、レート制限を追加する
- リモート利用ではstdioではなく、認証とOrigin検証を備えたStreamable HTTPを検討する

## ライセンス

[MIT License](LICENSE)

TDQS

B3.3/5.0

Scored across 1 tool

Disambiguation5/5

Only one tool exists, so there is no possibility of confusion or overlap.

Naming Consistency5/5

With a single tool, naming is trivially consistent; no pattern violations occur.

Tool Count2/5

A task management service with only one creation tool is too thin; typical requires at least list, read, update, and delete operations.

Completeness2/5

The tool surface lacks critical operations like listing, retrieving, updating, and deleting tasks, leaving significant gaps for agents.

Maintenance

ActivitySlowing
ResponsivenessNo issues