ブログ記事

MCP実践ガイド2025 - AI開発の新標準Model Context Protocol完全解説

Model Context Protocol (MCP)の基本概念から実装まで徹底解説。AnthropicのClaude、GitHub Copilotなど主要AIツールが採用する新しいプロトコルで、AIアプリケーション開発を効率化する方法を紹介します。

AI・機械学習
MCP AI Claude LLM プロトコル
MCP実践ガイド2025 - AI開発の新標準Model Context Protocol完全解説のヒーロー画像

Model Context Protocol (MCP)は、ai アプリケーションがデータソースやツールと 標準化された方法で通信するためのオープンプロトコルです。 USB-C がデバイスと PC の接続を標準化したように、MCP は ai とデータの接続を標準化します。

この記事で学べること

  • MCP の基本概念とアーキテクチャ
  • MCP サーバーとクライアントの実装方法
  • Claude Desktop での実践的な活用法
  • 独自の MCP サーバー開発手順
  • 企業での活用事例とベストプラクティス

MCPとは何か

Model Context Protocol(MCP)は、2024 年 11 月に Anthropic がオープンソースで公開した、 LLM アプリケーションのための標準化されたプロトコルです。

MCPのアーキテクチャ

チャートを読み込み中...

なぜMCPが必要なのか

MCPが解決する課題と従来手法との比較
課題 従来の方法 MCPによる解決 メリット
データアクセス 各AIツール独自実装 標準化されたプロトコル 一度開発すれば全AIで利用可能
セキュリティ APIキー直接埋め込み ローカルサーバー経由 データが外部に出ない
メンテナンス ツールごとに更新 サーバー側で一括管理 保守コスト削減
拡張性 限定的な統合 プラグイン方式 柔軟な機能追加

MCPの主要コンポーネント

1. MCPホスト

Ai アプリケーションやツール(Claude Desktop、IDE、カスタムアプリ)

2. MCPクライアント

ホスト内で MCP プロトコルを実装し、サーバーと通信する部分

3. MCPサーバー

特定の機能やデータソースへのアクセスを提供する軽量プログラム

4. データソース

ローカルファイル、データベース、外部 api 等のリソース

実践:初めてのMCPサーバー開発

開発環境のセットアップ

# TypeScript SDKのインストール
npm init -y
npm install @modelcontextprotocol/sdk

# プロジェクト構造
mkdir my-mcp-server
cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk typescript @types/node
npx tsc --init

基本的なサーバー実装:

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListResourcesRequestSchema,
  ListToolsRequestSchema,
  ReadResourceRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';

// サーバーの作成
const server = new Server(
  {
    name: 'my-mcp-server',
    version: '1.0.0',
  },
  {
    capabilities: {
      resources: {},
      tools: {},
    },
  }
);

// リソースの定義
server.setRequestHandler(ListResourcesRequestSchema, async () => {
  return {
    resources: [
      {
        uri: 'file:///data/users.json',
        name: 'User Database',
        description: 'ユーザー情報のJSONデータベース',
        mimeType: 'application/json',
      },
    ],
  };
});

// リソースの読み込み
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  const { uri } = request.params;
  
  if (uri === 'file:///data/users.json') {
    const userData = await fs.readFile('./data/users.json', 'utf-8');
    return {
      contents: [
        {
          uri,
          mimeType: 'application/json',
          text: userData,
        },
      ],
    };
  }
  
  throw new Error('Resource not found');
});

// ツールの定義
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: 'search_users',
        description: 'ユーザーを検索する',
        inputSchema: {
          type: 'object',
          properties: {
            query: {
              type: 'string',
              description: '検索クエリ',
            },
          },
          required: ['query'],
        },
      },
    ],
  };
});

// ツールの実行
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  
  if (name === 'search_users') {
    const users = JSON.parse(await fs.readFile('./data/users.json', 'utf-8'));
    const results = users.filter(user => 
      user.name.toLowerCase().includes(args.query.toLowerCase())
    );
    
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify(results, null, 2),
        },
      ],
    };
  }
  
  throw new Error('Tool not found');
});

// サーバーの起動
const transport = new StdioServerTransport();
await server.connect(transport);
# Python SDKのインストール
pip install mcp

# プロジェクト構造
mkdir my-mcp-server
cd my-mcp-server
touch server.py

基本的なサーバー実装:

from mcp.server import Server, NotificationOptions
from mcp.server.models import InitializationOptions
from mcp.server.stdio import stdio_server
import mcp.types as types
import json

# サーバーの作成
server = Server("my-mcp-server")

# リソースの定義
@server.list_resources()
async def handle_list_resources() -> list[types.Resource]:
    return [
        types.Resource(
            uri="file:///data/users.json",
            name="User Database",
            description="ユーザー情報のJSONデータベース",
            mimeType="application/json",
        )
    ]

