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

# Step 1 — Connect real-time events

> Give Hugo live awareness of what each user is doing in your app — Hugo pulls it on demand via the Autoplay MCP server.

## ⚡ Add this skill

<CardGroup cols={2}>
  <Card title="One command" icon="terminal">
    Add the Autoplay Crisp Hugo skill for an existing Crisp Hugo AI support agent setup.

    <CodeGroup>
      ```bash CLI theme={null}
      uvx --from autoplay-sdk autoplay-install-skills --chatbot crisp
      ```
    </CodeGroup>

    <a className="skill-card-link" href="/recipes/crisp-ai/step-1-connect-real-time-events">View the docs →</a>
  </Card>

  <Card title="Agent onboarding" icon="robot">
    Fetch this skill when a customer already uses Crisp Hugo and wants its AI support agent to consume Autoplay live user activity.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -s https://developers.autoplay.ai/chatbot-crisp/SKILL.md
      ```
    </CodeGroup>

    <a className="skill-card-link" href="https://developers.autoplay.ai/chatbot-crisp/SKILL.md" target="_blank">View the skill →</a>
  </Card>
</CardGroup>

**Hugo** (Crisp's AI agent) pulls a user's recent in-app activity on demand via the **Autoplay MCP server** — Hugo calls it the moment it needs context to answer. One MCP connection, one tool (`get_live_user_activity`), and a verified identity so Hugo asks for the right user.

## 🎬 End-to-end walkthrough

<div
  style={{
position: "relative",
paddingBottom: "calc(54.502% + 41px)",
height: 0,
width: "100%",
}}
>
  <iframe
    src="https://demo.arcade.software/14wVEGP1PRx814fUt3yw?embed&embed_mobile=tab&embed_desktop=inline&show_copy_link=true"
    title="Crisp Hugo — connect live user activity via MCP"
    frameBorder={0}
    loading="lazy"
    allow="clipboard-write; fullscreen"
    style={{
  position: "absolute",
  top: 0,
  left: 0,
  width: "100%",
  height: "100%",
  colorScheme: "light",
}}
  />
</div>

***

## 🔌 Add the Autoplay MCP server

In your Crisp dashboard, go to **AI Agent** (left sidebar) → **Integrations & MCP** (under Automate). Scroll to the **External MCP servers** section and click **Add MCP server**.

In the modal that appears:

1. **MCP Server URL:** `https://mcp.autoplay.ai/mcp`
2. Click **Authentication** to expand it → set **Authentication Method** to **Bearer Token** → enter your `mcp_key` in the **Bearer Token** field.

Click **Add MCP server**. Once connected, the server appears in your External MCP servers list showing **Online**.

## ⚙️ Configure the server — click Manage

Click **Manage** on the server. The Manage page has two places where you write descriptions — one at the **server level** and one at the **tool level**. Both matter.

### 1 — Server Description (Connection details)

In the **Connection details** section, fill in:

* **Name:** `App live activity`
* **Description:** This is the top-level prompt — Hugo reads it to decide when this MCP server is relevant at all. Keep it short and focused on the scenario:

```text theme={null}
Use this server to get a user's recent in-app activity, including
pages they visited, buttons they clicked, and actions they
took. Call it when a user seems stuck, asks about something
they were just doing, or when knowing their recent navigation
would help you give a better answer.
```

### 2 — Tool Description (MCP tools selector)

Scroll down to **MCP tools selector** and check **`get_live_user_activity`** to enable it. The tool card shows a description field — this is the detailed prompt that tells Hugo exactly when and how to call this specific tool (equivalent to the **Fin tab** prompt in Intercom).

Click the **edit icon (✏️)** on the `get_live_user_activity` card and set the description to:

```text theme={null}
Always call this tool before responding to any user message.
Use the returned user activity data, features visited,
actions taken, workflows completed, to understand what the
user has already done and what they haven't. Use this context
to better answer their question, surface context they didn't
mention, and diagnose what they're actually stuck on,
because sometimes users don't phrase what they need in the
best way since they may be stuck and don't understand the
product like an expert.

The product_id is always: YOUR_PRODUCT_ID
```

<Tip>
  Replace `YOUR_PRODUCT_ID` with your actual product id from your Activity provider dashboard. Including it in the tool description is how you pass a fixed value — there is no separate "fixed value" input field in Hugo.
</Tip>

## 🎛️ Configure the parameters

