ChatGPTやClaudeに質問して回答をもらう。この使い方はもう「普通」になった。2026年の焦点は、AIが自分で判断し、ツールを使い、タスクを完了する「AIエージェント」の構築に移っている。
その中核技術がMCPサーバーだ。この記事では、MCPサーバーを自分で作って、AIエージェントに新しい能力を持たせる方法を解説する。
AIエージェントとMCPサーバーの関係
AIエージェントは「考える」ことはできるが、そのままでは外の世界に手を伸ばせない。ファイルの読み書き、データベースへの問い合わせ、外部APIの呼び出し——こうした操作を可能にするのがMCPサーバーだ。
たとえば「先週のサポートチケットを集計して、カテゴリ別の傾向をSlackに投稿して」という指示を実行するには、AIエージェントが以下のツールにアクセスする必要がある。
- チケット管理システム(Zendesk, Intercomなど)のデータ取得
- データの集計・分析
- Slackへのメッセージ送信
MCPサーバーは、これらのツールへのアクセスを標準化されたインターフェースでAIに提供する。
AIエージェントの動作フロー
- ユーザーからの指示を受け取る
- 指示を達成するために必要なステップを計画する
- 各ステップで必要なMCPサーバーのツールを選択する
- ツールを呼び出し、結果を受け取る
- 結果を踏まえて次のステップに進む(あるいは計画を修正する)
- 最終結果をユーザーに返す
MCPサーバーの基本構造
MCPサーバーは、以下の3種類の機能を提供できる。
Tools(ツール)
AIが呼び出せるアクション。「メールを送信する」「データベースにレコードを追加する」などの操作を定義する。AIがいつ、どのツールを使うかを自分で判断する。
Resources(リソース)
AIが参照できるデータ。ファイルの内容やデータベースのレコードなど、読み取り専用の情報を提供する。
Prompts(プロンプト)
あらかじめ定義されたプロンプトテンプレート。特定のタスクに最適化されたプロンプトをサーバー側で用意しておき、AIが状況に応じて選択する。
実践:PythonでMCPサーバーを作る
ここからは実際にコードを書いていく。天気情報を取得するシンプルなMCPサーバーを例にする。
環境準備
Python 3.10以上が必要だ。MCPのPython SDKをインストールする。
pip install mcp
サーバーの実装
from mcp.server import Server
from mcp.types import Tool, TextContent
import httpx
app = Server("weather-server")
@app.list_tools()
async def list_tools():
return [
Tool(
name="get_weather",
description="指定した都市の現在の天気を取得する",
inputSchema={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "都市名(例: Tokyo, Osaka)"
}
},
"required": ["city"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "get_weather":
city = arguments["city"]
async with httpx.AsyncClient() as client:
response = await client.get(
f"https://wttr.in/{city}?format=j1"
)
data = response.json()
current = data["current_condition"][0]
result = (
f"{city}の天気: {current['weatherDesc'][0]['value']}, "
f"気温: {current['temp_C']}°C, "
f"湿度: {current['humidity']}%"
)
return [TextContent(type="text", text=result)]
if __name__ == "__main__":
import asyncio
from mcp.server.stdio import stdio_server
async def main():
async with stdio_server() as (read, write):
await app.run(
read, write,
app.create_initialization_options()
)
asyncio.run(main())
コードの解説
@app.list_tools(): AIに「このサーバーで使えるツールの一覧」を教えるハンドラ。ツール名、説明文、入力パラメータのスキーマを定義する。
@app.call_tool(): AIがツールを実行するときに呼ばれるハンドラ。引数を受け取り、実際の処理を行って結果を返す。
inputSchema: JSON Schemaで入力パラメータを定義する。AIはこのスキーマに従って引数を構成するため、正確に書くことが重要だ。
Claude Codeへの登録
{
"mcpServers": {
"weather": {
"command": "python",
"args": ["path/to/weather_server.py"]
}
}
}
TypeScriptで作る場合
npm install @modelcontextprotocol/sdk
Python vs TypeScript: どちらを選ぶか
| 観点 | Python | TypeScript |
|---|---|---|
| プロトタイピング速度 | 速い。数十行で動くものが作れる | やや手間がかかるが、型定義で安全 |
| データ処理・ML連携 | pandas, numpy等のエコシステムが豊富 | データ処理ライブラリは限定的 |
| 保守性 | 大規模になると型の恩恵が欲しくなる | 型安全性により長期保守が楽 |
| デプロイ | pip/uvで簡単 | npm/bunで簡単 |
実用的なMCPサーバーのアイデア
社内ナレッジベースサーバー
社内WikiやConfluenceの記事を検索・取得するサーバー。AIエージェントが「過去に同じ問題を対応した記録」を探して回答に活用できる。
CRMデータサーバー
SalesforceなどのCRMデータを取得・更新するサーバー。「先月の商談一覧を取得して、成約率が低い案件の共通点を分析して」といった指示が実行可能になる。
監視アラートサーバー
Datadog, Grafana, CloudWatchなどの監視ツールからアラート情報を取得するサーバー。AIが障害の一次切り分けを行い、過去の類似障害の対応手順を提案する。
データベースクエリサーバー
社内のPostgreSQLやBigQueryに接続し、自然言語の質問をSQLに変換して実行するサーバー。非エンジニアでも「先月の売上トップ10の商品は?」と聞くだけでデータを取得できるようになる。
MCPサーバー開発のベストプラクティス
ツールの説明文を丁寧に書く
AIはdescriptionを読んでツールの使い方を判断する。「データを取得する」ではなく「指定した期間内の売上データを取得し、商品カテゴリ別に集計した結果を返す」のように具体的に書く。
エラーハンドリングを手厚くする
外部APIの一時障害やタイムアウトは日常的に起こる。エラー時には人間が読める形式のエラーメッセージを返すことで、AIが適切に判断できる。
- 接続エラー: 「外部サービスに接続できません」
- 認証エラー: 「APIキーが無効です。設定を確認してください」
- レート制限: 「リクエスト制限に達しました」
- タイムアウト: 「リクエストがタイムアウトしました」
認証情報をハードコードしない
APIキーやパスワードは環境変数で注入する。コードに直接書くと、リポジトリ経由で漏洩するリスクがある。
冪等性を意識する
同じ引数で複数回呼び出されても問題が起きないように設計する。AIは同じツールを何度か呼び出すことがあるため、重複実行への耐性は必須だ。
レスポンスを簡潔にする
MCPサーバーの出力はAIのコンテキストウィンドウを消費する。不要なデータを含めると、トークン消費が増えて処理速度とコストに影響する。
MCPサーバーのテスト方法
npx @modelcontextprotocol/inspector python weather_server.py
ブラウザベースのUIが起動し、ツール一覧の確認やツールの手動実行ができる。AIを介さずにサーバー単体の動作を検証できるため、デバッグが効率的だ。
MCPサーバー開発を始めるには
MCPサーバーの開発は、AIエージェントの能力を拡張する最も実践的な方法だ。基本構造はシンプルで、Pythonなら数十行のコードから始められる。
重要なのは、ツールのdescriptionを丁寧に書くこと、エラーハンドリングを手厚くすること、そして小さく始めて段階的に機能を増やすことだ。まずは社内の1つのツールを接続するところから試してみてほしい。