## Hooks Hooks enable you to execute custom JavaScript code in response to MCP events in your Agen for SaaS pipeline. They sit within the guardrails layer of the control plane and allow you to implement custom validation, transformation, and enforcement logic beyond what built-in policies and access control provide. ### Hook types Agen for SaaS supports two hook types, each triggered by a different MCP event: | Hook type | Trigger event | Use case | | --- | --- | --- | | **Call tool** | An AI agent invokes a specific tool. | Validate parameters, transform requests, enforce custom business rules, log to external systems. | | **List tools** | An AI agent requests the list of available tools. | Filter tools dynamically, add context-specific tool descriptions, enforce custom visibility rules. | ### Creating a hook To create a hook: 1. Navigate to the **Hooks** section in the control plane (accessible from the Guardrails area of the pipeline view). 2. Click **Create hook**. 3. In the **Create hook** dialog: - Select a **Hook type** from the dropdown: `Call tool` or `List tools`. - Set the **Timeout** — the maximum execution time for the hook. Default: `5 seconds`. Adjustable with +/- controls. 4. Click **Create**. After creation, you are taken to the hook editor. ### Hook editor The hook editor has two tabs: **Body** and **Settings**. #### Body tab The Body tab contains a **Custom code JavaScript** editor with syntax highlighting. When you create a new **Call tool** hook, the editor is pre-populated with a default template: ```javascript /** * Handle the event * @param {CallToolEventData} eventData — the event details * @returns {Promise} event handler response */ async function onEvent(eventData) { return { verdict: 'allow', response: { } } } exports.onEvent = onEvent; ``` The `onEvent` function is the entry point for your hook logic: - **`eventData`** — Contains the event details, including the tool being called, the request parameters, user identity, and tenant context. - **Return value** — Must include: - **`verdict`** — Either `'allow'` to permit the action or `'deny'` to block it. - **`response`** — An optional object to include additional data or override the response. You can write any valid JavaScript in the hook body, including async operations, external HTTP calls, and conditional logic. #### Settings tab The Settings tab provides two configuration options: | Setting | Description | | --- | --- | | **Fail methodology** | Determines what happens when the hook throws an error or times out. **Fail Open** allows the request to proceed. **Fail Closed** blocks the request. | | **Timeout** | The maximum execution time for the hook in seconds. Default: `5 seconds`. If the hook does not return within this window, the fail methodology determines the outcome. | ### Testing a hook Click the **Test** button in the hook editor header to execute your hook with sample event data. This lets you validate your logic before activating the hook in production. ### Activating and deactivating hooks Each hook has an **Activate/Inactivate** toggle in the editor header. A hook must be active to execute during MCP events. Deactivating a hook disables it without deleting the code, so you can re-enable it later. ### Example use cases #### Custom parameter validation ```javascript async function onEvent(eventData) { const amount = eventData.params?.amount; if (amount && amount > 10000) { return { verdict: 'deny', response: { error: 'Amount exceeds maximum allowed value' } }; } return { verdict: 'allow', response: {} }; } exports.onEvent = onEvent; ``` #### Dynamic tool filtering (List tools hook) ```javascript async function onEvent(eventData) { // Custom logic to filter tools based on user context return { verdict: 'allow', response: {} }; } exports.onEvent = onEvent; ``` ### Best practices - **Keep hooks fast** — Hooks execute synchronously in the request pipeline. Keep execution time well under the timeout threshold to avoid latency. - **Use Fail Open for non-critical hooks** — If your hook provides supplementary logic (logging, enrichment), use Fail Open to prevent hook failures from blocking legitimate requests. - **Use Fail Closed for security hooks** — If your hook enforces a security requirement, use Fail Closed to ensure requests are blocked when the hook cannot execute. - **Test before activating** — Always use the Test button to validate hook logic before toggling to active. - **Handle errors gracefully** — Wrap external calls in try/catch blocks and return a clear verdict even when errors occur. ### Related topics - [Policies](/agen-for-saas/policies/overview) - [Access control](/agen-for-saas/access-control/overview) - [Tools → About tools](/agen-for-saas/tools/about-tools)