"""Utility client for validating the FastMCP sample server.""" from __future__ import annotations import argparse import asyncio from typing import Any, Iterable, Optional from fastmcp import Client from fastmcp.types import TextContent def extract_first_text_block(content_blocks: Optional[Iterable[Any]]) -> Optional[str]: """Return the first text block contained in the MCP tool response.""" if not content_blocks: return None for block in content_blocks: if isinstance(block, TextContent): return block.text return None async def run(url: str) -> None: """Execute a simple validation workflow against the MCP server.""" client = Client(url=url) async with client: ping_result = await client.ping() print("Ping:", ping_result) tools_response = await client.list_tools() print("Tools:", tools_response) tool_call = await client.call_tool("echo", {"text": "Hello MCP"}) text = extract_first_text_block(getattr(tool_call, "content", None)) if text is not None: print("Echo response:", text) else: print("Echo response contains no TextContent blocks:", tool_call) def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="FastMCP sample client") parser.add_argument( "--url", default="http://localhost:7860/mcp", help="MCP server URL (default: %(default)s)", ) return parser.parse_args() def main() -> None: args = parse_args() asyncio.run(run(args.url)) if __name__ == "__main__": main()