diff --git a/docs/client.md b/docs/client.md index 13c12d57..cbc4db8f 100644 --- a/docs/client.md +++ b/docs/client.md @@ -13,7 +13,7 @@ The SDK supports this as follows: **Client-side**: The SDK client always has the `roots.listChanged` capability. To add roots to a client, use the -[`Client.AddRoots`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#AddRoots) +[`Client.AddRoots`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Client.AddRoots) and [`Client.RemoveRoots`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Client.RemoveRoots) methods. If any servers are already [connected](protocol.md#lifecycle) to the diff --git a/docs/server.md b/docs/server.md index 5b17f2e5..e6af5d9c 100644 --- a/docs/server.md +++ b/docs/server.md @@ -11,7 +11,93 @@ ## 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. + +**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. + +```go +func Example_prompts() { + ctx := context.Background() + + promptHandler := func(ctx context.Context, req *mcp.GetPromptRequest) (*mcp.GetPromptResult, error) { + return &mcp.GetPromptResult{ + Description: "Hi prompt", + Messages: []*mcp.PromptMessage{ + { + Role: "user", + Content: &mcp.TextContent{Text: "Say hi to " + req.Params.Arguments["name"]}, + }, + }, + }, nil + } + + // Create a server with a single prompt. + s := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "v0.0.1"}, nil) + prompt := &mcp.Prompt{ + Name: "greet", + Arguments: []*mcp.PromptArgument{ + { + Name: "name", + Description: "the name of the person to greet", + Required: true, + }, + }, + } + s.AddPrompt(prompt, promptHandler) + + // Create a client. + c := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "v0.0.1"}, nil) + + // Connect the server and client. + t1, t2 := mcp.NewInMemoryTransports() + if _, err := s.Connect(ctx, t1, nil); err != nil { + log.Fatal(err) + } + cs, err := c.Connect(ctx, t2, nil) + if err != nil { + log.Fatal(err) + } + + // List the prompts. + for p, err := range cs.Prompts(ctx, nil) { + if err != nil { + log.Fatal(err) + } + fmt.Println(p.Name) + } + + // Get the prompt. + res, err := cs.GetPrompt(ctx, &mcp.GetPromptParams{ + Name: "greet", + Arguments: map[string]string{"name": "Pat"}, + }) + if err != nil { + log.Fatal(err) + } + for _, msg := range res.Messages { + fmt.Println(msg.Role, msg.Content.(*mcp.TextContent).Text) + } + // Output: + // greet + // user Say hi to Pat +} +``` ## Resources diff --git a/internal/docs/client.src.md b/internal/docs/client.src.md index f342719e..fc37d454 100644 --- a/internal/docs/client.src.md +++ b/internal/docs/client.src.md @@ -10,7 +10,7 @@ The SDK supports this as follows: **Client-side**: The SDK client always has the `roots.listChanged` capability. To add roots to a client, use the -[`Client.AddRoots`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#AddRoots) +[`Client.AddRoots`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Client.AddRoots) and [`Client.RemoveRoots`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#Client.RemoveRoots) methods. If any servers are already [connected](protocol.md#lifecycle) to the diff --git a/internal/docs/server.src.md b/internal/docs/server.src.md index a131bcd3..07ed6cb9 100644 --- a/internal/docs/server.src.md +++ b/internal/docs/server.src.md @@ -4,7 +4,27 @@ ## 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. + +**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. + +%include ../../mcp/server_example_test.go prompts - ## Resources diff --git a/mcp/server_example_test.go b/mcp/server_example_test.go new file mode 100644 index 00000000..d6b4d7e4 --- /dev/null +++ b/mcp/server_example_test.go @@ -0,0 +1,83 @@ +// Copyright 2025 The Go MCP SDK Authors. All rights reserved. +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package mcp_test + +import ( + "context" + "fmt" + "log" + + "github.com/modelcontextprotocol/go-sdk/mcp" +) + +// !+prompts + +func Example_prompts() { + ctx := context.Background() + + promptHandler := func(ctx context.Context, req *mcp.GetPromptRequest) (*mcp.GetPromptResult, error) { + return &mcp.GetPromptResult{ + Description: "Hi prompt", + Messages: []*mcp.PromptMessage{ + { + Role: "user", + Content: &mcp.TextContent{Text: "Say hi to " + req.Params.Arguments["name"]}, + }, + }, + }, nil + } + + // Create a server with a single prompt. + s := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "v0.0.1"}, nil) + prompt := &mcp.Prompt{ + Name: "greet", + Arguments: []*mcp.PromptArgument{ + { + Name: "name", + Description: "the name of the person to greet", + Required: true, + }, + }, + } + s.AddPrompt(prompt, promptHandler) + + // Create a client. + c := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "v0.0.1"}, nil) + + // Connect the server and client. + t1, t2 := mcp.NewInMemoryTransports() + if _, err := s.Connect(ctx, t1, nil); err != nil { + log.Fatal(err) + } + cs, err := c.Connect(ctx, t2, nil) + if err != nil { + log.Fatal(err) + } + + // List the prompts. + for p, err := range cs.Prompts(ctx, nil) { + if err != nil { + log.Fatal(err) + } + fmt.Println(p.Name) + } + + // Get the prompt. + res, err := cs.GetPrompt(ctx, &mcp.GetPromptParams{ + Name: "greet", + Arguments: map[string]string{"name": "Pat"}, + }) + if err != nil { + log.Fatal(err) + } + for _, msg := range res.Messages { + fmt.Println(msg.Role, msg.Content.(*mcp.TextContent).Text) + } + // Output: + // greet + // user Say hi to Pat +} + +// !-prompts