MCP(Model Context Protocol)とは?AIツール連携の新標準を解説

kento_morota 15分で読めます
社内のAI・IT活用、技術がわかる相手に無料相談。 相談 →
目次

「AIアシスタントに社内のデータベースを検索させたい」「LLMから外部APIを呼び出したいが、ツールごとに個別の連携コードを書くのが大変」——AIの活用が進む中で、こうした課題が顕在化しています。

MCP(Model Context Protocol)は、Anthropic社が2024年に公開した、AIモデルと外部ツール・データソースを接続するためのオープンプロトコルです。USBがさまざまなデバイスの接続を標準化したように、MCPはAIと外部システムの接続を標準化します。

本記事では、MCPの基本概念からアーキテクチャ、サーバーの実装方法、実践的なユースケースまで体系的に解説します。

MCPが解決する課題

MCPが登場する前、AIモデルと外部ツールの連携には「M×N問題」がありました。M個のAIアプリケーションとN個のツール・データソースを連携させるには、M×N個の個別実装が必要でした。

例えば、Claude、ChatGPT、GeminiといったAIアプリケーションが、それぞれGitHub、Slack、データベース、Google Driveと連携しようとすると、4×3=12の個別の連携コードが必要になります。新しいAIアプリケーションやツールが追加されるたびに、連携の組み合わせが爆発的に増えます。

MCPは、この問題を「プロトコルの標準化」で解決します。AIアプリケーション側はMCPクライアントを実装し、ツール側はMCPサーバーを実装すれば、どの組み合わせでも接続できます。USBポートに対応したデバイスが何でも接続できるのと同じ考え方です。

MCPのメリット

開発効率の向上
一度MCPサーバーを実装すれば、MCP対応のすべてのAIアプリケーションから利用できます。個別の連携コードを書く必要がなくなります。

エコシステムの共有
コミュニティやベンダーが公開するMCPサーバーを活用できます。GitHub、Slack、PostgreSQL、Google Driveなど、主要なサービスのMCPサーバーはすでに公開されています。

セキュリティの一元管理
認証・認可の仕組みがプロトコルレベルで定義されているため、ツールへのアクセス制御を統一的に管理できます。

MCPのアーキテクチャ

MCPは、クライアント-サーバーモデルに基づくアーキテクチャで構成されています。

3つの主要コンポーネント

MCPホスト(Host)
ユーザーが直接操作するAIアプリケーションです。Claude Desktop、IDE(VS Code + Cline)、AIエージェントなどがホストに該当します。ホストはMCPクライアントを内蔵しています。

MCPクライアント(Client)
ホスト内に存在し、MCPサーバーとの通信を担当するコンポーネントです。1つのクライアントは1つのサーバーと1対1で接続します。ホストは複数のクライアント(つまり複数のサーバーとの接続)を持てます。

MCPサーバー(Server)
外部ツールやデータソースへのアクセスを提供する軽量なプログラムです。MCPプロトコルに従ってツールやリソースを公開し、クライアントからのリクエストに応答します。

# MCPのアーキテクチャ図

[ユーザー]
    ↓
[MCPホスト(Claude Desktop / IDEなど)]
    ├── MCPクライアント ←→ MCPサーバー(GitHub)
    ├── MCPクライアント ←→ MCPサーバー(PostgreSQL)
    └── MCPクライアント ←→ MCPサーバー(Slack)

MCPサーバーが提供する3つの機能

MCPサーバーは、以下の3種類の機能をクライアントに対して公開できます。

1. ツール(Tools)
AIモデルが呼び出せる関数です。「メッセージの送信」「データベースクエリの実行」「ファイルの作成」など、外部システムに対するアクションを定義します。ツールの呼び出しは通常、AIモデルが判断して実行します。

2. リソース(Resources)
AIモデルがコンテキストとして読み込めるデータです。「ファイルの内容」「データベースのスキーマ」「APIのドキュメント」など、AIの判断に必要な情報を提供します。

3. プロンプト(Prompts)
再利用可能なプロンプトテンプレートです。特定のタスクに最適化されたプロンプトをサーバー側で定義し、ユーザーが選択して利用できます。

MCPサーバーの実装方法

