get_webhook_subscription
Retrieve your current webhook subscription details, if one exists.
Instructions
Return the user's current webhook subscription, if any.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/hevy_mcp/tools/webhooks.py:15-17 (handler)The `get_webhook_subscription` async function that performs a GET request to /webhook-subscription and returns the response data.
async def get_webhook_subscription() -> dict[str, Any]: """Return the user's current webhook subscription, if any.""" return {"data": await client.get("/webhook-subscription")} - src/hevy_mcp/tools/webhooks.py:13-17 (registration)The tool is registered via the @mcp.tool() decorator on line 13, inside the register() function of webhooks.py.
@mcp.tool() @tool_guard async def get_webhook_subscription() -> dict[str, Any]: """Return the user's current webhook subscription, if any.""" return {"data": await client.get("/webhook-subscription")} - src/hevy_mcp/tools/__init__.py:11-11 (registration)webhooks.register(mcp, ctx) is called from register_all() in the tools package init.
webhooks.register(mcp, ctx) - src/hevy_mcp/errors.py:47-80 (helper)The `tool_guard` decorator wraps the handler, catching exceptions (HevyApiError, timeout, ValueError, unexpected) and returning structured {error, hint} responses.
def tool_guard(func: Callable[..., Awaitable[Any]]) -> Callable[..., Awaitable[Any]]: """Decorator: convert exceptions into `{error, hint}` and emit structured logs.""" @functools.wraps(func) async def wrapper(*args: Any, **kwargs: Any) -> Any: start = time.monotonic() name = func.__name__ try: result = await func(*args, **kwargs) log.info("tool=%s status=ok duration_ms=%.1f", name, (time.monotonic() - start) * 1000) return result except HevyApiError as e: log.warning( "tool=%s status=hevy_error http=%d duration_ms=%.1f msg=%s", name, e.status, (time.monotonic() - start) * 1000, e.message, ) return {"error": e.message, "hint": e.hint, "http_status": e.status} except httpx.TimeoutException: log.warning("tool=%s status=timeout duration_ms=%.1f", name, (time.monotonic() - start) * 1000) return { "error": "Hevy API request timed out.", "hint": "Retry the call. If it keeps timing out, reduce page_size or scope.", } except ValueError as e: log.warning("tool=%s status=bad_input duration_ms=%.1f msg=%s", name, (time.monotonic() - start) * 1000, e) return {"error": str(e), "hint": "Re-read the tool's input schema and adjust the arguments."} except Exception as e: # noqa: BLE001 — last-resort guard so Claude never sees a stack trace log.exception("tool=%s status=internal_error duration_ms=%.1f", name, (time.monotonic() - start) * 1000) return { "error": f"Unexpected internal error: {type(e).__name__}: {e}", "hint": "This is a bug in hevy-mcp. Retry once; if it persists, file an issue with the tool name and inputs.", } return wrapper - src/hevy_mcp/errors.py:21-26 (helper)HevyApiError exception class used by tool_guard to surface structured API errors with status, message, and hint.
class HevyApiError(Exception): def __init__(self, status: int, message: str, hint: str | None = None) -> None: super().__init__(message) self.status = status self.message = message self.hint = hint or _default_hint(status)