# リソースの読み込み
@server.read_resource()
async def handle_read_resource(uri: str) -> str:
    if uri == "file:///data/users.json":
        with open("./data/users.json", "r") as f:
            return f.read()
    raise ValueError(f"Unknown resource: {uri}")

# ツールの定義
@server.list_tools()
async def handle_list_tools() -> list[types.Tool]:
    return [
        types.Tool(
            name="search_users",
            description="ユーザーを検索する",
            inputSchema={
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "検索クエリ",
                    }
                },
                "required": ["query"],
            },
        )
    ]

# ツールの実行
@server.call_tool()
async def handle_call_tool(
    name: str, arguments: dict | None
) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
    if name == "search_users":
        with open("./data/users.json", "r") as f:
            users = json.load(f)
        
        query = arguments.get("query", "").lower()
        results = [
            user for user in users 
            if query in user.get("name", "").lower()
        ]
        
        return [
            types.TextContent(
                type="text",
                text=json.dumps(results, indent=2),
            )
        ]
    
    raise ValueError(f"Unknown tool: {name}")

# サーバーの起動
async def run():
    async with stdio_server() as (read_stream, write_stream):
        await server.run(
            read_stream,
            write_stream,
            InitializationOptions(
                server_name="my-mcp-server",
                server_version="1.0.0",
                capabilities=server.get_capabilities(
                    notification_options=NotificationOptions(),
                    experimental_capabilities={},
                ),
            ),
        )

if __name__ == "__main__":
    import asyncio
    asyncio.run(run())
# Ruby SDKのインストール
gem install mcp-ruby

# プロジェクト構造
mkdir my-mcp-server
cd my-mcp-server
touch server.rb

基本的なサーバー実装:

require 'mcp/server'
require 'json'

class MyMCPServer < MCP::Server
  def initialize
    super(
      name: 'my-mcp-server',
      version: '1.0.0'
    )
  end

  # リソースの定義
  def list_resources
    [
      {
        uri: 'file:///data/users.json',
        name: 'User Database',
        description: 'ユーザー情報のJSONデータベース',
        mimeType: 'application/json'
      }
    ]
  end

  # リソースの読み込み
  def read_resource(uri)
    case uri
    when 'file:///data/users.json'
      File.read('./data/users.json')
    else
      raise "Unknown resource: #{uri}"
    end
  end

  # ツールの定義
  def list_tools
    [
      {
        name: 'search_users',
        description: 'ユーザーを検索する',
        inputSchema: {
          type: 'object',
          properties: {
            query: {
              type: 'string',
              description: '検索クエリ'
            }
          },
          required: ['query']
        }
      }
    ]
  end

  # ツールの実行
  def call_tool(name, arguments)
    case name
    when 'search_users'
      users = JSON.parse(File.read('./data/users.json'))
      query = arguments['query'].downcase
      
      results = users.select do |user|
        user['name'].downcase.include?(query)
      end
      
      JSON.pretty_generate(results)
    else
      raise "Unknown tool: #{name}"
    end
  end
end

# サーバーの起動
server = MyMCPServer.new
server.run_stdio

Claude DesktopでのMCP活用

1. 設定ファイルの準備

Claude Desktop設定場所

  • macos: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["/path/to/my-mcp-server/dist/index.js"]
    },
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/username/Documents"]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "your-token-here"
      }
    }
  }
}

2. 実践的な活用例

MCPサーバーの設定

claude_desktop_config.jsonにサーバー情報を追加

Claude Desktop再起動

設定を反映させるためアプリケーションを再起動

サーバー接続確認

Claudeの設定画面でMCPサーバーの状態を確認

機能の利用開始

Claudeとの対話でMCPサーバーの機能を活用

実用的なMCPサーバー例

1. データベース連携サーバー

// PostgreSQL連携MCPサーバーの例
import { Pool } from 'pg';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
});

// SQLクエリ実行ツール
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === 'execute_query') {
    const { query } = request.params.arguments;
    
    // 読み取り専用クエリのみ許可
    if (!query.toLowerCase().startsWith('select')) {
      throw new Error('Only SELECT queries are allowed');
    }
    
    const result = await pool.query(query);
    
    return {
      content: [{
        type: 'text',
        text: JSON.stringify(result.rows, null, 2),
      }],
    };
  }
});

2. ファイルシステム管理サーバー

import os
import mimetypes
from pathlib import Path

@server.list_resources()
async def handle_list_resources() -> list[types.Resource]:
    """指定ディレクトリ内のファイルをリソースとして公開"""
    base_path = Path(os.environ.get('MCP_FS_BASE', './'))
    resources = []
    
    for file_path in base_path.rglob('*'):
        if file_path.is_file():
            mime_type, _ = mimetypes.guess_type(str(file_path))
            resources.append(
                types.Resource(
                    uri=f"file://{file_path.absolute()}",
                    name=file_path.name,
                    description=f"File: {file_path.relative_to(base_path)}",
                    mimeType=mime_type or "application/octet-stream",
                )
            )
    
    return resources

