MCP
Golang
Tutorial
Engineering

How to Build an MCP Server in Go: A Complete Guide | ContexaAI

Akshay Galande

Author

December 2, 2025

Published

How to Build an MCP Server in Go: A Complete Guide | ContexaAI

How to Build an MCP Server in Go: A Complete Guide

The Model Context Protocol (MCP) is a powerful way to expose your application's tools and data to AI models in a structured and standardized way. With MCP, you can define tools (functions) in your service and make them available to AI clients through transports such as HTTP, WebSockets, or streams.

In this post, we'll walk through how to build a simple MCP server in Go using the go-sdk, and expose it via a streamable HTTP transport.

By the end, you'll have a working MCP server that supports tools like greeting someone and performing arithmetic operations.

Why MCP?

MCP allows developers to standardize the way AI systems talk to external tools. Instead of manually defining brittle prompts for APIs, MCP defines a contract between the client (LLM, agent, or app) and your server.

Why Go?

Lower Latency than Python — Go is compiled to machine code, while Python is interpreted. This gives Go servers faster startup times and consistently lower response latency.

Massive Concurrency with Goroutines — Unlike Python's Global Interpreter Lock (GIL), Go's goroutines allow true parallelism, enabling MCP servers to handle tens of thousands of concurrent requests smoothly.

Better for High-Scale Workloads — Go's memory model and lightweight goroutines make it more efficient under heavy load compared to Python's threading or asyncio, which often introduce overhead.

Production-Ready Performance — At scale (e.g., microservices or cloud-native MCP servers), Go typically requires fewer resources than Python, reducing costs while improving throughput.

👉 And the timing couldn't be better — the official go-sdk/mcp is launching in mid-September, giving Go developers first-class tooling to create MCP-compliant servers with minimal boilerplate.

Setting Up a Go MCP Server

Let's dive into building a small calculator MCP server in Go.

Step 1: Install the Go SDK

First, install the MCP Go SDK:

go get github.com/modelcontextprotocol/go-sdk/mcp

Step 2: Define Parameters

Each tool accepts typed parameters. For example:

1type HiParams struct {
2 Name string `json:"name" jsonschema:"the name of the person to greet"`
3}
4
5type ArithmeticParams struct {
6 A float64 `json:"a" jsonschema:"first number"`
7 B float64 `json:"b" jsonschema:"second number"`
8}

Here, jsonschema annotations provide metadata for clients (like LLMs) to understand argument requirements.

Step 3: Implement Tools

Each tool is just a Go function that receives parameters and returns a structured result.

1func SayHi(ctx context.Context, session *mcp.ServerSession, params *mcp.CallToolParamsFor[HiParams]) (*mcp.CallToolResultFor[any], error) {
2 return &mcp.CallToolResultFor[any]{
3  Content: []mcp.Content{&mcp.TextContent{Text: "Hi " + params.Arguments.Name}},
4 }, nil
5}

Arithmetic examples:

1func Add(ctx context.Context, session *mcp.ServerSession, params *mcp.CallToolParamsFor[ArithmeticParams]) (*mcp.CallToolResultFor[any], error) {
2 result := params.Arguments.A + params.Arguments.B
3 return &mcp.CallToolResultFor[any]{
4  Content: []mcp.Content{&mcp.TextContent{Text: fmt.Sprintf("Result: %.2f", result)}},
5 }, nil
6}

We can implement Subtract, Multiply, and Divide in the same pattern.

Step 4: Register Tools in the MCP Server

Now, we register all tools inside our server instance:

1server := mcp.NewServer(&mcp.Implementation{Name: "calculator", Version: "v1.0.0"}, nil)
2
3mcp.AddTool(server, &mcp.Tool{Name: "greet", Description: "say hi to someone"}, SayHi)
4mcp.AddTool(server, &mcp.Tool{Name: "add", Description: "add two numbers"}, Add)
5mcp.AddTool(server, &mcp.Tool{Name: "subtract", Description: "subtract second number from first"}, Subtract)
6mcp.AddTool(server, &mcp.Tool{Name: "multiply", Description: "multiply two numbers"}, Multiply)
7mcp.AddTool(server, &mcp.Tool{Name: "divide", Description: "divide first number by second"}, Divide)

Step 5: Expose via Streamable HTTP Transport

The Go SDK provides a ready-made streamable HTTP handler:

1handler := mcp.NewStreamableHTTPHandler(
2 func(*http.Request) *mcp.Server { return server },
3 &mcp.StreamableHTTPOptions{},
4)
5
6http.HandleFunc("/mcp", handler.ServeHTTP)

This ensures the communication is bidirectional and streaming-friendly, making it ideal for AI agents.

Step 6: Run the Server

Finally, start your HTTP server:

1log.Println("Starting MCP calculator server on :8080")
2if err := http.ListenAndServe(":8080", nil); err != nil {
3 log.Fatal(err)
4}

Testing the Server

  1. Run your server:
go run main.go
  1. It will start on:
http://localhost:8080/mcp
  1. Any MCP-compatible client can now connect and discover tools like greet, add, subtract, multiply, and divide.

What's Next?

This was a minimal example. You can extend this server by:

  • Adding more tools (like fetching data from APIs, databases, or files).
  • Exposing resources via MCP.
  • Using authentication headers in your HTTP handler.
  • Deploying the server to Kubernetes, Cloud Run, or any container runtime.

Conclusion

We just built a fully functional MCP server in Go with a streamable HTTP transport. This approach makes it simple to expose structured tools to AI systems. Whether it's a calculator, weather service, or a complex enterprise workflow — MCP provides a scalable way to plug your logic directly into AI models.

Full example available at GitHub

Want to learn more? Join us on Discord

Want to host and test MCP servers? Try ContexaAI