Documentation
¶
Index ¶
- Constants
- Variables
- func DummyResourceHandler() mcp.ResourceHandler
- func NewServer(opts *Options) *http.Server
- type Options
- type TestTool
- type ToolAddOrDeleteAnotherDummyResourceArgs
- type ToolContainsRootToolArgs
- type ToolCountDownArgs
- type ToolDelayArgs
- type ToolEchoArgs
- type ToolErrorArgs
- type ToolResourceUpdateNotificationArgs
- type ToolSumArgs
Constants ¶
const ToolAddOrDeleteDummyResourceName = "add_or_delete_dummy_resource"
const ToolAddPromptName = "add_prompt"
ToolAddPromptName is the name of the tool that adds a prompt dynamically which triggers the prompt handler.
const ToolNotificationCountsName = "notification_counts"
const ToolResourceUpdateNotificationName = "resource_update_notification"
Variables ¶
var ( DummyResource = &mcp.Resource{ Name: "dummy-resource", MIMEType: "text/plain", URI: "file:///dummy.txt", } AnotherDummyResource = &mcp.Resource{ Name: "another-dummy-resource", MIMEType: "text/plain", URI: "file:///another-dummy.txt", } DummyResourceTemplate = &mcp.ResourceTemplate{ Name: "dummy-template", Description: "A dummy resource template for testing", MIMEType: "text/plain", Title: "Dummy Template", URITemplate: "file:///{name}.txt", } )
var CodeReviewPrompt = &mcp.Prompt{ Name: "code_review", Description: "do a code review", Arguments: []*mcp.PromptArgument{{Name: "Code", Required: true}}, }
var DummyPrompt = &mcp.Prompt{ Name: "dummy", Description: "a dummy prompt that does nothing", Arguments: []*mcp.PromptArgument{}, }
var ToolContainsRootTool = TestTool[ToolContainsRootToolArgs, any]{ Tool: &mcp.Tool{ Name: "contains_root", Description: "Check if a root with the given name exists", InputSchema: &jsonschema.Schema{ Type: "object", Properties: map[string]*jsonschema.Schema{ "expected_root_name": {Type: "string", Description: "Expression to filter root names"}, }, Required: []string{"expected_root_name"}, }, }, Handler: func(ctx context.Context, request *mcp.CallToolRequest, args ToolContainsRootToolArgs) (*mcp.CallToolResult, any, error) { rs, err := request.Session.ListRoots(ctx, &mcp.ListRootsParams{}) if err != nil { return nil, nil, err } has := false for _, r := range rs.Roots { if r.Name == args.ExpectedRootName { has = true break } } if !has { return &mcp.CallToolResult{ IsError: true, Content: []mcp.Content{ &mcp.TextContent{Text: fmt.Sprintf("root %q not found", args.ExpectedRootName)}, }, }, nil, nil } return &mcp.CallToolResult{ Content: []mcp.Content{ &mcp.TextContent{Text: fmt.Sprintf("root %q found", args.ExpectedRootName)}, }, }, nil, nil }, }
ToolContainsRootTool - contains_root { expected_root_name: string } -> text.
This calls the server->client ListRoots method to check if a root with the given name exists. That will issue client->server JsonRPC response on the request path.
var ToolCountDown = TestTool[ToolCountDownArgs, any]{ Tool: &mcp.Tool{ Name: "countdown", Description: "Count down from a given number to zero", InputSchema: &jsonschema.Schema{ Type: "object", Properties: map[string]*jsonschema.Schema{ "from": {Type: "integer", Description: "Number to count down from"}, }, Required: []string{"from"}, }, }, Handler: func(ctx context.Context, request *mcp.CallToolRequest, args ToolCountDownArgs) (*mcp.CallToolResult, any, error) { interval, err := time.ParseDuration(args.Interval) if err != nil { return nil, nil, err } go func() { for i := args.From; i >= 0; i-- { err := request.Session.NotifyProgress(ctx, &mcp.ProgressNotificationParams{ Message: fmt.Sprintf("count down: %d", i), ProgressToken: args.From - i, }) if err != nil { return } err = request.Session.Log(ctx, &mcp.LoggingMessageParams{ Level: "debug", Data: `debug count down: ` + fmt.Sprint(i), }) if err != nil { return } err = request.Session.Log(ctx, &mcp.LoggingMessageParams{ Level: "error", Data: `count down: ` + fmt.Sprint(i), }) if err != nil { return } time.Sleep(interval) } }() return &mcp.CallToolResult{ Content: []mcp.Content{ &mcp.TextContent{Text: "Done!"}, }, }, nil, nil }, }
var ToolCreateMessage = TestTool[struct{}, any]{ Tool: &mcp.Tool{ Name: "create_message", Description: "Create a message", InputSchema: &jsonschema.Schema{ Type: "object", Properties: map[string]*jsonschema.Schema{}, }, }, Handler: func(ctx context.Context, req *mcp.CallToolRequest, _ struct{}) (*mcp.CallToolResult, any, error) { _, err := req.Session.CreateMessage(ctx, &mcp.CreateMessageParams{ Messages: []*mcp.SamplingMessage{ { Content: &mcp.TextContent{ Text: "You are a coding AI assistant.", }, Role: "system", }, { Content: &mcp.TextContent{ Text: "Build a MCP Gateway using Envoy AI Gateway.", }, Role: "user", }, }, Meta: map[string]any{ "progressToken": "sampling-foo", }, }) if err != nil { return nil, nil, err } return &mcp.CallToolResult{ Content: []mcp.Content{ &mcp.TextContent{Text: "Please create a message."}, }, }, nil, nil }, }
ToolCreateMessage - create_message {} -> text.
This tool simply asks the model to create a message, which will trigger a CreateMessageRequest.
var ToolDelay = TestTool[ToolDelayArgs, any]{ Tool: &mcp.Tool{ Name: "delay", Description: "Delay for a given duration", InputSchema: &jsonschema.Schema{ Type: "object", Properties: map[string]*jsonschema.Schema{ "duration": {Type: "string", Description: "Duration to delay (e.g.}, '2s', '500ms')"}, }, Required: []string{"duration"}, }, }, Handler: func(_ context.Context, _ *mcp.CallToolRequest, args ToolDelayArgs) (*mcp.CallToolResult, any, error) { d, err := time.ParseDuration(args.Duration) if err != nil { return nil, nil, err } time.Sleep(d) return &mcp.CallToolResult{ Content: []mcp.Content{ &mcp.TextContent{Text: fmt.Sprintf("Done after %s!", d)}, }, }, nil, nil }, }
ToolDelay - delay { duration: string } -> text.
This tool simply waits for the specified duration before returning.
var ToolDumbEcho = TestTool[ToolEchoArgs, any]{ Tool: &mcp.Tool{ Name: "dumb_echo", Description: "Echo back the provided text with an unnecessary prefix", InputSchema: &jsonschema.Schema{ Type: "object", Properties: map[string]*jsonschema.Schema{"text": {Type: "string", Description: "Text to echo"}}, Required: []string{"text"}, }, }, Handler: func(_ context.Context, _ *mcp.CallToolRequest, args ToolEchoArgs) (*mcp.CallToolResult, any, error) { return &mcp.CallToolResult{Content: []mcp.Content{&mcp.TextContent{Text: "dumb echo: " + args.Text}}}, nil, nil }, }
var ToolEcho = TestTool[ToolEchoArgs, any]{ Tool: &mcp.Tool{ Name: "echo", Description: "Echo back the provided text", InputSchema: &jsonschema.Schema{ Type: "object", Properties: map[string]*jsonschema.Schema{ "text": {Type: "string", Description: "Text to echo"}, }, Required: []string{"text"}, }, }, Handler: func(_ context.Context, _ *mcp.CallToolRequest, args ToolEchoArgs) (*mcp.CallToolResult, any, error) { return &mcp.CallToolResult{ Content: []mcp.Content{ &mcp.TextContent{Text: args.Text}, }, }, nil, nil }, }
ToolEcho - echo { text: string } -> text.
var ToolElicitEmail = TestTool[struct{}, any]{ Tool: &mcp.Tool{ Name: "elicit_email", Description: "Log the provided email address", InputSchema: &jsonschema.Schema{ Type: "object", Properties: map[string]*jsonschema.Schema{}, }, }, Handler: func(ctx context.Context, req *mcp.CallToolRequest, _ struct{}) (*mcp.CallToolResult, any, error) { _, err := req.Session.Elicit(ctx, &mcp.ElicitParams{ Message: "Please collect the user name and email.", }) if err != nil { return nil, nil, err } return &mcp.CallToolResult{ Content: []mcp.Content{&mcp.TextContent{Text: "done"}}, }, nil, nil }, }
ToolElicitEmail - elicit_email {} -> text.
This tool simply logs the provided email address.
var ToolError = TestTool[ToolErrorArgs, any]{ Tool: &mcp.Tool{ Name: "error", Description: "Return an error", InputSchema: &jsonschema.Schema{ Type: "object", Properties: map[string]*jsonschema.Schema{ "error": { Type: "string", Description: "Error message to return from the tool", MinLength: ptr(2), }, }, Required: []string{"error"}, }, }, Handler: func(_ context.Context, _ *mcp.CallToolRequest, args ToolErrorArgs) (*mcp.CallToolResult, any, error) { return &mcp.CallToolResult{ IsError: true, Content: []mcp.Content{ &mcp.TextContent{Text: args.Error}, }, }, nil, nil }, }
ToolError - error { tool_error: string, mcp_error: string } -> error.
var ToolSum = TestTool[ToolSumArgs, any]{ Tool: &mcp.Tool{ Name: "sum", Description: "Return a + b", InputSchema: &jsonschema.Schema{ Type: "object", Properties: map[string]*jsonschema.Schema{ "a": {Type: "number", Description: "First addend"}, "b": {Type: "number", Description: "Second addend"}, }, Required: []string{"a", "b"}, }, }, Handler: func(_ context.Context, _ *mcp.CallToolRequest, args ToolSumArgs) (*mcp.CallToolResult, any, error) { return &mcp.CallToolResult{ Content: []mcp.Content{ &mcp.TextContent{Text: fmt.Sprintf("%g", args.A+args.B)}, }, }, nil, nil }, }
ToolSum - sum { a: number, b: number } -> number.
Functions ¶
func DummyResourceHandler ¶
func DummyResourceHandler() mcp.ResourceHandler
func NewServer ¶
NewServer starts a demo MCP server with two tools: echo and sum.
When forceJSONResponse true, the server will respond with JSON responses instead of using text/even-stream. The spec allows both so it is useful for us to test both scenarios.
When dumbEchoServer is true, the server will only implement the echo tool, and will not implement any prompts or resources. This is useful for testing basic routing.
Types ¶
type TestTool ¶
type TestTool[In, Out any] struct { Tool *mcp.Tool Handler mcp.ToolHandlerFor[In, Out] }
TestTool combines a tool definition and its handler for testing.
type ToolAddOrDeleteAnotherDummyResourceArgs ¶
type ToolAddOrDeleteAnotherDummyResourceArgs struct {
Delete bool `json:"delete,omitempty"`
}
ToolAddOrDeleteAnotherDummyResourceArgs defines the arguments for the add_or_delete_dummy_resource tool.
type ToolContainsRootToolArgs ¶
type ToolContainsRootToolArgs struct {
ExpectedRootName string `json:"expected_root_name,omitempty"`
}
type ToolCountDownArgs ¶
type ToolDelayArgs ¶
type ToolDelayArgs struct {
Duration string `json:"duration,omitempty"`
}
type ToolEchoArgs ¶
type ToolEchoArgs struct {
Text string `json:"text,omitempty"`
}
ToolEchoArgs defines the arguments for the echo tool.
type ToolErrorArgs ¶
type ToolErrorArgs struct {
Error string `json:"error,omitempty"`
}
ToolErrorArgs defines the arguments for the error tool.
type ToolResourceUpdateNotificationArgs ¶
type ToolResourceUpdateNotificationArgs struct {
URI string `json:"uri"`
}
type ToolSumArgs ¶
ToolSumArgs defines the arguments for the sum tool.