This April we’ve added new APIs, released an AI tool, and improved our billing.

- [Subscribe to threads](#subscribe-to-threads): Users can subscribe to threads
  without participating.
- [MCP server](#mcp-server): Use AI to generate rooms, write comments, read
  data, and more.
- [Fairier billing with first day free](#fairier-billing-with-first-day-free):
  One-time users no longer count as MAU.

## Upgrade now

To use the latest features, update your packages with the following command.

```bash
npx create-liveblocks-app@latest --upgrade
```

If you were previously on Liveblocks 2.23 or below, make sure to follow our
[upgrade guides](/docs/platform/upgrading) before updating.

## Subscribe to threads

When using [Comments](/comments) and [Notifications](/notifications), end users
no longer need to be participating in threads to receive inbox notifications.
From now, users can choose to subscribe to individual threads meaning they’ll be
notified when new comments are added.

<Figure>
  <video autoPlay loop muted playsInline>
    <source
      src="/images/blog/whats-new-in-liveblocks-april-25/subscribe-to-threads.mp4"
      type="video/mp4"
    />
  </video>
</Figure>

Users can also choose to unsubscribe from threads they’ve participated in. After
upgrading, you’ll find the new menu option in your threads, as shown above, and
in notifications, shown below.

<Figure>
  <Image
    src="/images/blog/whats-new-in-liveblocks-april-25/notifications-unsubscribe.png"
    alt="Unsubscribe from a thread in a notification"
    width={768}
    height={512}
    quality={90}
  />
</Figure>

### Corresponding hooks

Along with the updated components, we’ve also added corresponding hooks for
thread subscriptions, allowing you to subscribe and unsubscribe from threads
programmatically. Here’s how the new
[`useSubscribeToThread`](/docs/api-reference/liveblocks-react#useSubscribeToThread)
hook can be used.

```tsx
import { useSubscribeToThread } from "@liveblocks/react/suspense";

function SubscribeButton({ threadId }) {
  const subscribeToThread = useSubscribeToThread();

  return (
    <button onClick={() => subscribeToThread(threadId)}>
      🔔 Subscribe to thread
    </button>
  );
}
```

We’ve also updated previous hooks, such as
[`useThreadSubscription`](/docs/api-reference/liveblocks-react#useThreadSubscription),
simplifying creating your own primitives.

```tsx
import { useThreadSubscription } from "@liveblocks/react/suspense";

function SubscribeButton({ threadId }) {
  const { status, subscribe, unsubscribe } = useThreadSubscription(threadId);

  if (status === "subscribed") {
    return <button onClick={unsubscribe}>🔕 Unsubscribe</button>;
  }

  return <button onClick={subscribe}>🔔 Subscribe</button>;
}
```

### Updated API names

To reduce confusion in our APIs, we’ve updated a number of names to better
reflect their purpose. Any previous methods related to `roomNotifications` now
refer to `roomSubscriptions`, learn more in
[our upgrade guide](/docs/platform/upgrading/2.24).

## MCP server

We’ve created an MCP server for Liveblocks, which allows you to talk to your
application in AI tools, such as Cursor and Claude, as you build it. Our server
has 39 different tools available, allowing AI to generate rooms, write comments,
send notifications, read realtime data, and more.

<Figure>
  <video autoPlay loop muted playsInline>
    <source
      src="/images/blog/whats-new-in-liveblocks-april-25/mcp-server.mp4"
      type="video/mp4"
    />
  </video>
</Figure>

It’s just one command to install it, find more info in our
[MCP server documentation](/docs/tools/mcp-server).

## Fairier billing with first day free

We’ve rolled out a major improvement to our pricing that makes it easier and
more predictable to scale real-time collaboration in your product: **you now
only pay for users who return after their first session.**

<Figure>
  <Image
    src="/images/blog/first-day-free/first-day-free.jpg"
    alt="First day free"
    width={768}
    height={512}
    quality={90}
  />
</Figure>

### Learn more in our blog post

To learn more, make sure to read our focused blog post on
[introducing fairer billing with first day free](/blog/introducing-fairer-billing-with-first-day-free).

## Minor improvements

Here’s a list of other improvements in [our changelog](/changelog) this month:

- `@liveblocks/client` methods which return threads and their associated inbox
  notifications now also return the thread’s associated subscriptions.
- Add support for `textMentions` in room subscription settings.
- Add `closeAi` Tiptap command to manually close the AI toolbar.
- Expose new property `triggeredAt` for notification webhook events.
- The `prepareThreadNotificationEmailAsHtml` and
  `prepareThreadNotificationEmailAsReact` functions now avoid duplicated
  comments between two emails data.
- Improve event propagation from `Composer` and the emoji pickers in
  `Comment`/`Thread`.
- The `InboxNotification` component now uses `resolveRoomsInfo` for
  `textMention` notifications to make them link to the mentions’ room
  automatically if `href` isn’t set.
- Add `emojibaseUrl` **advanced** option on `LiveblocksUIConfig` to allow
  choosing where Emojibase’s data used by the Liveblocks emoji picker is fetched
  from: another CDN, self-hosted files, etc.
- Fix: Occasional Yjs and Text Editor desync issue.
- Fix: Crash when unmounting BlockNote.
- Fix: `withLiveblocksEditorOptions` not passing all options to BlockNote.
- Fix: Names capitalization in lists. (e.g. the list of who reacted in
  reactions’ tooltips)
- Fix: `AiToolbar` focus behavior in Safari.
- Fix: `FloatingToolbar` focus behavior in Safari.
- Fix: Potential runtime error in browsers that do not support `Symbol.dispose`
  yet.
- Fix: Bug in `.mutateStorage()` and `.massMutateStorage()` where mutating
  storage could potentially corrupt the storage tree.
- Fix: Update dependencies resolution.
- Fix: Avoid `<AnchoredThreads />` threads rendering if the editor's view is
  `null`.

### Upgrade

To use these latest features, update your packages with:

```bash
npx create-liveblocks-app@latest --upgrade
```

## Contributors

<Contributors
  gitHubUsernames={[
    "marcbouchenoire",
    "flowflorent",
    "sugardarius",
    "nperez0111",
    "chadnorvell",
    "nvie",
    "ctnicholas",
    "pierrelevaillant",
    "jrowny",
  ]}
/>