MCPサーバーを自作してClaudeに外部ツールを接続する方法【2026年最新版】
MCPサーバーの自作に興味はあるけれど、「どこから手をつければいいかわからない」という方は多いのではないでしょうか。この記事では、MCPの基本概念から始まり、Python SDKを使った実装手順、Claude Desktopへの接続設定、デバッグ方法まで、実際のコードを交えながら解説します。
MCPとは何か——アーキテクチャを理解する
MCP(Model Context Protocol)の概念
MCP(Model Context Protocol)は、Anthropicが策定したオープンなプロトコルで、AIモデルと外部ツール・データソースを標準化された方法で接続するための仕様です。
従来、AIに外部ツールを使わせようとすると、各ツールごとにカスタムの統合コードを書く必要がありました。MCPはその問題を解決するために設計された「共通言語」のようなものです。
主な構成要素は次のとおりです。
- MCPホスト:Claude Desktopなど、AIモデルを動かすアプリケーション
- MCPクライアント:ホスト内でMCPサーバーと通信するコンポーネント
- MCPサーバー:外部ツールやデータソースを提供する軽量なプロセス
MCPサーバーは独立したプロセスとして動作し、標準入出力(stdio)またはHTTP経由でホストと通信します。この設計によって、サーバーをどの言語で書いても、どこにホスティングしても、Claude側の実装を変えることなく接続できます。
MCPが定義する3つのプリミティブ
MCPサーバーが提供できる機能は大きく3種類に分類されます。
| プリミティブ | 概要 | 主な使い方 |
|---|---|---|
| Tools(ツール) | AIが呼び出せる関数 | 計算・API呼び出し・DB操作など |
| Resources(リソース) | AIが読み取れるデータ | ファイル内容・設定値・ログなど |
| Prompts(プロンプト) | 再利用可能なプロンプトテンプレート | よく使う指示のテンプレート化 |
この記事では、最もよく使われる「Tools」と「Resources」の実装に焦点を当てて解説します。
Python SDKでMCPサーバーのスケルトンを作成する
開発環境の準備
まず必要なパッケージをインストールします。Python 3.10以上を前提とします。
pip install mcp
mcpパッケージにはサーバーとクライアントの両方が含まれています。uvicornなどを別途インストールする必要はなく、stdioモードであればこれ一つで動作します。
最小構成のスケルトン
以下が、MCPサーバーの最小構成です。ファイル名はserver.pyとします。
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types
import asyncio
# サーバーインスタンスを作成
app = Server("my-mcp-server")
@app.list_tools()
async def list_tools() -> list[types.Tool]:
"""利用可能なツールの一覧を返す"""
return [
types.Tool(
name="hello_world",
description="指定した名前に挨拶を返すサンプルツール",
inputSchema={
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "挨拶する相手の名前"
}
},
"required": ["name"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[types.TextContent]:
"""ツールの呼び出しを処理する"""
if name == "hello_world":
target_name = arguments.get("name", "world")
return [types.TextContent(
type="text",
text=f"こんにちは、{target_name}さん!"
)]
raise ValueError(f"未知のツール: {name}")
async def main():
async with stdio_server() as (read_stream, write_stream):
await app.run(read_stream, write_stream, app.create_initialization_options())
if __name__ == "__main__":
asyncio.run(main())
このスケルトンを理解するポイントは3つです。
@app.list_tools()— Claudeがどんなツールが使えるかを問い合わせてきたときに呼ばれる@app.call_tool()— Claudeが実際にツールを使おうとしたときに呼ばれるstdio_server()— 標準入出力でClaude Desktopと通信するためのコンテキストマネージャ
ToolsとResourcesの書き方
Toolsの定義——Claudeが「実行できる」機能を作る
Toolsは、ClaudeがAIの判断で自律的に呼び出せる関数です。inputSchemaにJSON Schemaを使って入力パラメータを定義するのがポイントです。
実用的な例として、外部APIを叩くツールを追加してみましょう。たとえば「指定したURLのHTTPステータスコードを確認するツール」は次のように書けます。
import httpx
@app.list_tools()
async def list_tools() -> list[types.Tool]:
return [
types.Tool(
name="check_url_status",
description="指定したURLのHTTPステータスコードを確認する",
inputSchema={
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "確認するURL(https://から始まる完全なURL)"
}
},
"required": ["url"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "check_url_status":
url = arguments["url"]
async with httpx.AsyncClient() as client:
response = await client.get(url, follow_redirects=True, timeout=10.0)
return [types.TextContent(
type="text",
text=f"URL: {url}\nステータスコード: {response.status_code}"
)]
descriptionはClaudeがツールを選択する際の判断材料になります。「いつ使うべきか」が明確にわかる説明文を書くことが、Claudeが適切にツールを使いこなすための重要なポイントです。
Resourcesの定義——Claudeが「参照できる」データを作る
Resourcesは、Claudeが読み取れる静的・動的なデータです。ファイルシステムやデータベースの内容を見せるときに使います。
@app.list_resources()
async def list_resources() -> list[types.Resource]:
return [
types.Resource(
uri="file:///config/settings.json",
name="アプリ設定ファイル",
description="現在のアプリケーション設定",
mimeType="application/json"
)
]
@app.read_resource()
async def read_resource(uri: str) -> str:
if uri == "file:///config/settings.json":
# 実際のアプリでは適切な読み込み処理を入れる
return '{"environment": "production", "version": "1.2.0"}'
raise ValueError(f"未知のリソース: {uri}")
ToolsとResourcesの使い分けは、「Claudeに何かをさせたい」ならTools、「Claudeに何かを見せたい」ならResourcesというシンプルな基準で判断するとよいでしょう。
Claude Desktopへの接続設定
claude_desktop_config.jsonの書き方
作成したMCPサーバーをClaude Desktopに接続するには、設定ファイルを編集します。設定ファイルの場所はOSによって異なります。
| OS | パス |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
設定ファイルの記述例は以下のとおりです。
{
"mcpServers": {
"my-mcp-server": {
"command": "python",
"args": ["/absolute/path/to/server.py"],
"env": {
"PYTHONPATH": "/absolute/path/to/your/project"
}
}
}
}
commandにはPythonの実行パスを指定します。仮想環境を使っている場合は、venv内のPythonの絶対パスを指定するのが確実です。Macであれば/Users/yourname/project/.venv/bin/pythonのような形になります。
設定ファイルを保存したら、Claude Desktopを再起動します。接続が成功すると、チャット画面の入力欄にハンマーアイコン(🔨)が表示され、登録したツールの一覧を確認できます。
環境変数を使った機密情報の管理
APIキーなどの機密情報はコードにハードコーディングせず、envフィールドを通じて渡すのがベストプラクティスです。
{
"mcpServers": {
"my-mcp-server": {
"command": "python",
"args": ["/path/to/server.py"],
"env": {
"API_KEY": "your-secret-key-here"
}
}
}
}
サーバー側ではos.environ.get("API_KEY")で受け取れます。
デバッグ方法と開発のコツ
MCP Inspectorを使ったローカルデバッグ
mcpパッケージにはmcp devコマンドが含まれており、ブラウザベースのインスペクターUIでサーバーを手軽にテストできます。
mcp dev server.py
このコマンドを実行すると、ローカルのブラウザでインスペクターが起動し、ツールの呼び出しやリソースの取得を対話的に試せます。Claude Desktopを再起動する手間なく動作確認できるため、開発中はこちらを積極的に活用するとよいでしょう。
ログ出力の注意点
MCPサーバーはstdioで通信するため、print()で標準出力にログを出すと通信が壊れます。デバッグログは必ずsys.stderrに出力してください。
import sys
# 正しいデバッグログの出し方
print("デバッグ情報", file=sys.stderr)
またはloggingモジュールを使ってログレベルを管理する方法も有効です。Claude Desktopのログは、macOSであれば~/Library/Logs/Claude/フォルダ内のファイルで確認できます。
AI鬼管理との連携ユースケース
MCPサーバーでAI鬼管理を拡張する
AI鬼管理のようなタスク・プロジェクト管理ツールとMCPを組み合わせることで、Claudeがタスクの確認・登録・更新を自然言語で直接操作できるようになります。
具体的なユースケースとしては、以下のような活用が考えられます。
- 「今日締め切りのタスクを一覧表示して」とClaudeに依頼すると、AI鬼管理のAPIを叩いて結果を返す
- 「このバグ修正タスクを完了にしておいて」という指示をツール経由で処理する
- プロジェクトのステータスをResourcesとして公開し、毎朝の進捗確認をClaude経由で行う
このような連携を実現するには、AI鬼管理が提供するAPIのエンドポイントをcall_tool()内で呼び出すMCPサーバーを作成します。認証情報は先述のenvフィールドで安全に渡せます。
MCPサーバーをどこにホスティングするかも重要な検討事項です。ローカルで動かすだけであれば特別な準備は不要ですが、チームで共有したり常時起動させたりしたい場合は、VPSへのデプロイを検討することになります。XサーバーのVPSプランや、ドメイン管理にお名前.comを活用すれば、HTTPベースのMCPサーバーとして外部公開することも選択肢の一つです。
まとめと次のアクション
この記事では、MCPサーバーの概念から実装・接続・デバッグまでの一通りの流れを解説しました。
改めて要点を整理すると、次のとおりです。
- MCPはAIと外部ツールをつなぐ標準プロトコルで、Tools・Resources・Promptsの3種類の機能を提供できる
- Python SDKの
mcpパッケージを使えば、少ないコード量でサーバーを起動できる - Claude Desktopへの接続は
claude_desktop_config.jsonに絶対パスで記述するだけ - デバッグには
mcp devコマンドが便利で、print()はstderrに向ける
次のアクションとして、まずはこの記事のスケルトンコードをそのまま動かしてみることをおすすめします。Claudeのチャット画面にハンマーアイコンが表示されたら、あとは自分のユースケースに合わせてツールを追加していくだけです。
MCPのエコシステムはまだ発展途上であり、仕様のアップデートも頻繁に行われています。実装の際はAnthropicの公式ドキュメントも併せて参照することを強くおすすめします。
関連記事
- AI時代の副業ロードマップ:Claudeで特化ブログ100記事量産 — AI副業の始め方から収益化まで
- 知識ゼロからClaude×Astroで110記事の爆速サイトを作った全手法 — Claude Code × Astro で一人メディアを構築した実績公開