@@ -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 {
@@ -829,6 +859,78 @@ func (s *Server) handleListResources(ctx context.Context, request *transport.Bas
829
859
}, nil
830
860
}
831
861
862
+ func (s * Server ) handleListResourceTemplates (ctx context.Context , request * transport.BaseJSONRPCRequest , extra protocol.RequestHandlerExtra ) (transport.JsonRpcBody , error ) {
863
+ type resourceTemplateRequestParams struct {
864
+ Cursor * string `json:"cursor"`
865
+ }
866
+ var params resourceTemplateRequestParams
867
+ if request .Params == nil {
868
+ params = resourceTemplateRequestParams {}
869
+ } else {
870
+ err := json .Unmarshal (request .Params , & params )
871
+ if err != nil {
872
+ return nil , errors .Wrap (err , "failed to unmarshal arguments" )
873
+ }
874
+ }
875
+
876
+ // Order by URI template for pagination
877
+ var orderedTemplates []* resourceTemplate
878
+ s .resourceTemplates .Range (func (k string , t * resourceTemplate ) bool {
879
+ orderedTemplates = append (orderedTemplates , t )
880
+ return true
881
+ })
882
+ sort .Slice (orderedTemplates , func (i , j int ) bool {
883
+ return orderedTemplates [i ].UriTemplate < orderedTemplates [j ].UriTemplate
884
+ })
885
+
886
+ startPosition := 0
887
+ if params .Cursor != nil {
888
+ // Base64 decode the cursor
889
+ c , err := base64 .StdEncoding .DecodeString (* params .Cursor )
890
+ if err != nil {
891
+ return nil , errors .Wrap (err , "failed to decode cursor" )
892
+ }
893
+ cString := string (c )
894
+ // Iterate through the templates until we find an entry > the cursor
895
+ for i := 0 ; i < len (orderedTemplates ); i ++ {
896
+ if orderedTemplates [i ].UriTemplate > cString {
897
+ startPosition = i
898
+ break
899
+ }
900
+ }
901
+ }
902
+ endPosition := len (orderedTemplates )
903
+ if s .paginationLimit != nil {
904
+ // Make sure we don't go out of bounds
905
+ if len (orderedTemplates ) > startPosition + * s .paginationLimit {
906
+ endPosition = startPosition + * s .paginationLimit
907
+ }
908
+ }
909
+
910
+ templatesToReturn := make ([]* ResourceTemplateSchema , 0 )
911
+ for i := startPosition ; i < endPosition ; i ++ {
912
+ t := orderedTemplates [i ]
913
+ templatesToReturn = append (templatesToReturn , & ResourceTemplateSchema {
914
+ Annotations : nil ,
915
+ Description : & t .Description ,
916
+ MimeType : & t .MimeType ,
917
+ Name : t .Name ,
918
+ UriTemplate : t .UriTemplate ,
919
+ })
920
+ }
921
+
922
+ return ListResourceTemplatesResponse {
923
+ Templates : templatesToReturn ,
924
+ NextCursor : func () * string {
925
+ if s .paginationLimit != nil && len (templatesToReturn ) >= * s .paginationLimit {
926
+ toString := base64 .StdEncoding .EncodeToString ([]byte (templatesToReturn [len (templatesToReturn )- 1 ].UriTemplate ))
927
+ return & toString
928
+ }
929
+ return nil
930
+ }(),
931
+ }, nil
932
+ }
933
+
832
934
func (s * Server ) handlePromptCalls (ctx context.Context , req * transport.BaseJSONRPCRequest , extra protocol.RequestHandlerExtra ) (transport.JsonRpcBody , error ) {
833
935
params := baseGetPromptRequestParamsArguments {}
834
936
// Instantiate a struct of the type of the arguments
0 commit comments