From 5d6c47a453215ecb2c744bfeb97aa17e1b443c7a Mon Sep 17 00:00:00 2001 From: Jonathan Amsterdam Date: Thu, 18 Sep 2025 09:45:46 -0400 Subject: [PATCH 1/3] mcp: add prompt feature doc --- docs/client.md | 2 +- docs/server.md | 18 ++++++++- internal/docs/client.src.md | 2 +- internal/docs/server.src.md | 18 ++++++++- mcp/server_example_test.go | 73 +++++++++++++++++++++++++++++++++++++ 5 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 mcp/server_example_test.go 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..68a092c5 100644 --- a/docs/server.md +++ b/docs/server.md @@ -11,7 +11,23 @@ ## Prompts - +**Server-side**: +MCP servers can provide LLM prompt templates (called simply _prompts_) to clients. +Associated with each prompt is a handler that expands the template given a set of key-value pairs. +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. ## 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..264b860a 100644 --- a/internal/docs/server.src.md +++ b/internal/docs/server.src.md @@ -4,7 +4,23 @@ ## Prompts - +**Server-side**: +MCP servers can provide LLM prompt templates (called simply _prompts_) to clients. +Associated with each prompt is a handler that expands the template given a set of key-value pairs. +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. ## Resources diff --git a/mcp/server_example_test.go b/mcp/server_example_test.go new file mode 100644 index 00000000..cd6780ff --- /dev/null +++ b/mcp/server_example_test.go @@ -0,0 +1,73 @@ +// 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) + s.AddPrompt(&mcp.Prompt{Name: "greet"}, 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 From 870e39e80cc2adf72d7ffc44130199ef708d791a Mon Sep 17 00:00:00 2001 From: Jonathan Amsterdam Date: Thu, 18 Sep 2025 10:18:33 -0400 Subject: [PATCH 2/3] doc name --- docs/server.md | 59 +++++++++++++++++++++++++++++++++++++ internal/docs/server.src.md | 2 ++ mcp/server_example_test.go | 1 + 3 files changed, 62 insertions(+) diff --git a/docs/server.md b/docs/server.md index 68a092c5..8bd0f5ba 100644 --- a/docs/server.md +++ b/docs/server.md @@ -29,6 +29,65 @@ Call [`ClientSession.GetPrompt`](https://pkg.go.dev/github.com/modelcontextproto 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) + // The name is required: it uniquely identifies the prompt. + s.AddPrompt(&mcp.Prompt{Name: "greet"}, 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/server.src.md b/internal/docs/server.src.md index 264b860a..4aa1c53f 100644 --- a/internal/docs/server.src.md +++ b/internal/docs/server.src.md @@ -22,6 +22,8 @@ Call [`ClientSession.GetPrompt`](https://pkg.go.dev/github.com/modelcontextproto 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 index cd6780ff..93635072 100644 --- a/mcp/server_example_test.go +++ b/mcp/server_example_test.go @@ -31,6 +31,7 @@ func Example_prompts() { // Create a server with a single prompt. s := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "v0.0.1"}, nil) + // The name is required: it uniquely identifies the prompt. s.AddPrompt(&mcp.Prompt{Name: "greet"}, promptHandler) // Create a client. From ddfe50e27b174758cde564291da96303fc8668c9 Mon Sep 17 00:00:00 2001 From: Jonathan Amsterdam Date: Thu, 18 Sep 2025 12:24:51 -0400 Subject: [PATCH 3/3] args --- docs/server.md | 17 ++++++++++++++--- internal/docs/server.src.md | 4 +++- mcp/server_example_test.go | 13 +++++++++++-- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/docs/server.md b/docs/server.md index 8bd0f5ba..e6af5d9c 100644 --- a/docs/server.md +++ b/docs/server.md @@ -13,7 +13,9 @@ **Server-side**: MCP servers can provide LLM prompt templates (called simply _prompts_) to clients. -Associated with each prompt is a handler that expands the template given a set of key-value pairs. +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. @@ -47,8 +49,17 @@ func Example_prompts() { // Create a server with a single prompt. s := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "v0.0.1"}, nil) - // The name is required: it uniquely identifies the prompt. - s.AddPrompt(&mcp.Prompt{Name: "greet"}, promptHandler) + 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) diff --git a/internal/docs/server.src.md b/internal/docs/server.src.md index 4aa1c53f..07ed6cb9 100644 --- a/internal/docs/server.src.md +++ b/internal/docs/server.src.md @@ -6,7 +6,9 @@ **Server-side**: MCP servers can provide LLM prompt templates (called simply _prompts_) to clients. -Associated with each prompt is a handler that expands the template given a set of key-value pairs. +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. diff --git a/mcp/server_example_test.go b/mcp/server_example_test.go index 93635072..d6b4d7e4 100644 --- a/mcp/server_example_test.go +++ b/mcp/server_example_test.go @@ -31,8 +31,17 @@ func Example_prompts() { // Create a server with a single prompt. s := mcp.NewServer(&mcp.Implementation{Name: "server", Version: "v0.0.1"}, nil) - // The name is required: it uniquely identifies the prompt. - s.AddPrompt(&mcp.Prompt{Name: "greet"}, promptHandler) + 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)