Skip to content

Commit 0f90bb6

Browse files
committed
feat: extend resource middlewares to resource templates
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 <t.hoplock@gmail.com>
1 parent 840879b commit 0f90bb6

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
@@ -940,7 +940,17 @@ func (s *MCPServer) handleReadResource(
940940
s.resourcesMu.RUnlock()
941941

942942
if matched {
943-
contents, err := matchedHandler(ctx, request)
943+
// If a match is found, then we have a final handler and can
944+
// apply middlewares.
945+
s.resourceMiddlewareMu.RLock()
946+
finalHandler := ResourceHandlerFunc(matchedHandler)
947+
mw := s.resourceHandlerMiddlewares
948+
// Apply middlewares in reverse order
949+
for i := len(mw) - 1; i >= 0; i-- {
950+
finalHandler = mw[i](finalHandler)
951+
}
952+
s.resourceMiddlewareMu.RUnlock()
953+
contents, err := finalHandler(ctx, request)
944954
if err != nil {
945955
return nil, &requestError{
946956
id: id,

0 commit comments

Comments
 (0)