@@ -52,6 +52,18 @@ type ServerTool struct {
5252 Handler ToolHandlerFunc
5353}
5454
55+ // ServerPrompt combines a Prompt with its handler function.
56+ type ServerPrompt struct {
57+ Prompt mcp.Prompt
58+ Handler PromptHandlerFunc
59+ }
60+
61+ // ServerResource combines a Resource with its handler function.
62+ type ServerResource struct {
63+ Resource mcp.Resource
64+ Handler ResourceHandlerFunc
65+ }
66+
5567// serverKey is the context key for storing the server instance
5668type serverKey struct {}
5769
@@ -305,28 +317,16 @@ func NewMCPServer(
305317 return s
306318}
307319
308- // AddResource registers a new resource and its handler
309- func (s * MCPServer ) AddResource (
310- resource mcp.Resource ,
311- handler ResourceHandlerFunc ,
312- ) {
313- s .capabilitiesMu .RLock ()
314- if s .capabilities .resources == nil {
315- s .capabilitiesMu .RUnlock ()
316-
317- s .capabilitiesMu .Lock ()
318- if s .capabilities .resources == nil {
319- s .capabilities .resources = & resourceCapabilities {}
320- }
321- s .capabilitiesMu .Unlock ()
322- } else {
323- s .capabilitiesMu .RUnlock ()
324- }
320+ // AddResources registers multiple resources at once
321+ func (s * MCPServer ) AddResources (resources ... ServerResource ) {
322+ s .implicitlyRegisterResourceCapabilities ()
325323
326324 s .resourcesMu .Lock ()
327- s .resources [resource .URI ] = resourceEntry {
328- resource : resource ,
329- handler : handler ,
325+ for _ , entry := range resources {
326+ s .resources [entry .Resource .URI ] = resourceEntry {
327+ resource : entry .Resource ,
328+ handler : entry .Handler ,
329+ }
330330 }
331331 s .resourcesMu .Unlock ()
332332
@@ -337,6 +337,14 @@ func (s *MCPServer) AddResource(
337337 }
338338}
339339
340+ // AddResource registers a new resource and its handler
341+ func (s * MCPServer ) AddResource (
342+ resource mcp.Resource ,
343+ handler ResourceHandlerFunc ,
344+ ) {
345+ s .AddResources (ServerResource {Resource : resource , Handler : handler })
346+ }
347+
340348// RemoveResource removes a resource from the server
341349func (s * MCPServer ) RemoveResource (uri string ) {
342350 s .resourcesMu .Lock ()
@@ -357,18 +365,7 @@ func (s *MCPServer) AddResourceTemplate(
357365 template mcp.ResourceTemplate ,
358366 handler ResourceTemplateHandlerFunc ,
359367) {
360- s .capabilitiesMu .RLock ()
361- if s .capabilities .resources == nil {
362- s .capabilitiesMu .RUnlock ()
363-
364- s .capabilitiesMu .Lock ()
365- if s .capabilities .resources == nil {
366- s .capabilities .resources = & resourceCapabilities {}
367- }
368- s .capabilitiesMu .Unlock ()
369- } else {
370- s .capabilitiesMu .RUnlock ()
371- }
368+ s .implicitlyRegisterResourceCapabilities ()
372369
373370 s .resourcesMu .Lock ()
374371 s .resourceTemplates [template .URITemplate .Raw ()] = resourceTemplateEntry {
@@ -384,24 +381,15 @@ func (s *MCPServer) AddResourceTemplate(
384381 }
385382}
386383
387- // AddPrompt registers a new prompt handler with the given name
388- func (s * MCPServer ) AddPrompt (prompt mcp.Prompt , handler PromptHandlerFunc ) {
389- s .capabilitiesMu .RLock ()
390- if s .capabilities .prompts == nil {
391- s .capabilitiesMu .RUnlock ()
392-
393- s .capabilitiesMu .Lock ()
394- if s .capabilities .prompts == nil {
395- s .capabilities .prompts = & promptCapabilities {}
396- }
397- s .capabilitiesMu .Unlock ()
398- } else {
399- s .capabilitiesMu .RUnlock ()
400- }
384+ // AddPrompts registers multiple prompts at once
385+ func (s * MCPServer ) AddPrompts (prompts ... ServerPrompt ) {
386+ s .implicitlyRegisterPromptCapabilities ()
401387
402388 s .promptsMu .Lock ()
403- s .prompts [prompt .Name ] = prompt
404- s .promptHandlers [prompt .Name ] = handler
389+ for _ , entry := range prompts {
390+ s .prompts [entry .Prompt .Name ] = entry .Prompt
391+ s .promptHandlers [entry .Prompt .Name ] = entry .Handler
392+ }
405393 s .promptsMu .Unlock ()
406394
407395 // When the list of available prompts changes, servers that declared the listChanged capability SHOULD send a notification.
@@ -411,6 +399,11 @@ func (s *MCPServer) AddPrompt(prompt mcp.Prompt, handler PromptHandlerFunc) {
411399 }
412400}
413401
402+ // AddPrompt registers a new prompt handler with the given name
403+ func (s * MCPServer ) AddPrompt (prompt mcp.Prompt , handler PromptHandlerFunc ) {
404+ s .AddPrompts (ServerPrompt {Prompt : prompt , Handler : handler })
405+ }
406+
414407// DeletePrompts removes prompts from the server
415408func (s * MCPServer ) DeletePrompts (names ... string ) {
416409 s .promptsMu .Lock ()
@@ -440,20 +433,39 @@ func (s *MCPServer) AddTool(tool mcp.Tool, handler ToolHandlerFunc) {
440433// listChanged: true, but don't change the value if we've already explicitly
441434// registered tools.listChanged false.
442435func (s * MCPServer ) implicitlyRegisterToolCapabilities () {
436+ s .implicitlyRegisterCapabilities (
437+ func () bool { return s .capabilities .tools != nil },
438+ func () { s .capabilities .tools = & toolCapabilities {listChanged : true } },
439+ )
440+ }
441+
442+ func (s * MCPServer ) implicitlyRegisterResourceCapabilities () {
443+ s .implicitlyRegisterCapabilities (
444+ func () bool { return s .capabilities .resources != nil },
445+ func () { s .capabilities .resources = & resourceCapabilities {} },
446+ )
447+ }
448+
449+ func (s * MCPServer ) implicitlyRegisterPromptCapabilities () {
450+ s .implicitlyRegisterCapabilities (
451+ func () bool { return s .capabilities .prompts != nil },
452+ func () { s .capabilities .prompts = & promptCapabilities {} },
453+ )
454+ }
455+
456+ func (s * MCPServer ) implicitlyRegisterCapabilities (check func () bool , register func ()) {
443457 s .capabilitiesMu .RLock ()
444- if s . capabilities . tools == nil {
458+ if check () {
445459 s .capabilitiesMu .RUnlock ()
460+ return
461+ }
462+ s .capabilitiesMu .RUnlock ()
446463
447- s .capabilitiesMu .Lock ()
448- if s .capabilities .tools == nil {
449- s .capabilities .tools = & toolCapabilities {
450- listChanged : true ,
451- }
452- }
453- s .capabilitiesMu .Unlock ()
454- } else {
455- s .capabilitiesMu .RUnlock ()
464+ s .capabilitiesMu .Lock ()
465+ if ! check () {
466+ register ()
456467 }
468+ s .capabilitiesMu .Unlock ()
457469}
458470
459471// AddTools registers multiple tools at once
0 commit comments