The Model Context Protocol (MCP) Server Platform for Go provides a simple way to create MCP-compliant servers in Go. This Platform allows you to:
- Create MCP servers with custom tools
- Handle tool calls with your own business logic
- Serve MCP over standard I/O
Usage
Creating a simple MCP server
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/FreePeak/cortex/pkg/server"
"github.com/FreePeak/cortex/pkg/tools"
)
func main() {
// Create the server
mcpServer := server.NewMCPServer("My MCP Server", "1.0.0")
// Create a tool
echoTool := tools.NewTool("echo",
tools.WithDescription("Echoes back the input message"),
tools.WithString("message",
tools.Description("The message to echo back"),
tools.Required(),
),
)
// Add the tool to the server with a handler
ctx := context.Background()
err := mcpServer.AddTool(ctx, echoTool, handleEcho)
if err != nil {
log.Fatalf("Error adding tool: %v", err)
}
// Start the server over stdio
if err := mcpServer.ServeStdio(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
// Echo tool handler
func handleEcho(ctx context.Context, request server.ToolCallRequest) (interface{}, error) {
// Extract the message parameter
message, ok := request.Parameters["message"].(string)
if !ok {
return nil, fmt.Errorf("missing or invalid 'message' parameter")
}
// Return the echo response
return map[string]interface{}{
"content": []map[string]interface{}{
{
"type": "text",
"text": message,
},
},
}, nil
}
The Platform provides a fluent interface for creating tools and their parameters:
// Create a calculator tool
calculatorTool := tools.NewTool("calculator",
tools.WithDescription("Performs basic arithmetic operations"),
tools.WithString("operation",
tools.Description("The operation to perform (add, subtract, multiply, divide)"),
tools.Required(),
),
tools.WithNumber("a",
tools.Description("First number"),
tools.Required(),
),
tools.WithNumber("b",
tools.Description("Second number"),
tools.Required(),
),
)
Tool handlers receive a ToolCallRequest and return a result or an error:
func handleCalculator(ctx context.Context, request server.ToolCallRequest) (interface{}, error) {
// Extract parameters
operation, ok := request.Parameters["operation"].(string)
if !ok {
return nil, fmt.Errorf("missing or invalid 'operation' parameter")
}
a, ok := request.Parameters["a"].(float64)
if !ok {
return nil, fmt.Errorf("missing or invalid 'a' parameter")
}
b, ok := request.Parameters["b"].(float64)
if !ok {
return nil, fmt.Errorf("missing or invalid 'b' parameter")
}
// Perform the calculation
var result float64
switch operation {
case "add":
result = a + b
case "subtract":
result = a - b
case "multiply":
result = a * b
case "divide":
if b == 0 {
return nil, fmt.Errorf("division by zero")
}
result = a / b
default:
return nil, fmt.Errorf("unknown operation: %s", operation)
}
// Return the result
return map[string]interface{}{
"content": []map[string]interface{}{
{
"type": "text",
"text": fmt.Sprintf("Result: %v", result),
},
},
}, nil
}
Package Structure
The Platform consists of several packages:
pkg/server: Core server implementation
pkg/tools: Utilities for creating and configuring tools
pkg/types: Common types and interfaces
Examples
Check out the examples directory for complete working examples.