Skip to main content
Glama
client.py9.66 kB
""" Example MCP Client - Demonstrates how to connect to and use the MCP Demo Server. This client shows: - Connecting to an MCP server - Listing available tools, resources, and prompts - Calling tools with arguments - Reading resources - Getting prompts """ import asyncio import json from typing import Any from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client class MCPDemoClient: """ Example client for interacting with the MCP Demo Server. This demonstrates the basic patterns for MCP client development. """ def __init__(self): """Initialize the client.""" self.session: ClientSession | None = None async def connect(self) -> None: """ Connect to the MCP server. The server is started as a subprocess and communicates via stdio. """ server_params = StdioServerParameters( command="python", args=["-m", "mcp_demo.server"], env=None, ) stdio_transport = await stdio_client(server_params) self.stdio, self.write = stdio_transport self.session = ClientSession(self.stdio, self.write) await self.session.initialize() print("✓ Connected to MCP Demo Server\n") async def list_tools(self) -> None: """List all available tools from the server.""" if not self.session: raise RuntimeError("Not connected to server") print("=== Available Tools ===") response = await self.session.list_tools() for tool in response.tools: print(f"\n📦 {tool.name}") print(f" Description: {tool.description}") print(f" Schema: {json.dumps(tool.inputSchema, indent=2)}") async def call_calculator(self, operation: str, a: float, b: float) -> None: """ Example: Call the calculator tool. Args: operation: Math operation (add, subtract, multiply, divide) a: First number b: Second number """ if not self.session: raise RuntimeError("Not connected to server") print(f"\n=== Calling Calculator: {a} {operation} {b} ===") result = await self.session.call_tool( "calculator", arguments={ "operation": operation, "a": a, "b": b, }, ) for content in result.content: if hasattr(content, "text"): print(f"Result: {content.text}") async def call_weather(self, city: str, units: str = "celsius") -> None: """ Example: Call the weather tool. Args: city: City name units: Temperature units (celsius or fahrenheit) """ if not self.session: raise RuntimeError("Not connected to server") print(f"\n=== Getting Weather for {city} ===") result = await self.session.call_tool( "weather", arguments={ "city": city, "units": units, }, ) for content in result.content: if hasattr(content, "text"): print(content.text) async def call_timestamp(self, format_type: str = "iso") -> None: """ Example: Call the timestamp tool. Args: format_type: Format type (iso, unix, human) """ if not self.session: raise RuntimeError("Not connected to server") print(f"\n=== Getting Timestamp ({format_type}) ===") result = await self.session.call_tool( "timestamp", arguments={"format": format_type}, ) for content in result.content: if hasattr(content, "text"): print(content.text) async def call_file_operations( self, operation: str, path: str, content: str | None = None ) -> None: """ Example: Call the file operations tool. Args: operation: Operation type (read, write, list, exists) path: File or directory path content: Content to write (for write operation) """ if not self.session: raise RuntimeError("Not connected to server") print(f"\n=== File Operation: {operation} on {path} ===") args: dict[str, Any] = { "operation": operation, "path": path, } if content is not None: args["content"] = content result = await self.session.call_tool("file_operations", arguments=args) for content_item in result.content: if hasattr(content_item, "text"): print(content_item.text) async def list_resources(self) -> None: """List all available resources from the server.""" if not self.session: raise RuntimeError("Not connected to server") print("\n=== Available Resources ===") response = await self.session.list_resources() for resource in response.resources: print(f"\n📄 {resource.name}") print(f" URI: {resource.uri}") print(f" Description: {resource.description}") print(f" MIME Type: {resource.mimeType}") async def read_resource(self, uri: str) -> None: """ Example: Read a resource. Args: uri: Resource URI to read """ if not self.session: raise RuntimeError("Not connected to server") print(f"\n=== Reading Resource: {uri} ===") result = await self.session.read_resource(uri) for content in result.contents: if hasattr(content, "text"): print(content.text) async def list_prompts(self) -> None: """List all available prompts from the server.""" if not self.session: raise RuntimeError("Not connected to server") print("\n=== Available Prompts ===") response = await self.session.list_prompts() for prompt in response.prompts: print(f"\n✏️ {prompt.name}") print(f" Description: {prompt.description}") if prompt.arguments: print(" Arguments:") for arg in prompt.arguments: required = " (required)" if arg.get("required") else "" print(f" - {arg['name']}: {arg.get('description', '')}{required}") async def get_prompt(self, name: str, arguments: dict[str, str] | None = None) -> None: """ Example: Get a prompt with arguments. Args: name: Prompt name arguments: Prompt arguments """ if not self.session: raise RuntimeError("Not connected to server") print(f"\n=== Getting Prompt: {name} ===") if arguments: print(f"Arguments: {arguments}") result = await self.session.get_prompt(name, arguments=arguments) print("\nPrompt Content:") print("-" * 60) for message in result.messages: if hasattr(message.content, "text"): print(message.content.text) print("-" * 60) async def run_demo(self) -> None: """Run a comprehensive demo of all server capabilities.""" try: # Connect to server await self.connect() # Demo 1: List and call tools await self.list_tools() # Call calculator tool await self.call_calculator("add", 15, 27) await self.call_calculator("multiply", 8, 7) await self.call_calculator("divide", 100, 4) # Call weather tool await self.call_weather("San Francisco", "fahrenheit") await self.call_weather("Tokyo", "celsius") # Call timestamp tool await self.call_timestamp("iso") await self.call_timestamp("unix") await self.call_timestamp("human") # Call file operations tool await self.call_file_operations( "write", "/tmp/mcp_demo_test.txt", "Hello from MCP Demo Client!", ) await self.call_file_operations("read", "/tmp/mcp_demo_test.txt") await self.call_file_operations("exists", "/tmp/mcp_demo_test.txt") # Demo 2: List and read resources await self.list_resources() await self.read_resource("config://server/settings") await self.read_resource("system://info") await self.read_resource("docs://getting-started") # Demo 3: List and get prompts await self.list_prompts() await self.get_prompt( "code-review", {"language": "Python", "complexity": "complex"}, ) await self.get_prompt( "documentation", {"type": "api", "project_name": "MCP Demo Server"}, ) await self.get_prompt( "debug-assistant", {"error_message": "NullPointerException in UserService.java:42"}, ) print("\n✓ Demo completed successfully!\n") except Exception as e: print(f"\n✗ Error during demo: {e}\n") raise async def main(): """Main entry point for the example client.""" print("=" * 60) print("MCP Demo Client - Example Usage") print("=" * 60) client = MCPDemoClient() await client.run_demo() if __name__ == "__main__": asyncio.run(main())

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/joohnnie/mcp-agent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server