Skip to main content
Tutorial3 min read

Build an MCP server in Go: the official Go SDK (2026)

The official Model Context Protocol Go SDK — maintained with Google — compiles your server to a single binary that starts in milliseconds. A minimal, production-shaped walkthrough for the 2026-07-28 spec.

Python and TypeScript get most of the MCP tutorials, but Go quietly became the language you reach for when a server has to ship as one binary and take real traffic. The official modelcontextprotocol/go-sdk — maintained in collaboration with Google, and one of the four Tier 1 SDKs with a beta for the 2026-07-28 spec — makes that path short. Here's the minimal, production-shaped version.

Why Go for an MCP server

A Go server compiles to a single static binary with no runtime to install, starts in milliseconds, and handles concurrent tool calls natively through goroutines. That matters the moment your server moves off a laptop: there's no node_modules, no virtualenv, no cold-start penalty, and the container image is tiny. For a tool that a fleet of agents hammers in parallel, those properties stop being nice-to-haves.

Install

The SDK lives at github.com/modelcontextprotocol/go-sdk. Add it to a fresh module:

go mod init weather-mcp
go get github.com/modelcontextprotocol/go-sdk/mcp

The server

The shape mirrors the other SDKs: create a server, register a tool with a typed handler, and run it over a transport. The win is that Go structs generate the JSON schema for you — no hand-written parameter definitions to drift out of sync.

package main

import (
	"context"
	"github.com/modelcontextprotocol/go-sdk/mcp"
)

type Args struct {
	City string `json:"city" jsonschema:"the city to look up"`
}

func GetWeather(ctx context.Context, req *mcp.CallToolRequest, args Args) (*mcp.CallToolResult, any, error) {
	text := args.City + ": 18°C, partly cloudy"
	return &mcp.CallToolResult{Content: []mcp.Content{&mcp.TextContent{Text: text}}}, nil, nil
}

func main() {
	server := mcp.NewServer(&mcp.Implementation{Name: "weather-mcp", Version: "0.1.0"}, nil)
	mcp.AddTool(server, &mcp.Tool{Name: "get_weather", Description: "Current weather for a city"}, GetWeather)
	server.Run(context.Background(), &mcp.StdioTransport{})
}

Build and test

go build -o weather-mcp .
npx @modelcontextprotocol/inspector ./weather-mcp

The inspector opens a browser UI; list tools, call get_weather with {"city":"Berlin"}, and confirm the response before you wire it into a host. Then point Claude Desktop at the compiled binary — "command": "/absolute/path/to/weather-mcp" with no args — restart, and the tool appears under the hammer icon.

stdio now, HTTP when you need it

The official SDK ships stdio and command transports out of the box, which is all a local server needs. When you outgrow that and want a remote endpoint, upgrading the SDK does not by itself change what the server speaks over the wire — serving the stateless 2026-07-28 revision is an explicit choice you make when you wire up the HTTP transport. If you need HTTP and SSE today, the community mark3labs/mcp-go is the well-trodden alternative; we compare the two in official Go SDK vs mark3labs/mcp-go.

Where to go next

The concepts are identical across languages, so the Python tutorial and Node.js version transfer cleanly if you switch stacks. Decide stdio versus HTTP with transports compared, understand the stateless shift in the 2026-07-28 spec changes, then publish your server to the registry. For live examples of well-built servers, browse the GitHub and filesystem entries — curated, categorised and vetted so you can copy patterns that already work.

Loadout

Build your AI agent loadout

The directory of MCP servers and AI agents that actually work. Pick the right loadout for Slack, Postgres, GitHub, Figma and 20+ integrations — with install commands ready to paste into Claude Desktop, Cursor or your own stack.

© 2026 Loadout. Built on Angular 21 SSR.