mcp: allow any value for schemas (#517)
As discussed at length in https://github.com/modelcontextprotocol/go-sdk/issues/518, coupling our schema fields to jsonschema.Schema limits our user's ability to use a different schema package, and makes it impossible for our client to talk to some backends. This CL relaxes the type of `*jsonschema.Schema` fields to be of type `any`, which is a breaking change but is unlikely to affect most server code. (It *is* a nontrivial change for clients). Fixes https://github.com/modelcontextprotocol/go-sdk/issues/518
This commit is contained in:
parent
5f05f8a43a
commit
964574b818
1 changed files with 201 additions and 47 deletions
|
|
@ -16,6 +16,49 @@ import (
|
|||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
)
|
||||
|
||||
func ExampleServer_AddTool_rawSchema() {
|
||||
// In some scenarios, you may want your server to be a pass-through, with
|
||||
// JSON schema coming from another source. Or perhaps you want to implement
|
||||
// tool validation using a different JSON schema library.
|
||||
//
|
||||
// For these cases, you can use [mcp.Server.AddTool], which is the "raw" form
|
||||
// of the API. Note that it is the caller's responsibility to validate inputs
|
||||
// and outputs.
|
||||
server := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "v0.0.1"}, nil)
|
||||
server.AddTool(&mcp.Tool{
|
||||
Name: "greet",
|
||||
InputSchema: json.RawMessage(`{"type":"object","properties":{"user":{"type":"string"}}}`),
|
||||
}, func(_ context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
// Note: no validation!
|
||||
var args struct{ User string }
|
||||
if err := json.Unmarshal(req.Params.Arguments, &args); err != nil {
|
||||
// TODO: we should use a jsonrpc error here, to be consistent with other
|
||||
// SDKs.
|
||||
return nil, err
|
||||
}
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{&mcp.TextContent{Text: "Hi " + args.User}},
|
||||
}, nil
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
session, err := connect(ctx, server)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
res, err := session.CallTool(ctx, &mcp.CallToolParams{
|
||||
Name: "greet",
|
||||
Arguments: map[string]any{"user": "you"},
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(res.Content[0].(*mcp.TextContent).Text)
|
||||
// Output: Hi you
|
||||
}
|
||||
|
||||
func ExampleAddTool_customMarshalling() {
|
||||
// Sometimes when you want to customize the input or output schema for a
|
||||
// tool, you need to customize the schema of a single helper type that's used
|
||||
|
|
@ -68,7 +111,7 @@ func ExampleAddTool_customMarshalling() {
|
|||
}
|
||||
// Output:
|
||||
// my_tool {
|
||||
// "type": "object",
|
||||
// "additionalProperties": false,
|
||||
// "properties": {
|
||||
// "end": {
|
||||
// "type": "string"
|
||||
|
|
@ -80,7 +123,7 @@ func ExampleAddTool_customMarshalling() {
|
|||
// "type": "string"
|
||||
// }
|
||||
// },
|
||||
// "additionalProperties": false
|
||||
// "type": "object"
|
||||
// }
|
||||
}
|
||||
|
||||
|
|
@ -200,9 +243,9 @@ func ExampleAddTool_complexSchema() {
|
|||
}
|
||||
// Formatting the entire schemas would be too much output.
|
||||
// Just check that our customizations were effective.
|
||||
fmt.Println("max days:", *t.InputSchema.Properties["days"].Maximum)
|
||||
fmt.Println("max confidence:", *t.OutputSchema.Properties["confidence"].Maximum)
|
||||
fmt.Println("weather types:", t.OutputSchema.Properties["dailyForecast"].Items.Properties["type"].Enum)
|
||||
fmt.Println("max days:", jsonPath(t.InputSchema, "properties", "days", "maximum"))
|
||||
fmt.Println("max confidence:", jsonPath(t.OutputSchema, "properties", "confidence", "maximum"))
|
||||
fmt.Println("weather types:", jsonPath(t.OutputSchema, "properties", "dailyForecast", "items", "properties", "type", "enum"))
|
||||
}
|
||||
// Output:
|
||||
// max days: 10
|
||||
|
|
@ -218,3 +261,10 @@ func connect(ctx context.Context, server *mcp.Server) (*mcp.ClientSession, error
|
|||
client := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "v0.0.1"}, nil)
|
||||
return client.Connect(ctx, t2, nil)
|
||||
}
|
||||
|
||||
func jsonPath(s any, path ...string) any {
|
||||
if len(path) == 0 {
|
||||
return s
|
||||
}
|
||||
return jsonPath(s.(map[string]any)[path[0]], path[1:]...)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue