GitHub - metoro-io/mcp-golang: Write Model Context Protocol servers in few lines of go code. Docs at https://mcpgolang.com (original) (raw)

Statusphere logo

GitHub stars GitHub forks GitHub issues GitHub pull requests GitHub license GitHub contributors GitHub last commit GoDoc Go Report Card Tests

mcp-golang

mcp-golang is an unofficial implementation of the Model Context Protocol in Go.

Write MCP servers and clients in golang with a few lines of code.

Docs at https://mcpgolang.com

Highlights

Example Usage

Install with go get github.com/metoro-io/mcp-golang

Server Example

package main

import ( "fmt" "github.com/metoro-io/mcp-golang" "github.com/metoro-io/mcp-golang/transport/stdio" )

// Tool arguments are just structs, annotated with jsonschema tags // More at https://mcpgolang.com/tools#schema-generation 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 thing calling this tool (openai, google, claude, etc)" 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

You can also create an HTTP-based server using either 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 if you need those features.

Client Example

Checkout the examples/client directory for a more complete example.

package main

import ( "context" "log" mcp "github.com/metoro-io/mcp-golang" "github.com/metoro-io/mcp-golang/transport/stdio" )

// Define type-safe arguments 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() // Create and initialize client transport := stdio.NewStdioServerTransportWithIO(stdout, stdin) client := mcp.NewClient(transport)

if _, err := client.Initialize(context.Background()); err != nil {
    log.Fatalf("Failed to initialize: %v", err)
}

// Call a tool with typed arguments
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 in ~/Library/Application Support/Claude/claude_desktop_config.json with the following contents:

{ "mcpServers": { "golang-mcp-server": { "command": "", "args": [], "env": {} } } }

Contributions

Contributions are more than welcome! Please check out our contribution guidelines.

Discord

Got any suggestions, have a question on the api or usage? Ask on the discord server. A maintainer will be happy to help you out.

Examples

Some more extensive examples using the library found here:

Open a PR to add your own projects!

Server Feature Implementation

Tools

Prompts

Resources

Transports

Client