MCPとは

MCP(Model Context Protocol)は、2024年末にAnthropicが発表したオープンプロトコルで、AIモデルと外部ツール/データソース間の通信を標準化することを目的としています。統一されたインターフェース仕様を定義し、あらゆるAIモデルが標準的な方法でツール、リソース、プロンプトテンプレートにアクセスできるようにします。2026年には、MCPはAIエージェント開発の事実上の標準となっています。

MCPの核となる概念

概念説明
Serverツール/リソースを提供するサーバー側GitHub Server、Filesystem Server
Clientツールを使用するAIホストClaude Desktop、カスタムエージェント
Tool呼び出し可能な関数機能search_code、create_issue
Resource読み取り可能なデータソースファイル内容、データベースレコード
Prompt定義済みのプロンプトテンプレートコードレビューテンプレート

MCPサーバーの構築

# weather_server.py
from mcp.server import Server, NotificationOptions
from mcp.server.models import InitializationCapabilities
import mcp.server.stdio
import mcp.types as types
import json

app = Server("weather-server")

@app.list_tools()
async def handle_list_tools() -> list[types.Tool]:
    return [
        types.Tool(
            name="get-weather",
            description="指定された都市の天気情報を取得",
            inputSchema={
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "都市名"}
                },
                "required": ["city"]
            }
        ),
        types.Tool(
            name="get-forecast",
            description="将来の天気予報を取得",
            inputSchema={
                "type": "object",
                "properties": {
                    "city": {"type": "string"},
                    "days": {"type": "integer", "minimum": 1, "maximum": 7}
                },
                "required": ["city"]
            }
        )
    ]

@app.call_tool()
async def handle_call_tool(name: str, arguments: dict) -> list[types.TextContent]:
    if name == "get-weather":
        city = arguments["city"]
        # 実際の天気APIを呼び出す
        weather = f"{city}は今日晴れ、25°C"
        return [types.TextContent(type="text", text=weather)]

    elif name == "get-forecast":
        city = arguments["city"]
        days = arguments.get("days", 3)
        forecast = f"{city}の今後{days}日間は晴れが中心"
        return [types.TextContent(type="text", text=forecast)]

    raise ValueError(f"不明なツール: {name}")

async def main():
    async with mcp.server.stdio.stdio_server() as (read, write):
        await app.run(read, write, InitializationCapabilities())

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

DeepSeek + MCP統合

# deepseek_mcp_client.py
from openai import OpenAI
import subprocess
import json
import os

class DeepSeekMCPClient:
    def __init__(self, server_script):
        self.client = OpenAI(
            api_key=os.getenv('DEEPSEEK_API_KEY'),
            base_url='https://api.deepseek.com'
        )
        self.server = server_script
        self.tools = self._load_tools()

    def _load_tools(self):
        """MCPサーバーからツールリストを読み込む"""
        # 実際にはMCPプロトコルで通信するが、ここでは簡略化して事前定義
        return [{
            "type": "function",
            "function": {
                "name": "get-weather",
                "description": "都市の天気を取得",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "city": {"type": "string"}
                    },
                    "required": ["city"]
                }
            }
        }]

    def chat_with_tools(self, user_message):
        messages = [{"role": "user", "content": user_message}]

        response = self.client.chat.completions.create(
            model='deepseek-v4-flash',
            messages=messages,
            tools=self.tools,
            tool_choice='auto'
        )

        msg = response.choices[0].message
        if msg.tool_calls:
            for tc in msg.tool_calls:
                result = self._execute_tool(tc.function.name, json.loads(tc.function.arguments))
                messages.append({"role": "tool", "tool_call_id": tc.id, "content": result})

            final = self.client.chat.completions.create(
                model='deepseek-v4-flash',
                messages=messages
            )
            return final.choices[0].message.content

        return msg.content

    def _execute_tool(self, name, args):
        # MCPサーバーを呼び出してツールを実行
        result = subprocess.run(
            ['python', self.server, name, json.dumps(args)],
            capture_output=True, text=True
        )
        return result.stdout

# 使用例
client = DeepSeekMCPClient('weather_server.py')
result = client.chat_with_tools("北京の今日の天気は?")
print(result)

Claude Desktop MCPの設定

// ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)
// %APPDATA%\Claude\claude_desktop_config.json (Windows)
{
  "mcpServers": {
    "deepseek-tools": {
      "command": "python",
      "args": ["/path/to/weather_server.py"]
    }
  }
}

おすすめの一般的なMCPサーバー

サーバーインストールコマンド機能
filesystemnpx -y @modelcontextprotocol/server-filesystem /pathファイル読み書き
githubnpx -y @modelcontextprotocol/server-githubGitHub操作
postgresnpx -y @modelcontextprotocol/server-postgresデータベースクエリ
brave-searchnpx -y @modelcontextprotocol/server-brave-searchウェブ検索
memorynpx -y @modelcontextprotocol/server-memory知識記憶

MCP vs Function Calling比較

MCPFunction Calling
標準化✅ オープンプロトコル、クロスプラットフォームベンダー固有の実装
再利用性一度構築すれば複数モデルで利用可能モデルごとに適応が必要
エコシステム30以上の公式サーバー自前で開発が必要
複雑さ独立したサーバープロセスが必要アプリケーションコードに組み込み

推奨:外部に汎用ツールを提供する場合はMCPを使用し、アプリケーション内のプライベートツールにはFunction Callingを使用してください。