Under **Parameters** on the tool card, each input has two options: **Let Hugo decide** or **Use an attribute**.

**product\_id** → set to **Let Hugo decide**

Hugo reads your product id from the description above (the `The product_id is always: ...` line) and passes automatically.

**user\_id** → set to **Use an attribute** → select the attribute that holds your app's stable user id

The dropdown shows contact attributes available in the conversation (e.g. **User email**). Choose the one that matches the id your activity source identifies the user with. See *Identity* below for how to make the right attribute available.

**limit** → leave as **Let Hugo decide**.

<Warning>
  For **user\_id**, do not use email unless email is literally the stable id your activity source identifies the user with. Activity is stored under that stable id — a mismatch means Hugo reads an empty bucket.
</Warning>

## 🔐 Identity — make the user id available as an attribute

Hugo can only pass the right `user_id` if the Crisp session carries it. Set it from your frontend via the Crisp JS SDK **after the user logs in**, using `session:data`:

```javascript theme={null}
// After login — push your app's stable user id into the Crisp session.
// The key name ("user_id") becomes the attribute name visible in Hugo's parameter dropdown.
$crisp.push(["set", "session:data", [[["user_id", currentUser.id]]]]);

// Optionally set standard Crisp contact fields too:
$crisp.push(["set", "user:email", [currentUser.email]]);
$crisp.push(["set", "user:nickname", [currentUser.name]]);
```

After you push `session:data` with a `user_id` key, that key appears in Hugo's **Use an attribute** dropdown. Select it for the `user_id` parameter.

The value you push **must exactly equal** the id your activity source uses:

<Tabs>
  <Tab title="PostHog">
    ```javascript theme={null}
    // These two must be identical:
    posthog.identify(currentUser.id);                                       // activity source
    $crisp.push(["set", "session:data", [[["user_id", currentUser.id]]]]);  // Crisp session
    ```
  </Tab>

  <Tab title="Amplitude">
    ```javascript theme={null}
    // These two must be identical:
    amplitude.setUserId(currentUser.id);                                    // activity source
    $crisp.push(["set", "session:data", [[["user_id", currentUser.id]]]]);  // Crisp session
    ```
  </Tab>

  <Tab title="Other activity source">
    ```javascript theme={null}
    // TODO: Replace this with the user identification method
    // provided by your activity source.

    // The user ID sent to your activity source and Crisp
    // must be exactly the same value.

    analytics.identify(currentUser.id);
    $crisp.push(["set", "session:data", [[["user_id", currentUser.id]]]]);
    ```
  </Tab>
</Tabs>

<Note>
  **How the pieces fit:** your frontend identifies the user in your activity source (PostHog or Amplitude) → Autoplay stores activity under that id → your frontend also pushes `session:data` with that same id → Hugo reads the attribute and fetches activity for it → the buckets match.
</Note>

## ✅ Test the full loop

1. **Log in** to your app as a test user — fires your activity source's identify call and sets `session:data` with `user_id`.
2. **Click around** — visit a couple of pages, click a button, submit a form.
3. **Open the Crisp chat widget** as that same logged-in user.
4. **Ask Hugo:** *"What have I been doing in the app recently?"*
5. Hugo calls **`get_live_user_activity`** and answers with **what you actually just did**.

Common issues:

* **401 / auth error** → the Bearer token is missing or incorrect, revisit *Add the Autoplay MCP server* above.
* **Empty activity returned** → identity is working but that user has no recent activity yet. Browse around in your app first, then re-test.
* **Wrong user's activity** → the `user_id` in `session:data` doesn't match the id your activity source uses. Check both are identical.

<Note>
  **"No recent activity" = identity mismatch.** Confirm the **same** value in all three:

  1. the stable id your activity source identifies the user with (PostHog: `posthog.identify(id)`, Amplitude: `amplitude.setUserId(id)`),
  2. the `user_id` key in `$crisp.push(["set", "session:data", ...])`,
  3. the attribute selected for the `user_id` parameter in Hugo's tool config.

  If they don't match, activity is stored under one key and fetched with another, and the lookup comes back empty.
</Note>

Once Hugo is answering with real activity, jump into our [Discord](https://discord.gg/jCbR2tQA5) — we'll confirm the tool is pulling activity cleanly and help you tune the trigger description.

***

**Next:** [Step 2 — Define proactive triggers](./step-2-define-proactive-triggers)
