mcp/server: add initial capability server option (#182)

This CL adds an option for servers to advertise support for features
that have not been added yet. This includes Prompts, Tools, and
Resources as these could be dynamically added after initialization.

Fixes: #135.
This commit is contained in:
Sam Thanawalla 2025-07-29 05:20:08 -04:00 • committed by GitHub
commit 2b6f7b5185
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 29 additions and 3 deletions

View file

@ -69,6 +69,15 @@ type ServerOptions struct {
SubscribeHandler func(context.Context, *SubscribeParams) error
// Function called when a client session unsubscribes from a resource.
UnsubscribeHandler func(context.Context, *UnsubscribeParams) error
// If true, advertises the prompts capability during initialization,
// even if no prompts have been registered.
HasPrompts bool
// If true, advertises the resources capability during initialization,
// even if no resources have been registered.
HasResources bool
// If true, advertises the tools capability during initialization,
// even if no tools have been registered.
HasTools bool
}
// NewServer creates a new MCP server. The resulting server has no features:
@ -229,16 +238,17 @@ func (s *Server) capabilities() *serverCapabilities {
defer s.mu.Unlock()
caps := &serverCapabilities{
// TODO(samthanawalla): check for completionHandler before advertising capability.
Completions: &completionCapabilities{},
Logging: &loggingCapabilities{},
}
if s.tools.len() > 0 {
if s.opts.HasTools || s.tools.len() > 0 {
caps.Tools = &toolCapabilities{ListChanged: true}
}
if s.prompts.len() > 0 {
if s.opts.HasPrompts || s.prompts.len() > 0 {
caps.Prompts = &promptCapabilities{ListChanged: true}
}
if s.resources.len() > 0 || s.resourceTemplates.len() > 0 {
if s.opts.HasResources || s.resources.len() > 0 || s.resourceTemplates.len() > 0 {
caps.Resources = &resourceCapabilities{ListChanged: true}
if s.opts.SubscribeHandler != nil {
caps.Resources.Subscribe = true

View file

@ -333,6 +333,22 @@ func TestServerCapabilities(t *testing.T) {
Tools: &toolCapabilities{ListChanged: true},
},
},
{
name: "With initial capabilities",
configureServer: func(s *Server) {},
serverOpts: ServerOptions{
HasPrompts: true,
HasResources: true,
HasTools: true,
},
wantCapabilities: &serverCapabilities{
Completions: &completionCapabilities{},
Logging: &loggingCapabilities{},
Prompts: &promptCapabilities{ListChanged: true},
Resources: &resourceCapabilities{ListChanged: true},
Tools: &toolCapabilities{ListChanged: true},
},
},
}
for _, tc := range testCases {