世界最小・外部依存なしのMCPサーバー"Hello World"をつくってMCPの仕組みを完全に学ぶ

2025年07月12日 | AI開発

MCPサーバーを学ぶ

この記事をシェア

🚀 MCPがAPIを置き換える時代がやってきた

皆さんは、Model Context Protocol(MCP)という新しいプロトコルをご存知でしょうか?Anthropic社が開発し、Claude Desktopで採用されているこのプロトコルは、AIと外部システムの連携方法に革命をもたらそうとしています

私は、インターネット上で展開されるサービスは、APIからMCPサーバーにとってかわるだろうと考えています。なぜなら、AIが自律的にWeb上のサービスを使うには、APIではなくMCPサーバーの方が圧倒的に適しているからです。

💡 なぜAPIではなくMCPなのか?

従来のAPIの限界

  • 設計思想の違い: APIは人間の開発者が使うことを前提に設計されている
  • 複雑な認証: OAuth、API Key、トークン管理など、AIにとって煩雑
  • ドキュメント依存: OpenAPI仕様書があってもAIには理解しづらい
  • エラー処理: 人間向けのエラーメッセージはAIには不親切

MCPの優位性

  • AI-First設計: 最初からAIエージェントが使うことを前提に設計
  • 統一プロトコル: JSON-RPCベースの標準化されたやり取り
  • ツール定義: AIが理解しやすいスキーマ定義
  • 双方向通信: stdioを通じたシンプルな通信モデル
  • コンテキスト保持: AIとツールが状態を共有しやすい

🎯 今回の目標:最小限のMCPサーバーを作る

そんなMCPサーバーを自作するための第一歩として、この記事では「Hello World!」を返すだけの最小限のMCPサーバーを作ってみます。外部依存関係を一切使わず、純粋なNode.jsだけで実装することで、MCPプロトコルの仕組みを完全に理解することができます。

MCPプロトコルの通信フロー

図1: MCPプロトコルはJSON-RPCベースでstdio経由で通信

📦 必要なファイルはたった2つ!

驚くほどシンプルです。必要なファイルは以下の2つだけです:

  1. package.json - プロジェクト設定ファイル
  2. server.js - MCPサーバー本体

📄 package.json

{
  "name": "minimal-mcp-server-manual",
  "version": "1.0.0",
  "description": "世界最小のMCPサーバー - 手動JSON-RPC実装版",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "keywords": ["mcp", "server", "minimal", "hello-world", "json-rpc"],
  "author": "",
  "license": "MIT"
}

注目すべきは dependencies がないことです。本当に外部依存がゼロなのです!

🔧 server.js - MCPサーバーの心臓部

以下が、MCPサーバーの完全なソースコードです。各部分を詳しく見ていきましょう:

💡 ポイント: コードは詳細なコメント付きで、MCPプロトコルの仕組みがよくわかるようになっています。
#!/usr/bin/env node

/**
 * 世界最小のMCPサーバー - 手動JSON-RPC実装版
 * MCPプロトコルの仕組み:
 * 1. Claude Desktop がstdio経由でJSON-RPCリクエストを送信
 * 2. サーバーがリクエストを処理してレスポンスを返す
 * 3. 通信は行ベースのJSON形式
 */

// 標準入力をUTF-8として設定
process.stdin.setEncoding('utf8');

// 不完全なJSON行を蓄積するバッファ
let buffer = '';

// サーバーの基本情報
const serverInfo = {
    name: "minimal-mcp-server-manual",
    version: "1.0.0"
};

// このサーバーが提供するツールの定義
const tools = [
    {
        name: "hello_world",
        description: "Hello World!を返すシンプルなツール",
        inputSchema: {
            type: "object",
            properties: {},
            required: []
        }
    }
];

