Module fastmcp_extensions.utils.describe_server
MCP server description and measurement utilities.
This module provides utilities for measuring the size of MCP tool lists, which is useful for tracking context truncation issues when AI agents call list_tools.
Usage
python -m fastmcp_extensions.utils.describe_server –app
Example: python -m fastmcp_extensions.utils.describe_server –app my_mcp_server.server:app
Poe task configuration: [tool.poe.tasks.mcp-describe-server] cmd = "python -m fastmcp_extensions.utils.describe_server –app my_mcp_server.server:app" help = "Describe MCP server tool list"
Output includes: - Tool count - Total characters (names + descriptions + schemas) - Average characters per tool
Functions
async def get_tool_details(app: FastMCP) ‑> list[dict[str, Any]]-
Expand source code
async def get_tool_details(app: FastMCP) -> list[dict[str, Any]]: """Get detailed information about each tool. Args: app: The FastMCP app instance Returns: List of dictionaries with tool details including name, description length, and schema length for each tool. """ async with Client(app) as client: tools = await client.list_tools() details = [] for tool in tools: name_len = len(tool.name) desc_len = len(tool.description) if tool.description else 0 schema_len = len(str(tool.inputSchema)) if tool.inputSchema else 0 details.append( { "name": tool.name, "name_length": name_len, "description_length": desc_len, "schema_length": schema_len, "total_length": name_len + desc_len + schema_len, } ) return detailsGet detailed information about each tool.
Args
app- The FastMCP app instance
Returns
List of dictionaries with tool details including name, description length, and schema length for each tool.
def main() ‑> None-
Expand source code
def main() -> None: """Main entry point for the MCP server description CLI.""" parser = argparse.ArgumentParser( description="Describe MCP server tool list", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=__doc__, ) parser.add_argument( "--app", required=True, help="App module path in format 'module.path:attribute'", ) parser.add_argument( "--name", help="Optional server name for reporting", ) cli_args = parser.parse_args() app = _import_app(cli_args.app) run_measurement(app, server_name=cli_args.name)Main entry point for the MCP server description CLI.
async def measure_tool_list(app: FastMCP) ‑> tuple[int, int]-
Expand source code
async def measure_tool_list(app: FastMCP) -> tuple[int, int]: """Measure the tool list size from the MCP server. This function connects to the MCP server and measures the character count of the tool list, including tool names, descriptions, and input schemas. Args: app: The FastMCP app instance Returns: Tuple of (tool_count, total_character_count) """ async with Client(app) as client: tools = await client.list_tools() tool_count = len(tools) total_chars = 0 for tool in tools: total_chars += len(tool.name) if tool.description: total_chars += len(tool.description) if tool.inputSchema: total_chars += len(str(tool.inputSchema)) return tool_count, total_charsMeasure the tool list size from the MCP server.
This function connects to the MCP server and measures the character count of the tool list, including tool names, descriptions, and input schemas.
Args
app- The FastMCP app instance
Returns
Tuple of (tool_count, total_character_count)
async def measure_tool_list_detailed(app: FastMCP, server_name: str | None = None) ‑> ToolListMeasurement-
Expand source code
async def measure_tool_list_detailed( app: FastMCP, server_name: str | None = None, ) -> ToolListMeasurement: """Measure the tool list size with detailed results. Args: app: The FastMCP app instance server_name: Optional name of the server for reporting Returns: ToolListMeasurement with detailed results """ tool_count, total_chars = await measure_tool_list(app) return ToolListMeasurement( tool_count=tool_count, total_characters=total_chars, average_chars_per_tool=total_chars // tool_count if tool_count > 0 else 0, server_name=server_name, )Measure the tool list size with detailed results.
Args
app- The FastMCP app instance
server_name- Optional name of the server for reporting
Returns
ToolListMeasurement with detailed results
def run_measurement(app: FastMCP, server_name: str | None = None) ‑> None-
Expand source code
def run_measurement(app: FastMCP, server_name: str | None = None) -> None: """Run tool list measurement and print results. This is a convenience function for CLI measurement scripts. Args: app: The FastMCP app instance server_name: Optional name of the server for reporting """ measurement = asyncio.run(measure_tool_list_detailed(app, server_name)) print(str(measurement))Run tool list measurement and print results.
This is a convenience function for CLI measurement scripts.
Args
app- The FastMCP app instance
server_name- Optional name of the server for reporting
Classes
class ToolListMeasurement (tool_count: int,
total_characters: int,
average_chars_per_tool: int,
server_name: str | None = None)-
Expand source code
@dataclass class ToolListMeasurement: """Measurement results for an MCP tool list.""" tool_count: int total_characters: int average_chars_per_tool: int server_name: str | None = None def __str__(self) -> str: """Return a human-readable string representation.""" lines = [] if self.server_name: lines.append(f"MCP Server: {self.server_name}") lines.append(f"Tool count: {self.tool_count}") lines.append(f"Total characters: {self.total_characters:,}") lines.append(f"Average chars per tool: {self.average_chars_per_tool:,}") return "\n".join(lines)Measurement results for an MCP tool list.
Instance variables
var average_chars_per_tool : intvar server_name : str | Nonevar tool_count : intvar total_characters : int