This is a Model Context Protocol (MCP) server implementation using the mark3labs/mcp-go library with Server-Sent Events (SSE) for streamable HTTP transport.
🚀 New to MCP? Check out the Quick Start Guide to get up and running in minutes!
- Quick Start Guide - Get started in 5 minutes
- API Reference - Complete API documentation
- Examples - Client examples in Go, Python, and JavaScript
- Project Summary - Overview of the entire project
- Streamable HTTP Transport: Uses SSE (Server-Sent Events) for real-time communication
- Tools: Provides example tools for echo, addition, and time retrieval
- Resources: Exposes server information as a resource
- Prompts: Includes example prompts for greetings and code reviews
- Go 1.25.1 or later
- The
mcp-golibrary (already included in go.mod)
The dependencies are already configured in go.mod. To ensure all dependencies are downloaded:
go mod downloadStart the server with:
go run main.goThe server will start on port 8080 by default. You should see:
Starting MCP server on port 8080
MCP endpoint: http://localhost:8080/mcp
Health check: http://localhost:8080/health
- MCP Endpoint:
http://localhost:8080/mcp- Main MCP communication endpoint (uses Server-Sent Events) - Health Check:
http://localhost:8080/health- Simple health check endpoint
Echoes back the input text.
Parameters:
message(string, required): The message to echo back
Adds two numbers together.
Parameters:
a(number, required): First numberb(number, required): Second number
Returns the current server time.
Parameters: None
- URI:
server://info - Type: text/plain
- Description: Provides information about the MCP server
Generates a personalized greeting.
Arguments:
name(string, required): Name of the person to greet
Generates a code review prompt template.
Arguments:
language(string, required): Programming language for the code review
You can test the server using curl or any HTTP client that supports SSE:
# Health check
curl http://localhost:8080/health
# Connect to MCP endpoint (requires MCP client)
curl -N -H "Accept: text/event-stream" http://localhost:8080/mcpYou can modify the following constants in main.go:
serverName: Name of the MCP serverserverVersion: Version of the serverserverPort: Port to run the server on (default: 8080)
The server is configured to run in stateless mode by default:
streamableServer := server.NewStreamableHTTPServer(s, server.WithStateLess(true))Stateless Mode:
- Each request is independent
- No session management required
- Easier to test and scale horizontally
- Recommended for most use cases
Stateful Mode:
- Sessions are maintained across requests
- Requires cookie-based session management
- Useful for complex workflows that need state persistence
To switch to stateful mode, change the configuration to:
streamableServer := server.NewStreamableHTTPServer(s)
// or explicitly
streamableServer := server.NewStreamableHTTPServer(s, server.WithStateLess(false))The server supports graceful shutdown. Press Ctrl+C to stop the server. It will:
- Stop accepting new connections
- Wait for existing connections to complete (up to 5 seconds)
- Shut down cleanly
The server uses:
- Streamable HTTP Server: Provided by
server.NewStreamableHTTPServer()for streamable HTTP transport using Server-Sent Events (SSE) - Tool Handlers: Custom functions for each tool
- Resource Handlers: Individual handlers for each resource
- Prompt Handlers: Custom functions for each prompt
newTool := mcp.NewTool("tool_name",
mcp.WithDescription("Tool description"),
mcp.WithString("param_name",
mcp.Required(),
mcp.Description("Parameter description"),
),
)
s.AddTool(newTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// Your tool logic here
return mcp.NewToolResultText("Result"), nil
})s.AddResource("resource://uri",
mcp.WithResourceName("Resource Name"),
mcp.WithResourceDescription("Resource description"),
mcp.WithResourceMIMEType("text/plain"),
)
// Handle in the resource handler functionnewPrompt := mcp.NewPrompt("prompt_name",
mcp.WithPromptDescription("Prompt description"),
mcp.WithPromptArgument("arg_name",
mcp.WithPromptArgumentDescription("Argument description"),
mcp.WithPromptArgumentRequired(true),
),
)
s.AddPrompt(newPrompt, func(ctx context.Context, request mcp.GetPromptRequest) (*mcp.GetPromptResult, error) {
// Your prompt logic here
return &mcp.GetPromptResult{
Description: "Prompt result",
Messages: []mcp.PromptMessage{...},
}, nil
})This is example code for demonstration purposes.