Skip to content
Last updated

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 typeTrigger eventUse case
Call toolAn AI agent invokes a specific tool.Validate parameters, transform requests, enforce custom business rules, log to external systems.
List toolsAn 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:

/**
 * Handle the event
 * @param {CallToolEventData} eventData — the event details
 * @returns {Promise<CallToolHandlerResponse>} 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:

SettingDescription
Fail methodologyDetermines what happens when the hook throws an error or times out. Fail Open allows the request to proceed. Fail Closed blocks the request.
TimeoutThe 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

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)

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.