Go言語でMCPサーバーを実装し、LMStudioから使ってみた

LMStudioもMCP(Model Context Protocol)に対応したので、Go言語で独自のMCPサーバーを作ってみました。作成したのはローン計算の計算ができる「金融電卓」です。この記事では、mcp-goを使ったMCPサーバーの実装例と、それをLMStudioから使う方法について解説します。
はじめに
MCPとは?
Model Context Protocol(MCP)はClaudeの開発元であるAnthropicにより提案された、大規模言語モデル(LLM)が外部のコンテキスト(情報)にアクセスする方法を標準化するためのオープンなプロトコルです。MCPはLLMと多様なデータソースやツールとの連携を標準化するとっても便利なプロトコルです。
これを使っていろんなサービスを連携させることができ、実際にたくさんのMPCサーバーが提供されています。この記事では、「使うのではなく、MCPサーバーをGo言語で作りたい」という方に向けた記事になります。
Go言語の対応状況
公式のドキュメントを見ると、Python、Node、Java、Kotlin、C#でMCPサーバーを作るサンプルはありますが、残念ながらGo言語については書かれていません。
とりあえず、検索すると以下のライブラリがGithubにアップされていました。
https://github.com/mark3labs/mcp-go

他のGo向けのmcpのパッケージがありましたが、スター(★)が多かったのでこれを選びました。
今回使うライブラリ
今回使うライブラリはmcp-go
というモデル コンテキスト プロトコル (MCP) の Go 実装です。ドキュメントはまだ整備されていない感じですがサンプルやexamples
のフォルダを眺めながらコードを作成していきました。
ちなみに、2025/03/21に公開されていたZennの記事のサンプルコードはエラーによりビルドできなかったので、ライブラリは活発に書き換えられている感じかもしれません。
Zennの記事:
「GoのModel Context Protocol (MCP)の開発フレームワークmcp-goを使ってみる」

もしかしたら、ここで作ったプログラムもライブラリの変更により動作しなくなるかも。とりあえず、バージョン指定の入ったgo.modを含めたコードを以下に置いておきます。
MCPサーバーを作ってみる
作成するMCPサーバーの機能
とりあえず、金融電卓を作ってみます。今回は、ファイナンシャル・プランニング使う6つの係数を使って計算する機能を実装します。
- 終価係数
現金X円が、年利r%でN年複利運用した場合にいくらになるかを計算する係数 - 現価係数
N年後にX円を準備したいとき、年利r%で複利運用した場合に元本はいくら必要かを計算する係数 - 年金終価係数
年利r%の複利運用で毎年X円積み立てるとN年後にいくらになるかを計算する係数 - 年金現価係数
N年間、毎年X円を受け取りたい時に、元本はいくらあれば良いかを計算する係数。なお、運用利率はr%とする - 資本回収係数
X万円を、運用利益r%で運用しながらN年間にわたって取り崩す場合、毎年いくら受け取れるかを計算する係数。X万円のローンを金利r%でN年間で返済する場合に、毎年いくら返済すれば良いかという計算にも使えます - 減債基金係数
年利r%で運用してN年後にX万円ためるには、毎年いくら積み立てれば良いかを計算する係数

