|
| 1 | +# Core Concepts |
| 2 | + |
| 3 | +Understanding the fundamental concepts of MCP and how MCP-Go implements them is essential for building effective MCP servers and clients. |
| 4 | + |
| 5 | +## MCP Protocol Fundamentals |
| 6 | + |
| 7 | +The Model Context Protocol defines four core concepts that enable LLMs to interact with external systems safely and effectively. |
| 8 | + |
| 9 | +### Resources |
| 10 | + |
| 11 | +Resources are like GET endpoints - they expose data to LLMs in a read-only manner. Think of them as files, database records, or API responses that an LLM can access. |
| 12 | + |
| 13 | +**Key characteristics:** |
| 14 | +- **Read-only**: LLMs can fetch but not modify resources |
| 15 | +- **URI-based**: Each resource has a unique identifier |
| 16 | +- **Typed content**: Resources specify their MIME type (text, JSON, binary, etc.) |
| 17 | +- **Dynamic or static**: Can be pre-defined or generated on-demand |
| 18 | + |
| 19 | +**Example use cases:** |
| 20 | +- File system access (`file:///path/to/document.txt`) |
| 21 | +- Database records (`db://users/123`) |
| 22 | +- API data (`api://weather/current`) |
| 23 | +- Configuration files (`config://app.json`) |
| 24 | + |
| 25 | +```go |
| 26 | +// Static resource |
| 27 | +resource := mcp.NewResource( |
| 28 | + "docs://readme", |
| 29 | + "Project README", |
| 30 | + mcp.WithResourceDescription("The project's main documentation"), |
| 31 | + mcp.WithMIMEType("text/markdown"), |
| 32 | +) |
| 33 | + |
| 34 | +// Dynamic resource with template |
| 35 | +userResource := mcp.NewResource( |
| 36 | + "users://{user_id}", |
| 37 | + "User Profile", |
| 38 | + mcp.WithResourceDescription("User profile information"), |
| 39 | + mcp.WithMIMEType("application/json"), |
| 40 | +) |
| 41 | +``` |
| 42 | + |
| 43 | +### Tools |
| 44 | + |
| 45 | +Tools are like POST endpoints - they provide functionality that LLMs can invoke to take actions or perform computations. |
| 46 | + |
| 47 | +**Key characteristics:** |
| 48 | +- **Action-oriented**: Tools do things rather than just return data |
| 49 | +- **Parameterized**: Accept structured input arguments |
| 50 | +- **Typed schemas**: Define expected parameter types and constraints |
| 51 | +- **Return results**: Provide structured output back to the LLM |
| 52 | + |
| 53 | +**Example use cases:** |
| 54 | +- Calculations (`calculate`, `convert_units`) |
| 55 | +- File operations (`create_file`, `search_files`) |
| 56 | +- API calls (`send_email`, `create_ticket`) |
| 57 | +- System commands (`run_command`, `check_status`) |
| 58 | + |
| 59 | +```go |
| 60 | +// Simple calculation tool |
| 61 | +calcTool := mcp.NewTool("calculate", |
| 62 | + mcp.WithDescription("Perform arithmetic operations"), |
| 63 | + mcp.WithString("operation", |
| 64 | + mcp.Required(), |
| 65 | + mcp.Enum("add", "subtract", "multiply", "divide"), |
| 66 | + ), |
| 67 | + mcp.WithNumber("x", mcp.Required()), |
| 68 | + mcp.WithNumber("y", mcp.Required()), |
| 69 | +) |
| 70 | + |
| 71 | +// File creation tool |
| 72 | +fileTool := mcp.NewTool("create_file", |
| 73 | + mcp.WithDescription("Create a new file with content"), |
| 74 | + mcp.WithString("path", mcp.Required()), |
| 75 | + mcp.WithString("content", mcp.Required()), |
| 76 | + mcp.WithString("encoding", mcp.Default("utf-8")), |
| 77 | +) |
| 78 | +``` |
| 79 | + |
| 80 | +### Prompts |
| 81 | + |
| 82 | +Prompts are reusable interaction templates that help structure conversations between users and LLMs. |
| 83 | + |
| 84 | +**Key characteristics:** |
| 85 | +- **Template-based**: Use placeholders for dynamic content |
| 86 | +- **Reusable**: Can be invoked multiple times with different arguments |
| 87 | +- **Structured**: Define clear input parameters and expected outputs |
| 88 | +- **Context-aware**: Can include relevant resources or tool suggestions |
| 89 | + |
| 90 | +**Example use cases:** |
| 91 | +- Code review templates |
| 92 | +- Documentation generation |
| 93 | +- Data analysis workflows |
| 94 | +- Creative writing prompts |
| 95 | + |
| 96 | +```go |
| 97 | +// Code review prompt |
| 98 | +reviewPrompt := mcp.NewPrompt("code_review", |
| 99 | + mcp.WithPromptDescription("Review code for best practices and issues"), |
| 100 | + mcp.WithPromptArgument("code", |
| 101 | + mcp.Required(), |
| 102 | + mcp.Description("The code to review"), |
| 103 | + ), |
| 104 | + mcp.WithPromptArgument("language", |
| 105 | + mcp.Description("Programming language"), |
| 106 | + ), |
| 107 | +) |
| 108 | + |
| 109 | +// Data analysis prompt |
| 110 | +analysisPrompt := mcp.NewPrompt("analyze_data", |
| 111 | + mcp.WithPromptDescription("Analyze dataset and provide insights"), |
| 112 | + mcp.WithPromptArgument("dataset_uri", mcp.Required()), |
| 113 | + mcp.WithPromptArgument("focus_areas", |
| 114 | + mcp.Description("Specific areas to focus analysis on"), |
| 115 | + ), |
| 116 | +) |
| 117 | +``` |
| 118 | + |
| 119 | +### Transports |
| 120 | + |
| 121 | +Transports define how MCP clients and servers communicate. MCP-Go supports multiple transport methods to fit different deployment scenarios. |
| 122 | + |
| 123 | +**Available transports:** |
| 124 | + |
| 125 | +1. **Stdio** - Standard input/output (most common) |
| 126 | + - Best for: Local tools, CLI integration, desktop applications |
| 127 | + - Pros: Simple, secure, no network setup |
| 128 | + - Cons: Local only, single client |
| 129 | + |
| 130 | +2. **Server-Sent Events (SSE)** - HTTP-based streaming |
| 131 | + - Best for: Web applications, real-time updates |
| 132 | + - Pros: Web-friendly, real-time, multiple clients |
| 133 | + - Cons: HTTP overhead, one-way streaming |
| 134 | + |
| 135 | +3. **HTTP** - Traditional request/response |
| 136 | + - Best for: Web services, REST-like APIs |
| 137 | + - Pros: Standard protocol, caching, load balancing |
| 138 | + - Cons: No real-time updates, more complex |
| 139 | + |
| 140 | +```go |
| 141 | +// Stdio transport (most common) |
| 142 | +server.ServeStdio(s) |
| 143 | + |
| 144 | +// HTTP transport |
| 145 | +server.ServeHTTP(s, ":8080") |
| 146 | + |
| 147 | +// SSE transport |
| 148 | +server.ServeSSE(s, ":8080") |
| 149 | +``` |
| 150 | + |
| 151 | +## SDK Architecture |
| 152 | + |
| 153 | +MCP-Go provides a clean architecture that abstracts the complexity of the MCP protocol while giving you full control when needed. |
| 154 | + |
| 155 | +### Server vs Client |
| 156 | + |
| 157 | +Understanding when to build servers versus clients is crucial for effective MCP integration. |
| 158 | + |
| 159 | +**MCP Servers:** |
| 160 | +- **Purpose**: Expose tools, resources, and prompts to LLMs |
| 161 | +- **Use cases**: |
| 162 | + - Database access layers |
| 163 | + - File system tools |
| 164 | + - API integrations |
| 165 | + - Custom business logic |
| 166 | +- **Characteristics**: Passive, respond to requests, stateful |
| 167 | + |
| 168 | +```go |
| 169 | +// Server example - exposes functionality |
| 170 | +s := server.NewMCPServer("Database Tools", "1.0.0") |
| 171 | +s.AddTool(queryTool, handleQuery) |
| 172 | +s.AddResource(tableResource, handleTableAccess) |
| 173 | +server.ServeStdio(s) |
| 174 | +``` |
| 175 | + |
| 176 | +**MCP Clients:** |
| 177 | +- **Purpose**: Connect to and use MCP servers |
| 178 | +- **Use cases**: |
| 179 | + - LLM applications |
| 180 | + - Orchestration tools |
| 181 | + - Testing and debugging |
| 182 | + - Server composition |
| 183 | +- **Characteristics**: Active, make requests, coordinate multiple servers |
| 184 | + |
| 185 | +```go |
| 186 | +// Client example - uses functionality |
| 187 | +client := client.NewStdioClient("database-server") |
| 188 | +tools, _ := client.ListTools(ctx) |
| 189 | +result, _ := client.CallTool(ctx, queryRequest) |
| 190 | +``` |
| 191 | + |
| 192 | +### Transport Layer |
| 193 | + |
| 194 | +The transport layer abstracts communication protocols, allowing you to focus on business logic rather than protocol details. |
| 195 | + |
| 196 | +**Key benefits:** |
| 197 | +- **Protocol agnostic**: Same server code works with any transport |
| 198 | +- **Automatic serialization**: JSON marshaling/unmarshaling handled automatically |
| 199 | +- **Error handling**: Transport-specific errors are normalized |
| 200 | +- **Connection management**: Automatic reconnection and cleanup |
| 201 | + |
| 202 | +```go |
| 203 | +// Same server works with any transport |
| 204 | +s := server.NewMCPServer("My Server", "1.0.0") |
| 205 | + |
| 206 | +// Choose transport at runtime |
| 207 | +switch transport { |
| 208 | +case "stdio": |
| 209 | + server.ServeStdio(s) |
| 210 | +case "http": |
| 211 | + server.ServeHTTP(s, ":8080") |
| 212 | +case "sse": |
| 213 | + server.ServeSSE(s, ":8080") |
| 214 | +} |
| 215 | +``` |
| 216 | + |
| 217 | +### Session Management |
| 218 | + |
| 219 | +MCP-Go handles session management automatically, supporting multiple concurrent clients with proper isolation. |
| 220 | + |
| 221 | +**Features:** |
| 222 | +- **Multi-client support**: Multiple LLMs can connect simultaneously |
| 223 | +- **Session isolation**: Each client has independent state |
| 224 | +- **Resource cleanup**: Automatic cleanup when clients disconnect |
| 225 | +- **Concurrent safety**: Thread-safe operations across all sessions |
| 226 | + |
| 227 | +**Session lifecycle:** |
| 228 | +1. **Initialize**: Client connects and exchanges capabilities |
| 229 | +2. **Active**: Client makes requests, server responds |
| 230 | +3. **Cleanup**: Connection closes, resources are freed |
| 231 | + |
| 232 | +```go |
| 233 | +// Server automatically handles multiple sessions |
| 234 | +s := server.NewMCPServer("Multi-Client Server", "1.0.0", |
| 235 | + server.WithHooks(&server.Hooks{ |
| 236 | + OnSessionStart: func(sessionID string) { |
| 237 | + log.Printf("Client %s connected", sessionID) |
| 238 | + }, |
| 239 | + OnSessionEnd: func(sessionID string) { |
| 240 | + log.Printf("Client %s disconnected", sessionID) |
| 241 | + }, |
| 242 | + }), |
| 243 | +) |
| 244 | +``` |
| 245 | + |
| 246 | +**State management patterns:** |
| 247 | + |
| 248 | +```go |
| 249 | +// Per-session state |
| 250 | +type SessionState struct { |
| 251 | + UserID string |
| 252 | + Settings map[string]interface{} |
| 253 | +} |
| 254 | + |
| 255 | +var sessions = make(map[string]*SessionState) |
| 256 | + |
| 257 | +func toolHandler(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { |
| 258 | + sessionID := server.GetSessionID(ctx) |
| 259 | + state := sessions[sessionID] |
| 260 | + |
| 261 | + // Use session-specific state |
| 262 | + return processWithState(state, req) |
| 263 | +} |
| 264 | +``` |
0 commit comments