go-go-mcp
A Go implementation of the Model Context Protocol (MCP), providing a framework for building MCP servers and clients.
Installation
To install the go-go-mcp command line tool with homebrew, run:
brew tap go-go-golems/go-go-go
brew install go-go-golems/go-go-go/go-go-mcp
To install the go-go-mcp command using apt-get, run:
echo "deb [trusted=yes] https://apt.fury.io/go-go-golems/ /" >> /etc/apt/sources.list.d/fury.list
apt-get update
apt-get install go-go-mcp
To install using yum, run:
echo "
[fury]
name=Gemfury Private Repo
baseurl=https://yum.fury.io/go-go-golems/
enabled=1
gpgcheck=0
" >> /etc/yum.repos.d/fury.repo
yum install go-go-mcp
To install using go get, run:
go get -u github.com/go-go-golems/go-go-mcp/cmd/go-go-mcp
Finally, install by downloading the binaries straight from github.
Overview
This project implements the Model Context Protocol, which enables standardized communication between AI applications and language models. The implementation includes:
- Core protocol message types and interfaces
- A modular registry system for managing prompts, resources, and tools
- Thread-safe provider implementations
- A stdio server implementation
- Support for custom handlers and subscriptions
Architecture
The project follows a modular, provider-based architecture with these main components:
- Protocol Types (pkg/protocol/types.go)
- Registry System
- Prompts Registry (pkg/prompts/registry.go)
- Resources Registry (pkg/resources/registry.go)
- Tools Registry (pkg/tools/registry.go)
 
