GitHub - ThinkInAIXYZ/go-mcp: Go-MCP is a powerful Go(Golang) version of the MCP SDK that implements the Model Context Protocol (MCP) to facilitate seamless communication between external systems and AI applications. (original) (raw)

Go-MCP

Statusphere logo

Release Stars Forks Issues Pull Requests License Contributors Last Commit

Go Reference Go Report Go Tests

简体中文 | 繁體中文 | Tiếng Việt

🚀 Overview

Go-MCP is a powerful Go version of the MCP SDK that implements the Model Context Protocol (MCP) to facilitate seamless communication between external systems and AI applications. Based on the strong typing and performance advantages of the Go language, it provides a concise and idiomatic API to facilitate your integration of external systems into AI applications.

✨ Key Features

🛠️ Installation

go get github.com/ThinkInAIXYZ/go-mcp

Requires Go 1.18 or higher.

🎯 Quick Start

Client Example

package main

import ( "context" "log"

"github.com/ThinkInAIXYZ/go-mcp/client"
"github.com/ThinkInAIXYZ/go-mcp/transport"

)

func main() { // Create SSE transport client transportClient, err := transport.NewSSEClientTransport("http://127.0.0.1:8080/sse") if err != nil { log.Fatalf("Failed to create transport client: %v", err) }

// Initialize MCP client
mcpClient, err := client.NewClient(transportClient)
if err != nil {
    log.Fatalf("Failed to create MCP client: %v", err)
}
defer mcpClient.Close()

// Get available tools
tools, err := mcpClient.ListTools(context.Background())
if err != nil {
    log.Fatalf("Failed to list tools: %v", err)
}
log.Printf("Available tools: %+v", tools)

}

Server Example

package main

import ( "context" "fmt" "log" "time"

"github.com/ThinkInAIXYZ/go-mcp/protocol"
"github.com/ThinkInAIXYZ/go-mcp/server"
"github.com/ThinkInAIXYZ/go-mcp/transport"

)

type TimeRequest struct { Timezone string json:"timezone" description:"timezone" required:"true" // Use field tag to describe input schema }

func main() { // Create SSE transport server transportServer, err := transport.NewSSEServerTransport("127.0.0.1:8080") if err != nil { log.Fatalf("Failed to create transport server: %v", err) }

// Initialize MCP server
mcpServer, err := server.NewServer(transportServer)
if err != nil {
    log.Fatalf("Failed to create MCP server: %v", err)
}

// Optional: Global middleware (variadic - multiple middleware supported)
// mcpServer.Use(
// 	LoggingMiddleware,
// 	AuthMiddleware,
// 	MetricsMiddleware,
// )

// Register time query tool
tool, err := protocol.NewTool("current_time", "Get current time for specified timezone", TimeRequest{})
if err != nil {
    log.Fatalf("Failed to create tool: %v", err)
    return
}
mcpServer.RegisterTool(tool, handleTimeRequest)

// Start server
if err = mcpServer.Run(); err != nil {
    log.Fatalf("Server failed to start: %v", err)
}

}

func handleTimeRequest(ctx context.Context, req *protocol.CallToolRequest) (*protocol.CallToolResult, error) { var timeReq TimeRequest if err := protocol.VerifyAndUnmarshal(req.RawArguments, &timeReq); err != nil { return nil, err }

loc, err := time.LoadLocation(timeReq.Timezone)
if err != nil {
    return nil, fmt.Errorf("invalid timezone: %v", err)
}

return &protocol.CallToolResult{
    Content: []protocol.Content{
        &protocol.TextContent{
            Type: "text",
            Text: time.Now().In(loc).String(),
        },
    },
}, nil

}

Integration With Gin Server

package main

import ( "context" "log"

"github.com/ThinkInAIXYZ/go-mcp/protocol"
"github.com/ThinkInAIXYZ/go-mcp/server"
"github.com/ThinkInAIXYZ/go-mcp/transport"
"github.com/gin-gonic/gin"

)

func main() { messageEndpointURL := "/message"

sseTransport, mcpHandler, err := transport.NewSSEServerTransportAndHandler(messageEndpointURL)
if err != nil {
    log.Panicf("new sse transport and hander with error: %v", err)
}

// new mcp server
mcpServer, _ := server.NewServer(sseTransport)

// register tool with mcpServer
// mcpServer.RegisterTool(tool, toolHandler)

// start mcp Server
go func() {
    mcpServer.Run()
}()

defer mcpServer.Shutdown(context.Background())

r := gin.Default()
r.GET("/sse", func(ctx *gin.Context) {
    mcpHandler.HandleSSE().ServeHTTP(ctx.Writer, ctx.Request)
})
r.POST(messageEndpointURL, func(ctx *gin.Context) {
    mcpHandler.HandleMessage().ServeHTTP(ctx.Writer, ctx.Request)
})

if err = r.Run(":8080"); err != nil {
    return
}

}

Reference:A more complete example

🏗️ Architecture Design

Go-MCP adopts an elegant three-layer architecture:

Architecture Overview

  1. Transport Layer: Handles underlying communication implementation, supporting multiple transport protocols
  2. Protocol Layer: Handles MCP protocol encoding/decoding and data structure definitions
  3. User Layer: Provides friendly client and server APIs

Currently supported transport methods:

Transport Methods

The transport layer uses a unified interface abstraction, making it simple to add new transport methods (like Streamable HTTP, WebSocket, gRPC) without affecting upper-layer code.

🤝 Contributing

We welcome all forms of contributions! Please see CONTRIBUTING.md for details.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

📞 Contact Us

WeChat QR Code

✨ Contributors

Thanks to all developers who have contributed to this project!

Contributors

Star History