🪐

GoでMCP(Model Context Protocol)サーバーを立ててみた

に公開

はじめに

MCP(Model Context Protocol)は、AIモデルが外部ツールやデータソースと安全かつシームレスに連携するためのオープンスタンダードのことです。
MCPを活用すると、AIモデルとデータソースの間で統一されたプロトコルに基づく通信が可能になり、汎用性の高いアーキテクチャを実現できます。

本記事では、Goを用いてMCPサーバーを構築し、JSON-RPC 2.0を通じてクライアントと通信する方法を解説します。

対象読者

  • MCPの基本概念を学びたい方
  • GoでJSON-RPC 2.0サーバーを実装したい方
  • AIモデルと外部ツールを連携させる仕組みを作りたい方

目次

  1. MCP(Model Context Protocol)とは?
    • MCPの役割と仕組み
    • なぜMCPを使うのか?
  2. GoでMCPサーバーを実装する
    • JSON-RPC 2.0の基本
    • MCPサーバーのエンドポイント定義
    • GoでのJSON-RPC 2.0サーバーの実装
  3. MCPクライアントを実装し、動作確認
    • JSON-RPC 2.0クライアントの実装
    • 実際にデータの送受信を行う
  4. まとめ

1. MCP(Model Context Protocol)とは?

1.1 MCPの役割と仕組み

MCPは、AIモデルが外部データソースやツールと安全にやり取りするための通信プロトコルです。
以下のような特徴を持っています。

特徴 説明
標準化 外部システムと統一されたインターフェースで通信可能
セキュア データの送受信時に認証・暗号化を実装可能
スケーラブル AIモデルのスケールアウトが容易になる

1.2 なぜMCPを使うのか?

MCPを導入することで、AIモデルのデータ連携がより柔軟かつ安全になります。

例えば、以下のようなユースケースがあります。

  • AIモデルがデータベースからリアルタイムで情報を取得
  • 外部のフィードバックシステムと統合し、モデルを自動調整
  • 異なるツールとAPIを統一的に管理

1.3 MCP は JSON-RPC 2.0 をベースにしている

MCPはJSON-RPC 2.0 を基盤としたプロトコルであり、リクエストとレスポンスの形式はJSONで統一されています。
このため、gRPCではなく、JSON-RPC 2.0に基づいたサーバーを実装する必要があります。(誤りがあったため修正しました。)


2. GoでMCPサーバーを実装する

2.1 JSON-RPC 2.0の基本

JSON-RPC 2.0は、JSON形式のリクエストとレスポンスを用いた軽量なRPC(Remote Procedure Call)プロトコルです。

基本的な JSON-RPC 2.0 のリクエスト・レスポンスのフォーマットは以下の通りです。

リクエストの例(AI モデルへの入力)

{
  "jsonrpc": "2.0",
  "method": "processInput",
  "params": { "model_id": "AI-001", "input_data": "Hello" },
  "id": 1
}

レスポンスの例(処理結果)

{
  "jsonrpc": "2.0",
  "result": { "output_data": "Processed: Hello", "success": true },
  "id": 1
}

2.2 GoでJSON-RPC 2.0サーバーを実装

MCP サーバー(server.go

package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type Request struct {
    JSONRPC string `json:"jsonrpc"`
    Method  string `json:"method"`
    Params  map[string]string `json:"params"`
    ID      int `json:"id"`
}

type Response struct {
    JSONRPC string `json:"jsonrpc"`
    Result  map[string]interface{} `json:"result"`
    ID      int `json:"id"`
}

func handleMCPRequest(w http.ResponseWriter, r *http.Request) {
    var req Request
    json.NewDecoder(r.Body).Decode(&req)
    log.Printf("Received request: %s", req.Method)
    
    response := Response{
        JSONRPC: "2.0",
        Result: map[string]interface{}{
            "output_data": "Processed: " + req.Params["input_data"],
            "success": true,
        },
        ID: req.ID,
    }
    json.NewEncoder(w).Encode(response)
}

func main() {
    http.HandleFunc("/mcp", handleMCPRequest)
    log.Println("MCP Server is running on port 8080")
    http.ListenAndServe(":8080", nil)
}
  • /mcp エンドポイントを作成し、JSON-RPC 2.0 のリクエストを処理
  • handleMCPRequest() でリクエストをパースし、レスポンスを生成

3. MCPクライアントを実装し、動作確認

3.1 JSON-RPC 2.0クライアントの実装

MCPクライアント(client.go

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    requestBody := map[string]interface{}{
        "jsonrpc": "2.0",
        "method": "processInput",
        "params": map[string]string{"model_id": "AI-001", "input_data": "Hello"},
        "id": 1,
    }

    jsonBody, _ := json.Marshal(requestBody)
    resp, _ := http.Post("http://localhost:8080/mcp", "application/json", bytes.NewBuffer(jsonBody))
    var response map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&response)
    fmt.Println(response)
}
  • クライアントがJSON-RPC 2.0のリクエストを送信
  • /mcp エンドポイントにHTTP POSTで送信し、レスポンスを受信

4. まとめ

項目 説明
MCP AIモデルと外部ツールを連携するプロトコル
JSON-RPC 2.0 軽量なRPCプロトコルで、MCPの基盤
MCP サーバー JSON-RPC 2.0を用いてGoで実装

少し高度な内容になりますが、話題のMCPサーバーに触れて見ました。
MCPの場合は、MCPサーバーとMCPクライアントが存在し、一定のプロトコルに沿ってやりとりするため、特定のAIモデルに依存せずいい感じにやり取りができます!

Discussion