Skip to content

Commit 8f5b048

Browse files
authored
Fix docs (#430)
1 parent 0fdb197 commit 8f5b048

File tree

4 files changed

+230
-428
lines changed

4 files changed

+230
-428
lines changed

www/docs/pages/transports/http.mdx

Lines changed: 46 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import (
4343
func main() {
4444
s := server.NewMCPServer("StreamableHTTP API Server", "1.0.0",
4545
server.WithToolCapabilities(true),
46-
server.WithResourceCapabilities(true),
46+
server.WithResourceCapabilities(true, true),
4747
)
4848

4949
// Add RESTful tools
@@ -60,7 +60,7 @@ func main() {
6060
mcp.WithDescription("Create a new user"),
6161
mcp.WithString("name", mcp.Required()),
6262
mcp.WithString("email", mcp.Required()),
63-
mcp.WithInteger("age", mcp.Minimum(0)),
63+
mcp.WithNumber("age", mcp.Min(0)),
6464
),
6565
handleCreateUser,
6666
)
@@ -69,8 +69,8 @@ func main() {
6969
mcp.NewTool("search_users",
7070
mcp.WithDescription("Search users with filters"),
7171
mcp.WithString("query", mcp.Description("Search query")),
72-
mcp.WithInteger("limit", mcp.Default(10), mcp.Maximum(100)),
73-
mcp.WithInteger("offset", mcp.Default(0), mcp.Minimum(0)),
72+
mcp.WithNumber("limit", mcp.DefaultNumber(10), mcp.Max(100)),
73+
mcp.WithNumber("offset", mcp.DefaultNumber(0), mcp.Min(0)),
7474
),
7575
handleSearchUsers,
7676
)
@@ -95,21 +95,29 @@ func main() {
9595
}
9696

9797
func handleGetUser(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
98-
userID := req.Params.Arguments["user_id"].(string)
98+
userID := req.GetString("user_id", "")
99+
if userID == "" {
100+
return nil, fmt.Errorf("user_id is required")
101+
}
99102

100103
// Simulate database lookup
101104
user, err := getUserFromDB(userID)
102105
if err != nil {
103106
return nil, fmt.Errorf("user not found: %s", userID)
104107
}
105108

106-
return mcp.NewToolResultJSON(user), nil
109+
return mcp.NewToolResultText(fmt.Sprintf(`{"id":"%s","name":"%s","email":"%s","age":%d}`,
110+
user.ID, user.Name, user.Email, user.Age)), nil
107111
}
108112

109113
func handleCreateUser(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
110-
name := req.Params.Arguments["name"].(string)
111-
email := req.Params.Arguments["email"].(string)
112-
age := int(req.Params.Arguments["age"].(float64))
114+
name := req.GetString("name", "")
115+
email := req.GetString("email", "")
116+
age := req.GetInt("age", 0)
117+
118+
if name == "" || email == "" {
119+
return nil, fmt.Errorf("name and email are required")
120+
}
113121

114122
// Validate input
115123
if !isValidEmail(email) {
@@ -129,11 +137,8 @@ func handleCreateUser(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTo
129137
return nil, fmt.Errorf("failed to create user: %w", err)
130138
}
131139

132-
return mcp.NewToolResultJSON(map[string]interface{}{
133-
"id": user.ID,
134-
"message": "User created successfully",
135-
"user": user,
136-
}), nil
140+
return mcp.NewToolResultText(fmt.Sprintf(`{"id":"%s","message":"User created successfully","user":{"id":"%s","name":"%s","email":"%s","age":%d}}`,
141+
user.ID, user.ID, user.Name, user.Email, user.Age)), nil
137142
}
138143

139144
// Helper functions and types for the examples
@@ -156,7 +161,6 @@ func getUserFromDB(userID string) (*User, error) {
156161
}
157162

158163
func isValidEmail(email string) bool {
159-
// Simple email validation
160164
return strings.Contains(email, "@") && strings.Contains(email, ".")
161165
}
162166

@@ -171,54 +175,38 @@ func saveUserToDB(user *User) error {
171175
}
172176

173177
func handleSearchUsers(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
174-
query := getStringParam(req.Params.Arguments, "query", "")
175-
limit := int(getFloatParam(req.Params.Arguments, "limit", 10))
176-
offset := int(getFloatParam(req.Params.Arguments, "offset", 0))
178+
query := req.GetString("query", "")
179+
limit := req.GetInt("limit", 10)
180+
offset := req.GetInt("offset", 0)
177181

178182
// Search users with pagination
179183
users, total, err := searchUsersInDB(query, limit, offset)
180184
if err != nil {
181185
return nil, fmt.Errorf("search failed: %w", err)
182186
}
183187

184-
return mcp.NewToolResultJSON(map[string]interface{}{
185-
"users": users,
186-
"total": total,
187-
"limit": limit,
188-
"offset": offset,
189-
"query": query,
190-
}), nil
188+
return mcp.NewToolResultText(fmt.Sprintf(`{"users":[{"id":"1","name":"John Doe","email":"[email protected]","age":30},{"id":"2","name":"Jane Smith","email":"[email protected]","age":25}],"total":%d,"limit":%d,"offset":%d,"query":"%s"}`,
189+
total, limit, offset, query)), nil
191190
}
192191

193-
func handleUserResource(ctx context.Context, req mcp.ReadResourceRequest) (*mcp.ReadResourceResult, error) {
192+
func handleUserResource(ctx context.Context, req mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
194193
userID := extractUserIDFromURI(req.Params.URI)
195194

196195
user, err := getUserFromDB(userID)
197196
if err != nil {
198197
return nil, fmt.Errorf("user not found: %s", userID)
199198
}
200199

201-
return mcp.NewResourceResultJSON(user), nil
202-
}
203-
204-
// Additional helper functions for parameter handling
205-
func getStringParam(args map[string]interface{}, key, defaultValue string) string {
206-
if val, ok := args[key]; ok && val != nil {
207-
if str, ok := val.(string); ok {
208-
return str
209-
}
210-
}
211-
return defaultValue
200+
return []mcp.ResourceContents{
201+
mcp.TextResourceContents{
202+
URI: req.Params.URI,
203+
MIMEType: "application/json",
204+
Text: fmt.Sprintf(`{"id":"%s","name":"%s","email":"%s","age":%d}`, user.ID, user.Name, user.Email, user.Age),
205+
},
206+
}, nil
212207
}
213208

214-
func getFloatParam(args map[string]interface{}, key string, defaultValue float64) float64 {
215-
if val, ok := args[key]; ok && val != nil {
216-
if f, ok := val.(float64); ok {
217-
return f
218-
}
219-
}
220-
return defaultValue
221-
}
209+
// Additional helper functions
222210

223211
func searchUsersInDB(query string, limit, offset int) ([]*User, int, error) {
224212
// Placeholder implementation
@@ -231,9 +219,8 @@ func searchUsersInDB(query string, limit, offset int) ([]*User, int, error) {
231219

232220
func extractUserIDFromURI(uri string) string {
233221
// Extract user ID from URI like "users://123"
234-
parts := strings.Split(uri, "://")
235-
if len(parts) > 1 {
236-
return parts[1]
222+
if len(uri) > 8 && uri[:8] == "users://" {
223+
return uri[8:]
237224
}
238225
return uri
239226
}
@@ -244,39 +231,24 @@ func extractUserIDFromURI(uri string) string {
244231
```go
245232
func main() {
246233
s := server.NewMCPServer("Advanced StreamableHTTP Server", "1.0.0",
247-
server.WithAllCapabilities(),
248-
server.WithRecovery(),
249-
server.WithHooks(&server.Hooks{
250-
OnToolCall: logToolCall,
251-
OnResourceRead: logResourceRead,
252-
}),
234+
server.WithResourceCapabilities(true, true),
235+
server.WithPromptCapabilities(true),
236+
server.WithToolCapabilities(true),
237+
server.WithLogging(),
253238
)
254239

255-
// Configure StreamableHTTP-specific options
256-
streamableHTTPOptions := server.StreamableHTTPOptions{
257-
BasePath: "/api/v1/mcp",
258-
ReadTimeout: 30 * time.Second,
259-
WriteTimeout: 30 * time.Second,
260-
IdleTimeout: 60 * time.Second,
261-
MaxBodySize: 10 * 1024 * 1024, // 10MB
262-
EnableCORS: true,
263-
AllowedOrigins: []string{"https://myapp.com", "http://localhost:3000"},
264-
AllowedMethods: []string{"GET", "POST", "OPTIONS"},
265-
AllowedHeaders: []string{"Content-Type", "Authorization"},
266-
EnableGzip: true,
267-
TrustedProxies: []string{"10.0.0.0/8", "172.16.0.0/12"},
268-
}
269-
270-
// Add middleware
271-
addStreamableHTTPMiddleware(s)
272-
273-
// Add comprehensive tools
240+
// Add comprehensive tools and resources
274241
addCRUDTools(s)
275242
addBatchTools(s)
276243
addAnalyticsTools(s)
277244

278245
log.Println("Starting advanced StreamableHTTP server on :8080")
279-
httpServer := server.NewStreamableHTTPServer(s, streamableHTTPOptions...)
246+
httpServer := server.NewStreamableHTTPServer(s,
247+
server.WithEndpointPath("/api/v1/mcp"),
248+
server.WithHeartbeatInterval(30*time.Second),
249+
server.WithStateLess(false),
250+
)
251+
280252
if err := httpServer.Start(":8080"); err != nil {
281253
log.Fatal(err)
282254
}

www/docs/pages/transports/inprocess.mdx

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,34 @@ func main() {
5656
)
5757

5858
// Create in-process client
59-
client := client.NewInProcessClient(s)
60-
defer client.Close()
59+
mcpClient, err := client.NewInProcessClient(s)
60+
if err != nil {
61+
log.Fatal(err)
62+
}
63+
defer mcpClient.Close()
6164

6265
ctx := context.Background()
6366

6467
// Initialize
65-
if err := client.Initialize(ctx); err != nil {
68+
_, err = mcpClient.Initialize(ctx, mcp.InitializeRequest{
69+
Params: mcp.InitializeRequestParams{
70+
ProtocolVersion: "2024-11-05",
71+
Capabilities: mcp.ClientCapabilities{
72+
Tools: &mcp.ToolsCapability{},
73+
},
74+
ClientInfo: mcp.Implementation{
75+
Name: "test-client",
76+
Version: "1.0.0",
77+
},
78+
},
79+
})
80+
if err != nil {
6681
log.Fatal(err)
6782
}
6883

6984
// Use the calculator
70-
result, err := client.CallTool(ctx, mcp.CallToolRequest{
71-
Params: mcp.CallToolRequestParams{
85+
result, err := mcpClient.CallTool(ctx, mcp.CallToolRequest{
86+
Params: mcp.CallToolParams{
7287
Name: "calculate",
7388
Arguments: map[string]interface{}{
7489
"operation": "add",
@@ -81,13 +96,18 @@ func main() {
8196
log.Fatal(err)
8297
}
8398

84-
fmt.Printf("Result: %s\n", result.Content[0].Text)
99+
// Extract text from the first content item
100+
if len(result.Content) > 0 {
101+
if textContent, ok := mcp.AsTextContent(result.Content[0]); ok {
102+
fmt.Printf("Result: %s\n", textContent.Text)
103+
}
104+
}
85105
}
86106

87107
func handleCalculate(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
88-
operation := req.Params.Arguments["operation"].(string)
89-
x := req.Params.Arguments["x"].(float64)
90-
y := req.Params.Arguments["y"].(float64)
108+
operation := req.GetString("operation", "")
109+
x := req.GetFloat("x", 0)
110+
y := req.GetFloat("y", 0)
91111

92112
var result float64
93113
switch operation {
@@ -134,7 +154,11 @@ func NewApplication(config *Config) *Application {
134154
app.addApplicationTools()
135155

136156
// Create in-process client for internal use
137-
app.mcpClient = client.NewInProcessClient(app.mcpServer)
157+
var err error
158+
app.mcpClient, err = client.NewInProcessClient(app.mcpServer)
159+
if err != nil {
160+
panic(err)
161+
}
138162

139163
return app
140164
}
@@ -151,12 +175,8 @@ func (app *Application) addApplicationTools() {
151175
mcp.WithDescription("Get current application status"),
152176
),
153177
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
154-
status := map[string]interface{}{
155-
"app_name": app.config.AppName,
156-
"debug": app.config.Debug,
157-
"status": "running",
158-
}
159-
return mcp.NewToolResultJSON(status), nil
178+
return mcp.NewToolResultText(fmt.Sprintf(`{"app_name":"%s","debug":%t,"status":"running"}`,
179+
app.config.AppName, app.config.Debug)), nil
160180
},
161181
)
162182

@@ -168,8 +188,8 @@ func (app *Application) addApplicationTools() {
168188
mcp.WithString("value", mcp.Required()),
169189
),
170190
func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
171-
key := req.Params.Arguments["key"].(string)
172-
value := req.Params.Arguments["value"].(string)
191+
key := req.GetString("key", "")
192+
value := req.GetString("value", "")
173193

174194
// Update configuration based on key
175195
switch key {
@@ -189,7 +209,7 @@ func (app *Application) addApplicationTools() {
189209
func (app *Application) ProcessWithMCP(ctx context.Context, operation string) (interface{}, error) {
190210
// Use MCP tools internally for processing
191211
result, err := app.mcpClient.CallTool(ctx, mcp.CallToolRequest{
192-
Params: mcp.CallToolRequestParams{
212+
Params: mcp.CallToolParams{
193213
Name: "calculate",
194214
Arguments: map[string]interface{}{
195215
"operation": operation,
@@ -202,7 +222,14 @@ func (app *Application) ProcessWithMCP(ctx context.Context, operation string) (i
202222
return nil, err
203223
}
204224

205-
return result.Content[0].Text, nil
225+
// Extract text from the first content item
226+
if len(result.Content) > 0 {
227+
if textContent, ok := mcp.AsTextContent(result.Content[0]); ok {
228+
return textContent.Text, nil
229+
}
230+
}
231+
232+
return "no result", nil
206233
}
207234

208235
// Usage example
@@ -216,7 +243,19 @@ func main() {
216243
ctx := context.Background()
217244

218245
// Initialize the embedded MCP client
219-
if err := app.mcpClient.Initialize(ctx); err != nil {
246+
_, err := app.mcpClient.Initialize(ctx, mcp.InitializeRequest{
247+
Params: mcp.InitializeRequestParams{
248+
ProtocolVersion: "2024-11-05",
249+
Capabilities: mcp.ClientCapabilities{
250+
Tools: &mcp.ToolsCapability{},
251+
},
252+
ClientInfo: mcp.Implementation{
253+
Name: "embedded-client",
254+
Version: "1.0.0",
255+
},
256+
},
257+
})
258+
if err != nil {
220259
log.Fatal(err)
221260
}
222261

0 commit comments

Comments
 (0)