React
npm install @axag/react
import { defineAction, useAxag } from '@axag/react';
const deactivateUser = defineAction({
intent: 'user.deactivate',
actionType: 'write',
riskLevel: 'critical',
confirmationRequired: true,
requiredParameters: [{ name: 'user_id', type: 'string', format: 'uuid' }],
});
export function DeactivateButton({ userId }: { userId: string }) {
const axag = useAxag(deactivateUser, { handler: () => api.deactivate(userId) });
return <button {...axag}>Deactivate</button>;
}
The hook returns the axag-* attributes and a ref. Spreading them puts the annotation in the DOM — where the DevTools extension and any other reader can see it — and registers the action while the component is mounted.
Options
| Option | Description |
|---|---|
handler | What the tool does. Without one, the element's form is filled and the control is pressed |
middleware | Wraps every call |
enabled | false keeps the action off the agent's list, e.g. by role |
onError | Registration failures, including browsers without WebMCP |
Components you don't own
import { AxagAction } from '@axag/react';
<AxagAction spec={deactivateUser} handler={deactivate}>
<Button variant="danger">Deactivate</Button>
</AxagAction>
Renders a display: contents span, so it changes no layout. as renders a different element.
Behaviour worth knowing
- StrictMode is safe. Each mount gets its own
AbortController; the double mount registers, unregisters and registers again cleanly. - Re-registration is by annotation, not by render. Changing
riskLevelre-registers; re-rendering with the same spec doesn't. - Unmounting unregisters, so conditional rendering and route changes keep the agent's tools in step with the screen.
Build-time extraction
A spec held in a module-level const is also read by @axag/compiler at build time, so the same action appears in the manifest without running the app. A spec built from props can't be, and is listed under dynamic_actions.