今回はこの2つだけ実装します。係数についてはこちらの記事を参考にしてください。
コード
以下、コードです。
mcp-goのexamples等をみながら試行錯誤で作成しました。
実装のポイントは以下のようになると思います。
- Descriptionで何のツールかを記述する(今回は英語で書いています)
- 各パラメータについても、必須かどうかと、パラメータの説明を記述する
- financeHandlerでパラメータを受け取って、処理を行う
- LLMへの返答は、少し無駄があってもLLM側が解析してくれるので問題なさそう
- 係数の計算は、デバッグしやすくするため別に関数定義
package main
import (
"context"
"fmt"
"math"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
// Define constants for financial calculation types
const (
FutureValueFactor = "Future Value Factor"
PresentValueFactor = "Present Value Factor"
FutureValueOfAnnuityFactor = "Future Value of Annuity Factor"
PresentValueOfAnnuityFactor = "Present Value of Annuity Factor"
SinkingFundFactor = "Sinking Fund Factor"
CapitalRecoveryFactor = "Capital Recovery Factor"
)
// Define a slice of available financial calculation operations
var financialOperations = []string{
FutureValueFactor,
PresentValueFactor,
FutureValueOfAnnuityFactor,
PresentValueOfAnnuityFactor,
SinkingFundFactor,
CapitalRecoveryFactor,
}
// main is the entry point for the Finance Calculator MCP server.
//
// The Finance Calculator performs the following financial calculations:
// 1. Future Value Factor: Calculates the future value of a present sum after a period of compound interest.
// 2. Present Value Factor: Calculates the present value of a future sum.
// 3. Future Value of Annuity Factor: Calculates the future value of a series of equal payments (annuity).
// 4. Present Value of Annuity Factor: Calculates the present value of a series of equal payments (annuity).
// 5. Sinking Fund Factor: Calculates the annual deposit required to reach a specific future sum.
// 6. Capital Recovery Factor: Calculates the payment required to recover an initial investment.
//
// The server is started with standard input/output.
func main() {
// Create a new MCP server
s := server.NewMCPServer(
"Finance Calculator",
"1.0.0",
server.WithResourceCapabilities(true, true), // Options used for Resource features
server.WithLogging(),
)
// Define the interface for the financial calculator tool
calculatorTool := mcp.NewTool("financial_calculator",
mcp.WithDescription("Performs financial calculations."),
mcp.WithString("operation",
mcp.Required(),
mcp.Description(`The financial calculation to perform. Select one of the following:
- Future Value Factor: Calculates the future value of a present sum after a period of compound interest.
- Present Value Factor: Calculates the present value of a future sum.
- Future Value of Annuity Factor: Calculates the future value of a series of equal payments (annuity).
- Present Value of Annuity Factor: Calculates the present value of a series of equal payments (annuity).
- Sinking Fund Factor: Calculates the annual deposit required to reach a specific future sum.
- Capital Recovery Factor: Calculates the payment required to recover an initial investment.`),
mcp.Enum(financialOperations...),
),
mcp.WithNumber("r",
mcp.Required(),
mcp.Description("interest rate(0.0 ~ 1.0)"),
),
mcp.WithNumber("n",
mcp.Required(),
mcp.Description("number of periods(years)"),
),
mcp.WithNumber("amount",
mcp.Required(),
mcp.Description("amount"),
),
)
// Add a tool handler
s.AddTool(calculatorTool, financeHandler)
// Start the server with standard I/O
if err := server.ServeStdio(s); err != nil {
fmt.Printf("Server error: %v\n", err)
}
}
// calculateFinancialRate calculates various financial rates based on the given operation.
// Parameters:
// - op: The type of financial calculation to perform. Supported operations include:
// "Future Value Factor", "Present Value Factor", "Future Value of Annuity Factor",
// "Present Value of Annuity Factor", "Sinking Fund Factor", and "Capital Recovery Factor".
// - r: The interest rate expressed as a decimal (e.g., 0.05 for 5%).
// - n: The number of periods (e.g., years) over which the calculation is performed.
//
// Returns:
// - The calculated rate as a float64 based on the specified operation.
// - An error if the provided operation is unknown.
func calculateFinancialRate(op string, r, n float64) (float64, error) {
var rate float64
// Branch calculation based on operation type
switch op {
case FutureValueFactor:
rate = math.Pow(1+r, n)
case PresentValueFactor:
rate = math.Pow(1+r, -n)
case FutureValueOfAnnuityFactor:
rate = (math.Pow(1+r, n) - 1) / r
case PresentValueOfAnnuityFactor:
rate = (1 - math.Pow(1+r, -n)) / r
case SinkingFundFactor:
rate = r / (math.Pow(1+r, n) - 1)
case CapitalRecoveryFactor:
rate = (r * math.Pow(1+r, n)) / (math.Pow(1+r, n) - 1)
default:
return 0, fmt.Errorf("unknown operation: %s", op)
}
return rate, nil
}
// financeHandler is the handler for the financial tool.
// It takes four parameters:
// - operation: The type of financial calculation to perform.
// - r: The interest rate expressed as a decimal (e.g., 0.05 for 5%).
// - n: The number of periods (e.g., years) over which the calculation is performed.
// - amount: The amount on which the calculation is based.
// It returns the calculated financial rate and the result as an integer.
func financeHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// Get operation from arguments
op, ok := request.GetArguments()["operation"].(string)
if !ok {
return nil, fmt.Errorf("missing operation")
}
// Get interest rate from arguments
r, ok := request.GetArguments()["r"].(float64)
if !ok {
return nil, fmt.Errorf("missing r")
}
// If the interest rate is greater than 1, divide by 10
if r > 1 {
r /= 10.0
}
// Get number of periods from arguments
n, ok := request.GetArguments()["n"].(float64)
if !ok {
return nil, fmt.Errorf("missing n")
}
// Get amount from arguments
amount, ok := request.GetArguments()["amount"].(float64)
if !ok {
return nil, fmt.Errorf("missing amount")
}
// Calculate financial rate
rate, err := calculateFinancialRate(op, r, n)
if err != nil {
return nil, err
}
// Calculate result
result := amount * rate
// Format and return the calculation result
return mcp.NewToolResultText(fmt.Sprintf("rate = %f n = %f amount = %f result rate = %f result is %d", r, n, amount, rate, int(result))), nil
}
上記のプログラムをビルドします。以下のコマンドを行うことでビルドできると思います。
go mod init
go mod tidy
go build
LMStuidoに登録して使ってみる
登録方法
LMStudioを立ち上げて、左側のタブを開いてProgramを選択し、InstallをクリックしてEdit mcp.json
でjsonファイルを開きます。