MCPサーバーの実装は、公式SDKを使うと比較的簡単です。TypeScript(Node.js)とPythonの両方にSDKが提供されています。

TypeScriptでの基本的なサーバー実装

// TypeScript MCP サーバーの例:社内ナレッジベース検索
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';

const server = new McpServer({
  name: 'knowledge-base',
  version: '1.0.0',
});

// ツールの定義:ナレッジベース検索
server.tool(
  'search_knowledge',
  '社内ナレッジベースを検索します。質問やキーワードで関連するドキュメントを検索できます。',
  {
    query: z.string().describe('検索キーワードまたは質問文'),
    category: z.string().optional().describe('検索カテゴリ(技術, 営業, 人事など)'),
    limit: z.number().default(5).describe('返す結果の最大数'),
  },
  async ({ query, category, limit }) => {
    // データベースやAPIからナレッジを検索
    const results = await searchKnowledgeBase(query, category, limit);
    return {
      content: [{
        type: 'text',
        text: JSON.stringify(results, null, 2),
      }],
    };
  }
);

// ツールの定義:ドキュメント作成
server.tool(
  'create_document',
  '社内ナレッジベースに新しいドキュメントを作成します。',
  {
    title: z.string().describe('ドキュメントのタイトル'),
    content: z.string().describe('ドキュメントの本文(Markdown形式)'),
    category: z.string().describe('カテゴリ'),
    tags: z.array(z.string()).describe('タグのリスト'),
  },
  async ({ title, content, category, tags }) => {
    const doc = await createDocument({ title, content, category, tags });
    return {
      content: [{
        type: 'text',
        text: `ドキュメントを作成しました: ${doc.title} (ID: ${doc.id})`,
      }],
    };
  }
);

// リソースの定義:カテゴリ一覧
server.resource(
  'categories',
  'knowledge://categories',
  async (uri) => ({
    contents: [{
      uri: uri.href,
      mimeType: 'application/json',
      text: JSON.stringify(await getCategories()),
    }],
  })
);

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

Pythonでのサーバー実装

# Python MCP サーバーの例
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
import json

server = Server("database-query")

@server.tool()
async def execute_query(query: str, database: str = "main") -> list[TextContent]:
    """
    社内データベースに対してSQLクエリを実行します。
    SELECT文のみ実行可能です。

    Args:
        query: 実行するSELECTクエリ
        database: 対象データベース名(デフォルト: main)
    """
    # セキュリティチェック
    if not query.strip().upper().startswith("SELECT"):
        return [TextContent(
            type="text",
            text="エラー: SELECT文のみ実行可能です"
        )]

    try:
        results = await db.execute(query, database)
        return [TextContent(
            type="text",
            text=json.dumps(results, ensure_ascii=False, indent=2)
        )]
    except Exception as e:
        return [TextContent(
            type="text",
            text=f"クエリ実行エラー: {str(e)}"
        )]

@server.tool()
async def get_table_schema(table_name: str) -> list[TextContent]:
    """
    指定したテーブルのスキーマ情報(カラム名、型、制約)を取得します。

    Args:
        table_name: テーブル名
    """
    schema = await db.get_schema(table_name)
    return [TextContent(
        type="text",
        text=json.dumps(schema, ensure_ascii=False, indent=2)
    )]

async def main():
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream)

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

MCPサーバーの接続と設定

実装したMCPサーバーをAIアプリケーション(ホスト)に接続する方法を解説します。

Claude Desktopでの設定

Claude Desktopでは、設定ファイルにMCPサーバーの情報を記述します。

// macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
// Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "knowledge-base": {
      "command": "node",
      "args": ["/path/to/knowledge-base-server/dist/index.js"],
      "env": {
        "DATABASE_URL": "postgresql://localhost:5432/knowledge"
      }
    },
    "database-query": {
      "command": "python",
      "args": ["/path/to/database-server/server.py"],
      "env": {
        "DB_HOST": "localhost",
        "DB_NAME": "mydb"
      }
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxx"
      }
    }
  }
}

設定後にClaude Desktopを再起動すると、指定したMCPサーバーが接続され、AIアシスタントがツールを使えるようになります。

トランスポートの選択

MCPでは、クライアントとサーバー間の通信方法として2つのトランスポートが定義されています。