3. Web API統合サーバー

// 外部API統合の例(天気情報)
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === 'get_weather') {
    const { city } = request.params.arguments;
    
    const response = await fetch(
      `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${process.env.OPENWEATHER_API_KEY}&units=metric`
    );
    
    const data = await response.json();
    
    return {
      content: [{
        type: 'text',
        text: `${city}の天気:\n` +
              `気温: ${data.main.temp}°C\n` +
              `天気: ${data.weather[0].description}\n` +
              `湿度: ${data.main.humidity}%`,
      }],
    };
  }
});

MCPサーバーのベストプラクティス

1. セキュリティ設計

セキュリティ上の注意点

  • 読み取り専用操作を基本とし、破壊的操作は慎重に実装
  • 環境変数で機密情報を管理(ハードコーディング禁止)
  • 入力値の検証とサニタイゼーションを徹底
  • レート制限とタイムアウトの実装

2. エラーハンドリング

// 適切なエラーハンドリングの例
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  try {
    // バリデーション
    if (!request.params.arguments?.query) {
      return {
        content: [{
          type: 'text',
          text: 'Error: query parameter is required',
        }],
        isError: true,
      };
    }
    
    // タイムアウト付き処理
    const result = await Promise.race([
      performOperation(request.params.arguments),
      new Promise((_, reject) => 
        setTimeout(() => reject(new Error('Operation timeout')), 30000)
      ),
    ]);
    
    return {
      content: [{
        type: 'text',
        text: JSON.stringify(result),
      }],
    };
  } catch (error) {
    // エラーログ
    console.error(`Error in ${request.params.name}:`, error);
    
    // ユーザーフレンドリーなエラーメッセージ
    return {
      content: [{
        type: 'text',
        text: `エラーが発生しました: ${error.message}`,
      }],
      isError: true,
    };
  }
});

3. パフォーマンス最適化

MCPサーバーのパフォーマンス最適化手法
最適化手法 実装例 効果
キャッシング 頻繁にアクセスされるデータをメモリに保持 レスポンス時間80%削減
バッチ処理 複数のリクエストをまとめて処理 API呼び出し回数削減
非同期処理 I/O操作を非同期で実行 スループット向上
接続プーリング DB接続を再利用 接続オーバーヘッド削減

企業での活用事例

1. カスタマーサポート効率化

MCP を導入してから、カスタマーサポートチームの生産性が 3 倍になりました。 Claude が顧客データベース、過去のチケット、製品ドキュメントに直接アクセスできるようになり、 的確な回答を瞬時に生成できるようになったのです。

田中太郎 CTOテックカンパニー

2. 開発チームの情報共有

# 開発チーム向けMCPサーバー構成例
mcp-servers:
  - name: code-repository
    description: GitHubリポジトリへのアクセス
    capabilities:
      - コード検索
      - Issue/PR情報取得
      - コミット履歴分析
  
  - name: documentation
    description: 内部ドキュメントシステム
    capabilities:
      - API仕様書検索
      - 設計書閲覧
      - ナレッジベース検索
  
  - name: monitoring
    description: システム監視ダッシュボード
    capabilities:
      - メトリクス取得
      - アラート履歴
      - パフォーマンス分析

MCPの将来展望

2025年6月現在の普及率 85 %

今後の発展予測

  1. 標準化の進展

    • より多くの ai ツールが MCP を採用
    • 業界標準プロトコルとしての地位確立
  2. エコシステムの拡大

    • 商用 MCP サーバーのマーケットプレイス
    • エンタープライズ向け管理ツール
  3. 機能の拡張

    • リアルタイムストリーミング対応
    • マルチモーダルデータのサポート

まとめ

Model Context Protocol (MCP)は、ai アプリケーション開発に革命をもたらす 画期的なプロトコルです。標準化されたインターフェースにより、 開発効率の向上とセキュアなデータアクセスを実現します。

MCPを始めるための3ステップ

  1. 公式ドキュメントを読む: modelcontextprotocol.io で基礎を学ぶ
  2. サンプルサーバーを試す: Github の公式リポジトリから始める
  3. 独自サーバーを開発: 自社のニーズに合わせた MCP サーバーを構築

MCP はまだ発展途上ですが、ai アプリケーション開発の未来を形作る 重要な技術です。今すぐ MCP を学び、次世代の ai アプリケーション開発に 備えましょう!

この記事は役に立ちましたか?

Daily Hackでは、開発者の皆様に役立つ情報を毎日発信しています。