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

# Custom Actions

> Extend HyperAgent with custom actions for specialized workflows

Custom actions let you extend HyperAgent's capabilities beyond browser automation. Add integrations with external APIs, databases, or any custom logic.

## Defining a Custom Action

A custom action requires three things:

1. **type**: A descriptive name for the action
2. **actionParams**: A Zod schema describing the parameters
3. **run**: A function that executes the action

```typescript theme={null}
import { HyperAgent, AgentActionDefinition, ActionContext, ActionOutput } from "@hyperbrowser/agent";
import { z } from "zod";

const SendEmailAction: AgentActionDefinition = {
  type: "send_email",
  actionParams: z.object({
    to: z.string().describe("Email recipient address"),
    subject: z.string().describe("Email subject line"),
    body: z.string().describe("Email body content"),
  }).describe("Send an email to a specified recipient"),
  
  run: async function(
    ctx: ActionContext,
    params: { to: string; subject: string; body: string }
  ): Promise<ActionOutput> {
    // Your email sending logic here
    await sendEmail(params.to, params.subject, params.body);
    
    return {
      success: true,
      message: `Successfully sent email to ${params.to}`,
    };
  },
};
```

## Using Custom Actions

Pass custom actions when creating the agent:

```typescript theme={null}
const agent = new HyperAgent({
  customActions: [SendEmailAction],
});

const result = await agent.executeTask(
  "Go to my inbox, find the latest newsletter, summarize it, and send the summary to boss@company.com"
);
```

The AI will automatically use your custom action when appropriate.

## Real-World Example: Web Search

Integrate with a search API like Exa:

```typescript theme={null}
import Exa from "exa-js";

const exaClient = new Exa(process.env.EXA_API_KEY);

const WebSearchAction: AgentActionDefinition = {
  type: "web_search",
  actionParams: z.object({
    query: z.string().describe("Search query - keep it concise and specific"),
  }).describe("Search the web and return relevant results"),
  
  run: async function(ctx, params): Promise<ActionOutput> {
    const results = await exaClient.search(params.query, {
      numResults: 5,
    });
    
    const formatted = results.results
      .map(r => `- ${r.title}: ${r.url}`)
      .join("\n");
    
    return {
      success: true,
      message: `Search results for "${params.query}":\n${formatted}`,
    };
  },
};

const agent = new HyperAgent({
  customActions: [WebSearchAction],
});

await agent.executeTask(
  "Search for the latest news about AI and summarize the top 3 stories"
);
```

## Action Context

The `ActionContext` provides access to:

```typescript theme={null}
interface ActionContext {
  page: Page;           // Current Playwright page
  agent: HyperAgent;    // Agent instance
  taskId: string;       // Current task ID
}
```

Use it to interact with the browser or agent state:

```typescript theme={null}
const SaveScreenshotAction: AgentActionDefinition = {
  type: "save_screenshot",
  actionParams: z.object({
    filename: z.string().describe("Filename to save the screenshot as"),
  }),
  
  run: async function(ctx, params): Promise<ActionOutput> {
    await ctx.page.screenshot({ path: params.filename });
    
    return {
      success: true,
      message: `Screenshot saved to ${params.filename}`,
    };
  },
};
```

## Action Output

Return an `ActionOutput` object:

```typescript theme={null}
interface ActionOutput {
  success: boolean;  // Whether the action succeeded
  message: string;   // Result message shown to the AI
}
```

The message helps the AI understand what happened and plan next steps.

## Multiple Custom Actions

Combine multiple actions for complex workflows:

```typescript theme={null}
const agent = new HyperAgent({
  customActions: [
    WebSearchAction,
    SendEmailAction,
    SaveToNotionAction,
    SlackNotifyAction,
  ],
});

await agent.executeTask(
  "Research competitors, save findings to Notion, and notify the team on Slack"
);
```

## Next Steps

<CardGroup cols={2}>
  <Card title="MCP Integration" icon="plug" href="/hyperagent/mcp">
    Connect to MCP servers for more tools
  </Card>

  <Card title="page.ai()" icon="brain" href="/hyperagent/page-ai">
    Learn about task execution
  </Card>
</CardGroup>
