Skip to main content
Glama

FastMCP Multi-Tenancy

mcp_sse_client.py13.2 kB
#!/usr/bin/env python3 """ Example MCP SSE Client for testing prompts functionality. This client demonstrates how to: 1. Connect to an MCP server using SSE 2. List available prompts 3. Get a specific prompt with arguments 4. List and call tools with various types of returns 5. Access resources with different patterns and formats """ import asyncio import json import logging import traceback from typing import Any, Dict import argparse import base64 from PIL import Image as PILImage from io import BytesIO from mcp import ClientSession, types from mcp.client.sse import sse_client # Configure logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger("mcp-client") async def handle_sampling_message( message: types.CreateMessageRequestParams, ) -> types.CreateMessageResult: """Optional sampling callback handler.""" logger.info(f"Received sampling request: {message}") return types.CreateMessageResult( role="assistant", content=types.TextContent( type="text", text="This is a response from the client-side model.", ), model="example-model", stopReason="endTurn", ) async def run_prompts_test(session: ClientSession): """Test the prompts functionality.""" # List available prompts logger.info("Testing prompts/list...") try: prompts = await session.list_prompts() logger.info(f"Found {len(prompts)} prompts:") for prompt in prompts: logger.info(f" - {prompt.name}: {prompt.description}") if prompt.arguments: logger.info(f" Arguments:") for arg in prompt.arguments: required = "(required)" if arg.required else "(optional)" logger.info(f" - {arg.name}: {arg.description} {required}") except Exception as e: logger.error(f"Error listing prompts: {e}") logger.error(traceback.format_exc()) # Get a simple prompt logger.info("\nTesting prompts/get with 'greeting' prompt...") try: prompt_result = await session.get_prompt( "greeting", arguments={"name": "Test User"} ) logger.info("Prompt result:") logger.info(f" Description: {prompt_result.description}") logger.info(" Messages:") for message in prompt_result.messages: logger.info(f" - Role: {message.role}") if hasattr(message.content, "text"): logger.info(f" Content: {message.content.text}") else: logger.info(f" Content: {message.content}") except Exception as e: logger.error(f"Error getting prompt: {e}") logger.error(traceback.format_exc()) # Get a structured prompt logger.info("\nTesting prompts/get with 'assistUser' prompt...") try: prompt_result = await session.get_prompt( "assistUser", arguments={"problem": "My application is crashing", "username": "John"} ) logger.info("Structured prompt result:") logger.info(f" Description: {prompt_result.description}") logger.info(" Messages:") for message in prompt_result.messages: logger.info(f" - Role: {message.role}") if hasattr(message.content, "text"): logger.info(f" Content: {message.content.text}") else: logger.info(f" Content: {message.content}") except Exception as e: logger.error(f"Error getting structured prompt: {e}") logger.error(traceback.format_exc()) # Get the tutorial prompt logger.info("\nTesting prompts/get with 'tutorialCode' prompt...") try: prompt_result = await session.get_prompt( "tutorialCode", arguments={"language": "Python", "concept": "async/await"} ) logger.info("Tutorial prompt result:") logger.info(f" Description: {prompt_result.description}") logger.info(" Messages:") for message in prompt_result.messages: logger.info(f" - Role: {message.role}") if hasattr(message.content, "text"): logger.info(f" Content: {message.content.text}") else: logger.info(f" Content: {message.content}") except Exception as e: logger.error(f"Error getting tutorial prompt: {e}") logger.error(traceback.format_exc()) async def run_tools_test(session: ClientSession): """Test the tools functionality.""" # List available tools logger.info("\nTesting tools/list...") try: tools = await session.list_tools() logger.info(f"Found {len(tools)} tools:") for tool in tools: logger.info(f" - {tool.name}: {tool.description}") except Exception as e: logger.error(f"Error listing tools: {e}") logger.error(traceback.format_exc()) # Test the hello tool logger.info("\nTesting tools/call with 'hello' tool...") try: hello_result = await session.call_tool("hello", {"name": "Test User"}) logger.info("Tool result:") for content in hello_result: if hasattr(content, "text"): logger.info(f" Content: {content.text}") else: logger.info(f" Content: {content}") except Exception as e: logger.error(f"Error calling hello tool: {e}") logger.error(traceback.format_exc()) # Test the calculate tool logger.info("\nTesting tools/call with 'calculate' tool...") try: calc_result = await session.call_tool( "calculate", {"a": 10, "b": 5, "operation": "multiply"} ) logger.info("Tool result:") for content in calc_result: if hasattr(content, "text"): logger.info(f" Content: {content.text}") else: logger.info(f" Content: {content}") except Exception as e: logger.error(f"Error calling calculate tool: {e}") logger.error(traceback.format_exc()) # Test the user profile tool logger.info("\nTesting tools/call with 'getUserProfile' tool...") try: profile_result = await session.call_tool( "getUserProfile", {"user_id": "12345"} ) logger.info("User profile result:") for content in profile_result: if hasattr(content, "text"): logger.info(f" Content: {content.text}") else: logger.info(f" Content: {content}") except Exception as e: logger.error(f"Error calling getUserProfile tool: {e}") logger.error(traceback.format_exc()) # Test the color swatch image tool logger.info("\nTesting tools/call with 'generateColorSwatch' tool...") try: swatch_result = await session.call_tool( "generateColorSwatch", {"color": "#3498DB"} # Blue color ) logger.info("Color swatch result:") for content in swatch_result: if hasattr(content, "type") and content.type == "image": logger.info(f" Received image with source starting with: {content.source[:30]}...") # Optionally save the image try: if content.source.startswith("data:image/png;base64,"): b64_data = content.source.split(",")[1] img_data = base64.b64decode(b64_data) img = PILImage.open(BytesIO(img_data)) logger.info(f" Image size: {img.size}") except Exception as img_err: logger.error(f"Error processing image: {img_err}") else: logger.info(f" Content: {content}") except Exception as e: logger.error(f"Error calling generateColorSwatch tool: {e}") logger.error(traceback.format_exc()) # Test long process tool with progress logger.info("\nTesting tools/call with 'longProcess' tool...") try: # Use a small number of steps to keep the test short long_result = await session.call_tool( "longProcess", {"steps": 3} ) logger.info("Long process result:") for content in long_result: if hasattr(content, "text"): logger.info(f" Content: {content.text}") else: logger.info(f" Content: {content}") except Exception as e: logger.error(f"Error calling longProcess tool: {e}") logger.error(traceback.format_exc()) async def run_resources_test(session: ClientSession): """Test the resources functionality.""" # List available resources logger.info("\nTesting resources/list...") try: resources = await session.list_resources() logger.info(f"Found {len(resources)} resources:") for resource in resources: logger.info(f" - {resource.uri}: {resource.name} ({resource.mimeType})") logger.info(f" Description: {resource.description}") except Exception as e: logger.error(f"Error listing resources: {e}") logger.error(traceback.format_exc()) # Test reading standard resource logger.info("\nTesting resources/read with 'resource://data'...") try: data_content, mime_type = await session.read_resource("resource://data") logger.info(f"Resource content (mime type: {mime_type}):") logger.info(f" {data_content}") except Exception as e: logger.error(f"Error reading data resource: {e}") logger.error(traceback.format_exc()) # Test reading parameterized resource logger.info("\nTesting resources/read with parameterized URI 'users://123/documents/456'...") try: doc_content, mime_type = await session.read_resource("users://123/documents/456") logger.info(f"Document resource content (mime type: {mime_type}):") logger.info(f" {doc_content}") except Exception as e: logger.error(f"Error reading document resource: {e}") logger.error(traceback.format_exc()) # Test reading markdown resource logger.info("\nTesting resources/read with 'resource://sample/markdown'...") try: md_content, mime_type = await session.read_resource("resource://sample/markdown") logger.info(f"Markdown resource content (mime type: {mime_type}):") logger.info(f" {md_content}") except Exception as e: logger.error(f"Error reading markdown resource: {e}") logger.error(traceback.format_exc()) async def main(): """Run the MCP SSE client.""" # Parse command line arguments parser = argparse.ArgumentParser(description="MCP SSE Client for testing") parser.add_argument("--url", default="http://localhost:8000", help="Server URL") parser.add_argument("--entity", default="test-entity", help="Entity ID") args = parser.parse_args() # Server URL and entity ID server_url = args.url entity_id = args.entity logger.info(f"Connecting to MCP server at {server_url} with entity ID: {entity_id}") try: # Connect to the server using SSE async with sse_client(f"{server_url}/{entity_id}/sse") as (read, write): # Create a client session async with ClientSession( read, write, sampling_callback=handle_sampling_message ) as session: # Initialize the connection logger.info("Initializing session...") init_result = await session.initialize() logger.info("Connection initialized successfully") logger.info(f"Server info: {init_result.serverInfo.name} v{init_result.serverInfo.version}") logger.info(f"Protocol version: {init_result.protocolVersion}") logger.info(f"Server capabilities: {init_result.capabilities}") # Wait a moment before sending requests await asyncio.sleep(1) # Run the prompts test await run_prompts_test(session) # Run the tools test await run_tools_test(session) # Run the resources test await run_resources_test(session) # Keep the connection alive for a moment logger.info("Connection established. Waiting 5 seconds before disconnecting...") await asyncio.sleep(5) logger.info("Client shutting down...") except Exception as e: logger.error(f"Error connecting to server: {e}") logger.error(traceback.format_exc()) if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: logger.info("Client terminated by user") except Exception as e: logger.error(f"Unexpected error: {e}") logger.error(traceback.format_exc())

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/timothywangdev/McpToolKit'

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