nato243 weblog.n-jitter brand iconweblog.n-jitter
テクノロジー

Golang でRemote MCP Server(SSE)の素振り

2025.05.18
GolangAI
Golang でRemote MCP Server(SSE)の素振り アイキャッチ

各自のローカルPCでMCPサーバーを動作させるstdioインターフェースから、サーバーサイドで直接MCPサーバー自体をホストするリモートMCPの流れが進んでいる。

Developers IO / ClaudeのWeb版で待望のModel Context Protocol (MCP)連携ができるようになりました!

ローカルMCPサーバーはPCソフトウェアの自動化文脈では残るだろうが、基本的には今後リモートMCPの流れになるだろう。
バイナリやアプリを配布しなくても非開発者にMCPサーバーを使わせやすくなるし、好きな場所でアプリをホストできるからだ。

そろそろ私もRemoteMCPもやっとこうと思い、今回はその素振りである。

mark3labs/mcp-go



以前の記事 では MCPサーバーのフレームワークとして https://github.com/metoro-io/mcp-golang を利用していたが、現在はhttps://github.com/mark3labs/mcp-go をメインで使っている。

Star数や今後のGo x MCPの開発動向的にどうやらこちらのほうが活発そうだったのがひとつ。
もうひとつは、「Goのフィールドタグにjsonschemaの説明を書く」、というgithub.com/metoro-io/mcp-golangのアプローチだと、どうしても説明が短文にならざるをえず、書きづらかった。
mark3labs/mcp-goはフォーマット自由にDescriptionを書けるライブラリなので、プロンプトが大事になるLLMの世界とは相性が良い。

サッと動く実装は以下である。
サンプルによくあるHellow World MCPである。

package main

import (
    "context"
    "errors"
    "fmt"
    "github.com/mark3labs/mcp-go/mcp"
    "github.com/mark3labs/mcp-go/server"
)

/* 
claude desktop等の場合
   "helloworld": {
       "command": "npx",
       "args": [
          "-y",
           "mcp-remote@latest",
           "http://localhost:9094/sse"
       ]
    }

*/

func main() {

    // Create MCP server
    s := server.NewMCPServer(
       "挨拶サーバー",
       "1.0.0",
    )

    // Add tool
    tool := mcp.NewTool("hello_world",
       mcp.WithDescription("Say hello to someone"),
       mcp.WithString("name",
          mcp.Required(),
          mcp.Description("Name of the person to greet"),
       ),
    )

    // Add tool handler
    s.AddTool(tool, helloHandler)

    sseServer := server.NewSSEServer(s)

    if err := sseServer.Start(`:9094`); err != nil {
       fmt.Printf("Server error: %v\n", err)
    }

}

func helloHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    name, ok := request.Params.Arguments["name"].(string)
    if !ok {
       return nil, errors.New("name must be a string")
    }

    return mcp.NewToolResultText(fmt.Sprintf("おはよう, %s!", name)), nil
}

リモートMCPサーバーの中でもtrasnportには複数種類あり、
SSE(サーバー送信イベント)とStreamable HTTPが仕様として定義されている。今後主流になるのはStreamable HTTPとされているが、残念なことに、github.com/mark3labs/mcp-go ではまだ 2025.05時点で開発中のようだ。
そこで今回は上記のコードの通りSSEで定義している。

Claude DesktopでリモートMCPがネイティブサポートされていない

手元のClaude Desktop から開発したローカルMCPサーバーをどう叩くのかな?と調べていたが、なんと2025.05時点でサポートしていないようだ。

リモートで動作する MCP Server を実装し、Claude アプリから呼び出してみる
しかたがないので、このサイトを参考に、
NodeJSコマンド mcp-remote を導入し、このローカルMCP経由で実行した。
以下のように記載する。


// claude desktop等の場合
   "helloworld": {
       "command": "npx",
       "args": [
          "-y",
           "mcp-remote@latest",
           "http://localhost:9094/sse"
       ]
    }

問題なく実行できていますね。
今後はこれを直接AWS LambdaでHTTPサーバーとしてホストしていこう。