---
description: "Calls a listener for every agent event while the component is mounted: the React form of onAgentEvent."
---

# `useAgentEvents`

Calls a listener for every agent event while the component is mounted: the React form of [`onAgentEvent`](/docs/reference/core/on-agent-event). Reach for it to show what the agent is doing (a status line, a log) or to react to it (close a drawer before a tool runs).

## Import

```ts
import { useAgentEvents } from "@webmcp-agents/react";
```

## Example

A status line that follows the agent.

```tsx title="components/agent-status.tsx"
import { useAgentEvents } from "@webmcp-agents/react";
import { useState } from "react";

// A line of status text that follows what the agent is doing.
export function AgentStatus() {
  const [status, setStatus] = useState("The agent is idle.");

  useAgentEvents((event) => {
    if (event.type === "start") setStatus(`Running ${event.tool}…`);
    if (event.type === "park") setStatus(event.prompt);
    if (event.type === "result")
      setStatus(`${event.tool} took ${Math.round(event.ms)} ms.`);
    if (event.type === "error") setStatus(event.error);
    if (event.type === "yield") setStatus("You took over.");
  });

  return <p aria-live="polite">{status}</p>;
}
```

## Options

`useAgentEvents(listener)`.

| Name | Type | Default | Description |
|---|---|---|---|
| `listener` | `(event: AgentEvent) => void` | required | Called for each event. The latest render's listener is used, so an inline function that closes over state is fine. |

### `AgentEvent`

From `@webmcp-agents/core`. Branch on `type`:

| `type` | Fields | When |
|---|---|---|
| `start` | `tool`, `at`, `args?` | A tool run started. `at` is `performance.now()`. `args` when known (tools from `defineWebTool` / `useWebTool`). |
| `fill` | `tool`, `field`, `value` | The agent's value went into a field (of a declarative form, or the field a tool's parameter is typed into), once the cursor has typed it. |
| `park` | `tool`, `prompt` | The tool is waiting for the person. |
| `result` | `tool`, `result`, `ms` | The tool answered the agent. |
| `error` | `tool`, `error`, `ms` | The tool failed. |
| `cancel` | `tool` | The call was cancelled. |
| `yield` | `reason` | The person started interacting; the cursor got out of the way. |
| `resume` | none | The person was quiet long enough for the cursor to show again. |

## Returns

Nothing.

## Notes

- Works without a provider. Most events come from the visual layer, so they only flow while it is installed ([`<WebAgentsProvider>`](/docs/reference/react/web-agents-provider) installs it unless `visuals={false}`). `park` is also emitted by confirm-gated tools and by [`waitingForUser`](/docs/reference/core/waiting-for-user).
- It subscribes once on mount and unsubscribes on unmount. Changing the listener never resubscribes.
- A listener that throws is logged and never breaks a tool run.

## See also

- [Devtools](/docs/build/devtools), a timeline built on the same events
- [`onAgentEvent`](/docs/reference/core/on-agent-event)
- [`waitingForUser`](/docs/reference/core/waiting-for-user) (emits `park`)
- [`installAgentVisuals`](/docs/reference/core/install-agent-visuals) (its `log` option gets the same events)
