list_resources
Retrieve all available resources from the connected MCP server, including URIs, names, descriptions, and MIME types for accurate access.
Instructions
List all resources available on the connected MCP server.
Retrieves comprehensive information about all resources exposed by the target server, including URIs, names, descriptions, and MIME types to enable accurate resource access.
Returns: Dictionary with resource listing including: - success: True on successful retrieval - resources: List of resource objects with uri, name, description, mimeType - metadata: Total count, server info, timing information
Raises: Returns error dict if not connected or retrieval fails
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- The core handler function for the 'list_resources' tool, decorated with @mcp.tool. It verifies the connection, calls the connected client's list_resources method, processes the results into a standardized dictionary format with metadata, handles errors gracefully, and provides user feedback via ctx.info/error.@mcp.tool async def list_resources(ctx: Context) -> dict[str, Any]: """List all resources available on the connected MCP server. Retrieves comprehensive information about all resources exposed by the target server, including URIs, names, descriptions, and MIME types to enable accurate resource access. Returns: Dictionary with resource listing including: - success: True on successful retrieval - resources: List of resource objects with uri, name, description, mimeType - metadata: Total count, server info, timing information Raises: Returns error dict if not connected or retrieval fails """ start_time = time.perf_counter() try: # Verify connection exists client, state = ConnectionManager.require_connection() # User-facing progress update await ctx.info("Listing resources from connected MCP server") # Detailed technical log logger.info("Listing resources from connected MCP server") # Get resources from the server resources_result = await client.list_resources() elapsed_ms = (time.perf_counter() - start_time) * 1000 # Convert resources to dictionary format with full metadata # Note: client.list_resources() returns a list directly, not an object with .resources resources_list = [] for resource in resources_result: resource_dict = { "uri": resource.uri, "name": resource.name if resource.name else "", "description": resource.description if resource.description else "", "mimeType": resource.mimeType if hasattr(resource, "mimeType") and resource.mimeType else None, } resources_list.append(resource_dict) metadata = { "total_resources": len(resources_list), "server_url": state.server_url, "retrieved_at": time.time(), "request_time_ms": round(elapsed_ms, 2), } # Add server info if available if state.server_info: metadata["server_name"] = state.server_info.get("name", "unknown") metadata["server_version"] = state.server_info.get("version") # User-facing success update await ctx.info(f"Retrieved {len(resources_list)} resources from server") # Detailed technical log logger.info( f"Retrieved {len(resources_list)} resources from server", extra={ "resource_count": len(resources_list), "server_url": state.server_url, "duration_ms": elapsed_ms, }, ) return { "success": True, "resources": resources_list, "metadata": metadata, } except ConnectionError as e: elapsed_ms = (time.perf_counter() - start_time) * 1000 # User-facing error update await ctx.error(f"Not connected: {str(e)}") # Detailed technical log logger.error(f"Not connected: {str(e)}", extra={"duration_ms": elapsed_ms}) return { "success": False, "error": { "error_type": "not_connected", "message": str(e), "details": {}, "suggestion": "Use connect_to_server() to establish a connection first", }, "resources": [], "metadata": { "request_time_ms": round(elapsed_ms, 2), }, } except Exception as e: elapsed_ms = (time.perf_counter() - start_time) * 1000 # User-facing error update await ctx.error(f"Failed to list resources: {str(e)}") # Detailed technical log logger.exception("Failed to list resources", extra={"duration_ms": elapsed_ms}) # Increment error counter ConnectionManager.increment_stat("errors") return { "success": False, "error": { "error_type": "execution_error", "message": f"Failed to list resources: {str(e)}", "details": {"exception_type": type(e).__name__}, "suggestion": "Check that the server supports the resources capability and is responding correctly", }, "resources": [], "metadata": { "request_time_ms": round(elapsed_ms, 2), }, }
- node-wrapper/python-src/src/mcp_test_mcp/server.py:96-182 (registration)The import of the resources module (line 98) triggers automatic registration of the list_resources tool via its @mcp.tool decorator. The subsequent debug log confirms the tool is among the registered tools.# Import tool modules to trigger decorator registration # This MUST happen after mcp instance is imported but before the server runs from .tools import connection, tools, resources, prompts, llm # Note: Logging during module import can interfere with stdio transport # Only log at DEBUG level to avoid corrupting JSON-RPC protocol on stdout logger.debug("FastMCP server instance created", extra={"server_name": "mcp-test-mcp"}) @mcp.tool() async def health_check(ctx: Context) -> Dict[str, Any]: """ Health check endpoint that verifies the server is running. Returns: Dictionary with status and server information """ await ctx.info("Health check requested") return { "status": "healthy", "server": "mcp-test-mcp", "version": "0.1.6", "transport": "stdio" } @mcp.tool() async def ping(ctx: Context) -> str: """ Simple ping tool that responds with 'pong'. Useful for testing basic connectivity and server responsiveness. Returns: The string 'pong' """ await ctx.debug("Ping received") return "pong" @mcp.tool() def echo(message: str) -> str: """ Echo back a message. Args: message: The message to echo back Returns: The same message that was provided """ logger.debug(f"Echo tool called with message: {message}") return message @mcp.tool() def add(a: int, b: int) -> int: """ Add two numbers together. Args: a: First number b: Second number Returns: The sum of a and b """ logger.debug(f"Add tool called: {a} + {b}") return a + b # Tool registration happens automatically via decorators in imported modules # No need for manual mcp.tool() calls here # Note: Logging during module import can interfere with stdio transport # Only log at DEBUG level to avoid corrupting JSON-RPC protocol on stdout logger.debug("MCP tools registered", extra={ "tools": [ "health_check", "ping", "echo", "add", "connect_to_server", "disconnect", "get_connection_status", "list_tools", "call_tool", "list_resources", "read_resource", "list_prompts", "get_prompt", "execute_prompt_with_llm" ] })