1+ from typing import Any
2+
3+
4+ class MCPResolver :
5+ def __init__ (self , container : Any , server : Any ):
6+ # Type of server is FastMCP, but keep Any to avoid hard import at module import time
7+ self .container = container
8+ self .server = server
9+
10+ def register (self ):
11+ for module in self .container .modules .values ():
12+ for controller in module .controllers .values ():
13+ self ._register_controller (controller )
14+
15+ def _register_controller (self , controller : type ):
16+ # Bind methods to the controller class object so that `self` refers to the class
17+ for attr_name , attr_value in controller .__dict__ .items ():
18+ if not callable (attr_value ):
19+ continue
20+
21+ if hasattr (attr_value , "_mcp_tool" ):
22+ bound_fn = attr_value .__get__ (controller , controller )
23+ meta = getattr (attr_value , "_mcp_tool" , {}) or {}
24+ # Use call-form registration to preserve signature
25+ self .server .tool (
26+ bound_fn ,
27+ name = meta .get ("name" ),
28+ description = meta .get ("description" ),
29+ tags = meta .get ("tags" ),
30+ output_schema = meta .get ("output_schema" ),
31+ annotations = meta .get ("annotations" ),
32+ exclude_args = meta .get ("exclude_args" ),
33+ meta = meta .get ("meta" ),
34+ enabled = meta .get ("enabled" ),
35+ )
36+
37+ if hasattr (attr_value , "_mcp_resource" ):
38+ bound_fn = attr_value .__get__ (controller , controller )
39+ meta = getattr (attr_value , "_mcp_resource" , {}) or {}
40+ uri = meta .get ("uri" )
41+ if not uri :
42+ continue
43+ self .server .add_resource_fn (
44+ bound_fn ,
45+ uri ,
46+ name = meta .get ("name" ),
47+ description = meta .get ("description" ),
48+ mime_type = meta .get ("mime_type" ),
49+ tags = meta .get ("tags" ),
50+ )
51+
52+ if hasattr (attr_value , "_mcp_prompt" ):
53+ bound_fn = attr_value .__get__ (controller , controller )
54+ meta = getattr (attr_value , "_mcp_prompt" , {}) or {}
55+ self .server .prompt (
56+ bound_fn ,
57+ name = meta .get ("name" ),
58+ description = meta .get ("description" ),
59+ tags = meta .get ("tags" ),
60+ enabled = meta .get ("enabled" ),
61+ meta = meta .get ("meta" ),
62+ )
0 commit comments