「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サーバーの開発にも、ぜひ挑戦してみましょう。
関連記事
AIエージェント開発入門|自律型AIの仕組みと構築方法を解説【2026年版】
AI駆動コーディングワークフロー|Claude Code・Cursor・Copilotの実践的使い分け
プロンプトエンジニアリング上級編|Chain-of-Thought・Few-Shot・ReActの実践
APIレート制限の設計と実装|トークンバケット・スライディングウィンドウ解説
APIバージョニング戦略|URL・ヘッダー・クエリパラメータの使い分け
BIツール入門|Metabase・Redash・Looker Studioでデータ可視化する方法
チャットボット開発入門|LINE Bot・Slack Botの構築方法と活用事例
CI/CDパイプラインの基礎|継続的インテグレーション・デリバリーの全体像