MCP (Model Context Protocol) でAIとツールを接続する

12分 read | 2025.01.10

MCPとは

MCP(Model Context Protocol)は、Anthropic社が開発したAIモデルと外部ツールを接続するためのオープンプロトコルです。AIが安全かつ構造化された方法で外部リソースにアクセスできます。

なぜMCPが必要か

従来のAI統合では、各ツールごとに個別の実装が必要でした。MCPは標準化されたプロトコルを提供し、一度の実装で多くのAIアプリケーションと連携できます。

従来: AI → 個別実装 → ツールA
      AI → 個別実装 → ツールB
      AI → 個別実装 → ツールC

MCP:  AI → MCP → ツールA
             ↘ ツールB
             ↘ ツールC

MCPの構成要素

Resources(リソース)

AIがアクセスできるデータソースです。

// リソースの定義
{
  resources: [
    {
      uri: "file:///project/src",
      name: "Source Code",
      description: "プロジェクトのソースコード",
      mimeType: "text/plain"
    }
  ]
}

Tools(ツール)

AIが実行できるアクションです。

// ツールの定義
{
  tools: [
    {
      name: "search_codebase",
      description: "コードベースを検索する",
      inputSchema: {
        type: "object",
        properties: {
          query: { type: "string", description: "検索クエリ" },
          fileType: { type: "string", description: "ファイル種類" }
        },
        required: ["query"]
      }
    }
  ]
}

Prompts(プロンプト)

再利用可能なプロンプトテンプレートです。

// プロンプトの定義
{
  prompts: [
    {
      name: "code_review",
      description: "コードレビューを実行",
      arguments: [
        { name: "file_path", description: "レビュー対象ファイル" }
      ]
    }
  ]
}

MCPサーバーの実装

基本構造

// mcp-server.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new Server(
  {
    name: "my-mcp-server",
    version: "1.0.0"
  },
  {
    capabilities: {
      resources: {},
      tools: {}
    }
  }
);

// リソースのリスト
server.setRequestHandler("resources/list", async () => {
  return {
    resources: [
      {
        uri: "file:///data",
        name: "Data Files",
        description: "データファイル"
      }
    ]
  };
});

// リソースの読み込み
server.setRequestHandler("resources/read", async (request) => {
  const { uri } = request.params;
  const content = await readFile(uri);

  return {
    contents: [
      {
        uri,
        mimeType: "text/plain",
        text: content
      }
    ]
  };
});

// ツールのリスト
server.setRequestHandler("tools/list", async () => {
  return {
    tools: [
      {
        name: "search",
        description: "ファイルを検索",
        inputSchema: {
          type: "object",
          properties: {
            query: { type: "string" }
          },
          required: ["query"]
        }
      }
    ]
  };
});

// ツールの実行
server.setRequestHandler("tools/call", async (request) => {
  const { name, arguments: args } = request.params;

  if (name === "search") {
    const results = await searchFiles(args.query);
    return {
      content: [
        { type: "text", text: JSON.stringify(results) }
      ]
    };
  }
});

// サーバー起動
const transport = new StdioServerTransport();
await server.connect(transport);

公式MCPサーバー

Anthropic社が提供する公式サーバー:

Filesystem

ローカルファイルシステムへのアクセス

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/directory"]
    }
  }
}

PostgreSQL

データベースへのクエリ実行

{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"]
    }
  }
}

GitHub

GitHubリポジトリの操作

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "your-token"
      }
    }
  }
}

Claude Desktopでの設定

// ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "ghp_xxxx"
      }
    }
  }
}

セキュリティ考慮事項

アクセス制御

// 許可されたディレクトリのみアクセス
const ALLOWED_PATHS = ['/project/src', '/project/docs'];

server.setRequestHandler("resources/read", async (request) => {
  const { uri } = request.params;

  if (!ALLOWED_PATHS.some(p => uri.startsWith(p))) {
    throw new Error("Access denied");
  }

  // ...
});

入力検証

// ツール入力の検証
server.setRequestHandler("tools/call", async (request) => {
  const { arguments: args } = request.params;

  // SQLインジェクション対策
  if (args.query && /[;'"\\]/.test(args.query)) {
    throw new Error("Invalid query");
  }

  // ...
});

今後の発展

  • より多くのツール統合
  • 権限管理の強化
  • パフォーマンス最適化
  • クラウドネイティブ対応

関連記事

← Back to list