get_webhook_subscription
Retrieve your current webhook subscription details, if one exists.
Instructions
Return the user's current webhook subscription, if any.
Tool call template
This tool declares no required parameters. Add optional parameters from the input schema as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {},
"name": "get_webhook_subscription"
}
}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)