-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmain.go
More file actions
116 lines (107 loc) · 5.14 KB
/
main.go
File metadata and controls
116 lines (107 loc) · 5.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Example: Model-Optimized Weather Service — the same tools with different
// descriptions and schemas optimized for different LLM families. This
// demonstrates the SEP-2053 primary use case where tool descriptions are
// tailored per model family for optimal tool-calling performance.
//
// Capability demonstrated: Same tools, different descriptions per variant.
//
// Variants:
// - claude-optimized: Detailed, structured descriptions with explicit guidance
// - gpt-optimized: Concise function-style descriptions with JSON Schema emphasis
// - compact: Minimal descriptions for context-constrained environments
//
// Run:
//
// go run ./examples/server/model-optimized
//
// Then connect any MCP client to http://localhost:8080.
package main
import (
"context"
"log"
"net/http"
"slices"
"strings"
"github.com/modelcontextprotocol/go-sdk/mcp"
"github.com/modelcontextprotocol/experimental-ext-variants/go/sdk/variants"
)
func main() {
// Claude-optimized variant: verbose, structured descriptions with
// explicit guidance on when and how to use each tool.
claudeServer := mcp.NewServer(&mcp.Implementation{Name: "weather-service", Version: "v1.0.0"}, nil)
mcp.AddTool(claudeServer, &mcp.Tool{
Name: "get_weather",
Description: "Get the current weather conditions for a specific location. " +
"Use this tool when the user asks about current weather, temperature, or conditions. " +
"Accepts city names (e.g., 'San Francisco, CA'), country names, or lat/long coordinates. " +
"Returns temperature, humidity, wind speed, and a human-readable condition description. " +
"Prefer this over get_forecast when the user only needs current conditions.",
}, getWeather)
mcp.AddTool(claudeServer, &mcp.Tool{
Name: "get_forecast",
Description: "Get a multi-day weather forecast for a specific location. " +
"Use this tool when the user asks about future weather, upcoming conditions, or wants to plan ahead. " +
"Returns daily high/low temperatures and conditions for 1-7 days. " +
"Defaults to 3 days if not specified. Use get_weather instead if only current conditions are needed.",
}, getForecast)
// GPT-optimized variant: concise function-style descriptions with
// JSON Schema emphasis for OpenAI-family models.
gptServer := mcp.NewServer(&mcp.Implementation{Name: "weather-service", Version: "v1.0.0"}, nil)
mcp.AddTool(gptServer, &mcp.Tool{
Name: "get_weather",
Description: "Returns current weather data (temperature, humidity, wind, conditions) for a given location.",
}, getWeather)
mcp.AddTool(gptServer, &mcp.Tool{
Name: "get_forecast",
Description: "Returns multi-day forecast (high/low temps, conditions) for a location. Days: 1-7, default 3.",
}, getForecast)
// Compact variant: minimal descriptions for context-constrained
// environments where token budget is limited.
compactServer := mcp.NewServer(&mcp.Implementation{Name: "weather-service", Version: "v1.0.0"}, nil)
mcp.AddTool(compactServer, &mcp.Tool{
Name: "get_weather",
Description: "Current weather for a location.",
}, getWeather)
mcp.AddTool(compactServer, &mcp.Tool{
Name: "get_forecast",
Description: "Multi-day forecast for a location.",
}, getForecast)
vs := variants.NewServer(&mcp.Implementation{Name: "weather-service", Version: "v1.0.0"}).
WithVariant(variants.ServerVariant{
ID: "claude-optimized",
Description: "Detailed, structured tool descriptions with explicit usage guidance. Optimized for Anthropic Claude models that benefit from rich context and clear instructions.",
Hints: map[string]string{"modelFamily": "anthropic", "contextSize": "verbose"},
Status: variants.Stable,
}, claudeServer, 0).
WithVariant(variants.ServerVariant{
ID: "gpt-optimized",
Description: "Concise function-style descriptions with JSON Schema emphasis. Optimized for OpenAI GPT models that work well with terse, specification-like tool definitions.",
Hints: map[string]string{"modelFamily": "openai", "contextSize": "standard"},
Status: variants.Stable,
}, gptServer, 1).
WithVariant(variants.ServerVariant{
ID: "compact",
Description: "Minimal tool descriptions for context-constrained environments. Use when token budget is severely limited or tools are self-explanatory from their schemas.",
Hints: map[string]string{"modelFamily": "any", "contextSize": "compact"},
Status: variants.Stable,
}, compactServer, 2).
// Custom ranking: match by modelFamily hint, fall back to priority.
WithRanking(func(_ context.Context, hints variants.VariantHints, vs []variants.ServerVariant) []variants.ServerVariant {
requested, _ := variants.HintValue[string](hints, "modelFamily")
slices.SortStableFunc(vs, func(a, b variants.ServerVariant) int {
aMatch := strings.EqualFold(a.Hints["modelFamily"], requested)
bMatch := strings.EqualFold(b.Hints["modelFamily"], requested)
if aMatch != bMatch {
if aMatch {
return -1
}
return 1
}
return a.Priority() - b.Priority()
})
return vs
})
handler := variants.NewStreamableHTTPHandler(vs, nil)
log.Println("Listening on :8080")
log.Fatal(http.ListenAndServe(":8080", handler))
}