- Server Implementation (pkg/server/server.go)
- Error Handling (pkg/registry.go)
For detailed architecture documentation, see Architecture Documentation.
Features
Registry System
The registry system provides thread-safe management of prompts, resources, and tools:
// Create registries
promptRegistry := prompts.NewRegistry()
resourceRegistry := resources.NewRegistry()
toolRegistry := tools.NewRegistry()
// Register a prompt with custom handler
promptRegistry.RegisterPromptWithHandler(protocol.Prompt{
    Name: "hello",
    Description: "A simple greeting prompt",
    Arguments: []protocol.PromptArgument{
        {
            Name: "name",
            Description: "Name to greet",
            Required: false,
        },
    },
}, func(prompt protocol.Prompt, args map[string]string) (*protocol.PromptMessage, error) {
    return &protocol.PromptMessage{
        Role: "user",
        Content: protocol.PromptContent{
            Type: "text",
            Text: fmt.Sprintf("Hello, %s!", args["name"]),
        },
    }, nil
})
Custom Handlers
Each registry supports custom handlers for flexible behavior:
- Prompts: Custom message generation
- Resources: Custom content providers with subscription support
- Tools: Custom tool execution handlers
Error Handling
Standardized error handling with JSON-RPC compatible error codes:
var (
    ErrPromptNotFound   = NewError("prompt not found", -32000)
    ErrResourceNotFound = NewError("resource not found", -32001)
    ErrToolNotFound     = NewError("tool not found", -32002)
    ErrNotImplemented   = NewError("not implemented", -32003)
)
Example Server
The project includes an example stdio server that demonstrates the registry system:
package main
import (
    "io"
    "github.com/go-go-golems/go-go-mcp/pkg/prompts"
    "github.com/go-go-golems/go-go-mcp/pkg/protocol"
    "github.com/go-go-golems/go-go-mcp/pkg/resources"
    "github.com/go-go-golems/go-go-mcp/pkg/server"
    "github.com/go-go-golems/go-go-mcp/pkg/tools"
    "github.com/rs/zerolog/log"
)
func main() {
    srv := server.NewServer()
    // Create registries
    promptRegistry := prompts.NewRegistry()
    resourceRegistry := resources.NewRegistry()
    toolRegistry := tools.NewRegistry()
    // Register with server
    srv.GetRegistry().RegisterPromptProvider(promptRegistry)
    srv.GetRegistry().RegisterResourceProvider(resourceRegistry)
    srv.GetRegistry().RegisterToolProvider(toolRegistry)
    if err := srv.Start(); err != nil && err != io.EOF {
        log.Fatal().Err(err).Msg("Server error")
    }
}
Supported Methods
The server implements the MCP specification methods:
- initialize- Protocol initialization and capability negotiation
- ping- Connection health check
- prompts/list- List available prompts
- prompts/get- Retrieve prompt content
- resources/list- List available resources
- resources/read- Read resource content
- resources/subscribe- Subscribe to resource updates
- tools/list- List available tools
- tools/call- Execute a tool
Running
Building the Binary
Build the binary which includes both server and client functionality:
go build -o go-go-mcp ./cmd/mcp-server/main.go
Basic Usage
The binary can be run in two modes:
- Server mode (default): Run as an MCP server process
- Client mode: Use client commands to interact with an MCP server
Server Mode
Start the server with either stdio or SSE transport:
# Start with stdio transport (default)
go-go-mcp start --transport stdio
# Start with SSE transport
go-go-mcp start --transport sse --port 3001
Client Mode
Use the client subcommand to interact with an MCP server:
# List available prompts (uses default server: go-go-mcp start --transport stdio)
go-go-mcp client prompts list
# List available tools
go-go-mcp client tools list
# Execute a prompt with arguments
go-go-mcp client prompts execute hello --args '{"name":"World"}'
# Call a tool with arguments
go-go-mcp client tools call echo --args '{"message":"Hello, MCP!"}'
You can customize the server command and arguments if needed:
# Use a different server binary with custom arguments
go-go-mcp client --command custom-server,start,--debug,--port,8001 prompts list
# Use a server with a specific configuration
go-go-mcp client -c go-go-mcp,start,--config,config.yaml prompts list
Using SSE Transport
For web-based applications, use the SSE transport:
# Start the server with SSE transport
go-go-mcp start --transport sse --port 3001
# In another terminal, connect using the client
go-go-mcp client --transport sse --server http://localhost:3001 prompts list
Using go-go-mcp as a Bridge
go-go-mcp can be used as a bridge to expose an SSE server as a stdio server. This is useful when you need to connect a stdio-based client to an SSE server:
# Start an SSE server on port 3000
go-go-mcp start --transport sse --port 3000
# In another terminal, start the bridge to expose the SSE server as stdio
go-go-mcp bridge --sse-url http://localhost:3000 --log-level debug
# Now you can use stdio-based clients to connect to the bridge
This is particularly useful when integrating with tools that only support stdio communication but need to connect to a web-based MCP server.
Debug Mode
Add the --debug flag to enable detailed logging:
go-go-mcp client --debug prompts list
Check the version:
go-go-mcp version
Configuration
go-go-mcp can be configured using YAML configuration files that allow you to:
- Define multiple profiles for different environments
- Configure tool and prompt sources
- Set parameter defaults and overrides
- Control access through blacklists/whitelists
- Manage security through parameter filtering
For detailed configuration documentation, use:
# View configuration file documentation
go-go-mcp help config-file
# View example configuration
go-go-mcp help config-file --example
Shell Commands
go-go-mcp supports defining custom shell commands in YAML files, providing:
- Template-based command generation with Go templates and Sprig functions
- Rich parameter type system
- Environment variable management
- Working directory control
- Error handling and output capture
Example Commands
The examples/ directory contains various ready-to-use commands. You can view the schema for any command using go-go-mcp schema <command.yaml>, which shows the full parameter documentation that is passed to the LLM:
go-go-mcp schema examples/github/list-github-issues.yaml
GitHub Integration
Web Content Tools
Research and Documentation
For any command, you can view its full schema and documentation using:
# View the full parameter schema and documentation
go-go-mcp schema examples/github/list-github-issues.yaml
# View the command help
go-go-mcp run-command examples/github/list-github-issues.yaml --help
Running Shell Commands Directly
You can run shell commands directly using the run-command subcommand. This allows you to execute any shell command YAML file without loading it into a server first:
# View command help and available flags
go-go-mcp run-command examples/github/list-github-issues.yaml --help
# Run a command with specific parameters
go-go-mcp run-command examples/github/list-github-issues.yaml --author wesen
# Run a Google Calendar command
go-go-mcp run-command examples/google/get-calendar.yaml --start today --end "next week"
# Run a URL fetching command
go-go-mcp run-command examples/shell-commands/fetch-url.yaml --url https://example.com
This provides a simpler way to use shell commands as standalone command-line tools without setting up a server.
Generating Shell Commands with Pinocchio
You can use Pinocchio to generate shell commands for go-go-mcp. First, add your local go-go-mcp repository as a Pinocchio repository:
pinocchio config repositories add $(pwd)/pinocchio
Then generate a new command using:
pinocchio go-go-mcp create-command --description "A command description"
This will create a new shell command YAML file with the appropriate structure and configuration.
For detailed shell commands documentation, use:
# View shell commands documentation
go-go-mcp help shell-commands
# View example shell commands
go-go-mcp help shell-commands --example
Help System
go-go-mcp comes with comprehensive built-in documentation. To explore:
# List all available help topics
go-go-mcp help --all
# Get help on a specific topic
go-go-mcp help <topic>
# Show examples for a topic
go-go-mcp help <topic> --example
Project Structure