@@ -496,6 +496,21 @@ def _get_transport_config(self, transport_type: str) -> dict:
496496
497497 return config
498498
499+ def _is_resource_template (self , component : ParsedComponent ) -> bool :
500+ """Check if a resource component is a template (has URI parameters).
501+
502+ Args:
503+ component: The parsed component to check
504+
505+ Returns:
506+ True if the resource has URI parameters, False otherwise
507+ """
508+ return (
509+ component .type == ComponentType .RESOURCE
510+ and component .parameters is not None
511+ and len (component .parameters ) > 0
512+ )
513+
499514 def _generate_server (self ) -> None :
500515 """Generate the main server entry point."""
501516 server_file = self .output_dir / "server.py"
@@ -514,7 +529,7 @@ def _generate_server(self) -> None:
514529 imports = [
515530 "from fastmcp import FastMCP" ,
516531 "from fastmcp.tools import Tool" ,
517- "from fastmcp.resources import Resource" ,
532+ "from fastmcp.resources import Resource, ResourceTemplate " ,
518533 "from fastmcp.prompts import Prompt" ,
519534 "import os" ,
520535 "import sys" ,
@@ -654,12 +669,20 @@ def _generate_server(self) -> None:
654669 registration += f".with_annotations({ component .annotations } )"
655670 registration += "\n mcp.add_tool(_tool)"
656671 elif component_type == ComponentType .RESOURCE :
657- registration += (
658- f"\n _resource = Resource.from_function(_wrapped_func, "
659- f'uri="{ component .uri_template } ", name="{ component .name } ", '
660- f'description="{ component .docstring or "" } ")\n '
661- f"mcp.add_resource(_resource)"
662- )
672+ if self ._is_resource_template (component ):
673+ registration += (
674+ f"\n _template = ResourceTemplate.from_function(_wrapped_func, "
675+ f'uri_template="{ component .uri_template } ", name="{ component .name } ", '
676+ f'description="{ component .docstring or "" } ")\n '
677+ f"mcp.add_template(_template)"
678+ )
679+ else :
680+ registration += (
681+ f"\n _resource = Resource.from_function(_wrapped_func, "
682+ f'uri="{ component .uri_template } ", name="{ component .name } ", '
683+ f'description="{ component .docstring or "" } ")\n '
684+ f"mcp.add_resource(_resource)"
685+ )
663686 else : # PROMPT
664687 registration += (
665688 f"\n _prompt = Prompt.from_function(_wrapped_func, "
@@ -692,12 +715,20 @@ def _generate_server(self) -> None:
692715 registration += f".with_annotations({ component .annotations } )"
693716 registration += "\n mcp.add_tool(_tool)"
694717 elif component_type == ComponentType .RESOURCE :
695- registration += (
696- f"\n _resource = Resource.from_function(_wrapped_func, "
697- f'uri="{ component .uri_template } ", name="{ component .name } ", '
698- f'description="{ component .docstring or "" } ")\n '
699- f"mcp.add_resource(_resource)"
700- )
718+ if self ._is_resource_template (component ):
719+ registration += (
720+ f"\n _template = ResourceTemplate.from_function(_wrapped_func, "
721+ f'uri_template="{ component .uri_template } ", name="{ component .name } ", '
722+ f'description="{ component .docstring or "" } ")\n '
723+ f"mcp.add_template(_template)"
724+ )
725+ else :
726+ registration += (
727+ f"\n _resource = Resource.from_function(_wrapped_func, "
728+ f'uri="{ component .uri_template } ", name="{ component .name } ", '
729+ f'description="{ component .docstring or "" } ")\n '
730+ f"mcp.add_resource(_resource)"
731+ )
701732 else : # PROMPT
702733 registration += (
703734 f"\n _prompt = Prompt.from_function(_wrapped_func, "
@@ -737,33 +768,64 @@ def _generate_server(self) -> None:
737768 registration += "\n mcp.add_tool(_tool)"
738769
739770 elif component_type == ComponentType .RESOURCE :
740- registration = f"# Register the resource '{ component .name } ' from { full_module_path } "
741-
742- # Use the entry_function if available, otherwise try the
743- # export variable
744- if hasattr (component , "entry_function" ) and component .entry_function :
745- registration += (
746- f"\n _resource = Resource.from_function("
747- f"{ full_module_path } .{ component .entry_function } , "
748- f'uri="{ component .uri_template } "'
749- )
750- else :
751- registration += (
752- f"\n _resource = Resource.from_function("
753- f"{ full_module_path } .export, "
754- f'uri="{ component .uri_template } "'
771+ if self ._is_resource_template (component ):
772+ registration = (
773+ f"# Register the resource template '{ component .name } ' from { full_module_path } "
755774 )
756775
757- # Add the name parameter
758- registration += f', name="{ component .name } "'
759-
760- # Add description from docstring
761- if component .docstring :
762- # Escape any quotes in the docstring
763- escaped_docstring = component .docstring .replace ('"' , '\\ "' )
764- registration += f', description="{ escaped_docstring } "'
765-
766- registration += ")\n mcp.add_resource(_resource)"
776+ # Use the entry_function if available, otherwise try the
777+ # export variable
778+ if hasattr (component , "entry_function" ) and component .entry_function :
779+ registration += (
780+ f"\n _template = ResourceTemplate.from_function("
781+ f"{ full_module_path } .{ component .entry_function } , "
782+ f'uri_template="{ component .uri_template } "'
783+ )
784+ else :
785+ registration += (
786+ f"\n _template = ResourceTemplate.from_function("
787+ f"{ full_module_path } .export, "
788+ f'uri_template="{ component .uri_template } "'
789+ )
790+
791+ # Add the name parameter
792+ registration += f', name="{ component .name } "'
793+
794+ # Add description from docstring
795+ if component .docstring :
796+ # Escape any quotes in the docstring
797+ escaped_docstring = component .docstring .replace ('"' , '\\ "' )
798+ registration += f', description="{ escaped_docstring } "'
799+
800+ registration += ")\n mcp.add_template(_template)"
801+ else :
802+ registration = f"# Register the resource '{ component .name } ' from { full_module_path } "
803+
804+ # Use the entry_function if available, otherwise try the
805+ # export variable
806+ if hasattr (component , "entry_function" ) and component .entry_function :
807+ registration += (
808+ f"\n _resource = Resource.from_function("
809+ f"{ full_module_path } .{ component .entry_function } , "
810+ f'uri="{ component .uri_template } "'
811+ )
812+ else :
813+ registration += (
814+ f"\n _resource = Resource.from_function("
815+ f"{ full_module_path } .export, "
816+ f'uri="{ component .uri_template } "'
817+ )
818+
819+ # Add the name parameter
820+ registration += f', name="{ component .name } "'
821+
822+ # Add description from docstring
823+ if component .docstring :
824+ # Escape any quotes in the docstring
825+ escaped_docstring = component .docstring .replace ('"' , '\\ "' )
826+ registration += f', description="{ escaped_docstring } "'
827+
828+ registration += ")\n mcp.add_resource(_resource)"
767829
768830 else : # PROMPT
769831 registration = f"# Register the prompt '{ component .name } ' from { full_module_path } "
0 commit comments