// JSON-RPCリクエストを処理するメイン関数
function handleRequest(request) {
    const { jsonrpc, id, method, params } = request;
    
    switch (method) {
        case "initialize":
            // 初期化:MCPサーバーの機能を宣言
            return {
                jsonrpc: "2.0",
                id,
                result: {
                    protocolVersion: "2024-11-05",
                    capabilities: { tools: {} },
                    serverInfo
                }
            };
            
        case "tools/list":
            // ツール一覧を返す
            return {
                jsonrpc: "2.0",
                id,
                result: { tools }
            };
            
        case "tools/call":
            // ツールを実行
            if (params.name === "hello_world") {
                return {
                    jsonrpc: "2.0",
                    id,
                    result: {
                        content: [{
                            type: "text",
                            text: "Hello World!"
                        }]
                    }
                };
            }
    }
}

// 標準入力からのデータを処理
process.stdin.on('data', (data) => {
    buffer += data.toString();
    const lines = buffer.split('\n');
    buffer = lines.pop() || '';
    
    lines.forEach(line => {
        if (!line.trim()) return;
        
        try {
            const request = JSON.parse(line);
            const response = handleRequest(request);
            if (response) {
                process.stdout.write(JSON.stringify(response) + '\n');
            }
        } catch (error) {
            console.error('Error:', error);
        }
    });
});

🔄 MCPプロトコルの通信フロー

上記のコードから、MCPプロトコルの通信フローが見えてきます。以下の3つのステップで通信が行われます:

1️⃣ 初期化フェーズ

Claude Desktopが接続すると、まずinitializeメソッドを呼び出します:

→ {"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {}}
← {"jsonrpc": "2.0", "id": 1, "result": {"protocolVersion": "2024-11-05", ...}}

2️⃣ ツール一覧取得

次に、利用可能なツールの一覧を取得します:

→ {"jsonrpc": "2.0", "id": 2, "method": "tools/list"}
← {"jsonrpc": "2.0", "id": 2, "result": {"tools": [...]}}

3️⃣ ツール実行

ユーザーがツールを使用すると:

→ {"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "hello_world"}}
← {"jsonrpc": "2.0", "id": 3, "result": {"content": [{"type": "text", "text": "Hello World!"}]}}

🚀 実際に動かしてみよう!

1. プロジェクトのセットアップ

mkdir my-mcp-server
cd my-mcp-server

# package.jsonとserver.jsを作成(上記のコードをコピー&ペースト)

2. Claude Desktopの設定

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-hello-world": {
      "command": "node",
      "args": ["/path/to/my-mcp-server/server.js"],
      "env": {}
    }
  }
}

3. 動作確認

  1. Claude Desktopを再起動
  2. 新しいチャットで「hello_worldツールを使って」と入力
  3. 「Hello World!」が返されれば成功!🎉

🎓 まとめ:MCPの未来に向けて

この記事では、外部依存なしの最小限のMCPサーバーを作成し、MCPプロトコルの仕組みを学びました。

📚 学んだこと

  • ✅ MCPがAPIに代わる理由とその優位性
  • ✅ JSON-RPCベースの通信プロトコル
  • ✅ stdio経由でのメッセージ交換
  • ✅ ツールの定義と実行方法

🚀 次のステップ

  1. より複雑なツールの実装(パラメータ付き、非同期処理など)
  2. エラーハンドリングの強化
  3. 複数ツールの提供
  4. 実用的なMCPサーバーの開発(データベース連携、API連携など)

MCPの世界は始まったばかりです。この記事が、あなたがMCPサーバーを開発する第一歩となることを願っています。APIからMCPへ、新しい時代のインターフェースを一緒に作っていきましょう!

💡 ヒント: この記事で紹介したコードは、実際にダウンロードして試すことができます。ぜひ自分の手で動かして、MCPの仕組みを体感してください!

この記事が役に立ったらシェアしてください

MCPの可能性を多くの開発者に知ってもらいましょう!

カテゴリ

AI開発

公開日

2025年07月12日

お気軽にご相談ください

記事に関するご質問や、AI・IT技術導入のご相談など、お気軽にお問い合わせください。

お問い合わせ サービス一覧