-
Notifications
You must be signed in to change notification settings - Fork 315
Description
In #135 we addressed a simple problem--that there was no way to force advertising unused capabilities--by adding the simplest possible API: ServerOptions.Has{Tools,Prompts,Resources} allowed server authors to advertise the relevant capability even if there were no features (yet) registered on the server.
However, as I work on the 2025-11-25 version of the spec, particularly #629, I am finding problems with this design.
Problem statement
- What if the user wants to customize those capabilities, for example by disabling the
listChangedfeature? - Lack of discoverability, and confusing semantics: if I set
HasTools: false, that doesn't actually mean that my server has no tools, it just means that it has no tools yet. - Explosion of API: as we require further customization of capabilities, we have to add more and more arbitrary fields to the
{Client,Server}Optionsstructs.
This was already a problem, but is becoming more noticeable with 2025-11-25 version of the spec, which added more capability configuration (URL elicitation and Tool sampling, to name two). For example, in #623 I added ClientOptions.ElicitationModes, but didn't like it. Fortunately, we've not yet had a release and so can change that API.
Proposal
I propose the following solution, which I believe is similar to what the typescript SDK does (CC @felixweinberger for any advice from typescript).
- Add
{Client.Server}Options.Capabilities, an optional field that may be set by the API user to configure default capabilities. This overrides the current default capabilities, which are not currently empty (we always advertise"roots"from the client, and"logging"from the server). - Whenever the user adds a new capability, for example by adding a tool or prompt, or by setting an
ElicitationHandler, augment the advertised capabilities to reflect that new capability. So if the user setsServerOptions.Capabilitiestonew(ServerCapabilities), but then adds a tool, we WILL advertise tool capabilities. - Check
listChangedcapabilities before sending notifications, so that server behavior is consistent with its advertised capabilities. - Deprecate
Has{Tools,Prompts,Resources}, and removeClientOptions.ElicitationModes(which has not yet been released).
That's it.
Notes
- This means there's no way to e.g. add a tool but not advertise the tool capability (but why would you want to do that?).
- I wish we didn't advertise the
"roots"capability by default (see also How to check client capabilities and handle unsupported capability errors? #607), but this at least provides a way to disable the capability: settingClientOptions.Capabilitiestonew(ClientCapabilities)disables advertisement of"roots"if no root is added. - We'll need to record the user-provided default capabilities explicitly, rather than just copying and mutating: if the users passes new(ToolCapabilities), then adds and removes a tool, we should not revert to not advertising the tool capability.
- Unlike typescript, let's not provide any sort of
RegisterCapabilityAPI. I think the configuration option is enough for now.
I believe this solves all the limitations listed above.
CC @jba @markus-kusano @SamMorrowDrums
Now that I've seen it, I think this proposal is obvious (but please let me know if you disagree!), so I'm going to send a PR now, which we can perhaps land while the proposal is still pending.