Stdio(標準入出力)
ローカルのプロセス間通信に使用します。サーバーを子プロセスとして起動し、stdin/stdoutで通信します。ローカル環境でのMCPサーバー実行に適しています。

SSE(Server-Sent Events)/ Streamable HTTP
HTTP経由での通信に使用します。リモートサーバーへの接続や、Web経由でのMCPサーバー公開に適しています。

公開MCPサーバーの活用

自分でサーバーを実装しなくても、コミュニティやベンダーが公開しているMCPサーバーを活用できます。

主要な公開MCPサーバー

ファイル・データ系

Filesystem:ローカルファイルシステムの読み書き
PostgreSQL:PostgreSQLデータベースへのクエリ実行
SQLite:SQLiteデータベースの操作
Google Drive:Google Driveのファイル管理

開発ツール系

GitHub:リポジトリ、イシュー、プルリクエストの管理
GitLab:GitLabプロジェクトの操作
Sentry:エラー監視データの取得

コミュニケーション系

Slack:メッセージの送受信、チャンネル管理
Gmail:メールの検索・送信

情報収集系

Brave Search:Web検索
Fetch:Webページの取得

# 公開MCPサーバーの利用例(npxで直接実行)
# GitHub MCPサーバー
npx -y @modelcontextprotocol/server-github

# PostgreSQL MCPサーバー
npx -y @modelcontextprotocol/server-postgres "postgresql://localhost/mydb"

# Filesystem MCPサーバー(許可するディレクトリを指定)
npx -y @modelcontextprotocol/server-filesystem /path/to/allowed/directory

MCPのセキュリティと運用上の注意点

MCPサーバーは外部システムへのアクセスを提供するため、セキュリティの考慮が不可欠です。

セキュリティのベストプラクティス

最小権限の原則
MCPサーバーに付与するアクセス権限は必要最小限にします。データベースサーバーならSELECTのみの読み取り専用ユーザーを使い、ファイルシステムサーバーなら特定のディレクトリのみアクセスを許可します。

入力のバリデーション
AIモデルからのリクエスト内容を必ず検証します。SQLインジェクションやパストラバーサルなどの攻撃を防止するためのサニタイズ処理を実装しましょう。

認証情報の管理
APIキーやデータベースの接続情報は環境変数で管理し、MCPサーバーのコードに直接記述しないでください。設定ファイルのパーミッションも適切に制限します。

ログと監査
MCPサーバーが処理したリクエストのログを記録し、不審な操作を検出できるようにします。特にデータの変更や削除を伴う操作は詳細にログを残しましょう。

人間による承認フロー

MCPの仕様では、ツールの実行前にユーザーの承認を求める仕組みが考慮されています。データの変更や外部への送信を行うツールは、実行前に必ずユーザーの確認を求めるように設計しましょう。

まとめ

MCPは、AIモデルと外部ツールの連携を標準化するオープンプロトコルです。本記事のポイントを振り返ります。

・MCPはAIアプリケーションと外部ツールのM×N問題を解決する標準プロトコル
・ホスト・クライアント・サーバーの3層アーキテクチャで構成される
・MCPサーバーはツール・リソース・プロンプトの3種類の機能を公開できる
・TypeScriptまたはPythonのSDKで比較的容易にサーバーを実装できる
・GitHub、PostgreSQL、Slackなど多数の公開MCPサーバーが利用可能
・セキュリティ(最小権限、入力バリデーション、ログ)への配慮が不可欠

MCPの普及により、AIアシスタントが企業の業務システムやツールとシームレスに連携する未来が近づいています。まずは公開MCPサーバーをClaude Desktopに接続して、AIとツール連携の可能性を体感してみてください。自社の業務に特化したMCPサーバーの開発にも、ぜひ挑戦してみましょう。

#MCP#プロトコル#AI連携

Harmonic Society

この記事の内容、自社の業務でも活かせそうですか?

ローカルLLM・AI・クラウドなどの技術導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK。まずは30分の無料相談から。売り込みはしません。

共有:
無料メルマガ

週1回、最新の技術記事をお届け

AI・クラウド・開発の最新記事を毎週月曜にメールでお届けします。登録は無料、いつでも解除できます。

プライバシーポリシーに基づき管理します

