Skip to content

Commit 8891432

Browse files
authored
feat: extend resource middlewares to resource templates (#582)
The existing logic for resource middlewares was based heavily off of the prior art for tool middlewares. Tools, however, don't have the concept of templates. This change ensures that resource middlewares also get applied to resource templates. While they are defined as separate types, both `ResourceHandlerFunc` and `ResourceTemplateHandlerFunc` have the same function signature, and therefore satisfy the same underlying type. This seems intentional since resource templates are only actually executed within the same `handleReadResource` function, and only when A) no direct resources match and B) the resource uri matches the template -- executing in the same function and returning an `mcp.ReadResourceResult` regardless of direct resource or template. Since the uri needs to match in order for the template to be executed, we build the chain of middleware funcs after matching the uri to avoid wasted cycles. In order to apply the middlewares to the `ResourceTemplateHandlerFunc`, we explicitly cast to a `ResourceHandlerFunc`. This is safe, as they point to the same underlying type. If resource handler funcs ever diverge, this should also safely surface as a compile time warning, allowing ample time to address and not have a silent breakage slip through in builds. Signed-off-by: TJ Hoplock <[email protected]>
1 parent 056bc8c commit 8891432

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

server/server.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,17 @@ func (s *MCPServer) handleReadResource(
945945
s.resourcesMu.RUnlock()
946946

947947
if matched {
948-
contents, err := matchedHandler(ctx, request)
948+
// If a match is found, then we have a final handler and can
949+
// apply middlewares.
950+
s.resourceMiddlewareMu.RLock()
951+
finalHandler := ResourceHandlerFunc(matchedHandler)
952+
mw := s.resourceHandlerMiddlewares
953+
// Apply middlewares in reverse order
954+
for i := len(mw) - 1; i >= 0; i-- {
955+
finalHandler = mw[i](finalHandler)
956+
}
957+
s.resourceMiddlewareMu.RUnlock()
958+
contents, err := finalHandler(ctx, request)
949959
if err != nil {
950960
return nil, &requestError{
951961
id: id,

0 commit comments

Comments
 (0)