Go

go‑mcpではまったポイントメモ

記事内に商品プロモーションを含む場合があります

Go製MCPサーバー開発は軽量バイナリと高並列で魅力的ですが、つまづきポイントに引っかかると「動かない」「つながらない」で時間を溶かしてしまいます。本記事では 私のGitHub の実験リポジトリと公開 Issue を読み解き、典型的なつまずきを 1,500 字程度で整理しました。

go‑mcpとは?

Model Context Protocol(MCP)は LLM アプリと外部ツール・データを橋渡しする新興プロトコルです。Go 版 SDK は mark3labs/mcp-go など複数あり、型安全な API と単一バイナリ配布を売りに急速にスターを伸ばしています。しかし仕様も実装も日進月歩で、安定運用には罠を踏み抜かない工夫が必須です。*4

失敗ポイント1 go runとgo.modの位置

実験リポジトリ go-mcp-abc では「go run /path/to/main.go だと go.mod が見つからず解決失敗」という報告が最初の壁に挙がっています。go run -C /path/to のように作業ディレクトリを切り替えるか、ビルド済みバイナリを呼び出すことで回避できます。

  • NG 例:go run /path/to/main.go

  • OK 例:go -C /path/to run main.go

  • OK 例:ビルドして絶対パス実行

プロジェクトルートとサーバープロセスを切り離すと依存解決が破綻する典型例です。

失敗ポイント2 — 標準出力の「余計なおしゃべり」

MCP は JSON‑RPC 2.0 を stdio でやり取りします。fmt.Println(“Starting server…”) といったログが最初に出るとクライアントは JSON 解析に失敗し、Unexpected token ‘S’ で即終了します。README でも「余計な出力はエラーになる」と強調されており、実際に同様の Issue が多数報告されています。

ワンポイント対策

  • ログは log パッケージで SetOutput(io.Discard) しておき、デバッグ時だけ環境変数で切り替える

  • 専用フラグ –verbose を付けたときだけ人間向けログを出す

回避策とベストプラクティス

  • 固定タグ運用

    • SDK は commit hash か semver タグで pin する

  • CI に JSON スモークテストを追加

    • echo ‘{}’ | your‑server | jq で JSON 妥当性を確認

  • エディタ拡張のバージョンも合わせる

    • VS Code / Claude CLI / Cursor などクライアントごとに検証

  • ServeStdio ラッパを自作

    • プリ/ポストフックでログ抑制やパニックリカバリを統一

まとめ

go‑mcp は Go の強みを活かせる一方、「モジュールパスの解決」「人間向けログの混入」「仕様日付のズレ」「SDK の揺れ」という 4 大失敗ポイントを知らないと開発初日にハマります。本稿で紹介した原因と対策を事前に押さえ、最小構成で E2E スモークテストを組んだうえで本格実装に進むのが安全です。アップデートは慎重に、タグ固定と自動テストで“動く状態”を守りましょう。

出典一覧

*1 https://github.com/kazuki-oshino/go-mcp-abc

*2 https://github.com/AgentDeskAI/browser-tools-mcp/issues/103

*3 https://github.com/anthropics/claude-code/issues/768

*4 https://github.com/mark3labs/mcp-go