mcp.json
が開くので、ここに以下を追加します。フォルダは、作成したGo作成した実行プログラムへのパスをフルパスで指定します。
{
"mcpServers": {
"finance calc": {
"command": "/フォルダ/作成した実行プログラム名",
"args": []
}
}
}
保存すると、右のタブに登録されますので、ONにします。

これで利用準備が整いました。
いざ、実行
ツールに対応している(ツールマークのあるLLM)をロードして、ツールが実行されるか試してみます。
今回は、qwen3-30b-a3b-mlx
を使ってみました(実行環境はMacです)。
モデル名の横にある工具のアイコン(青いアイコン)がツール対応を示しています。

質問No.1
とりあえず、以下のような質問をします。
/no_think
年率3%で20年後に2000万円を受け取りたい場合、いくらずつ積み立てれば良いか?
※/no_think
は、推論モードをOFFにするQwen3の指示です。
すると、ツールを使用するかどうか尋ねてきますので、許可します。

ちゃんとツール(Sinking Fund Factor
)を使って回答していることがわかります。

LMStudioを一旦終了させないと、Goのソースコードを書き換えても反映させる、デバッグに少し苦労しました。修正するときはLMStudioも終了した方が良いです。

途中からgemini cli
にmcpサーバー
を登録して、デバッグしました。個人的にはコードのデバッグはvscodeのターミナルから実行できるコマンドラインツールの方が楽でした。
質問No.2
続けて、次のように質問します。
1000万借りて金利4%で10年で返済する場合、毎年いくら返せば良い?

今度は、ツールのCapital Recovery Factor
を呼び出して回答してきました。
高度な質問例
では、もう少し難しめの質問をしてみます。
/no_think
5年後に定価が400万円の車を購入しようと考えています。5年間金利1%で一定額を積み立てて購入するのと、金利2.9%の自動車ローンで一定額を支払って購入するのでは総支払い額はいくら違う?
このような質問に対して適切にツールを使ってくれると嬉しいです。回答は以下のようになりました。

出力結果を見ると、積み立ての場合はSinking Fund Factor
を、ローンの場合はCapital Recovery Factor
をそれぞれ使っていることがわかります。このように、必要な計算がある場合に自動で呼び出してくれて便利です。

プロンプトにより呼び出さなかったり、間違った係数を使ったりしていました。Qwen3-30B-A3Bでも、2回目に実行したときは間違った係数を使っていました。ミスは、特に小さいモデルで多かったです。MCPを使う場合は大きいモデルがよいと思います。

あと、Descriptionも工夫すべきですね。
まとめ
MCPサーバーをGo言語で作成する方法について解説しました。Goでツールを作る人は少ないかと思いますが、参考になれば幸いです。