Widget Tools

Updated on June 28, 2026

Widget Tools let Hugo run actions directly inside your visitor's browser, through the Crisp chatbox widget — no server required.

Unlike MCP integrations (which call your backend), a Widget Tool is implemented in your website's JavaScript using the Crisp Widget JS SDK. When Hugo decides an action is needed during a live conversation, it asks the visitor's chatbox to run your handler, then uses the returned value to continue the conversation.

Overview

A Widget Tool is made of two parts:

Part Where Description
Definition Hugo dashboard The tool name, description and parameters Hugo can call
Handler Your website The JavaScript function that actually runs in the visitor's browser

How a call flows:

  1. During a widget conversation, Hugo decides to use one of your actions.
  2. Hugo dispatches the call to the visitor's chatbox widget.
  3. Your registered handler runs in the visitor's browser with the parameters Hugo provided.
  4. Your handler returns a result (or an error), which Hugo receives and uses to continue.
Widget Tools only run on widget conversations. They cannot run in test runs, simulations, or any context where there is no active visitor browser to execute the handler.

Why use Widget Tools

  • Run straight from the frontend. Much like WebMCP, tools execute in the page the visitor is already on — you reuse your existing frontend code and app state instead of building and hosting a separate backend.
  • The visitor is already authenticated. Handlers run in the visitor's own browser session, so they inherit the user's logged-in context (cookies, tokens, session). There is no need to re-authenticate the user or pass credentials to Hugo.
  • Easier to set up. No server to deploy, no endpoint to expose, no auth to configure — define an action in Hugo and register a JavaScript handler. You can be up and running in minutes.

Defining a Widget Tool

In your Crisp dashboard, open Hugo › Integrations › Widget Tools and add a new Widget Tool.

Each Widget Tool has:

  • A name — a human-readable name for the tool.
  • A description — tells Hugo when it should use this tool.
  • One or more actions, each with its own name, description and parameters.

Action parameters

Each action can declare parameters that Hugo will fill in when calling it:

Field Type Description
name string The parameter name (letters, numbers, _ and -)
type string One of string, number, integer, boolean
description string Helps Hugo understand what to pass (optional)
required boolean Whether Hugo must provide it (optional)

Defining actions as JSON

Actions can be authored directly as JSON in the configuration editor:

{
  "name": "Cart",
  "description": "Tools to read and update the visitor's shopping cart.",
  "actions": [
    {
      "name": "get_cart",
      "description": "Return the items currently in the visitor's cart.",
      "parameters": []
    },
    {
      "name": "apply_coupon",
      "description": "Apply a discount coupon to the visitor's cart.",
      "parameters": [
        {
          "name": "code",
          "type": "string",
          "description": "The coupon code to apply.",
          "required": true
        }
      ]
    }
  ]
}

Implementing the handler

Handlers are registered on your website with the $crisp chatbox SDK, using the $crisp.push(["on", ...]) syntax. The event name is always hugo:tool: followed by your action name.

$crisp.push(["on", "hugo:tool:apply_coupon", async (args) => {
  // args contains the parameters Hugo provided, eg. { code: "SUMMER25" }
  const result = await myStore.applyCoupon(args.code);

  return result;
}]);

Return format

Just return the value you want Hugo to use — any JSON-serializable value (object, array, string, number, boolean). Hugo passes it straight back to the conversation.

return { items: 3, total: 49.9, currency: "EUR" };

The handler may be async and return a promise — Hugo waits for it to resolve. To signal a failure, throw an error:

throw new Error("Coupon code is invalid");

Full example

Defining a get_cart action in Hugo and implementing it on your site:

$crisp.push(["on", "hugo:tool:get_cart", async () => {
  const cart = await fetch("/api/cart").then((res) => res.json());

  return cart;
}]);

When a visitor asks Hugo "what's in my cart?", Hugo calls get_cart, your handler runs in the visitor's browser, and the returned cart contents are used to answer.


Generating the snippet

When configuring a Widget Tool in Hugo, the Implementation section automatically generates a ready-to-paste JavaScript snippet for each of your actions, including the expected parameters. Copy it into your website's code and fill in your implementation.


Notes & limitations

  • Widget conversations only. A call fails if there is no active visitor browser running the handler.
  • Timeout. Each call waits up to 10 seconds for your handler to respond before failing.
  • No authentication. Widget Tools never require user authentication — they run in the visitor's own browser context.
  • You own the implementation. Handlers run on your own UI, so it's up to you to call safe, guarded endpoints that enforce their own authorization rather than trusting the call blindly.