Define types and architecture for a variant-aware MCP server (#2)
Defines the core types and API for server variants extension, laying groundwork for multi-variant server implementation. Server.Run() is not yet implemented but architecture is designed and documented. - Add Server type with variant registration - Implement default priority-based ranking - Define ServerVariant, VariantHints, and related types per SEP spec - Add comprehensive example demonstrating intended multi-variant usage - Document implementation plan for Server.Run() dispatch architecture Next PRs: - Unit Tests - Implementation for Server.Run - Conformance Testing Signed-off-by: Kurt Degiorgio <kdegiorgio@bloomberg.net>
This commit is contained in:
parent
4f98e0aab3
commit
dbf99bebf0
1 changed files with 576 additions and 7 deletions
111
go/sdk/examples/server/variants/main.go
Normal file
111
go/sdk/examples/server/variants/main.go
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
// Example: Setting up a variant-aware MCP server with multiple variants.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
mcp "github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
|
||||
"github.com/modelcontextprotocol/experimental-ext-variants/go/sdk/variants"
|
||||
)
|
||||
|
||||
// -- Coding variant tool types ------------------------------------------------
|
||||
|
||||
type AnalyzeCodeInput struct {
|
||||
Code string `json:"code" jsonschema:"source code to analyze"`
|
||||
Language string `json:"language" jsonschema:"programming language"`
|
||||
}
|
||||
|
||||
type AnalyzeCodeOutput struct {
|
||||
Issues []string `json:"issues"`
|
||||
Suggestions []string `json:"suggestions"`
|
||||
}
|
||||
|
||||
func AnalyzeCode(_ context.Context, _ *mcp.CallToolRequest, in AnalyzeCodeInput) (*mcp.CallToolResult, AnalyzeCodeOutput, error) {
|
||||
return nil, AnalyzeCodeOutput{
|
||||
Issues: []string{"unused variable on line 3"},
|
||||
Suggestions: []string{"consider using a switch statement"},
|
||||
}, nil
|
||||
}
|
||||
|
||||
type RefactorInput struct {
|
||||
Code string `json:"code" jsonschema:"source code to refactor"`
|
||||
Action string `json:"action" jsonschema:"refactoring action, e.g. extract-function"`
|
||||
}
|
||||
|
||||
type RefactorOutput struct {
|
||||
Refactored string `json:"refactored"`
|
||||
}
|
||||
|
||||
func Refactor(_ context.Context, _ *mcp.CallToolRequest, in RefactorInput) (*mcp.CallToolResult, RefactorOutput, error) {
|
||||
return nil, RefactorOutput{Refactored: "// refactored\n" + in.Code}, nil
|
||||
}
|
||||
|
||||
// -- Compact variant tool types -----------------------------------------------
|
||||
|
||||
type SummarizeInput struct {
|
||||
Text string `json:"text" jsonschema:"text to summarize"`
|
||||
}
|
||||
|
||||
type SummarizeOutput struct {
|
||||
Summary string `json:"summary"`
|
||||
}
|
||||
|
||||
func Summarize(_ context.Context, _ *mcp.CallToolRequest, in SummarizeInput) (*mcp.CallToolResult, SummarizeOutput, error) {
|
||||
return nil, SummarizeOutput{Summary: in.Text[:min(len(in.Text), 50)]}, nil
|
||||
}
|
||||
|
||||
type LookupInput struct {
|
||||
Query string `json:"query" jsonschema:"lookup query"`
|
||||
}
|
||||
|
||||
type LookupOutput struct {
|
||||
Result string `json:"result"`
|
||||
}
|
||||
|
||||
func Lookup(_ context.Context, _ *mcp.CallToolRequest, in LookupInput) (*mcp.CallToolResult, LookupOutput, error) {
|
||||
return nil, LookupOutput{Result: "result for: " + in.Query}, nil
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
func main() {
|
||||
// Server 1: coding-focused tools
|
||||
server1 := mcp.NewServer(&mcp.Implementation{Name: "my-server", Version: "v1.0.0"}, nil)
|
||||
mcp.AddTool(server1, &mcp.Tool{Name: "analyze_code", Description: "Perform static analysis on source code"}, AnalyzeCode)
|
||||
mcp.AddTool(server1, &mcp.Tool{Name: "refactor", Description: "Apply a refactoring action to source code"}, Refactor)
|
||||
|
||||
// Server 2: compact / minimal tools
|
||||
server2 := mcp.NewServer(&mcp.Implementation{Name: "my-server", Version: "v1.0.0"}, nil)
|
||||
mcp.AddTool(server2, &mcp.Tool{Name: "summarize", Description: "Summarize text"}, Summarize)
|
||||
mcp.AddTool(server2, &mcp.Tool{Name: "lookup", Description: "Quick fact lookup"}, Lookup)
|
||||
|
||||
coding := variants.ServerVariant{
|
||||
ID: "coding-assistant",
|
||||
Description: "Optimized for coding workflows",
|
||||
Hints: map[string]string{"useCase": "coding", "contextSize": "standard"},
|
||||
Status: variants.Stable,
|
||||
}
|
||||
|
||||
compact := variants.ServerVariant{
|
||||
ID: "compact",
|
||||
Description: "Minimal token usage",
|
||||
Hints: map[string]string{"contextSize": "small"},
|
||||
Status: variants.Experimental,
|
||||
}
|
||||
|
||||
vs := variants.NewServer().
|
||||
WithVariant(coding, server1, 0).
|
||||
WithVariant(compact, server2, 1).
|
||||
WithRanking(func(_ context.Context, _ variants.VariantHints, vs []variants.ServerVariant) []variants.ServerVariant {
|
||||
// rank based on client hints, return sorted
|
||||
// note: this is optional, defults to ranking by priority.
|
||||
return vs
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
if err := vs.Run(ctx, nil); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue