-
Notifications
You must be signed in to change notification settings - Fork 266
mcp: add ClientCapabilities.Roots.Supported #608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| <!-- Autogenerated by weave; DO NOT EDIT --> | ||
| # "Warts" - API oversights to reconsider for v2 | ||
|
|
||
| This file collects a list of API oversights or rough edges that we've uncovered | ||
| post v1.0, both to address them a potential future v2, and to document their | ||
| current workarounds. | ||
|
|
||
| - `EventStore.Open` is unnecessary. This was an artifact of an earlier version | ||
| of the SDK where event persistence and delivery were combined. | ||
|
|
||
| **Workaround**: `Open` may be implemented as a no-op. | ||
|
|
||
| - `ClientCapabilities.Roots` should have been a distinguished struct pointer. | ||
| This was simply an oversight. | ||
|
|
||
| **Workaround**: the `ClientCapabilities.Roots.Supported` field is managed by | ||
| custom marshaling of `ClientCapabilities`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # "Warts" - API oversights to reconsider for v2 | ||
|
|
||
| This file collects a list of API oversights or rough edges that we've uncovered | ||
| post v1.0, both to address them a potential future v2, and to document their | ||
| current workarounds. | ||
|
|
||
| - `EventStore.Open` is unnecessary. This was an artifact of an earlier version | ||
| of the SDK where event persistence and delivery were combined. | ||
|
|
||
| **Workaround**: `Open` may be implemented as a no-op. | ||
|
|
||
| - `ClientCapabilities.Roots` should have been a distinguished struct pointer. | ||
| This was simply an oversight. | ||
|
|
||
| **Workaround**: the `ClientCapabilities.Roots.Supported` field is managed by | ||
| custom marshaling of `ClientCapabilities`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -183,17 +183,71 @@ func (x *CancelledParams) SetProgressToken(t any) { setProgressToken(x, t) } | |
| type ClientCapabilities struct { | ||
| // Experimental, non-standard capabilities that the client supports. | ||
| Experimental map[string]any `json:"experimental,omitempty"` | ||
| // Present if the client supports listing roots. | ||
|
|
||
| // Roots reports roots capabilities. | ||
| // | ||
| // Due to an API oversight (#607), roots is a non-pointer. Check the | ||
| // Supported field to see if the roots capability is present | ||
| Roots struct { | ||
| // Suppported reports whether roots/list is supported. It works around an | ||
| // API oversight: roots capabilities should have been a distinguished type, | ||
| // similar to other capabilities. | ||
| Supported bool `json:"-"` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is added, then I prefer that the other capabilities structs have a similar Right now, my server must assume the client supports Sampling if |
||
|
|
||
| // Whether the client supports notifications for changes to the roots list. | ||
| ListChanged bool `json:"listChanged,omitempty"` | ||
| } `json:"roots,omitempty"` | ||
| // Present if the client supports sampling from an LLM. | ||
| } `json:"roots"` | ||
|
|
||
| // Sampling is present if the client supports sampling from an LLM. | ||
| Sampling *SamplingCapabilities `json:"sampling,omitempty"` | ||
| // Present if the client supports elicitation from the server. | ||
|
|
||
| // Elicitation is present if the client supports elicitation from the server. | ||
| Elicitation *ElicitationCapabilities `json:"elicitation,omitempty"` | ||
| } | ||
|
|
||
| // clientCapabilitiesV2 is a version of ClientCapabilities fixes | ||
| type clientCapabilitiesV2 struct { | ||
| Experimental map[string]any `json:"experimental,omitempty"` | ||
| Roots *rootsCapabilities `json:"roots,omitempty"` | ||
| Sampling *SamplingCapabilities `json:"sampling,omitempty"` | ||
| Elicitation *ElicitationCapabilities `json:"elicitation,omitempty"` | ||
| } | ||
|
|
||
| // See #607: rootsCapabilities is for internal use, fixing an API oversight. | ||
| type rootsCapabilities struct { | ||
| Supported bool `json:"-"` | ||
| ListChanged bool `json:"listChanged,omitempty"` | ||
| } | ||
|
|
||
| func (c ClientCapabilities) MarshalJSON() ([]byte, error) { | ||
| c2 := &clientCapabilitiesV2{ | ||
| Experimental: c.Experimental, | ||
| Sampling: c.Sampling, | ||
| Elicitation: c.Elicitation, | ||
| } | ||
| if c.Roots.Supported { | ||
| c2.Roots = &rootsCapabilities{ | ||
| ListChanged: c.Roots.ListChanged, | ||
| } | ||
| } | ||
| return json.Marshal(c2) | ||
| } | ||
|
|
||
| func (c *ClientCapabilities) UnmarshalJSON(data []byte) error { | ||
| var c2 clientCapabilitiesV2 | ||
| if err := json.Unmarshal(data, &c2); err != nil { | ||
| return err | ||
| } | ||
| c.Experimental = c2.Experimental | ||
| c.Elicitation = c2.Elicitation | ||
| c.Sampling = c2.Sampling | ||
| if c2.Roots != nil { | ||
| c.Roots = *c2.Roots | ||
| c.Roots.Supported = true | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| type CompleteParamsArgument struct { | ||
| // The name of the argument | ||
| Name string `json:"name"` | ||
|
|
@@ -1035,8 +1089,6 @@ type ResourceUpdatedNotificationParams struct { | |
|
|
||
| func (*ResourceUpdatedNotificationParams) isParams() {} | ||
|
|
||
| // TODO(jba): add CompleteRequest and related types. | ||
|
|
||
| // A request from the server to elicit additional information from the user via the client. | ||
| type ElicitParams struct { | ||
| // This property is reserved by the protocol to allow clients and servers to | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inclusion of this file is a great idea- but is
wartspart of an internal coding style? I'd prefer it calledknown_issues.mdbut that's just my 2¢.WRT the content of the file, I'd suggest creating a PR with the inclusion of the file, and then update the content to add each entry in a different PR, instead of adding the file and the 2 entries here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback! Yes, I had intended to change the name of this file -- "warts" is a term I've hear before, but isn't nice.
"known issues" is good, but makes me think of "bugs we haven't yet fixed" rather than "API decisions we can't revert". In #609 I went with "rough edges", but let me know what you think.