diff --git a/examples/server/toolschemas/main.go b/examples/server/toolschemas/main.go index a53acd47..8517b6ef 100644 --- a/examples/server/toolschemas/main.go +++ b/examples/server/toolschemas/main.go @@ -139,7 +139,7 @@ func main() { if err != nil { log.Fatal(err) } - server.AddTool(&mcp.Tool{ + server.AddRawTool(&mcp.Tool{ Name: "manual greeting", InputSchema: inputSchema, OutputSchema: outputSchema, diff --git a/mcp/mcp_test.go b/mcp/mcp_test.go index 9cc105cd..9a754dce 100644 --- a/mcp/mcp_test.go +++ b/mcp/mcp_test.go @@ -277,7 +277,7 @@ func TestEndToEnd(t *testing.T) { } // Check tools-changed notifications. - s.AddTool(&Tool{Name: "T", InputSchema: &jsonschema.Schema{Type: "object"}}, nopHandler) + s.AddRawTool(&Tool{Name: "T", InputSchema: &jsonschema.Schema{Type: "object"}}, nopHandler) waitForNotification(t, "tools") s.RemoveTools("T") waitForNotification(t, "tools") @@ -1525,8 +1525,8 @@ func TestAddTool_DuplicateNoPanicAndNoDuplicate(t *testing.T) { // This case was written specifically to reproduce a bug where duplicate tools where causing jsonschema errors t1 := &Tool{Name: "dup", Description: "first", InputSchema: &jsonschema.Schema{Type: "object"}} t2 := &Tool{Name: "dup", Description: "second", InputSchema: &jsonschema.Schema{Type: "object"}} - s.AddTool(t1, nopHandler) - s.AddTool(t2, nopHandler) + s.AddRawTool(t1, nopHandler) + s.AddRawTool(t2, nopHandler) }) defer cleanup() diff --git a/mcp/server.go b/mcp/server.go index 27de09a3..a157b4da 100644 --- a/mcp/server.go +++ b/mcp/server.go @@ -159,7 +159,18 @@ func (s *Server) RemovePrompts(names ...string) { func() bool { return s.prompts.remove(names...) }) } -// AddTool adds a [Tool] to the server, or replaces one with the same name. +// AddTool was a misnamed way to add a 'raw' tool, that doesn't perform any +// parsing or validation validation. It is being renamed to AddRawTool so that +// AddTool is available in the future (see #530). +// +// Deprecated: use AddRawTool. AddTool will be remove for v1.0.0. +// +//go:fix inline +func (s *Server) AddTool(t *Tool, h ToolHandler) { + s.AddRawTool(t, h) +} + +// AddRawTool adds a [Tool] to the server, or replaces one with the same name. // The Tool argument must not be modified after this call. // // The tool's input schema must be non-nil and have the type "object". For a tool @@ -179,9 +190,9 @@ func (s *Server) RemovePrompts(names ...string) { // Setting the result's Content, StructuredContent and IsError fields are the caller's // responsibility. // -// Most users should use the top-level function [AddTool], which handles all these +// Most users should use the top-level function [AddRawTool], which handles all these // responsibilities. -func (s *Server) AddTool(t *Tool, h ToolHandler) { +func (s *Server) AddRawTool(t *Tool, h ToolHandler) { if t.InputSchema == nil { // This prevents the tool author from forgetting to write a schema where // one should be provided. If we papered over this by supplying the empty @@ -358,7 +369,7 @@ func setSchema[T any](sfield **jsonschema.Schema, rfield **jsonschema.Resolved) // output schema is set to the schema inferred from the Out type argument, // which also must be a map or struct. // -// Unlike [Server.AddTool], AddTool does a lot automatically, and forces tools +// Unlike [Server.AddRawTool], AddTool does a lot automatically, and forces tools // to conform to the MCP spec. See [ToolHandlerFor] for a detailed description // of this automatic behavior. func AddTool[In, Out any](s *Server, t *Tool, h ToolHandlerFor[In, Out]) { @@ -366,7 +377,7 @@ func AddTool[In, Out any](s *Server, t *Tool, h ToolHandlerFor[In, Out]) { if err != nil { panic(fmt.Sprintf("AddTool: tool %q: %v", t.Name, err)) } - s.AddTool(tt, hh) + s.AddRawTool(tt, hh) } // RemoveTools removes the tools with the given names. diff --git a/mcp/server_test.go b/mcp/server_test.go index 249ef90b..134a0d5d 100644 --- a/mcp/server_test.go +++ b/mcp/server_test.go @@ -299,7 +299,7 @@ func TestServerCapabilities(t *testing.T) { { name: "With tools", configureServer: func(s *Server) { - s.AddTool(tool, nil) + s.AddRawTool(tool, nil) }, wantCapabilities: &ServerCapabilities{ Logging: &LoggingCapabilities{}, @@ -325,7 +325,7 @@ func TestServerCapabilities(t *testing.T) { s.AddPrompt(&Prompt{Name: "p"}, nil) s.AddResource(&Resource{URI: "file:///r"}, nil) s.AddResourceTemplate(&ResourceTemplate{URITemplate: "file:///rt"}, nil) - s.AddTool(tool, nil) + s.AddRawTool(tool, nil) }, serverOpts: ServerOptions{ SubscribeHandler: func(context.Context, *SubscribeRequest) error { diff --git a/mcp/streamable_test.go b/mcp/streamable_test.go index 3576d2b5..b5ed1db1 100644 --- a/mcp/streamable_test.go +++ b/mcp/streamable_test.go @@ -837,7 +837,7 @@ func TestStreamableServerTransport(t *testing.T) { // Create a server containing a single tool, which runs the test tool // behavior, if any. server := NewServer(&Implementation{Name: "testServer", Version: "v1.0.0"}, nil) - server.AddTool( + server.AddRawTool( &Tool{Name: "tool", InputSchema: &jsonschema.Schema{Type: "object"}}, func(ctx context.Context, req *CallToolRequest) (*CallToolResult, error) { if test.tool != nil { diff --git a/mcp/tool.go b/mcp/tool.go index 12b02b7b..1864f7ec 100644 --- a/mcp/tool.go +++ b/mcp/tool.go @@ -14,7 +14,7 @@ import ( // A ToolHandler handles a call to tools/call. // -// This is a low-level API, for use with [Server.AddTool]. It does not do any +// This is a low-level API, for use with [Server.AddRawTool]. It does not do any // pre- or post-processing of the request or result: the params contain raw // arguments, no input validation is performed, and the result is returned to // the user as-is, without any validation of the output.