mcp-golang
by: metoro-io
Write Model Context Protocol servers in few lines of go code. Docs at https://mcpgolang.com
📌Overview
Purpose: To provide a framework for developing servers and clients that implement the Model Context Protocol (MCP) in the Go programming language.
Overview: mcp-golang is an unofficial Go implementation of the Model Context Protocol, designed to facilitate the quick and efficient creation of MCP servers and clients. It offers type safety, modularity, and low boilerplate code, making it easier for developers to integrate this protocol into their applications.
Key Features:
-
Type Safety: Utilize native Go structs for tool arguments, enabling automatic schema generation, deserialization, and error handling.
-
Custom Transports: Choose from built-in transport options (stdio for full features, HTTP for stateless communication) or create custom transports as needed.
-
Low Boilerplate: Automatically generate all required MCP endpoints, minimizing the amount of code developers must write for functionality.
-
Modular Design: The library consists of separate components for transport, protocol, and server/client, allowing developers to use only what they need.
-
Bi-directional Communication: Supports both server and client implementations through stdio transport, facilitating interactive applications.
mcp-golang
mcp-golang is an unofficial implementation of the Model Context Protocol in Go. Write MCP servers and clients in Go with minimal code.
Docs at https://mcpgolang.com
Highlights
- 🛡️ Type safety - Define your tool arguments as native Go structs. Automatic schema generation, deserialization, error handling, etc.
- 🚛 Custom transports - Use built-in transports (stdio for full feature support, HTTP for stateless communication) or write your own.
- ⚡ Low boilerplate - mcp-golang generates all MCP endpoints except for your tools, prompts, and resources.
- 🧩 Modular - The library is split into transport, protocol, and server/client components. Use all or what you need.
- 🔄 Bi-directional - Full support for both server and client implementations through stdio transport.
Example Usage
Install with:
go get github.com/metoro-io/mcp-golang
Server Example
package main
import (
"fmt"
mcp_golang "github.com/metoro-io/mcp-golang"
"github.com/metoro-io/mcp-golang/transport/stdio"
)
type Content struct {
Title string `json:"title" jsonschema:"required,description=The title to submit"`
Description *string `json:"description" jsonschema:"description=The description to submit"`
}
type MyFunctionsArguments struct {
Submitter string `json:"submitter" jsonschema:"required,description=The name of the caller"`
Content Content `json:"content" jsonschema:"required,description=The content of the message"`
}
func main() {
done := make(chan struct{})
server := mcp_golang.NewServer(stdio.NewStdioServerTransport())
err := server.RegisterTool("hello", "Say hello to a person", func(arguments MyFunctionsArguments) (*mcp_golang.ToolResponse, error) {
return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(fmt.Sprintf("Hello, %server!", arguments.Submitter))), nil
})
if err != nil {
panic(err)
}
err = server.RegisterPrompt("promt_test", "This is a test prompt", func(arguments Content) (*mcp_golang.PromptResponse, error) {
return mcp_golang.NewPromptResponse("description", mcp_golang.NewPromptMessage(mcp_golang.NewTextContent(fmt.Sprintf("Hello, %server!", arguments.Title)), mcp_golang.RoleUser)), nil
})
if err != nil {
panic(err)
}
err = server.RegisterResource("test://resource", "resource_test", "This is a test resource", "application/json", func() (*mcp_golang.ResourceResponse, error) {
return mcp_golang.NewResourceResponse(mcp_golang.NewTextEmbeddedResource("test://resource", "This is a test resource", "application/json")), nil
})
err = server.Serve()
if err != nil {
panic(err)
}
<-done
}
HTTP Server Example
Create an HTTP-based server using the standard HTTP transport or Gin framework:
// Standard HTTP
transport := http.NewHTTPTransport("/mcp")
transport.WithAddr(":8080")
server := mcp_golang.NewServer(transport)
// Or with Gin framework
transport := http.NewGinTransport()
router := gin.Default()
router.POST("/mcp", transport.Handler())
server := mcp_golang.NewServer(transport)
Note: HTTP transports are stateless and don't support bidirectional features like notifications. Use stdio transport for those features.
Client Example
package main
import (
"context"
"log"
mcp "github.com/metoro-io/mcp-golang"
"github.com/metoro-io/mcp-golang/transport/stdio"
"os/exec"
)
type CalculateArgs struct {
Operation string `json:"operation"`
A int `json:"a"`
B int `json:"b"`
}
func main() {
cmd := exec.Command("go", "run", "./server/main.go")
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatalf("Failed to get stdin pipe: %v", err)
}
stdout, err := cmd.StdoutPipe()
if err != nil {
log.Fatalf("Failed to get stdout pipe: %v", err)
}
if err := cmd.Start(); err != nil {
log.Fatalf("Failed to start server: %v", err)
}
defer cmd.Process.Kill()
transport := stdio.NewStdioServerTransportWithIO(stdout, stdin)
client := mcp.NewClient(transport)
if _, err := client.Initialize(context.Background()); err != nil {
log.Fatalf("Failed to initialize: %v", err)
}
args := CalculateArgs{
Operation: "add",
A: 10,
B: 5,
}
response, err := client.CallTool(context.Background(), "calculate", args)
if err != nil {
log.Fatalf("Failed to call tool: %v", err)
}
if response != nil && len(response.Content) > 0 {
log.Printf("Result: %s", response.Content[0].TextContent.Text)
}
}
Using with Claude Desktop
Create a file at ~/Library/Application Support/Claude/claude_desktop_config.json
with the following contents:
{
"mcpServers": {
"golang-mcp-server": {
"command": "<your path to golang MCP server go executable>",
"args": [],
"env": {}
}
}
}
Contributions
Contributions are welcome! Please check out our contribution guidelines.
Discord
Have suggestions or questions about the API or usage? Ask on the discord server. A maintainer will be happy to help.
Examples
Some extensive examples using the library can be found here:
- Metoro - Query and interact with Kubernetes environments monitored by Metoro
https://github.com/metoro-io/metoro-mcp-server
Open a PR to add your own projects!
Server Feature Implementation
Tools
- Tool Calls
- Native Go structs as arguments
- Programmatically generated tool list endpoint
- Change notifications
- Pagination
Prompts
- Prompt Calls
- Programmatically generated prompt list endpoint
- Change notifications
- Pagination
Resources
- Resource Calls
- Programmatically generated resource list endpoint
- Change notifications
- Pagination
Transports
- Stdio - Full support for all features including bidirectional communication
- HTTP - Stateless transport for simple request-response (no notifications support)
- Gin - HTTP transport with Gin framework integration (stateless, no notifications support)
- SSE
- Custom transport support
- HTTPS with custom auth support (in progress)
Client
- Call tools
- Call prompts
- Call resources
- List tools
- List prompts
- List resources