MCP HubMCP Hub
metoro-io

mcp-golang

by: metoro-io

Write Model Context Protocol servers in few lines of go code. Docs at https://mcpgolang.com

709created 07/12/2024
Visit
Go
Protocol

📌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, allowing you to write MCP servers and clients with minimal code.

Documentation: https://mcpgolang.com

Highlights

  • 🛡️ Type Safety: Define tool arguments as native Go structs, with automatic schema generation and error handling.
  • 🚛 Custom Transports: Use built-in transports like stdio and HTTP or create your own.
  • Low Boilerplate: Automatically generate MCP endpoints, reducing the amount of code you write.
  • 🧩 Modular Components: Use the transport, protocol, and server/client components as needed.
  • 🔄 Bi-directional Support: Full support for both server and client implementations through stdio transport.

Example Usage

Installation

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 defined as structs
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, %s!", arguments.Submitter))), nil
	})
	if err != nil {
		panic(err)
	}

	err = server.Serve()
	if err != nil {
		panic(err)
	}
	<-done
}

HTTP Server Example

// Standard HTTP transport
transport := http.NewHTTPTransport("/mcp")
transport.WithAddr(":8080")
server := mcp_golang.NewServer(transport)

// HTTP transport with Gin framework
transport := http.NewGinTransport()
router := gin.Default()
router.POST("/mcp", transport.Handler())
server := mcp_golang.NewServer(transport)

Client Example

package main

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

type CalculateArgs struct {
	Operation string `json:"operation"`
	A         int    `json:"a"`
	B         int    `json:"b"`
}

func main() {
	transport := stdio.NewStdioServerTransport()
	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)
	}
}

Contributions

Contributions are welcome! Please check out 1.

Discord

For suggestions or questions about the API or usage, join our Discord server.

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
  • HTTP - Stateless transport
  • Gin - HTTP transport with Gin framework
  • Custom transport support
  • HTTPS with custom auth support - in progress

Client

  • Call tools
  • Call prompts
  • Call resources
  • List tools
  • List prompts
  • List resources