@@ -107,6 +107,7 @@ type Server struct {
107
107
tools * datastructures.SyncMap [string , * tool ]
108
108
prompts * datastructures.SyncMap [string , * prompt ]
109
109
resources * datastructures.SyncMap [string , * resource ]
110
+ resourceTemplates * datastructures.SyncMap [string , * resourceTemplate ]
110
111
serverInstructions * string
111
112
serverName string
112
113
serverVersion string
@@ -134,6 +135,13 @@ type resource struct {
134
135
Handler func (context.Context ) * resourceResponseSent
135
136
}
136
137
138
+ type resourceTemplate struct {
139
+ Name string
140
+ Description string
141
+ UriTemplate string
142
+ MimeType string
143
+ }
144
+
137
145
type ServerOptions func (* Server )
138
146
139
147
func WithProtocol (protocol * protocol.Protocol ) ServerOptions {
@@ -163,11 +171,12 @@ func WithVersion(version string) ServerOptions {
163
171
164
172
func NewServer (transport transport.Transport , options ... ServerOptions ) * Server {
165
173
server := & Server {
166
- protocol : protocol .NewProtocol (nil ),
167
- transport : transport ,
168
- tools : new (datastructures.SyncMap [string , * tool ]),
169
- prompts : new (datastructures.SyncMap [string , * prompt ]),
170
- resources : new (datastructures.SyncMap [string , * resource ]),
174
+ protocol : protocol .NewProtocol (nil ),
175
+ transport : transport ,
176
+ tools : new (datastructures.SyncMap [string , * tool ]),
177
+ prompts : new (datastructures.SyncMap [string , * prompt ]),
178
+ resources : new (datastructures.SyncMap [string , * resource ]),
179
+ resourceTemplates : new (datastructures.SyncMap [string , * resourceTemplate ]),
171
180
}
172
181
for _ , option := range options {
173
182
option (server )
@@ -299,6 +308,26 @@ func validateResourceHandler(handler any) error {
299
308
return nil
300
309
}
301
310
311
+ func (s * Server ) RegisterResourceTemplate (uriTemplate string , name string , description string , mimeType string ) error {
312
+ s .resourceTemplates .Store (uriTemplate , & resourceTemplate {
313
+ Name : name ,
314
+ Description : description ,
315
+ UriTemplate : uriTemplate ,
316
+ MimeType : mimeType ,
317
+ })
318
+ return s .sendResourceListChangedNotification ()
319
+ }
320
+
321
+ func (s * Server ) CheckResourceTemplateRegistered (uriTemplate string ) bool {
322
+ _ , ok := s .resourceTemplates .Load (uriTemplate )
323
+ return ok
324
+ }
325
+
326
+ func (s * Server ) DeregisterResourceTemplate (uriTemplate string ) error {
327
+ s .resourceTemplates .Delete (uriTemplate )
328
+ return s .sendResourceListChangedNotification ()
329
+ }
330
+
302
331
func (s * Server ) RegisterPrompt (name string , description string , handler any ) error {
303
332
err := validatePromptHandler (handler )
304
333
if err != nil {
@@ -553,6 +582,7 @@ func (s *Server) Serve() error {
553
582
pr .SetRequestHandler ("prompts/list" , s .handleListPrompts )
554
583
pr .SetRequestHandler ("prompts/get" , s .handlePromptCalls )
555
584
pr .SetRequestHandler ("resources/list" , s .handleListResources )
585
+ pr .SetRequestHandler ("resources/templates/list" , s .handleListResourceTemplates )
556
586
pr .SetRequestHandler ("resources/read" , s .handleResourceCalls )
557
587
err := pr .Connect (s .transport )
558
588
if err != nil {
@@ -825,6 +855,78 @@ func (s *Server) handleListResources(ctx context.Context, request *transport.Bas
825
855
}, nil
826
856
}
827
857
858
+ func (s * Server ) handleListResourceTemplates (ctx context.Context , request * transport.BaseJSONRPCRequest , extra protocol.RequestHandlerExtra ) (transport.JsonRpcBody , error ) {
859
+ type resourceTemplateRequestParams struct {
860
+ Cursor * string `json:"cursor"`
861
+ }
862
+ var params resourceTemplateRequestParams
863
+ if request .Params == nil {
864
+ params = resourceTemplateRequestParams {}
865
+ } else {
866
+ err := json .Unmarshal (request .Params , & params )
867
+ if err != nil {
868
+ return nil , errors .Wrap (err , "failed to unmarshal arguments" )
869
+ }
870
+ }
871
+
872
+ // Order by URI template for pagination
873
+ var orderedTemplates []* resourceTemplate
874
+ s .resourceTemplates .Range (func (k string , t * resourceTemplate ) bool {
875
+ orderedTemplates = append (orderedTemplates , t )
876
+ return true
877
+ })
878
+ sort .Slice (orderedTemplates , func (i , j int ) bool {
879
+ return orderedTemplates [i ].UriTemplate < orderedTemplates [j ].UriTemplate
880
+ })
881
+
882
+ startPosition := 0
883
+ if params .Cursor != nil {
884
+ // Base64 decode the cursor
885
+ c , err := base64 .StdEncoding .DecodeString (* params .Cursor )
886
+ if err != nil {
887
+ return nil , errors .Wrap (err , "failed to decode cursor" )
888
+ }
889
+ cString := string (c )
890
+ // Iterate through the templates until we find an entry > the cursor
891
+ for i := 0 ; i < len (orderedTemplates ); i ++ {
892
+ if orderedTemplates [i ].UriTemplate > cString {
893
+ startPosition = i
894
+ break
895
+ }
896
+ }
897
+ }
898
+ endPosition := len (orderedTemplates )
899
+ if s .paginationLimit != nil {
900
+ // Make sure we don't go out of bounds
901
+ if len (orderedTemplates ) > startPosition + * s .paginationLimit {
902
+ endPosition = startPosition + * s .paginationLimit
903
+ }
904
+ }
905
+
906
+ templatesToReturn := make ([]* ResourceTemplateSchema , 0 )
907
+ for i := startPosition ; i < endPosition ; i ++ {
908
+ t := orderedTemplates [i ]
909
+ templatesToReturn = append (templatesToReturn , & ResourceTemplateSchema {
910
+ Annotations : nil ,
911
+ Description : & t .Description ,
912
+ MimeType : & t .MimeType ,
913
+ Name : t .Name ,
914
+ UriTemplate : t .UriTemplate ,
915
+ })
916
+ }
917
+
918
+ return ListResourceTemplatesResponse {
919
+ Templates : templatesToReturn ,
920
+ NextCursor : func () * string {
921
+ if s .paginationLimit != nil && len (templatesToReturn ) >= * s .paginationLimit {
922
+ toString := base64 .StdEncoding .EncodeToString ([]byte (templatesToReturn [len (templatesToReturn )- 1 ].UriTemplate ))
923
+ return & toString
924
+ }
925
+ return nil
926
+ }(),
927
+ }, nil
928
+ }
929
+
828
930
func (s * Server ) handlePromptCalls (ctx context.Context , req * transport.BaseJSONRPCRequest , extra protocol.RequestHandlerExtra ) (transport.JsonRpcBody , error ) {
829
931
params := baseGetPromptRequestParamsArguments {}
830
932
// Instantiate a struct of the type of the arguments
0 commit comments