関連記事

Related / 9 articles

  1. プログラミング

    DDoS攻撃の仕組みと対策入門|レイヤー別の防御とCDN・クラウドの活用

    DDoS攻撃をボリューム型・プロトコル型・アプリ層に分けて仕組みを解説し、自前サーバーで防げない理由、CloudflareやAWS Shieldの標準防御、オリジンIPの隠し方、レートリミットとBot対策、攻撃を受けたときの初動、費用が跳ね上がるDenial of Walletへの備えまでわかります。

  2. プログラミング

    WAFとは?仕組み・導入パターン・誤検知対策|Webアプリを攻撃から守る実践ガイド

    WAFがファイアウォールやIDSと何が違うのか、シグネチャとマネージドルールの仕組み、Cloudflare WAF・AWS WAF・ModSecurityの比較、フォーム送信がブロックされる誤検知の調査と例外設定、ログ監視、WAFが代替できないことまで実践的に解説します。

  3. プログラミング

    セキュリティヘッダー入門|CSP・HSTS・X-Frame-Optionsの設定と効果を実践解説

    CSP・HSTS・X-Frame-Options・X-Content-Type-Optionsなど主要セキュリティヘッダーが防ぐ攻撃と、CSPのReport-Onlyからの段階導入、nonce/hash、HSTS preloadの不可逆リスク、Nginx・Next.js・Astroでの設定例、確認方法を解説します。

  4. プログラミング

    クラウドの通信費(Egress)入門|データ転送量課金の仕組みと転送コストを抑える設計

    クラウドの「受信無料・送信有料」の原則、AZ間・リージョン間・インターネット向けの単価差、NATゲートウェイ処理料の罠、CDNで転送量を減らす方法、バックアップやログ転送の見落とし、請求書で転送料を特定する手順を解説。想定外の請求を防げます。

  5. プログラミング

    秘密情報をGitに入れない仕組み|.gitignore・git-secrets・履歴から漏れた鍵の削除

    APIキーや.envをGitにコミットしてしまう典型経路と、.gitignore・.env.exampleの運用、pre-commitでのgitleaks検知、GitHub secret scanningの活用、漏れた鍵の無効化と履歴書き換え(git filter-repo)の手順を解説。仕組みで再発を防げます。

  6. プログラミング

    開発・ステージング・本番環境の分離設計|環境差分をなくす構成とアクセス制御

    開発・ステージング・本番それぞれの目的と、構成をコードで揃える方法、環境別の設定注入、本番データを使わないテストデータ戦略、ステージングの保護(Basic認証・IP制限・noindex)、コストを抑える運用までを解説。環境差分による本番障害を防げます。

  7. プログラミング

    ngrok・Cloudflare Tunnelでローカルを公開|Webhook開発とデモ環境の作り方

    NAT内のローカル環境にStripeやLINEのWebhookを届けるトンネリングの仕組みを解説。ngrok・Cloudflare Tunnel・localtunnelの比較、固定ドメインと認証、リクエスト検査、公開時のセキュリティ、自宅サーバー公開への応用までわかります。

  8. プログラミング

    ローカル開発環境のHTTPS化|mkcert・hostsファイル・自己署名証明書の正しい使い方

    ローカル開発をHTTPS前提にすべき理由(Secure Cookie・Service Worker・OAuth)と、mkcertでローカルCAを作りhostsで独自ドメインを割り当ててVite・Next.js・Dockerで使う手順を解説。証明書警告を無視する癖の危険も理解できます。

  9. プログラミング

    localhost・0.0.0.0・127.0.0.1の違い|ポートとUnixソケットを理解して「つながらない」を解決

    localhost・127.0.0.1・0.0.0.0の意味の違い、Dockerで外から接続できない原因、host.docker.internal、ポート競合の調べ方、Unixソケットの利点と権限、1024未満ポートの制約を解説。「つながらない」を仕組みから解決できます。

Harmonic Society

「読んで終わり」にせず、自社の業務で試してみませんか?

AI・ローカルLLM・クラウドの導入を、要件整理からPoC・社内展開まで代表エンジニアが伴走します。オンライン対応・全国OK・売り込みなし。

無料・30分・オンラインOK|1営業日以内に返信します