@@ -188,11 +188,21 @@ class Args:
188188 def _register_tools (self ):
189189 @self .app .tool (name = "list_structures" , description = "List all available structure definitions" )
190190 async def list_structures (structures_path : Optional [str ] = None ) -> str :
191- return self ._list_structures_logic (structures_path )
191+ self .logger .debug (f"MCP request: list_structures args={{'structures_path': { structures_path !r} }}" )
192+ result = self ._list_structures_logic (structures_path )
193+ preview = result if len (result ) <= 1000 else result [:1000 ] + f"... [truncated { len (result )- 1000 } chars]"
194+ self .logger .debug (f"MCP response: list_structures len={ len (result )} preview=\n { preview } " )
195+ return result
192196
193197 @self .app .tool (name = "get_structure_info" , description = "Get detailed information about a specific structure" )
194198 async def get_structure_info (structure_name : str , structures_path : Optional [str ] = None ) -> str :
195- return self ._get_structure_info_logic (structure_name , structures_path )
199+ self .logger .debug (
200+ f"MCP request: get_structure_info args={{'structure_name': { structure_name !r} , 'structures_path': { structures_path !r} }}"
201+ )
202+ result = self ._get_structure_info_logic (structure_name , structures_path )
203+ preview = result if len (result ) <= 1000 else result [:1000 ] + f"... [truncated { len (result )- 1000 } chars]"
204+ self .logger .debug (f"MCP response: get_structure_info len={ len (result )} preview=\n { preview } " )
205+ return result
196206
197207 @self .app .tool (name = "generate_structure" , description = "Generate a project structure using specified definition and options" )
198208 async def generate_structure (
@@ -203,18 +213,36 @@ async def generate_structure(
203213 mappings : Optional [Dict [str , str ]] = None ,
204214 structures_path : Optional [str ] = None ,
205215 ) -> str :
206- return self ._generate_structure_logic (
216+ self .logger .debug (
217+ "MCP request: generate_structure args=%s" ,
218+ {
219+ "structure_definition" : structure_definition ,
220+ "base_path" : base_path ,
221+ "output" : output ,
222+ "dry_run" : dry_run ,
223+ "mappings" : mappings ,
224+ "structures_path" : structures_path ,
225+ },
226+ )
227+ result = self ._generate_structure_logic (
207228 structure_definition ,
208229 base_path ,
209230 output ,
210231 dry_run ,
211232 mappings ,
212233 structures_path ,
213234 )
235+ preview = result if len (result ) <= 1000 else result [:1000 ] + f"... [truncated { len (result )- 1000 } chars]"
236+ self .logger .debug (f"MCP response: generate_structure len={ len (result )} preview=\n { preview } " )
237+ return result
214238
215239 @self .app .tool (name = "validate_structure" , description = "Validate a structure configuration YAML file" )
216240 async def validate_structure (yaml_file : str ) -> str :
217- return self ._validate_structure_logic (yaml_file )
241+ self .logger .debug (f"MCP request: validate_structure args={{'yaml_file': { yaml_file !r} }}" )
242+ result = self ._validate_structure_logic (yaml_file )
243+ preview = result if len (result ) <= 1000 else result [:1000 ] + f"... [truncated { len (result )- 1000 } chars]"
244+ self .logger .debug (f"MCP response: validate_structure len={ len (result )} preview=\n { preview } " )
245+ return result
218246
219247 async def run (
220248 self ,
@@ -226,6 +254,7 @@ async def run(
226254 path : str | None = None ,
227255 log_level : str | None = None ,
228256 stateless_http : bool | None = None ,
257+ fastmcp_log_level : str | None = None ,
229258 ):
230259 """Run the FastMCP server with the specified transport.
231260
@@ -240,9 +269,16 @@ async def run(
240269 path: Endpoint path for HTTP/SSE transports
241270 log_level: Log level for the HTTP server (uvicorn)
242271 stateless_http: Whether to use stateless HTTP mode (HTTP only)
272+ fastmcp_log_level: Log level for FastMCP internals (e.g., DEBUG, INFO)
243273 """
244274 loop = asyncio .get_running_loop ()
245275 def _run ():
276+ # Apply FastMCP-specific logger level if provided
277+ if fastmcp_log_level :
278+ try :
279+ logging .getLogger ('fastmcp' ).setLevel (getattr (logging , fastmcp_log_level .upper ()))
280+ except Exception :
281+ logging .getLogger ('fastmcp' ).setLevel (logging .DEBUG if str (fastmcp_log_level ).upper () == 'DEBUG' else logging .INFO )
246282 kwargs = {"show_banner" : show_banner }
247283 if transport in {"http" , "sse" }:
248284 if host is not None :
@@ -255,6 +291,16 @@ def _run():
255291 kwargs ["log_level" ] = log_level
256292 if stateless_http is not None and transport == "http" :
257293 kwargs ["stateless_http" ] = stateless_http
294+ logging .getLogger (__name__ ).info (
295+ "Starting FastMCP %s server on http://%s:%s%s (uvicorn log_level=%s)" ,
296+ transport ,
297+ kwargs .get ("host" , "127.0.0.1" ),
298+ kwargs .get ("port" , 8000 ),
299+ kwargs .get ("path" , "/mcp" ),
300+ kwargs .get ("log_level" , None ),
301+ )
302+ else :
303+ logging .getLogger (__name__ ).info ("Starting FastMCP stdio server" )
258304 self .app .run (transport , ** kwargs )
259305 await loop .run_in_executor (None , _run )
260306
0 commit comments