docs: document tool support (#498)
Document tool support, and tweak the wording for prompts. For #442
This commit is contained in:
parent
28753c9f12
commit
5985a7cbba
7 changed files with 358 additions and 56 deletions
|
|
@ -56,9 +56,12 @@ func Example_roots() {
|
|||
if _, err := s.Connect(ctx, t1, nil); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if _, err := c.Connect(ctx, t2, nil); err != nil {
|
||||
|
||||
clientSession, err := c.Connect(ctx, t2, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer clientSession.Close()
|
||||
|
||||
// ...and add a root. The server is notified about the change.
|
||||
c.AddRoots(&mcp.Root{URI: "file://b"})
|
||||
|
|
|
|||
209
docs/server.md
209
docs/server.md
|
|
@ -11,25 +11,32 @@
|
|||
|
||||
## Prompts
|
||||
|
||||
**Server-side**:
|
||||
MCP servers can provide LLM prompt templates (called simply _prompts_) to clients.
|
||||
Every prompt has a required name which identifies it, and a set of named arguments, which are strings.
|
||||
Construct a prompt with a name and descriptions of its arguments.
|
||||
Associated with each prompt is a handler that expands the template given values for its arguments.
|
||||
Use [`Server.AddPrompt`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Server.AddPrompt)
|
||||
to add a prompt along with its handler.
|
||||
If `AddPrompt` is called before a server is connected, the server will have the `prompts` capability.
|
||||
If all prompts are to be added after connection, set [`ServerOptions.HasPrompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.HasPrompts)
|
||||
to advertise the capability.
|
||||
MCP servers can provide LLM prompt templates (called simply
|
||||
[_prompts_](https://modelcontextprotocol.io/specification/2025-06-18/server/prompts))
|
||||
to clients. Every prompt has a required name which identifies it, and a set of
|
||||
named arguments, which are strings.
|
||||
|
||||
**Client-side**:
|
||||
To list the server's prompts, call
|
||||
Call [`ClientSession.Prompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.Prompts) to get an iterator.
|
||||
If needed, you can use the lower-level
|
||||
[`ClientSession.ListPrompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.ListPrompts) to list the server's prompts.
|
||||
Call [`ClientSession.GetPrompt`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.GetPrompt) to retrieve a prompt by name, providing
|
||||
arguments for expansion.
|
||||
Set [`ClientOptions.PromptListChangedHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientOptions.PromptListChangedHandler) to be notified of changes in the list of prompts.
|
||||
**Client-side**: To list the server's prompts, use the
|
||||
[`ClientSession.Prompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.Prompts)
|
||||
iterator, or the lower-level
|
||||
[`ClientSession.ListPrompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.ListPrompts)
|
||||
(see [pagination](#pagination) below). Set
|
||||
[`ClientOptions.PromptListChangedHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientOptions.PromptListChangedHandler)
|
||||
to be notified of changes in the list of prompts.
|
||||
|
||||
Call
|
||||
[`ClientSession.GetPrompt`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.GetPrompt)
|
||||
to retrieve a prompt by name, providing arguments for expansion.
|
||||
|
||||
**Server-side**: Use
|
||||
[`Server.AddPrompt`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Server.AddPrompt)
|
||||
to add a prompt to the server along with its handler.
|
||||
The server will have the `prompts` capability if any prompt is added before the
|
||||
server is connected to a client, or if
|
||||
[`ServerOptions.HasPrompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.HasPrompts)
|
||||
is explicitly set. When a prompt is added, any clients already connected to the
|
||||
server will be notified via a `notifications/prompts/list_changed`
|
||||
notification.
|
||||
|
||||
```go
|
||||
func Example_prompts() {
|
||||
|
|
@ -73,6 +80,7 @@ func Example_prompts() {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer cs.Close()
|
||||
|
||||
// List the prompts.
|
||||
for p, err := range cs.Prompts(ctx, nil) {
|
||||
|
|
@ -105,7 +113,170 @@ func Example_prompts() {
|
|||
|
||||
## Tools
|
||||
|
||||
<!-- TODO -->
|
||||
MCP servers can provide
|
||||
[tools](https://modelcontextprotocol.io/specification/2025-06-18/server/tools)
|
||||
to allow clients to interact with external systems or functionality. Tools are
|
||||
effectively remote function calls, and the Go SDK provides mechanisms to bind
|
||||
them to ordinary Go functions.
|
||||
|
||||
**Client-side**: To list the server's tools, use the
|
||||
[`ClientSession.Tools`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.Tools)
|
||||
iterator, or the lower-level
|
||||
[`ClientSession.ListTools`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.ListTools)
|
||||
(see [pagination](#pagination)). Set
|
||||
[`ClientOptions.ToolListChangedHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientOptions.ToolListChangedHandler)
|
||||
to be notified of changes in the list of tools.
|
||||
|
||||
To call a tool, use
|
||||
[`ClientSession.CallTool`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.CallTool)
|
||||
with `CallToolParams` holding the name and arguments of the tool to call.
|
||||
|
||||
```go
|
||||
res, err := session.CallTool(ctx, &mcp.CallToolParams{
|
||||
Name: "my_tool",
|
||||
Arguments: map[string]any{"name": "user"},
|
||||
})
|
||||
```
|
||||
|
||||
Arguments may be any value that can be marshaled to JSON.
|
||||
|
||||
**Server-side**: the basic API for adding a tool is symmetrical with the API
|
||||
for prompts or resources:
|
||||
[`Server.AddTool`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Server.AddTool)
|
||||
adds a
|
||||
[`Tool`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Tool) to
|
||||
the server along with its
|
||||
[`ToolHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ToolHandler)
|
||||
to handle it. The server will have the `tools` capability if any tool is added
|
||||
before the server is connected to a client, or if
|
||||
[`ServerOptions.HasTools`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.HasPrompts)
|
||||
is explicitly set. When a tool is added, any clients already connected to the
|
||||
server will be notified via a `notifications/tools/list_changed` notification.
|
||||
|
||||
However, the `Server.AddTool` API leaves it to the user to implement the tool
|
||||
handler correctly according to the spec, providing very little out of the box.
|
||||
In order to implement a tool, the user must do all of the following:
|
||||
|
||||
- Provide a tool input and output schema.
|
||||
- Validate the tool arguments against its input schema.
|
||||
- Unmarshal the input schema into a Go value
|
||||
- Execute the tool logic.
|
||||
- Marshal the tool's structured output (if any) to JSON, and store it in the
|
||||
result's `StructuredOutput` field as well as the unstructured `Content` field.
|
||||
- Validate that output JSON against the tool's output schema.
|
||||
- If any tool errors occurred, pack them into the unstructured content and set
|
||||
`IsError` to `true.`
|
||||
|
||||
For this reason, the SDK provides a generic
|
||||
[`AddTool`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#AddTool)
|
||||
function that handles this for you. It can bind a tool to any function with the
|
||||
following shape:
|
||||
|
||||
```go
|
||||
func(_ context.Context, request *CallToolRequest, input In) (result *CallToolResult, output Out, _ error)
|
||||
```
|
||||
|
||||
This is like a `ToolHandler`, but with an extra arbitrary `In` input parameter,
|
||||
and `Out` output parameter.
|
||||
|
||||
Such a function can then be bound to the server using `AddTool`:
|
||||
|
||||
```go
|
||||
mcp.AddTool(server, &mcp.Tool{Name: "my_tool"}, handler)
|
||||
```
|
||||
|
||||
This does the following automatically:
|
||||
|
||||
- If `Tool.InputSchema` or `Tool.OutputSchema` are unset, the input and output
|
||||
schemas are inferred from the `In` type, which must be a struct or map.
|
||||
Optional `jsonschema` struct tags provide argument descriptions.
|
||||
- Tool arguments are validated against the input schema.
|
||||
- Tool arguments are marshaled into the `In` value.
|
||||
- Tool output (the `Out` value) is marshaled into the result's
|
||||
`StructuredOutput`, as well as the unstructured `Content`.
|
||||
- Output is validated against the tool's output schema.
|
||||
- If an ordinary error is returned, it is stored int the `CallToolResult` and
|
||||
`IsError` is set to `true`.
|
||||
|
||||
In fact, under ordinary circumstances, the user can ignore `CallToolRequest`
|
||||
and `CallToolResult`.
|
||||
|
||||
For a more realistic example, consider a tool that retrieves the weather:
|
||||
|
||||
```go
|
||||
type WeatherInput struct {
|
||||
Location Location `json:"location" jsonschema:"user location"`
|
||||
Days int `json:"days" jsonschema:"number of days to forecast"`
|
||||
}
|
||||
|
||||
type WeatherOutput struct {
|
||||
Summary string `json:"summary" jsonschema:"a summary of the weather forecast"`
|
||||
Confidence Probability `json:"confidence" jsonschema:"confidence, between 0 and 1"`
|
||||
AsOf time.Time `json:"asOf" jsonschema:"the time the weather was computed"`
|
||||
DailyForecast []Forecast `json:"dailyForecast" jsonschema:"the daily forecast"`
|
||||
Source string `json:"source,omitempty" jsonschema:"the organization providing the weather forecast"`
|
||||
}
|
||||
|
||||
func WeatherTool(ctx context.Context, req *mcp.CallToolRequest, in WeatherInput) (*mcp.CallToolResult, WeatherOutput, error) {
|
||||
perfectWeather := WeatherOutput{
|
||||
Summary: "perfect",
|
||||
Confidence: 1.0,
|
||||
AsOf: time.Now(),
|
||||
}
|
||||
for range in.Days {
|
||||
perfectWeather.DailyForecast = append(perfectWeather.DailyForecast, Forecast{
|
||||
Forecast: "another perfect day",
|
||||
Type: Sunny,
|
||||
Rain: 0.0,
|
||||
High: 72.0,
|
||||
Low: 72.0,
|
||||
})
|
||||
}
|
||||
return nil, perfectWeather, nil
|
||||
}
|
||||
```
|
||||
|
||||
In this case, we want to customize part of the inferred schema, though we can
|
||||
still infer the rest. Since we want to control the inference ourselves, we set
|
||||
the `Tool.InputSchema` explicitly:
|
||||
|
||||
```go
|
||||
// Distinguished Go types allow custom schemas to be reused during inference.
|
||||
customSchemas := map[any]*jsonschema.Schema{
|
||||
Probability(0): {Type: "number", Minimum: jsonschema.Ptr(0.0), Maximum: jsonschema.Ptr(1.0)},
|
||||
WeatherType(""): {Type: "string", Enum: []any{Sunny, PartlyCloudy, Cloudy, Rainy, Snowy}},
|
||||
}
|
||||
opts := &jsonschema.ForOptions{TypeSchemas: customSchemas}
|
||||
in, err := jsonschema.For[WeatherInput](opts)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Furthermore, we can tweak the inferred schema, in this case limiting
|
||||
// forecasts to 0-10 days.
|
||||
daysSchema := in.Properties["days"]
|
||||
daysSchema.Minimum = jsonschema.Ptr(0.0)
|
||||
daysSchema.Maximum = jsonschema.Ptr(10.0)
|
||||
|
||||
// Output schema inference can reuse our custom schemas from input inference.
|
||||
out, err := jsonschema.For[WeatherOutput](opts)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Now add our tool to a server. Since we've customized the schemas, we need
|
||||
// to override the default schema inference.
|
||||
server := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "v0.0.1"}, nil)
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
Name: "weather",
|
||||
InputSchema: in,
|
||||
OutputSchema: out,
|
||||
}, WeatherTool)
|
||||
```
|
||||
|
||||
_See [mcp/tool_example_test.go](../mcp/tool_example_test.go) for the full
|
||||
example, or [examples/server/toolschemas](examples/server/toolschemas/main.go)
|
||||
for more examples of customizing tool schemas._
|
||||
|
||||
## Utilities
|
||||
|
||||
|
|
|
|||
|
|
@ -29,16 +29,21 @@ func ExampleLoggingTransport() {
|
|||
ctx := context.Background()
|
||||
t1, t2 := mcp.NewInMemoryTransports()
|
||||
server := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "v0.0.1"}, nil)
|
||||
if _, err := server.Connect(ctx, t1, nil); err != nil {
|
||||
serverSession, err := server.Connect(ctx, t1, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer serverSession.Wait()
|
||||
|
||||
client := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "v0.0.1"}, nil)
|
||||
var b bytes.Buffer
|
||||
logTransport := &mcp.LoggingTransport{Transport: t2, Writer: &b}
|
||||
if _, err := client.Connect(ctx, logTransport, nil); err != nil {
|
||||
clientSession, err := client.Connect(ctx, logTransport, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer clientSession.Close()
|
||||
|
||||
// Sort for stability: reads are concurrent to writes.
|
||||
for _, line := range slices.Sorted(strings.SplitSeq(b.String(), "\n")) {
|
||||
fmt.Println(line)
|
||||
|
|
|
|||
|
|
@ -4,25 +4,32 @@
|
|||
|
||||
## Prompts
|
||||
|
||||
**Server-side**:
|
||||
MCP servers can provide LLM prompt templates (called simply _prompts_) to clients.
|
||||
Every prompt has a required name which identifies it, and a set of named arguments, which are strings.
|
||||
Construct a prompt with a name and descriptions of its arguments.
|
||||
Associated with each prompt is a handler that expands the template given values for its arguments.
|
||||
Use [`Server.AddPrompt`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Server.AddPrompt)
|
||||
to add a prompt along with its handler.
|
||||
If `AddPrompt` is called before a server is connected, the server will have the `prompts` capability.
|
||||
If all prompts are to be added after connection, set [`ServerOptions.HasPrompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.HasPrompts)
|
||||
to advertise the capability.
|
||||
MCP servers can provide LLM prompt templates (called simply
|
||||
[_prompts_](https://modelcontextprotocol.io/specification/2025-06-18/server/prompts))
|
||||
to clients. Every prompt has a required name which identifies it, and a set of
|
||||
named arguments, which are strings.
|
||||
|
||||
**Client-side**:
|
||||
To list the server's prompts, call
|
||||
Call [`ClientSession.Prompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.Prompts) to get an iterator.
|
||||
If needed, you can use the lower-level
|
||||
[`ClientSession.ListPrompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.ListPrompts) to list the server's prompts.
|
||||
Call [`ClientSession.GetPrompt`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.GetPrompt) to retrieve a prompt by name, providing
|
||||
arguments for expansion.
|
||||
Set [`ClientOptions.PromptListChangedHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientOptions.PromptListChangedHandler) to be notified of changes in the list of prompts.
|
||||
**Client-side**: To list the server's prompts, use the
|
||||
[`ClientSession.Prompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.Prompts)
|
||||
iterator, or the lower-level
|
||||
[`ClientSession.ListPrompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.ListPrompts)
|
||||
(see [pagination](#pagination) below). Set
|
||||
[`ClientOptions.PromptListChangedHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientOptions.PromptListChangedHandler)
|
||||
to be notified of changes in the list of prompts.
|
||||
|
||||
Call
|
||||
[`ClientSession.GetPrompt`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.GetPrompt)
|
||||
to retrieve a prompt by name, providing arguments for expansion.
|
||||
|
||||
**Server-side**: Use
|
||||
[`Server.AddPrompt`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Server.AddPrompt)
|
||||
to add a prompt to the server along with its handler.
|
||||
The server will have the `prompts` capability if any prompt is added before the
|
||||
server is connected to a client, or if
|
||||
[`ServerOptions.HasPrompts`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.HasPrompts)
|
||||
is explicitly set. When a prompt is added, any clients already connected to the
|
||||
server will be notified via a `notifications/prompts/list_changed`
|
||||
notification.
|
||||
|
||||
%include ../../mcp/server_example_test.go prompts -
|
||||
|
||||
|
|
@ -32,7 +39,107 @@ Set [`ClientOptions.PromptListChangedHandler`](https://pkg.go.dev/github.com/mod
|
|||
|
||||
## Tools
|
||||
|
||||
<!-- TODO -->
|
||||
MCP servers can provide
|
||||
[tools](https://modelcontextprotocol.io/specification/2025-06-18/server/tools)
|
||||
to allow clients to interact with external systems or functionality. Tools are
|
||||
effectively remote function calls, and the Go SDK provides mechanisms to bind
|
||||
them to ordinary Go functions.
|
||||
|
||||
**Client-side**: To list the server's tools, use the
|
||||
[`ClientSession.Tools`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.Tools)
|
||||
iterator, or the lower-level
|
||||
[`ClientSession.ListTools`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.ListTools)
|
||||
(see [pagination](#pagination)). Set
|
||||
[`ClientOptions.ToolListChangedHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientOptions.ToolListChangedHandler)
|
||||
to be notified of changes in the list of tools.
|
||||
|
||||
To call a tool, use
|
||||
[`ClientSession.CallTool`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientSession.CallTool)
|
||||
with `CallToolParams` holding the name and arguments of the tool to call.
|
||||
|
||||
```go
|
||||
res, err := session.CallTool(ctx, &mcp.CallToolParams{
|
||||
Name: "my_tool",
|
||||
Arguments: map[string]any{"name": "user"},
|
||||
})
|
||||
```
|
||||
|
||||
Arguments may be any value that can be marshaled to JSON.
|
||||
|
||||
**Server-side**: the basic API for adding a tool is symmetrical with the API
|
||||
for prompts or resources:
|
||||
[`Server.AddTool`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Server.AddTool)
|
||||
adds a
|
||||
[`Tool`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Tool) to
|
||||
the server along with its
|
||||
[`ToolHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ToolHandler)
|
||||
to handle it. The server will have the `tools` capability if any tool is added
|
||||
before the server is connected to a client, or if
|
||||
[`ServerOptions.HasTools`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.HasPrompts)
|
||||
is explicitly set. When a tool is added, any clients already connected to the
|
||||
server will be notified via a `notifications/tools/list_changed` notification.
|
||||
|
||||
However, the `Server.AddTool` API leaves it to the user to implement the tool
|
||||
handler correctly according to the spec, providing very little out of the box.
|
||||
In order to implement a tool, the user must do all of the following:
|
||||
|
||||
- Provide a tool input and output schema.
|
||||
- Validate the tool arguments against its input schema.
|
||||
- Unmarshal the input schema into a Go value
|
||||
- Execute the tool logic.
|
||||
- Marshal the tool's structured output (if any) to JSON, and store it in the
|
||||
result's `StructuredOutput` field as well as the unstructured `Content` field.
|
||||
- Validate that output JSON against the tool's output schema.
|
||||
- If any tool errors occurred, pack them into the unstructured content and set
|
||||
`IsError` to `true.`
|
||||
|
||||
For this reason, the SDK provides a generic
|
||||
[`AddTool`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#AddTool)
|
||||
function that handles this for you. It can bind a tool to any function with the
|
||||
following shape:
|
||||
|
||||
```go
|
||||
func(_ context.Context, request *CallToolRequest, input In) (result *CallToolResult, output Out, _ error)
|
||||
```
|
||||
|
||||
This is like a `ToolHandler`, but with an extra arbitrary `In` input parameter,
|
||||
and `Out` output parameter.
|
||||
|
||||
Such a function can then be bound to the server using `AddTool`:
|
||||
|
||||
```go
|
||||
mcp.AddTool(server, &mcp.Tool{Name: "my_tool"}, handler)
|
||||
```
|
||||
|
||||
This does the following automatically:
|
||||
|
||||
- If `Tool.InputSchema` or `Tool.OutputSchema` are unset, the input and output
|
||||
schemas are inferred from the `In` type, which must be a struct or map.
|
||||
Optional `jsonschema` struct tags provide argument descriptions.
|
||||
- Tool arguments are validated against the input schema.
|
||||
- Tool arguments are marshaled into the `In` value.
|
||||
- Tool output (the `Out` value) is marshaled into the result's
|
||||
`StructuredOutput`, as well as the unstructured `Content`.
|
||||
- Output is validated against the tool's output schema.
|
||||
- If an ordinary error is returned, it is stored int the `CallToolResult` and
|
||||
`IsError` is set to `true`.
|
||||
|
||||
In fact, under ordinary circumstances, the user can ignore `CallToolRequest`
|
||||
and `CallToolResult`.
|
||||
|
||||
For a more realistic example, consider a tool that retrieves the weather:
|
||||
|
||||
%include ../../mcp/tool_example_test.go weathertool -
|
||||
|
||||
In this case, we want to customize part of the inferred schema, though we can
|
||||
still infer the rest. Since we want to control the inference ourselves, we set
|
||||
the `Tool.InputSchema` explicitly:
|
||||
|
||||
%include ../../mcp/tool_example_test.go customschemas -
|
||||
|
||||
_See [mcp/tool_example_test.go](../mcp/tool_example_test.go) for the full
|
||||
example, or [examples/server/toolschemas](examples/server/toolschemas/main.go)
|
||||
for more examples of customizing tool schemas._
|
||||
|
||||
## Utilities
|
||||
|
||||
|
|
|
|||
|
|
@ -571,8 +571,9 @@ func (cs *ClientSession) ListTools(ctx context.Context, params *ListToolsParams)
|
|||
return handleSend[*ListToolsResult](ctx, methodListTools, newClientRequest(cs, orZero[Params](params)))
|
||||
}
|
||||
|
||||
// CallTool calls the tool with the given name and arguments.
|
||||
// The arguments can be any value that marshals into a JSON object.
|
||||
// CallTool calls the tool with the given parameters.
|
||||
//
|
||||
// The params.Arguments can be any value that marshals into a JSON object.
|
||||
func (cs *ClientSession) CallTool(ctx context.Context, params *CallToolParams) (*CallToolResult, error) {
|
||||
if params == nil {
|
||||
params = new(CallToolParams)
|
||||
|
|
|
|||
|
|
@ -42,11 +42,14 @@ type Annotations struct {
|
|||
|
||||
// CallToolParams is used by clients to call a tool.
|
||||
type CallToolParams struct {
|
||||
// This property is reserved by the protocol to allow clients and servers to
|
||||
// Meta is reserved by the protocol to allow clients and servers to
|
||||
// attach additional metadata to their responses.
|
||||
Meta `json:"_meta,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Arguments any `json:"arguments,omitempty"`
|
||||
Meta `json:"_meta,omitempty"`
|
||||
// Name is the name of the tool to call.
|
||||
Name string `json:"name"`
|
||||
// Arguments holds the tool arguments. It can hold any value that can be
|
||||
// marshaled to JSON.
|
||||
Arguments any `json:"arguments,omitempty"`
|
||||
}
|
||||
|
||||
// CallToolParamsRaw is passed to tool handlers on the server. Its arguments
|
||||
|
|
@ -55,8 +58,12 @@ type CallToolParams struct {
|
|||
type CallToolParamsRaw struct {
|
||||
// This property is reserved by the protocol to allow clients and servers to
|
||||
// attach additional metadata to their responses.
|
||||
Meta `json:"_meta,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Meta `json:"_meta,omitempty"`
|
||||
// Name is the name of the tool being called.
|
||||
Name string `json:"name"`
|
||||
// Arguments is the raw arguments received over the wire from the client. It
|
||||
// is the responsibility of the tool handler to unmarshal and validate the
|
||||
// Arguments (see [AddTool]).
|
||||
Arguments json.RawMessage `json:"arguments,omitempty"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,11 +83,6 @@ func ExampleAddTool_customMarshalling() {
|
|||
// }
|
||||
}
|
||||
|
||||
type WeatherInput struct {
|
||||
Location Location `json:"location" jsonschema:"user location"`
|
||||
Days int `json:"days" jsonschema:"number of days to forecast"`
|
||||
}
|
||||
|
||||
type Location struct {
|
||||
Name string `json:"name"`
|
||||
Latitude *float64 `json:"latitude,omitempty"`
|
||||
|
|
@ -114,6 +109,13 @@ const (
|
|||
|
||||
type Probability float64
|
||||
|
||||
// !+weathertool
|
||||
|
||||
type WeatherInput struct {
|
||||
Location Location `json:"location" jsonschema:"user location"`
|
||||
Days int `json:"days" jsonschema:"number of days to forecast"`
|
||||
}
|
||||
|
||||
type WeatherOutput struct {
|
||||
Summary string `json:"summary" jsonschema:"a summary of the weather forecast"`
|
||||
Confidence Probability `json:"confidence" jsonschema:"confidence, between 0 and 1"`
|
||||
|
|
@ -140,11 +142,15 @@ func WeatherTool(ctx context.Context, req *mcp.CallToolRequest, in WeatherInput)
|
|||
return nil, perfectWeather, nil
|
||||
}
|
||||
|
||||
// !-weathertool
|
||||
|
||||
func ExampleAddTool_complexSchema() {
|
||||
// This example demonstrates a tool with a more 'realistic' input and output
|
||||
// schema. We use a combination of techniques to tune our input and output
|
||||
// schemas.
|
||||
|
||||
// !+customschemas
|
||||
|
||||
// Distinguished Go types allow custom schemas to be reused during inference.
|
||||
customSchemas := map[any]*jsonschema.Schema{
|
||||
Probability(0): {Type: "number", Minimum: jsonschema.Ptr(0.0), Maximum: jsonschema.Ptr(1.0)},
|
||||
|
|
@ -177,6 +183,8 @@ func ExampleAddTool_complexSchema() {
|
|||
OutputSchema: out,
|
||||
}, WeatherTool)
|
||||
|
||||
// !-customschemas
|
||||
|
||||
ctx := context.Background()
|
||||
session, err := connect(ctx, server) // create an in-memory connection
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Reference in a new issue