Skip to content

Instantly share code, notes, and snippets.

@kuc-arc-f
Created October 3, 2025 05:23
Show Gist options
  • Save kuc-arc-f/350f81552f9314756da4c35162b1a755 to your computer and use it in GitHub Desktop.
Save kuc-arc-f/350f81552f9314756da4c35162b1a755 to your computer and use it in GitHub Desktop.
GoLang , MCP Server
module example.com/go-mcp-server-2
go 1.24.4
package main
import (
"bufio"
"encoding/json"
"fmt"
"os"
)
// JSONRPCリクエスト構造体
type JSONRPCRequest struct {
JSONRPC string `json:"jsonrpc"`
ID interface{} `json:"id"`
Method string `json:"method"`
Params json.RawMessage `json:"params,omitempty"`
}
// JSONRPCレスポンス構造体
type JSONRPCResponse struct {
JSONRPC string `json:"jsonrpc"`
ID interface{} `json:"id"`
Result interface{} `json:"result,omitempty"`
Error *RPCError `json:"error,omitempty"`
}
// RPCエラー構造体
type RPCError struct {
Code int `json:"code"`
Message string `json:"message"`
}
// ツールパラメータ
type AddTenParams struct {
Number int `json:"number"`
}
// ツールリスト
type ToolsList struct {
Tools []Tool `json:"tools"`
}
type Tool struct {
Name string `json:"name"`
Description string `json:"description"`
InputSchema InputSchema `json:"inputSchema"`
}
type InputSchema struct {
Type string `json:"type"`
Properties map[string]Property `json:"properties"`
Required []string `json:"required"`
}
type Property struct {
Type string `json:"type"`
Description string `json:"description"`
}
// ツール呼び出しパラメータ
type CallToolParams struct {
Name string `json:"name"`
Arguments json.RawMessage `json:"arguments"`
}
// ツール実行結果
type ToolResult struct {
Content []Content `json:"content"`
}
type Content struct {
Type string `json:"type"`
Text string `json:"text"`
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
for scanner.Scan() {
line := scanner.Text()
var req JSONRPCRequest
if err := json.Unmarshal([]byte(line), &req); err != nil {
sendError(writer, nil, -32700, "Parse error")
continue
}
handleRequest(writer, req)
}
}
func handleRequest(writer *bufio.Writer, req JSONRPCRequest) {
switch req.Method {
case "initialize":
handleInitialize(writer, req)
case "tools/list":
handleToolsList(writer, req)
case "tools/call":
handleToolsCall(writer, req)
default:
sendError(writer, req.ID, -32601, "Method not found")
}
}
func handleInitialize(writer *bufio.Writer, req JSONRPCRequest) {
result := map[string]interface{}{
"protocolVersion": "2024-11-05",
"serverInfo": map[string]string{
"name": "add-ten-server",
"version": "1.0.0",
},
"capabilities": map[string]interface{}{
"tools": map[string]bool{},
},
}
sendResponse(writer, req.ID, result)
}
func handleToolsList(writer *bufio.Writer, req JSONRPCRequest) {
tools := ToolsList{
Tools: []Tool{
{
Name: "add_ten",
Description: "入力された数値に10を加算します",
InputSchema: InputSchema{
Type: "object",
Properties: map[string]Property{
"number": {
Type: "integer",
Description: "加算する元の数値",
},
},
Required: []string{"number"},
},
},
},
}
sendResponse(writer, req.ID, tools)
}
func handleToolsCall(writer *bufio.Writer, req JSONRPCRequest) {
var params CallToolParams
if err := json.Unmarshal(req.Params, &params); err != nil {
sendError(writer, req.ID, -32602, "Invalid params")
return
}
if params.Name != "add_ten" {
sendError(writer, req.ID, -32602, "Unknown tool")
return
}
var args AddTenParams
if err := json.Unmarshal(params.Arguments, &args); err != nil {
sendError(writer, req.ID, -32602, "Invalid arguments")
return
}
result := args.Number + 10
toolResult := ToolResult{
Content: []Content{
{
Type: "text",
Text: fmt.Sprintf("計算結果: %d + 10 = %d", args.Number, result),
},
},
}
sendResponse(writer, req.ID, toolResult)
}
func sendResponse(writer *bufio.Writer, id interface{}, result interface{}) {
resp := JSONRPCResponse{
JSONRPC: "2.0",
ID: id,
Result: result,
}
data, _ := json.Marshal(resp)
writer.Write(data)
writer.WriteByte('\n')
writer.Flush()
}
func sendError(writer *bufio.Writer, id interface{}, code int, message string) {
resp := JSONRPCResponse{
JSONRPC: "2.0",
ID: id,
Error: &RPCError{
Code: code,
Message: message,
},
}
data, _ := json.Marshal(resp)
writer.Write(data)
writer.WriteByte('\n')
writer.Flush()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment