🚀 MyTaskly MCP Server
MyTaskly のためのモデルコンテキストプロトコル (MCP) サーバーです。OAuth 2.1 JWT 認証を採用し、FastAPI バックエンドとシームレスに統合されています。
✨ 主な機能
🔐 エンタープライズグレードの認証
- OAuth 2.1 JWT - MCP 2025 標準 (RFC 8707) に準拠したセキュアなトークンベースの認証
- マルチユーザーサポート - 単一のデプロイで JWT トークン検証を通じてすべてのユーザーにサービスを提供
- オーディエンスクレーム検証 - サービス間でのトークンの再利用を防止
🚀 高性能な統合
- HTTP API ゲートウェイ - FastAPI バックエンドと通信し、直接のデータベースアクセスは行いません
- ステートレスアーキテクチャ - セッション管理が不要で、完全にスケーラブル
- コネクションプーリング - 高スループットを実現する最適化された HTTP クライアント
📱 モバイルファーストなデザイン
- React Native 最適化 - ネイティブモバイルコンポーネント用にフォーマットされたデータを返します
- 音声対応レスポンス - チャットアプリケーションの TTS 用の音声要約を含みます
- 事前フォーマット済みの UI データ - 絵文字、色、フォーマットされた日付が表示準備完了
🛠️ 利用可能な MCP ツール (合計 20 個)
MCP サーバーは、包括的なタスク管理のために 5 つのカテゴリに分類された20 個のツールを提供します。
📋 タスクツール (8 個)
| ツール |
説明 |
認証が必要 |
get_tasks |
フィルター付きでタスクを取得 (React Native 用にフォーマット済み) |
✅ はい |
add_task |
スマートなカテゴリ管理で新しいタスクを作成 |
✅ はい |
update_task |
タスクフィールドを更新 |
✅ はい |
complete_task |
タスクを完了としてマークするためのクイックショートカット |
✅ はい |
get_task_stats |
統計情報 (合計、完了、優先度別) を取得 |
✅ はい |
get_next_due_task |
次の N 個の期限切れタスクを取得 |
✅ はい |
get_overdue_tasks |
すべての期限切れタスクを取得 |
✅ はい |
get_upcoming_tasks |
次の N 日以内に期限が迫っているタスクを取得 |
✅ はい |
get_tasks のレスポンス例:
{
"type": "task_list",
"tasks": [
{
"id": 123,
"title": "Pizza",
"endTimeFormatted": "Venerdì 15 dicembre, 18:00",
"category": "Cibo",
"categoryColor": "#EF4444",
"priority": "Alta",
"priorityEmoji": "⚡",
"status": "Pending",
"actions": {
"canEdit": true,
"canDelete": true,
"canComplete": true
}
}
],
"summary": {
"total": 10,
"pending": 5,
"completed": 3,
"high_priority": 2
},
"voice_summary": "Hai 10 task, di cui 2 ad alta priorità. 5 sono in sospeso e 3 completati."
}
📂 カテゴリツール (4 個)
| ツール |
説明 |
認証が必要 |
get_my_categories |
すべてのユーザーカテゴリを取得 |
✅ はい |
create_category |
新しいカテゴリを作成 |
✅ はい |
update_category |
ID でカテゴリを更新 |
✅ はい |
search_categories |
ファジーマッチングでカテゴリを検索 |
✅ はい |
get_my_categories のレスポンス例:
{
"categories": [
{
"category_id": 1,
"name": "Lavoro",
"description": "Task di lavoro",
"is_shared": true,
"owner_id": 1,
"permission_level": "READ_WRITE"
}
],
"total": 5,
"owned": 3,
"shared_with_me": 2
}
📝 ノートツール (4 個)
| ツール |
説明 |
認証が必要 |
get_notes |
すべてのユーザーノートを取得 |
✅ はい |
create_note |
新しいノート (付箋スタイル) を作成 |
✅ はい |
update_note |
ノートのテキスト/位置/色を更新 |
✅ はい |
delete_note |
ノートを削除 |
✅ はい |
create_note のレスポンス例:
{
"note_id": 456,
"title": "Comprare il latte",
"color": "#FFEB3B",
"position_x": 100.5,
"position_y": 250.0,
"created_at": "2025-01-15T10:30:00Z",
"message": "✅ Nota creata con successo"
}
🔧 メタツール (3 個)
| ツール |
説明 |
認証が必要 |
get_or_create_category |
ファジーマッチングでスマートにカテゴリを検索/作成 |
✅ はい |
move_all_tasks_between_categories |
カテゴリ間で一括でタスクを移動 |
✅ はい |
add_multiple_tasks |
一度に複数のタスクを一括で作成 |
✅ はい |
⚕️ システムツール (1 個)
| ツール |
説明 |
認証が必要 |
health_check |
サーバーのヘルスチェックと接続状況を確認 |
❌ いいえ |
health_check のレスポンス例:
{
"mcp_server": "healthy",
"fastapi_server": "healthy",
"fastapi_url": "http://localhost:8080",
"timestamp": "2025-01-15T10:30:00Z",
"version": "2.0.0"
}
🚀 クイックスタート
利用オプション
MyTaskly MCP サーバーを利用する方法は2 通りあります。
オプション 1: 公式の公開サーバーを利用する (推奨)
公式の MyTaskly MCP サーバー (近日公開) を利用すると、セットアップ不要です!
メリット:
- ✅ インストールや設定が不要
- ✅ 常に最新の機能が利用可能
- ✅ MyTaskly チームによる管理と監視
- ✅ MyTaskly モバイルアプリとそのまま動作
オプション 2: 自前でホストする (上級者向け)
自分自身のローカル MCP サーバーインスタンスを実行します。
前提条件:
- Python 3.11 以上 (仮想環境を推奨)
- ローカルで実行されている MyTaskly FastAPI サーバー (MyTaskly-server を参照)
- FastAPI サーバーの設定と一致する JWT シークレットキー
- カスタムサーバーを使用するように設定された 修正済みの MyTaskly アプリ
クイックスタート (5 分):
git clone https://github.com/Gabry848/MyTaskly-mcp.git
cd MyTaskly-mcp
python -m venv venv && pip install -r requirements.txt
cp .env.example .env && python main.py
⚠️ 重要: 自前でホストする場合は、以下のことも行う必要があります。
- MyTaskly-server のローカルインスタンスを実行する
- MyTaskly モバイルアプリをカスタムサーバーの URL を指すように修正する
自前でホストする場合のセットアップガイド
1. クローンとインストール
git clone https://github.com/Gabry848/MyTaskly-mcp.git
cd MyTaskly-mcp
python -m venv venv
venv\Scripts\activate
source venv/bin/activate
pip install -r requirements.txt
2. 環境変数を設定する
ルートディレクトリに .env ファイルを作成します。
# ============ FASTAPI バックエンド ============
FASTAPI_BASE_URL=http://localhost:8080
FASTAPI_API_KEY=your_api_key_here
# ============ JWT 設定 ============
# 重要: FastAPI サーバーの設定と一致する必要があります!
JWT_SECRET_KEY=your_jwt_secret_key_here
JWT_ALGORITHM=HS256
MCP_AUDIENCE=mytaskly-mcp
# ============ サーバー設定 ============
MCP_SERVER_NAME=MyTaskly-MCP
MCP_SERVER_VERSION=2.0.0
LOG_LEVEL=INFO
⚠️ 重要: JWT_SECRET_KEY は FastAPI サーバーの SECRET_KEY 環境変数と一致する必要があります!
3. MCP サーバーを起動する
python main.py
サーバーは stdio モードで起動し、利用可能なツールが表示されます。MCP クライアントをこのサーバーに接続するように設定します。
🔐 認証とセキュリティ
OAuth 2.1 フロー
MCP サーバーは、OAuth 2.1 および RFC 8707 標準に準拠した JWT トークンを使用します。
┌─────────────────┐
│ モバイルクライアント │
│ (React Native) │
└────────┬────────┘
│ 1. ログインリクエスト
▼
┌─────────────────┐
│ FastAPI サーバー │ 2. 資格情報を検証
│ (認証サーバー) │ 3. MCP オーディエンスクレーム付きの JWT を生成
└────────┬────────┘
│ 4. JWT トークンを返す
▼
┌─────────────────┐
│ モバイルクライアント │ 5. トークンを安全に保存
└────────┬────────┘
│ 6. 認証ヘッダー付きで MCP ツールを呼び出す
▼
┌─────────────────┐
│ MCP サーバー │ 7. JWT 署名を検証
│ (このプロジェクト) │ 8. オーディエンスクレームを検証
│ │ 9. トークンからユーザー ID を抽出
└────────┬────────┘
│ 10. ユーザー ID 付きで FastAPI に HTTP リクエストを送信
▼
┌─────────────────┐
│ FastAPI サーバー │ 11. ユーザー固有のデータを返す
│ (リソース API) │
└────────┬────────┘
│ 12. モバイル UI 用にデータをフォーマット
▼
┌─────────────────┐
│ MCP サーバー │ 13. フォーマットされたレスポンスを返す
└────────┬────────┘
│
▼
┌─────────────────┐
│ モバイルクライアント │ 14. UI をレンダリング / TTS を再生
└─────────────────┘
JWT トークンの構造
JWT は、次のクレームを含む必要があります (RFC 7519 および RFC 8707 に準拠)。
{
"sub": "123",
"aud": "mcp://mytaskly-mcp-server",
"iss": "https://api.mytasklyapp.com",
"exp": 1735689600,
"iat": 1735686000,
"scope": "tasks:read tasks:write notes:write"
}
セキュリティ機能:
| 機能 |
実装 |
| 署名検証 |
共有シークレットを使用した HS256 |
| オーディエンスクレーム |
サービス間でのトークンの再利用を防止 |
| 有効期限チェック |
自動的なトークン無効化 |
| ユーザー分離 |
各リクエストは認証されたユーザーにスコープされる |
JWT トークンの取得
オプション 1: FastAPI から取得する (本番環境用)
FastAPI サーバーに次のエンドポイントを追加する必要があります。
@router.post("/auth/mcp-token")
async def get_mcp_token(current_user: User = Depends(get_current_user)):
"""MCP サーバーへのアクセス用の JWT トークンを生成します。"""
payload = {
"sub": str(current_user.user_id),
"aud": "mcp://mytaskly-mcp-server",
"iss": "https://api.mytasklyapp.com",
"exp": datetime.utcnow() + timedelta(minutes=30),
"iat": datetime.utcnow(),
"scope": "tasks:read tasks:write categories:read notes:read notes:write"
}
token = jwt.encode(payload, settings.JWT_SECRET_KEY, algorithm="HS256")
return {"mcp_token": token, "expires_in": 1800}
オプション 2: テストトークンを生成する (開発環境用)
from src.auth import create_test_token
token = create_test_token(user_id=1, expires_minutes=30)
print(f"テストトークン: {token}")
🧪 テストと開発
Python を使用した手動テスト
import asyncio
from src.auth import create_test_token
from src.server import get_tasks, get_categories, create_note
async def test_mcp_tools():
"""生成されたトークンですべての MCP ツールをテストします。"""
token = create_test_token(user_id=1, expires_minutes=30)
auth_header = f"Bearer {token}"
print("🔑 ユーザー ID が 1 のテストトークンを生成しました。\n")
print("1️⃣ get_tasks をテスト中...")
tasks = await get_tasks(authorization=auth_header)
print(f" ✅ {tasks['summary']['total']} 個のタスクを取得しました。")
print(f" 📊 概要: {tasks['summary']}")
print(f" 🎤 音声: {tasks['voice_summary']}\n")
print("2️⃣ get_categories をテスト中...")
categories = await get_categories(authorization=auth_header)
print(f" ✅ {categories['total']} 個のカテゴリを取得しました。")
print(f" 📂 所有: {categories.get('owned', 0)}")
print(f" 🤝 共有: {categories.get('shared_with_me', 0)}\n")
print("3️⃣ create_note をテスト中...")
note = await create_note(
authorization=auth_header,
title="Test note from MCP",
color="#4CAF50",
position_x=100.0,
position_y=200.0
)
print(f" ✅ ノート #{note['note_id']} を作成しました。")
print(f" 📝 タイトル: {note['title']}")
print(f" 🎨 色: {note['color']}\n")
print("✅ すべてのテストが正常に完了しました!")
if __name__ == "__main__":
asyncio.run(test_mcp_tools())
cURL を使用したテスト
python -c "from src.auth import create_test_token; print(create_test_token(1))"
export MCP_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl -X POST http://localhost:8000/mcp/get_tasks \
-H "Authorization: Bearer $MCP_TOKEN" \
-H "Content-Type: application/json"
curl -X POST http://localhost:8000/mcp/get_categories \
-H "Authorization: Bearer $MCP_TOKEN" \
-H "Content-Type: application/json"
curl -X POST http://localhost:8000/mcp/create_note \
-H "Authorization: Bearer $MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Meeting notes",
"color": "#FF5722",
"position_x": 150.5,
"position_y": 300.0
}'
curl -X GET http://localhost:8000/mcp/health_check
自動テストスイート
python -m pytest tests/ -v
python -m pytest tests/test_auth.py -v
python -m pytest tests/ --cov=src --cov-report=html
python -m pytest tests/ -v -s
📱 React Native との統合
get_tasks ツールは、React Native コンポーネント用に最適化されたデータを返します。
import { FlatList, View, Text } from 'react-native';
async function fetchTasks() {
const token = await getAuthToken();
const response = await mcpClient.call('get_tasks', {
authorization: `Bearer ${token}`
});
return response;
}
function TasksList() {
const [data, setData] = useState(null);
useEffect(() => {
fetchTasks().then(setData);
}, []);
if (!data) return <Loading />;
return (
<View>
{/* アクセシビリティ用の音声要約 */}
<Text accessible>{data.voice_summary}</Text>
{/* タスクリストをレンダリング */}
<FlatList
data={data.tasks}
renderItem={({ item }) => (
<TaskCard
title={item.title}
date={item.endTimeFormatted}
category={item.category}
categoryColor={item.categoryColor}
priority={item.priorityEmoji}
/>
)}
/>
</View>
);
}
🎤 ボイスチャットとの統合
レスポンスには、TTS 用の voice_summary が含まれています。
response = await mcp_client.call('get_tasks', {
'authorization': f'Bearer {user_jwt}'
})
ui_data = response['tasks']
tts_text = response['voice_summary']
🔒 セキュリティのベストプラクティス
- 本番環境では常に HTTPS を使用する
- JWT_SECRET_KEY を安全に保管する - git にコミットしない
- 短期間のトークンを使用する (15 - 30 分)
- クライアントで トークンのリフレッシュを実装する
- オーディエンスクレームを検証する (RFC 8707) - トークンの再利用を防止
- 認証失敗をログに記録して監視する
🏗️ アーキテクチャとプロジェクト構造
システムアーキテクチャ
┌─────────────────────────────────────────────────────────────┐
│ MyTaskly エコシステム │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ モバイルクライアント │ 1. ユーザー認証 │
│ │ (React Native) │ 2. JWT トークンを受け取る │
│ └────────┬────────┘ 3. MCP ツールを呼び出す │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ MCP サーバー │ 4. JWT を検証する (OAuth 2.1) │
│ │ (このプロジェクト) │ 5. トークンからユーザー ID を抽出 │
│ └────────┬────────┘ 6. モバイル UI 用にデータをフォーマット │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ FastAPI サーバー │ 7. ビジネスロジックを処理 │
│ │ (MyTaskly-API) │ 8. データベース操作を管理 │
│ └────────┬────────┘ 9. 生データを返す │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ PostgreSQL │ 10. 永続的なストレージ │
│ │ データベース │ 11. トリガーと通知 │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
プロジェクト構造
MyTaskly-mcp/
├── src/
│ ├── core/ # コア MCP サーバー
│ │ ├── __init__.py
│ │ └── server.py # FastMCP インスタンスとツールの登録
│ │
│ ├── client/ # HTTP クライアント層
│ │ ├── __init__.py
│ │ ├── base.py # 認証付きの基本 HTTP クライアント
│ │ ├── categories.py # カテゴリ API エンドポイント
│ │ ├── tasks.py # タスク API エンドポイント
│ │ ├── notes.py # ノート API エンドポイント
│ │ └── health.py # ヘルスチェックエンドポイント
│ │
│ ├── tools/ # MCP ツール (ビジネスロジック)
│ │ ├── __init__.py
│ │ ├── categories.py # カテゴリツール (4 つのメソッド)
│ │ ├── tasks.py # タスクツール (8 つのメソッド)
│ │ ├── notes.py # ノートツール (4 つのメソッド)
│ │ ├── meta.py # メタツール (3 つのメソッド)
│ │ └── health.py # ヘルスチェックツール (1 つのメソッド)
│ │
│ ├── formatters/ # レスポンスフォーマッター
│ │ ├── __init__.py
│ │ └── tasks.py # React Native UI 用のタスクフォーマット
│ │
│ ├── auth.py # JWT 認証
│ ├── config.py # 設定
│ └── http_server.py # オプションの HTTP サーバーラッパー
│
├── tests/ # テストスイート
├── main.py # メインエントリーポイント
├── pyproject.toml # プロジェクト設定
├── requirements.txt # Python 依存関係
├── ARCHITECTURE.md # 詳細なアーキテクチャドキュメント
└── README.md # このファイル
レイヤーアーキテクチャ
| レイヤー |
ファイル |
責任 |
| コアレイヤー |
src/core/ |
MCP サーバーインスタンスとツールの登録 |
| ツールレイヤー |
src/tools/ |
ビジネスロジックを持つ MCP ツールの定義 (20 個のツール) |
| クライアントレイヤー |
src/client/ |
FastAPI サーバーとの HTTP 通信 |
| フォーマッターレイヤー |
src/formatters/ |
API レスポンスを React Native UI 用に変換 |
主要コンポーネント
| コンポーネント |
技術 |
目的 |
| MCP サーバー |
FastMCP と asyncio |
リクエストの処理とツールの調整 |
| JWT 認証 |
PyJWT と HS256 |
セキュアなトークンベースの認証 |
| HTTP クライアント |
httpx (非同期) |
FastAPI バックエンドとの通信 |
| データフォーマット |
カスタムフォーマッター |
モバイル最適化されたレスポンス構造 |
📚 詳細なアーキテクチャ情報については、ARCHITECTURE.md を参照してください。
🛠️ 開発ガイド
新しい MCP ツールの追加
レイヤードアーキテクチャパターンに従ってください。
1. HTTP クライアントメソッドを追加する
async def new_operation(self, user_id: int, params...) -> Dict[str, Any]:
"""新しい FastAPI エンドポイントを呼び出します。"""
token = await self._get_user_token(user_id)
return await self._post("/new-endpoint", token, json={...})
2. MCP ツールを追加する
async def new_tool(authorization: str, params...) -> Dict[str, Any]:
"""ここにツールのドキュメントを記述します。"""
user_id = verify_jwt_token(authorization)
result = await task_client.new_operation(user_id, params)
return format_response(result)
3. ツールを登録する
from src.tools.tasks import new_tool
mcp.tool()(new_tool)
4. main.py のバナーを更新する
print_banner() のリストに新しいツールを追加します。
詳細については、ARCHITECTURE.md を参照してください。
コード品質
black src/ tests/
ruff check src/ tests/
mypy src/
pytest tests/ --cov=src --cov-report=html
一般的な開発タスク
| タスク |
コマンド |
| サーバーを起動する |
python main.py |
| テストトークンを生成する |
python -c "from src.auth import create_test_token; print(create_test_token(1))" |
| テストを実行する |
pytest tests/ -v |
| カバレッジを確認する |
pytest tests/ --cov=src |
| コードをフォーマットする |
black src/ tests/ |
| 依存関係をインストールする |
pip install -r requirements.txt |
📚 リソースと関連プロジェクト
MyTaskly エコシステム
ドキュメント
🤝 コントリビューション
コントリビューションを歓迎します!このプロジェクトは MyTaskly エコシステムの一部です。
コントリビュートする方法
- リポジトリをフォークする
- 機能ブランチを作成する:
git checkout -b feature/my-feature
- 変更を加える 明確なコミットメッセージを付ける
- 新しい機能に対してテストを追加する
- テストが通過することを確認する:
pytest tests/ -v
- コードをフォーマットする:
black src/ tests/
- プルリクエストを送信する
開発ワークフロー
git clone https://github.com/YOUR_USERNAME/MyTaskly-mcp.git
cd MyTaskly-mcp
git checkout -b feature/my-feature
pytest tests/ -v
git commit -m "feat: タスク統計用の新しい MCP ツールを追加"
git push origin feature/my-feature
📄 ライセンス
このプロジェクトは MIT ライセンス の下でライセンスされています。詳細については LICENSE ファイルを参照してください。
MIT ライセンスにより、以下のことが許可されます。
📞 サポートとフィードバック
Gabry848 による ❤️ で作られた MyTaskly プロジェクトの一部です。
スターをいただけると幸いです! ⭐
⬆ ページの先頭に戻る