Skip to content
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This SDK provides high-level and dynamic access to those tools, making it easy t
- Retrieve tool definitions and schemas for one or all servers
- Dynamically invoke any tool using a clean, attribute-based syntax
- Generate self-contained, deepcopy-safe tool functions for frameworks like [any-agent](https://github.com/mozilla-ai/any-agent)
- Minimal dependencies (`requests` only)
- Minimal dependencies (`requests` and `cachetools` only)

## Installation in your project

Expand Down Expand Up @@ -121,7 +121,8 @@ from mcpd import McpdClient

# Initialize the client with your mcpd API endpoint.
# api_key is optional and sends an 'MCPD-API-KEY' header.
client = McpdClient(api_endpoint="http://localhost:8090", api_key="optional-key")
# server_health_cache_ttl is optional and sets the time in seconds to cache a server health response.
client = McpdClient(api_endpoint="http://localhost:8090", api_key="optional-key", server_health_cache_ttl=10)
```

### Core Methods
Expand All @@ -140,6 +141,12 @@ client = McpdClient(api_endpoint="http://localhost:8090", api_key="optional-key"

* `client.call.<server_name>.<tool_name>(**kwargs)` - The primary way to dynamically call any tool using keyword arguments.

* `client.server_health() -> dict[str, dict]` - Returns a dictionary mapping each server name to the health information of that server.

* `client.server_health(server_name: str) -> dict` - Returns the health information for only the specified server.

* `client.is_server_healthy(server_name: str) -> bool` - Checks if the specified server is healthy and can handle requests.

## Error Handling

All SDK-level errors, including HTTP and connection errors, will raise a `McpdError` exception.
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ readme = "README.md"
license = {text = "Apache-2.0"}
requires-python = ">=3.11"
dependencies = [
"cachetools>=6.2.0",
"requests>=2.32.4",
]

Expand Down
5 changes: 4 additions & 1 deletion src/mcpd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,22 @@
ConnectionError,
McpdError,
ServerNotFoundError,
ServerUnhealthyError,
TimeoutError,
ToolExecutionError,
ToolNotFoundError,
ValidationError,
)
from .mcpd_client import McpdClient
from .mcpd_client import HealthStatus, McpdClient

__all__ = [
"McpdClient",
"HealthStatus",
"McpdError",
"AuthenticationError",
"ConnectionError",
"ServerNotFoundError",
"ServerUnhealthyError",
"TimeoutError",
"ToolExecutionError",
"ToolNotFoundError",
Expand Down
35 changes: 35 additions & 0 deletions src/mcpd/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,41 @@ def __init__(self, message: str, server_name: str = None):
self.server_name = server_name


class ServerUnhealthyError(McpdError):
"""Raised when a specified MCP server is not healthy.
This indicates that the server exists but is currently unhealthy:
- The server is down or unreachable
- Timeout occurred while checking health
- No health data is available for the server
Attributes:
server_name: The name of the server that is unhealthy.
health_status: Details about the server's health status (if available).
Can be one of timeout, unreachable, unknown.
Example:
>>> try:
>>> tools = client.tools("unhealthy_server")
>>> except ServerUnhealthyError as e:
>>> print(f"Server '{e.server_name}' is unhealthy")
>>> if e.health_status:
>>> print(f"Health details: {e.health_status}")
"""

def __init__(self, message: str, server_name: str, health_status: str):
"""Initialize ServerUnhealthyError.
Args:
message: The error message.
server_name: The name of the server that is unhealthy.
health_status: Details about the server's health status.
"""
super().__init__(message)
self.server_name = server_name
self.health_status = health_status


class ToolNotFoundError(McpdError):
"""Raised when a specified tool doesn't exist on a server.
Expand Down
Loading