> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xpander.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Decorators

> Wire your code into the agent runtime (task handlers, lifecycle, and tool hooks).

Decorators are how your Python module becomes a deployed agent worker. The platform dispatches incoming task events to your `@on_task` handler over SSE, calls `@on_boot` once at startup, runs `@on_tool_*` hooks around every tool invocation, and routes auth events through `@on_auth_event`.

| Decorator                                                               | Purpose                                                                 |
| ----------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| [`@on_task`](/developers/sdk-reference/decorators/on-task)              | Handle incoming tasks. The primary entry point for any SDK-based agent. |
| [`@on_boot`](/developers/sdk-reference/decorators/on-boot-shutdown)     | Run once at startup, before the SSE listener subscribes.                |
| [`@on_shutdown`](/developers/sdk-reference/decorators/on-boot-shutdown) | Run once during graceful shutdown.                                      |
| [`@on_auth_event`](/developers/sdk-reference/decorators/on-auth-event)  | Receive MCP/OAuth authentication events as they happen.                 |
| [`@on_tool_before`](/developers/sdk-reference/decorators/on-tool)       | Run before any tool invocation.                                         |
| [`@on_tool_after`](/developers/sdk-reference/decorators/on-tool)        | Run after a successful tool invocation.                                 |
| [`@on_tool_error`](/developers/sdk-reference/decorators/on-tool)        | Run when a tool invocation raises.                                      |

For the tool-registration decorator, see [`@register_tool`](/developers/sdk-reference/tools/register-tool): it lives next to the tools API, since it constructs `Tool` objects rather than wiring runtime hooks.

## Minimal worker

```python theme={"dark"}
from xpander_sdk import Backend, on_task, on_boot, on_shutdown
from xpander_sdk.modules.tasks.sub_modules.task import Task
from agno.agent import Agent as AgnoAgent

backend = Backend()

@on_boot
async def boot():
    print("Worker starting…")

@on_shutdown
async def shutdown():
    print("Worker stopping…")

@on_task
async def handler(task: Task) -> Task:
    args = await backend.aget_args(
        agent_id=task.agent_id,
        agent_version=task.agent_version,
        task=task,
    )
    agno_agent = AgnoAgent(**args)
    result = await agno_agent.arun(input=task.to_message())
    task.result = result.content
    return task
```

Run this module: `python worker.py`: and the worker subscribes to the platform's SSE stream, picks up tasks dispatched to its agent, runs them, and saves results. Tasks are auto-marked `Completed` (or `Error` on raise) and metrics are reported automatically when `task.tokens` is set.

## Required environment

`@on_task` validates required env vars eagerly at import. Missing any of these raises `ModuleException`:

| Variable                  | Required for         |
| ------------------------- | -------------------- |
| `XPANDER_API_KEY`         | Authentication.      |
| `XPANDER_ORGANIZATION_ID` | Routing.             |
| `XPANDER_AGENT_ID`        | Worker registration. |

For local development without an org-managed agent, set these to your dev values.
