Skip to content

Commit f0c79e7

Browse files
committed
address review comments
1 parent cb0fcb7 commit f0c79e7

File tree

8 files changed

+207
-84
lines changed

8 files changed

+207
-84
lines changed

docs/client.md

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
1. [Sampling](#sampling)
66
1. [Elicitation](#elicitation)
77
1. [Capabilities](#capabilities)
8+
1. [Capability inference](#capability-inference)
9+
1. [Explicit capabilities](#explicit-capabilities)
810

911
## Roots
1012

@@ -131,7 +133,9 @@ allows servers to request user inputs. It is implemented in the SDK as follows:
131133
**Client-side**: To add the `elicitation` capability to a client, set
132134
[`ClientOptions.ElicitationHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientOptions.ElicitationHandler).
133135
The elicitation handler must return a result that matches the requested schema;
134-
otherwise, elicitation returns an error.
136+
otherwise, elicitation returns an error. If your handler supports [URL mode
137+
elicitation](https://modelcontextprotocol.io/specification/2025-11-25/client/elicitation#url-mode-elicitation-requests),
138+
you must declare that capability explicitly (see [Capabilities](#capabilities))
135139

136140
**Server-side**: To use elicitation from the server, call
137141
[`ServerSession.Elicit`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerSession.Elicit).
@@ -176,13 +180,36 @@ func Example_elicitation() {
176180
## Capabilities
177181

178182
Client capabilities are advertised to servers during the initialization
179-
handshake. By default, the SDK advertises the `roots` capability with
180-
`listChanged: true`. Additional capabilities are automatically added when
181-
handlers are set (e.g., setting `CreateMessageHandler` adds the `sampling`
182-
capability).
183+
handshake. [By default](rough_edges.md), the SDK advertises the `logging`
184+
capability. Additional capabilities are automatically added when server
185+
features are added (e.g. via `AddTool`), or when handlers are set in the
186+
`ServerOptions` struct (e.g., setting `CompletionHandler` adds the
187+
`completions` capability), or may be configured explicitly.
183188

184-
To customize capabilities, set
189+
### Capability inference
190+
191+
When handlers are set on `ClientOptions` (e.g., `CreateMessageHandler` or
192+
`ElicitationHandler`), the corresponding capability is automatically added if
193+
not already present, with a default configuration.
194+
195+
For elicitation, if the handler is set but no `Capabilities.Elicitation` is
196+
specified, the client defaults to form elicitation. To enable URL elicitation
197+
or both modes, [configure `Capabilities.Elicitation`
198+
explicitly](#explicit-capabilities).
199+
200+
See the [`ClientCapabilities`
201+
documentation](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientCapabilities)
202+
for further details on inference.
203+
204+
### Explicit capabilities
205+
206+
To explicitly declare capabilities, or to override the [default inferred
207+
capability](#capability-inference), set
185208
[`ClientOptions.Capabilities`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientOptions.Capabilities).
209+
This sets the initial client capabilities, before any capabilities are added
210+
based on configured handlers. If a capability is already present in
211+
`Capabilities`, adding a handler will not change its configuration.
212+
186213
This allows you to:
187214

188215
- **Disable default capabilities**: Pass an empty `&ClientCapabilities{}` to
@@ -194,7 +221,7 @@ This allows you to:
194221
the client supports.
195222

196223
```go
197-
// Configure elicitation modes and disable roots
224+
// Configure elicitation modes and disable roots.
198225
client := mcp.NewClient(impl, &mcp.ClientOptions{
199226
Capabilities: &mcp.ClientCapabilities{
200227
Elicitation: &mcp.ElicitationCapabilities{
@@ -206,11 +233,3 @@ client := mcp.NewClient(impl, &mcp.ClientOptions{
206233
})
207234
```
208235

209-
When handlers are set on `ClientOptions` (e.g., `CreateMessageHandler` or
210-
`ElicitationHandler`), the corresponding capability is automatically added if
211-
not already present. However, user-specified capability settings are preserved
212-
and not overridden.
213-
214-
For elicitation, if the handler is set but no `Capabilities.Elicitation` is
215-
specified, the client defaults to form elicitation. To enable URL elicitation
216-
or both modes, configure `Capabilities.Elicitation` explicitly.

docs/server.md

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
1. [Utilities](#utilities)
88
1. [Completion](#completion)
99
1. [Logging](#logging)
10-
1. [Capabilities](#capabilities)
10+
1. [Capabilities](#capabilities)
11+
1. [Capability inference](#capability-inference)
12+
1. [Explicit capabilities](#explicit-capabilities)
1113
1. [Pagination](#pagination)
1214

1315
## Prompts
@@ -536,15 +538,30 @@ func Example_logging() {
536538
}
537539
```
538540

539-
### Capabilities
541+
## Capabilities
540542

541543
Server capabilities are advertised to clients during the initialization
542544
handshake. By default, the SDK advertises only the `logging` capability.
543545
Additional capabilities are automatically added when features are registered
544546
(e.g., adding a tool adds the `tools` capability).
545547

546-
To customize capabilities, set
548+
### Capability inference
549+
550+
When features such as tools, prompts, or resources are added to the server
551+
(e.g., via `Server.AddTool`), their capability is automatically inferred, with
552+
default value `{listChanged:true}`. Similarly, if the
553+
`ServerOptions.SubscribeHandler` or `ServerOptions.CompletionHandler` are set,
554+
the corresponding capability is added.
555+
556+
### Explicit capabilities
557+
558+
To explicitly declare capabilities, or to override the [default inferred
559+
capability](#capability-inference), set
547560
[`ServerOptions.Capabilities`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.Capabilities).
561+
This sets the initial server capabilities, before any capabilities are added
562+
based on configured handlers. If a capability is already present in
563+
`Capabilities`, adding a feature or handler will not change its configuration.
564+
548565
This allows you to:
549566

550567
- **Disable default capabilities**: Pass an empty `&ServerCapabilities{}` to
@@ -565,11 +582,6 @@ server := mcp.NewServer(impl, &mcp.ServerOptions{
565582
})
566583
```
567584

568-
When features are added dynamically (e.g., via `Server.AddTool`), the
569-
corresponding capability is automatically added if not already present.
570-
However, user-specified capability settings (like `ListChanged: false`) are
571-
preserved and not overridden.
572-
573585
**Deprecated**: The `HasPrompts`, `HasResources`, and `HasTools` fields on
574586
`ServerOptions` are deprecated. Use `Capabilities` instead.
575587

internal/docs/client.src.md

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ allows servers to request user inputs. It is implemented in the SDK as follows:
4747
**Client-side**: To add the `elicitation` capability to a client, set
4848
[`ClientOptions.ElicitationHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientOptions.ElicitationHandler).
4949
The elicitation handler must return a result that matches the requested schema;
50-
otherwise, elicitation returns an error.
50+
otherwise, elicitation returns an error. If your handler supports [URL mode
51+
elicitation](https://modelcontextprotocol.io/specification/2025-11-25/client/elicitation#url-mode-elicitation-requests),
52+
you must declare that capability explicitly (see [Capabilities](#capabilities))
5153

5254
**Server-side**: To use elicitation from the server, call
5355
[`ServerSession.Elicit`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerSession.Elicit).
@@ -57,13 +59,36 @@ otherwise, elicitation returns an error.
5759
## Capabilities
5860

5961
Client capabilities are advertised to servers during the initialization
60-
handshake. By default, the SDK advertises the `roots` capability with
61-
`listChanged: true`. Additional capabilities are automatically added when
62-
handlers are set (e.g., setting `CreateMessageHandler` adds the `sampling`
63-
capability).
62+
handshake. [By default](rough_edges.md), the SDK advertises the `logging`
63+
capability. Additional capabilities are automatically added when server
64+
features are added (e.g. via `AddTool`), or when handlers are set in the
65+
`ServerOptions` struct (e.g., setting `CompletionHandler` adds the
66+
`completions` capability), or may be configured explicitly.
6467

65-
To customize capabilities, set
68+
### Capability inference
69+
70+
When handlers are set on `ClientOptions` (e.g., `CreateMessageHandler` or
71+
`ElicitationHandler`), the corresponding capability is automatically added if
72+
not already present, with a default configuration.
73+
74+
For elicitation, if the handler is set but no `Capabilities.Elicitation` is
75+
specified, the client defaults to form elicitation. To enable URL elicitation
76+
or both modes, [configure `Capabilities.Elicitation`
77+
explicitly](#explicit-capabilities).
78+
79+
See the [`ClientCapabilities`
80+
documentation](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientCapabilities)
81+
for further details on inference.
82+
83+
### Explicit capabilities
84+
85+
To explicitly declare capabilities, or to override the [default inferred
86+
capability](#capability-inference), set
6687
[`ClientOptions.Capabilities`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ClientOptions.Capabilities).
88+
This sets the initial client capabilities, before any capabilities are added
89+
based on configured handlers. If a capability is already present in
90+
`Capabilities`, adding a handler will not change its configuration.
91+
6792
This allows you to:
6893

6994
- **Disable default capabilities**: Pass an empty `&ClientCapabilities{}` to
@@ -75,7 +100,7 @@ This allows you to:
75100
the client supports.
76101

77102
```go
78-
// Configure elicitation modes and disable roots
103+
// Configure elicitation modes and disable roots.
79104
client := mcp.NewClient(impl, &mcp.ClientOptions{
80105
Capabilities: &mcp.ClientCapabilities{
81106
Elicitation: &mcp.ElicitationCapabilities{
@@ -87,11 +112,3 @@ client := mcp.NewClient(impl, &mcp.ClientOptions{
87112
})
88113
```
89114

90-
When handlers are set on `ClientOptions` (e.g., `CreateMessageHandler` or
91-
`ElicitationHandler`), the corresponding capability is automatically added if
92-
not already present. However, user-specified capability settings are preserved
93-
and not overridden.
94-
95-
For elicitation, if the handler is set but no `Capabilities.Elicitation` is
96-
specified, the client defaults to form elicitation. To enable URL elicitation
97-
or both modes, configure `Capabilities.Elicitation` explicitly.

internal/docs/server.src.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -243,15 +243,30 @@ Call [`ClientSession.SetLevel`](https://pkg.go.dev/github.com/modelcontextprotoc
243243

244244
%include ../../mcp/server_example_test.go logging -
245245

246-
### Capabilities
246+
## Capabilities
247247

248248
Server capabilities are advertised to clients during the initialization
249249
handshake. By default, the SDK advertises only the `logging` capability.
250250
Additional capabilities are automatically added when features are registered
251251
(e.g., adding a tool adds the `tools` capability).
252252

253-
To customize capabilities, set
253+
### Capability inference
254+
255+
When features such as tools, prompts, or resources are added to the server
256+
(e.g., via `Server.AddTool`), their capability is automatically inferred, with
257+
default value `{listChanged:true}`. Similarly, if the
258+
`ServerOptions.SubscribeHandler` or `ServerOptions.CompletionHandler` are set,
259+
the corresponding capability is added.
260+
261+
### Explicit capabilities
262+
263+
To explicitly declare capabilities, or to override the [default inferred
264+
capability](#capability-inference), set
254265
[`ServerOptions.Capabilities`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.Capabilities).
266+
This sets the initial server capabilities, before any capabilities are added
267+
based on configured handlers. If a capability is already present in
268+
`Capabilities`, adding a feature or handler will not change its configuration.
269+
255270
This allows you to:
256271

257272
- **Disable default capabilities**: Pass an empty `&ServerCapabilities{}` to
@@ -272,11 +287,6 @@ server := mcp.NewServer(impl, &mcp.ServerOptions{
272287
})
273288
```
274289

275-
When features are added dynamically (e.g., via `Server.AddTool`), the
276-
corresponding capability is automatically added if not already present.
277-
However, user-specified capability settings (like `ListChanged: false`) are
278-
preserved and not overridden.
279-
280290
**Deprecated**: The `HasPrompts`, `HasResources`, and `HasTools` fields on
281291
`ServerOptions` are deprecated. Use `Capabilities` instead.
282292

mcp/client.go

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,29 +63,45 @@ func NewClient(impl *Implementation, opts *ClientOptions) *Client {
6363
type ClientOptions struct {
6464
// CreateMessageHandler handles incoming requests for sampling/createMessage.
6565
//
66-
// Setting CreateMessageHandler to a non-nil value causes the client to
67-
// advertise the sampling capability.
66+
// Setting CreateMessageHandler to a non-nil value automatically causes the
67+
// client to advertise the sampling capability, with default value
68+
// &SamplingCapabilities{}. If [ClientOptions.Capabilities] is set and has a
69+
// non nil value for [ClientCapabilities.Sampling], that value overrides the
70+
// inferred capability.
6871
CreateMessageHandler func(context.Context, *CreateMessageRequest) (*CreateMessageResult, error)
6972
// ElicitationHandler handles incoming requests for elicitation/create.
7073
//
71-
// Setting ElicitationHandler to a non-nil value causes the client to
72-
// advertise the elicitation capability.
74+
// Setting ElicitationHandler to a non-nil value automatically causes the
75+
// client to advertise the elicitation capability, with default value
76+
// &ElicitationCapabilities{}. If [ClientOptions.Capabilities] is set and has
77+
// a non nil value for [ClientCapabilities.ELicitattion], that value
78+
// overrides the inferred capability.
7379
ElicitationHandler func(context.Context, *ElicitRequest) (*ElicitResult, error)
74-
75-
// Capabilities configures the client's default capabilities.
76-
// If non-nil, this overrides the default capabilities (which includes
77-
// only roots with listChanged). Features like sampling and elicitation
78-
// are automatically added to the capabilities when their handlers are set.
80+
// Capabilities optionally configures the client's initial capabilities,
81+
// before any capabilities are inferred from other configuration.
7982
//
80-
// Set to an empty &ClientCapabilities{} to disable all default capabilities,
81-
// including roots.
82-
// For example, to enable sampling but disable roots:
83+
// If Capabilities is nil, the initial client capabilities defaults to
84+
// {"roots":{"listChanged":true}}, for historical reasons. Setting
85+
// Capabilities to a non-nil value overrides this default. As a special case,
86+
// to work around #607, Capabilities.Roots is ignored: set
87+
// Capabilities.RootsV2 to configure the roots capability. This allows the
88+
// "roots" capability to be disabled entirely.
8389
//
84-
// Capabilities: &ClientCapabilities{
85-
// Sampling: &SamplingCapabilities{},
86-
// }
90+
// For example:
91+
// - To disable the "roots" capability, use &ClientCapabilities{}
92+
// - To configure "roots", but disable "listChanged" notifications, use
93+
// &ClientCapabilities{RootsV2:&RootCapabilities{}}.
8794
//
88-
// To configure elicitation modes:
95+
// # Interaction with capability inference
96+
//
97+
// Sampling and elicitation capabilities are automatically added when their
98+
// corresponding handlers are set, with the default value described at
99+
// [ClientOptions.CreateMessageHandler] and
100+
// [ClientOptions.ElicitationHandler]. If the Sampling or Elicitation fields
101+
// are set in the Capabilities field, their values overrides the default
102+
// inferred value.
103+
//
104+
// For example, to to configure elicitation modes:
89105
//
90106
// Capabilities: &ClientCapabilities{
91107
// Elicitation: &ElicitationCapabilities{
@@ -94,7 +110,6 @@ type ClientOptions struct {
94110
// },
95111
// }
96112
Capabilities *ClientCapabilities
97-
98113
// ElicitationCompleteHandler handles incoming notifications for notifications/elicitation/complete.
99114
ElicitationCompleteHandler func(context.Context, *ElicitationCompleteNotificationRequest)
100115
// Handlers for notifications from the server.
@@ -150,7 +165,7 @@ type ClientSessionOptions struct {
150165
protocolVersion string
151166
}
152167

153-
func (c *Client) capabilities() *ClientCapabilities {
168+
func (c *Client) capabilities(protocolVersion string) *ClientCapabilities {
154169
// Start with user-provided capabilities as defaults, or use SDK defaults.
155170
var caps *ClientCapabilities
156171
if c.opts.Capabilities != nil {
@@ -181,9 +196,11 @@ func (c *Client) capabilities() *ClientCapabilities {
181196
// Augment with elicitation capability if handler is set.
182197
if c.opts.ElicitationHandler != nil {
183198
if caps.Elicitation == nil {
184-
// Default to form elicitation for backward compatibility.
185-
caps.Elicitation = &ElicitationCapabilities{
186-
Form: &FormElicitationCapabilities{},
199+
caps.Elicitation = &ElicitationCapabilities{}
200+
// Form elicitation was added in 2025-11-25; for older versions,
201+
// {} is treated the same as {"form":{}}.
202+
if protocolVersion >= protocolVersion20251125 {
203+
caps.Elicitation.Form = &FormElicitationCapabilities{}
187204
}
188205
}
189206
}
@@ -210,7 +227,7 @@ func (c *Client) Connect(ctx context.Context, t Transport, opts *ClientSessionOp
210227
params := &InitializeParams{
211228
ProtocolVersion: protocolVersion,
212229
ClientInfo: c.impl,
213-
Capabilities: c.capabilities(),
230+
Capabilities: c.capabilities(protocolVersion),
214231
}
215232
req := &InitializeRequest{Session: cs, Params: params}
216233
res, err := handleSend[*InitializeResult](ctx, methodInitialize, req)

0 commit comments

Comments
 (0)