MCPサーバー自作 調査・計画¶
📁 docs/dev-environment/artifact/wip/20260313_MCPサーバー自作_調査・計画.md
作成日: 2026-03-13 目的: 個人開発でMCPサーバーを自作するための調査結果と実装計画
1. MCPサーバとは何か¶
1.1 MCPの概要¶
MCP(Model Context Protocol) は、AIアプリケーションと外部システムを接続するためのオープンソース標準プロトコル。USBのように「AI版の統一コネクタ」として機能し、一度サーバーを作れば、Claude Code、Claude Desktop、VS Code (Copilot)、Cursor、ChatGPTなど複数のクライアントから利用できる。
1.2 アーキテクチャ(Host / Client / Server)¶
┌─────────────────────────────────────────┐
│ MCP Host(AIアプリケーション) │
│ 例: Claude Code, Claude Desktop, VS Code │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │MCP Client│ │MCP Client│ │MCP Client│ │
│ │ #1 │ │ #2 │ │ #3 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
└───────┼──────────────┼──────────────┼──────┘
│ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│MCP Server │ │MCP Server │ │MCP Server │
│(ローカル) │ │(ローカル) │ │(リモート) │
│ Filesystem│ │ MyLab │ │ Sentry │
└───────────┘ └───────────┘ └───────────┘
| 参加者 | 役割 |
|---|---|
| Host | AIアプリケーション本体。複数のClientを管理する(例: Claude Code) |
| Client | Host内部のコンポーネント。1つのServerとの接続を維持する |
| Server | コンテキスト(ツール・データ・プロンプト)を提供するプログラム |
1.3 3つの主要プリミティブ¶
| プリミティブ | 用途 | 例 |
|---|---|---|
| Tools | LLMが実行できるアクション(副作用あり) | ファイル操作、API呼び出し、DB クエリ |
| Resources | 読み取り専用のデータ提供(副作用なし) | ファイル内容、DB スキーマ、API レスポンス |
| Prompts | 再利用可能なテンプレート | システムプロンプト、few-shot 例 |
1.4 通信方式¶
| 方式 | 概要 | 用途 |
|---|---|---|
| stdio | 標準入出力でJSON-RPCをやりとり | ローカルサーバー(最も一般的) |
| Streamable HTTP | HTTP POST + SSE | リモートサーバー(推奨) |
| SSE (非推奨) | Server-Sent Events | レガシー互換 |
個人開発でClaude Codeと組み合わせる場合は stdio が最もシンプル。
1.5 既存MCPサーバーの代表例¶
公式リファレンスサーバー¶
| サーバー名 | 概要 |
|---|---|
| Filesystem | ファイルシステムへの安全なアクセス |
| Git | Gitリポジトリの読取・検索・操作 |
| Memory | ナレッジグラフベースの永続メモリ |
| Fetch | Webコンテンツの取得と変換 |
| Sequential Thinking | 段階的推論プロセスのサポート |
コミュニティ/パートナー(一部)¶
- Sentry - エラー監視・デバッグ
- GitHub - PR/Issue/コードレビュー
- Notion - ページ検索・作成
- Playwright - ブラウザ自動操作
- PostgreSQL (dbhub) - データベースクエリ
MCP Registryに130以上のサーバーが登録されている。
2. 自作MCPサーバーの候補アイデア¶
現状の把握¶
既に projects/mcp-server-mylab/server.py に以下のツールを持つMCPサーバーが存在する: - GitHub Issue管理(list/get/create/close/search) - ファイル検索(名前パターン/内容grep) - プロジェクト管理(一覧/ドキュメント/サマリー)
また scripts/mcp/youtube_transcribe_server.py にYouTube文字起こしサーバーもある。
以下は まだ存在しない、作ったら便利な MCPサーバーのアイデア。
アイデア一覧¶
| # | 名前 | 概要 | 難易度 | 推奨言語 |
|---|---|---|---|---|
| 1 | Obsidian Vault サーバー | ノート検索・作成・リンク探索 | Easy | Python |
| 2 | n8n ワークフロー操作サーバー | ワークフロー一覧/実行/有効化 | Medium | Python |
| 3 | AI漫画パイプラインサーバー | SD WebUI連携で画像生成 | Hard | Python |
| 4 | Google Tasks同期サーバー | タスクの取得・作成・更新 | Medium | Python |
| 5 | 情報キュレーションサーバー | HN/GitHub Trending/Zennの収集・要約 | Medium | Python |
| 6 | SD WebUI Forgeサーバー | 画像生成APIのMCPラッパー | Medium | Python |
| 7 | Credentials管理サーバー | 認証情報の安全な取得 | Easy | Python |
| 8 | 会話ログ管理サーバー | ログの保存・検索・要約 | Easy | Python |
| 9 | Discord Bot管理サーバー | メッセージ送信・チャンネル操作 | Medium | Python |
| 10 | MyLab統合ダッシュボードサーバー | 全プロジェクトの横断的ステータス | Medium | Python |
各アイデアの詳細¶
1. Obsidian Vault サーバー¶
概要: Obsidian Vaultのノートを検索・作成・編集できるMCPサーバー。Claude Codeから「あのメモどこだっけ」「新しいメモ作って」が可能に。
提供するTools: | ツール | 説明 | |--------|------| | search_notes | ノートのタイトル/内容をキーワード検索 | | read_note | 指定パスのノートを読み取り | | create_note | 新しいノートを作成(フォルダ指定可) | | update_note | 既存ノートの内容を更新 | | list_recent_notes | 最近更新されたノート一覧 | | get_backlinks | 指定ノートへのバックリンク一覧 |
提供するResources: | リソース | 説明 | |----------|------| | vault://structure | Vaultのフォルダ構造 | | vault://daily/{date} | デイリーノートの内容 |
難易度: Easy(ファイルシステム操作のみ) 推奨言語: Python
2. n8n ワークフロー操作サーバー¶
概要: n8nのREST APIを叩いて、ワークフローの一覧表示・実行・有効化/無効化ができる。「バズコレクタのワークフロー実行して」のような操作が可能。
提供するTools: | ツール | 説明 | |--------|------| | list_workflows | ワークフロー一覧(名前・状態) | | get_workflow | ワークフロー詳細(ノード構成含む) | | execute_workflow | ワークフローを手動実行 | | toggle_workflow | 有効化/無効化の切替 | | list_executions | 実行履歴(成功/失敗/時刻) | | get_execution_log | 特定の実行の詳細ログ |
難易度: Medium(n8n REST API理解が必要) 推奨言語: Python 前提: n8nインスタンスのAPIキー
3. AI漫画パイプライン サーバー¶
概要: AI漫画パイプライン(projects/ai-manga-pipeline/)をMCP経由で操作。プロンプトからの画像生成、レイアウト適用、パイプライン全体の実行が可能。
提供するTools: | ツール | 説明 | |--------|------| | generate_image | プロンプトから画像生成(SD WebUI API経由) | | apply_layout | ページレイアウトの適用 | | run_pipeline | パイプライン全体の実行 | | list_prompts | prompt-libraryの一覧 | | preview_page | 生成結果のプレビュー |
難易度: Hard(SD WebUI API + 画像処理 + 既存パイプラインとの統合) 推奨言語: Python
4. Google Tasks 同期サーバー¶
概要: 既存の scripts/task_sync/ の機能をMCP化。Google Tasksのタスクを直接操作できる。
提供するTools: | ツール | 説明 | |--------|------| | list_tasks | タスクリストの一覧 | | get_tasks | 特定リストのタスク取得 | | create_task | タスク作成 | | complete_task | タスクを完了にする | | sync_with_github | GitHub Issueとの同期実行 |
難易度: Medium(Google API認証が必要) 推奨言語: Python
5. 情報キュレーション サーバー¶
概要: scripts/insight/ のHacker News/GitHub Trending収集機能をMCP化。「今日のテックニュースまとめて」が1コマンドで可能。
提供するTools: | ツール | 説明 | |--------|------| | fetch_hackernews | HN トップストーリー取得 | | fetch_github_trending | GitHub Trending取得 | | fetch_zenn_likes | Zennの人気記事取得 | | summarize_articles | 取得記事のAI要約 | | save_digest | ダイジェストをファイルに保存 |
提供するResources: | リソース | 説明 | |----------|------| | insight://latest | 最新のダイジェスト | | insight://history/{date} | 過去のダイジェスト |
難易度: Medium(既存スクリプトのラッパー) 推奨言語: Python
6. SD WebUI Forge サーバー¶
概要: Stable Diffusion WebUI ForgeのAPIをMCPでラップ。テキストから画像生成、モデル切替、LoRA選択などをClaude Codeから操作。
提供するTools: | ツール | 説明 | |--------|------| | txt2img | テキストから画像生成 | | img2img | 画像を元に変換生成 | | list_models | 利用可能なモデル一覧 | | list_loras | 利用可能なLoRA一覧 | | get_progress | 現在の生成進捗 |
難易度: Medium(REST APIのラッパーだが画像データの扱いが複雑) 推奨言語: Python
7. Credentials 管理サーバー¶
概要: Credentials/ ディレクトリの認証情報を安全に取得するMCPサーバー。他のサーバーやスクリプトが認証情報を必要とする際に使える。
提供するTools: | ツール | 説明 | |--------|------| | list_credentials | 利用可能な認証情報の名前一覧(値は含まない) | | get_credential_key | 特定サービスの特定キーを取得 |
難易度: Easy(JSONファイル読み取りのみ) 推奨言語: Python 注意: セキュリティ上、出力をログに残さない設計が必要
8. 会話ログ管理サーバー¶
概要: scripts/conversation/ と logs/ の会話ログをMCPから操作。ログの保存・検索・要約ができる。
提供するTools: | ツール | 説明 | |--------|------| | save_log | 会話ログを保存 | | search_logs | 過去ログをキーワード検索 | | list_recent_logs | 最近のログ一覧 | | summarize_log | 指定ログの要約を生成 |
難易度: Easy(ファイル操作 + 既存スクリプトの活用) 推奨言語: Python
9. Discord Bot 管理サーバー¶
概要: Discord Botの操作をMCPから行う。メッセージ送信、チャンネル一覧、特定チャンネルの最近のメッセージ取得など。
提供するTools: | ツール | 説明 | |--------|------| | send_message | 指定チャンネルにメッセージ送信 | | list_channels | チャンネル一覧 | | get_recent_messages | 最近のメッセージ取得 | | send_notification | 通知メッセージ送信 |
難易度: Medium(Discord API/Webhook連携) 推奨言語: Python
10. MyLab統合ダッシュボード サーバー¶
概要: MyLab全体の横断的なステータスを提供。各プロジェクトの最新コミット、n8nワークフローの状態、GitHub Issueの進捗を統合表示。
提供するTools: | ツール | 説明 | |--------|------| | get_dashboard | 全体ダッシュボード表示 | | get_project_status | 特定プロジェクトの詳細ステータス | | get_weekly_summary | 今週の作業サマリー |
提供するResources: | リソース | 説明 | |----------|------| | dashboard://overview | リアルタイム概要 |
難易度: Medium(複数データソースの集約) 推奨言語: Python
3. MCPサーバーの実装方法¶
3.1 公式SDK¶
| SDK | 言語 | パッケージ | 特徴 |
|---|---|---|---|
| Python SDK | Python | mcp | FastMCPフレームワーク、デコレータベース |
| TypeScript SDK | TypeScript | @modelcontextprotocol/sdk | Node.js向け |
個人開発でPythonメインなら Python SDK (FastMCP) 一択。
3.2 最小構成サンプルコード¶
"""
最小構成のMCPサーバー例
pip install "mcp[cli]" でインストール
"""
from mcp.server.fastmcp import FastMCP
# サーバーインスタンス作成
mcp = FastMCP("my-server")
# === Tool(LLMが実行するアクション)===
@mcp.tool()
def greet(name: str) -> str:
"""指定された名前に挨拶する"""
return f"こんにちは、{name}さん!"
@mcp.tool()
def add(a: int, b: int) -> int:
"""2つの数値を加算する"""
return a + b
# === Resource(読み取り専用データ)===
@mcp.resource("info://server")
def server_info() -> str:
"""サーバー情報を返す"""
return "これはMyLabのテスト用MCPサーバーです。"
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
"""パーソナライズされた挨拶"""
return f"ようこそ、{name}さん!"
# === Prompt(再利用テンプレート)===
@mcp.prompt()
def code_review(language: str = "python") -> str:
"""コードレビュー用のプロンプトテンプレート"""
return f"以下の{language}コードをレビューしてください。バグ、改善点、ベストプラクティスの観点でフィードバックしてください。"
# エントリーポイント
if __name__ == "__main__":
mcp.run() # デフォルトはstdio
3.3 stdio と HTTP/SSE の違い¶
| 項目 | stdio | Streamable HTTP |
|---|---|---|
| 通信 | 標準入出力(stdin/stdout) | HTTP POST + SSE |
| 起動 | 親プロセス(Host)がサーバーを起動 | 独立したHTTPサーバーとして起動 |
| ネットワーク | 不要(ローカルのみ) | 必要(リモート対応可) |
| クライアント数 | 1対1 | 1対多 |
| 用途 | ローカル開発、個人利用 | チーム共有、リモートアクセス |
| 起動方法 | mcp.run() | mcp.run(transport="streamable-http") |
個人開発の推奨: stdio(最もシンプルで、Claude Codeとの相性が良い)
3.4 Claude Code への登録方法¶
方法1: CLIコマンド(推奨)¶
# stdioサーバーの登録
claude mcp add --transport stdio mylab -- python D:/Kazuma_Teramachi/MyLab/projects/mcp-server-mylab/server.py
# スコープ指定(ローカル=デフォルト / プロジェクト / ユーザー)
claude mcp add --transport stdio --scope user mylab -- python server.py
# HTTPサーバーの登録
claude mcp add --transport http my-server http://localhost:8000/mcp
# 環境変数付き
claude mcp add --transport stdio --env API_KEY=xxx myserver -- python server.py
方法2: .mcp.json ファイル(プロジェクト共有向け)¶
プロジェクトルートに .mcp.json を置く:
{
"mcpServers": {
"mylab": {
"command": "python",
"args": ["projects/mcp-server-mylab/server.py"]
}
}
}
方法3: JSON直接指定¶
claude mcp add-json mylab '{"type":"stdio","command":"python","args":["projects/mcp-server-mylab/server.py"]}'
管理コマンド¶
Claude Code内では /mcp コマンドで状態確認・認証が可能。
Windows 注意点¶
npx を使うサーバーは cmd /c ラッパーが必要:
3.5 デバッグ方法¶
MCP Inspector(公式ツール)¶
# インストール不要、npxで起動
npx -y @modelcontextprotocol/inspector
# ブラウザが開く → サーバーURLを入力して接続
# stdioサーバー: コマンドを指定して起動
# HTTPサーバー: http://localhost:8000/mcp を入力
MCP Inspectorでできること: - ツール一覧の確認 - ツールの手動実行とレスポンス確認 - リソース/プロンプトの確認 - JSON-RPCメッセージのモニタリング
ログ出力¶
from mcp.server.fastmcp import FastMCP, Context
from mcp.server.session import ServerSession
import logging
logging.basicConfig(level=logging.DEBUG)
mcp = FastMCP("debug-server")
@mcp.tool()
async def debug_tool(message: str, ctx: Context[ServerSession, None]) -> str:
"""デバッグ用ツール"""
await ctx.info(f"実行中: {message}") # クライアントにログ送信
return f"OK: {message}"
Claude Code内でのデバッグ¶
4. 推奨する「最初の1本」¶
推奨: Obsidian Vault サーバー¶
| 評価軸 | スコア | 理由 |
|---|---|---|
| 難易度 | Easy | ファイルシステム操作のみ。外部API不要 |
| 有用性 | 高 | 日常的にObsidianを使っている。ノート検索・作成の需要大 |
| 学習効果 | 高 | Tool/Resource/Prompt の3プリミティブすべてを実装できる |
| 既存資産との重複 | なし | まだObsidian連携のMCPサーバーは未作成 |
| 拡張性 | 高 | タグ検索、テンプレート適用、デイリーノート自動生成など拡張しやすい |
既存の mcp-server-mylab はGitHub Issue/ファイル検索に特化しており、Obsidian Vaultサーバーは別の価値を提供する。
実装計画(ステップ)¶
Step 1: プロジェクトセットアップ(30分)¶
ファイル構成:
projects/mcp-server-obsidian/
├── server.py # MCPサーバー本体
├── README.md # 使い方
└── tests/
└── test_server.py
Step 2: 基本ツール実装(1時間)¶
from mcp.server.fastmcp import FastMCP
from pathlib import Path
import re
VAULT_ROOT = Path("D:/Kazuma_Teramachi/MyLab/vault")
mcp = FastMCP("obsidian-vault")
@mcp.tool()
def search_notes(query: str, limit: int = 20) -> str:
"""Vault内のノートをキーワード検索する"""
results = []
for md in VAULT_ROOT.rglob("*.md"):
try:
content = md.read_text(encoding="utf-8", errors="ignore")
if query.lower() in content.lower() or query.lower() in md.stem.lower():
# タイトル(最初のH1または ファイル名)
title = md.stem
for line in content.splitlines():
if line.startswith("# "):
title = line[2:].strip()
break
rel = md.relative_to(VAULT_ROOT)
results.append(f"- **{title}** (`{rel}`)")
if len(results) >= limit:
break
except Exception:
continue
if not results:
return f"'{query}' に一致するノートが見つかりませんでした。"
return f"## 検索結果: '{query}' ({len(results)}件)\n\n" + "\n".join(results)
@mcp.tool()
def read_note(path: str) -> str:
"""指定パスのノートを読み取る(Vaultルートからの相対パス)"""
note = VAULT_ROOT / path
if not note.exists():
return f"ノートが見つかりません: {path}"
return note.read_text(encoding="utf-8", errors="ignore")
@mcp.tool()
def create_note(path: str, content: str) -> str:
"""新しいノートを作成する"""
note = VAULT_ROOT / path
if note.exists():
return f"既にノートが存在します: {path}"
note.parent.mkdir(parents=True, exist_ok=True)
note.write_text(content, encoding="utf-8")
return f"ノートを作成しました: {path}"
@mcp.tool()
def list_recent_notes(limit: int = 10) -> str:
"""最近更新されたノートを一覧する"""
notes = sorted(
VAULT_ROOT.rglob("*.md"),
key=lambda p: p.stat().st_mtime,
reverse=True,
)[:limit]
lines = [f"## 最近更新されたノート({len(notes)}件)\n"]
for n in notes:
rel = n.relative_to(VAULT_ROOT)
lines.append(f"- `{rel}`")
return "\n".join(lines)
if __name__ == "__main__":
mcp.run()
Step 3: Resource/Prompt追加(30分)¶
@mcp.resource("vault://structure")
def vault_structure() -> str:
"""Vaultのフォルダ構造を返す"""
# トップレベルのフォルダ一覧
...
@mcp.resource("vault://daily/{date}")
def daily_note(date: str) -> str:
"""デイリーノートを返す(例: 2026-03-13)"""
...
@mcp.prompt()
def new_note_template(topic: str) -> str:
"""新しいノートのテンプレートプロンプト"""
return f"「{topic}」について以下の構成でノートを作成してください:\n- 概要\n- キーポイント\n- 参考リンク\n- 次のアクション"
Step 4: テスト・デバッグ(30分)¶
# MCP Inspectorで動作確認
npx -y @modelcontextprotocol/inspector
# Claude Codeに登録
claude mcp add --transport stdio obsidian-vault -- python D:/Kazuma_Teramachi/MyLab/projects/mcp-server-obsidian/server.py
# 動作確認
claude mcp list
# Claude Code内で /mcp → 状態確認
Step 5: ドキュメント整備・コミット(15分)¶
- README.md作成(ツール一覧、起動方法、設定方法)
- issueにコメント更新
- コミット&プッシュ