Ably is a hosted realtime messaging service: clients publish and subscribe to named channels over WebSockets, see who is present, replay message history, and resume after a dropped connection.

Apache-2.0Auto-check passedBackend & APIs

Install Ably

skills CLI
$ npx skills add TerminalSkills/skills --skill ably -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install TerminalSkills/skills ably --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/TerminalSkills/skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/ably .claude/skills/ably && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
ably
GitHub stars
163
Token cost
~3.1k tokens
SKILL.md length
835 words
Files
2
Skills in repo
10
Repo updated
First seen
Licence
Apache-2.0

At a glance

Ably is a hosted realtime messaging service: clients publish and subscribe to named channels over WebSockets, see who is present, replay message history, and resume after a dropped connection.

  • A user asks to add realtime updates
  • SKILL.md covers Overview, Instructions, Examples and Guidelines
  • Calls npm; needs ABLY_API_KEY
  • Push live notifications to the browser

What it does

Ably is an agent skill from TerminalSkills/skills. Ably is a hosted realtime messaging service: clients publish and subscribe to named channels over WebSockets, see who is present, replay message history, and resume after a dropped connection. Use when a user asks to "add realtime updates", "push live notifications to the browser", "show who is online", "add a chat room with typing indicators", "publish from a serverless function", or "authenticate Ably clients without exposing the API key". Covers the ably 2.x JavaScript SDK (Realtime and REST), JWT token…

Its SKILL.md is about 3.1k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file (for example `_scores.json`). Compatibility notes: Requires an Ably account and API key. ably 2.x runs in browsers and Node.js 16+; @ably/chat 1.x needs Node.js 20+ and ably ^2.19.

It sits in Backend & APIs, covering Authentication, Realtime and WebSockets and Serverless. It works with JavaScript. The repository describes itself as: Open-source library of AI agent skills — SKILL.md files for Claude Code, Codex, Gemini CLI, Cursor. The licence is Apache-2.0.

When your agent uses it

  • A user asks to add realtime updates
  • Push live notifications to the browser
  • Show who is online
  • Add a chat room with typing indicators

Example prompts

  • “add realtime updates”
  • “push live notifications to the browser”
  • “show who is online”
  • “/ably”

Requirements

  • Node.js
  • A credential in ABLY_API_KEY
  • Compatibility (from SKILL.md): Requires an Ably account and API key. ably 2.x runs in browsers and Node.js 16+; @ably/chat 1.x needs Node.js 20+ and ably ^2.19.

What it can do on your machine

Read from SKILL.md and the folder at commit a021875. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • ABLY_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

  • Compatibility

    Requires an Ably account and API key. ably 2.x runs in browsers and Node.js 16+; @ably/chat 1.x needs Node.js 20+ and ably ^2.19.

    From compatibility in the SKILL.md frontmatter.

Context cost

Ably loads about 3.1k tokens when it runs. Until then it costs about 152 tokens; SKILL.md has 835 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~152
When it runs · the whole SKILL.md, loaded when a task matches
~3.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from TerminalSkills/skills at commit a021875, republished under its Apache-2.0 licence (© TerminalSkills). 835 words, ~3,148 tokens.

Download SKILL.mdSave it as .claude/skills/ably/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
ably
description
Ably is a hosted realtime messaging service: clients publish and subscribe to named channels over WebSockets, see who is present, replay message history, and resume after a dropped connection. Use when a user asks to "add realtime updates", "push live notifications to the browser", "show who is online", "add a chat room with typing indicators", "publish from a serverless function", or "authenticate Ably clients without exposing the API key". Covers the ably 2.x JavaScript SDK (Realtime and REST), JWT token authentication, presence, history and rewind, batch publishing, and the @ably/chat 1.x SDK.
compatibility
Requires an Ably account and API key. ably 2.x runs in browsers and Node.js 16+; @ably/chat 1.x needs Node.js 20+ and ably ^2.19.
license
Apache-2.0
metadata.author
terminal-skills
metadata.version
1.1.0
metadata.category
development
metadata.tags
realtime, pubsub, websocket, messaging, presence

Ably — Realtime Infrastructure as a Service

Overview

Ably is a managed pub/sub platform. An application publishes messages to named channels and every subscribed client receives them over a WebSocket connection that the SDK keeps alive and resumes after a short network drop. On top of plain messaging it provides presence (who is on a channel), message history, token authentication with per-channel permissions, and a separate Chat SDK with rooms, typing indicators and reactions.

Two clients exist in the ably package: Ably.Realtime holds a connection and can subscribe; Ably.Rest is stateless HTTP and is the right choice for servers and serverless functions that only publish or issue tokens.

Instructions

Install
bash
npm install ably
npm install @ably/chat        # Chat SDK, optional; built on top of ably
npm install jsonwebtoken      # server side, to sign tokens for browser clients

Create an app in the Ably dashboard and copy an API key. A key looks like I2E_JQ.OqUdfg:EVKVT...: the part before the colon is the key name, the part after it is the secret. Keep it in ABLY_API_KEY on the server only.

Authenticate clients with a JWT

Browsers and mobile apps must never receive the API key. The server signs a short-lived JWT with the key secret; the SDK fetches it through authUrl (or authCallback) and renews it before it expires.

typescript
// server/ably-token.ts
import jwt from "jsonwebtoken";

const [keyName, keySecret] = process.env.ABLY_API_KEY!.split(":");

export function createAblyToken(userId: string): string {
  return jwt.sign(
    {
      "x-ably-clientId": userId,
      // capability is a JSON string: resource -> allowed operations
      "x-ably-capability": JSON.stringify({
        "orders:*": ["subscribe", "history"],
        [`notifications:${userId}`]: ["subscribe"],
        "support:*": ["publish", "subscribe", "presence", "history", "message-update-own"],
      }),
    },
    keySecret,
    { algorithm: "HS256", keyid: keyName, expiresIn: "1h" },   // 24 hours is the maximum
  );
}

Return that string as the plain-text body of an authenticated endpoint such as GET /api/ably-token. ably.auth.createTokenRequest({ clientId, capability }) on an Ably.Rest client is the older alternative; it still works, but JWTs are the format Ably recommends.

Publish, subscribe and presence (Realtime)
typescript
// client/orders.ts
import * as Ably from "ably";

const realtime = new Ably.Realtime({ authUrl: "/api/ably-token" });
await realtime.connection.once("connected");

const channel = realtime.channels.get("orders:store-17");

// subscribe() attaches the channel; filter by event name or receive everything
await channel.subscribe("status-update", (message) => {
  console.log(message.name, message.data, message.clientId, message.timestamp);
});

// Publishing needs the publish capability; the token above grants it on support:* only
const lobby = realtime.channels.get("support:lobby");
await lobby.publish("question", { text: "Is anyone from billing online?" });

// Presence needs an identified client (clientId comes from the token)
await lobby.presence.subscribe((member) => {
  console.log(member.action, member.clientId, member.data);   // enter | leave | update | present
});
await lobby.presence.enter({ name: "Dana Whitfield", status: "available" });
await lobby.presence.update({ name: "Dana Whitfield", status: "busy" });
const members = await lobby.presence.get();
console.log("Online:", members.map((m) => m.clientId));

realtime.close();   // release the connection when the page or process is done
History and rewind

Messages are kept for two minutes by default, enough for the SDK to resume a dropped connection. Longer retention is switched on with a channel rule in the app settings: a match expression such as orders:* with "Persist all messages" enabled (24 hours on the free plan, 72 hours on paid plans).

typescript
// client/history.ts
import * as Ably from "ably";

const realtime = new Ably.Realtime({ authUrl: "/api/ably-token" });

// Option 1, rewind: attach and immediately receive the last 10 messages, then live ones
const feed = realtime.channels.get("orders:store-17", { params: { rewind: "10" } });
await feed.subscribe((message) => console.log(message.data));

// Option 2, history: page backwards from the point of attachment, with no gap.
// Pick one: the first history page repeats the messages rewind already delivered.
const page = await feed.history({ untilAttach: true, limit: 50 });
for (const message of page.items) console.log(message.timestamp, message.data);
if (page.hasNext()) {
  const older = await page.next();
  console.log(older?.items.length);
}
Publish from a server (REST)
typescript
// server/notify.ts
import * as Ably from "ably";

const rest = new Ably.Rest({ key: process.env.ABLY_API_KEY });

// No connection is opened: one HTTP request per publish
await rest.channels.get("notifications:usr_8f3a21").publish("alert", {
  title: "Payment received",
  amount: 150.0,
});

// One request, many channels
const result = await rest.batchPublish({
  channels: ["notifications:usr_8f3a21", "notifications:usr_c04d77"],
  messages: [{ name: "alert", data: { title: "Scheduled maintenance at 02:00 UTC" } }],
});
console.log(result.successCount, result.failureCount);
Chat SDK

A room wraps a channel and adds messages, typing, reactions, presence and occupancy. rooms.get() is asynchronous, and nothing arrives until the room is attached. The underlying client must have a clientId.

typescript
// client/support-chat.ts
import * as Ably from "ably";
import { ChatClient } from "@ably/chat";

const realtime = new Ably.Realtime({ authUrl: "/api/ably-token" });
const chat = new ChatClient(realtime);

const room = await chat.rooms.get("support:ticket-4812");

const { unsubscribe, historyBeforeSubscribe } = room.messages.subscribe((event) => {
  console.log(`${event.message.clientId}: ${event.message.text}`);
});
room.typing.subscribe((event) => {
  console.log("Typing:", event.currentTypers.map((t) => t.clientId).join(", "));
});
room.reactions.subscribe((event) => {
  console.log(`${event.reaction.clientId} reacted with ${event.reaction.name}`);
});

await room.attach();

const earlier = await historyBeforeSubscribe({ limit: 20 });
console.log(earlier.items.map((m) => m.text));

await room.typing.keystroke();                    // call on each keypress; the SDK throttles it
const sent = await room.messages.send({ text: "How can I help you?" });
await room.typing.stop();
await room.messages.update(sent.serial, sent.copy({ text: "How can I help you today?" }));
await room.reactions.send({ name: "like" });

unsubscribe();
await chat.rooms.release("support:ticket-4812");   // detach and free the room

Examples

Example 1: Live order status in the browser without exposing the API key

User request: "Our dashboard should update the moment an order ships. The backend is a Next.js app; don't put the Ably key in the client."

typescript
// app/api/ably-token/route.ts
import { createAblyToken } from "../../../server/ably-token";
import { getSessionUser } from "../../../server/session";

export async function GET(request: Request) {
  const user = await getSessionUser(request);
  if (!user) return new Response("Unauthorized", { status: 401 });
  return new Response(createAblyToken(user.id), { headers: { "Content-Type": "text/plain" } });
}
typescript
// server/ship-order.ts
import * as Ably from "ably";

const rest = new Ably.Rest({ key: process.env.ABLY_API_KEY });

export async function markShipped(storeId: string, orderId: string) {
  await rest.channels.get(`orders:${storeId}`).publish("status-update", { orderId, status: "shipped" });
}

The browser runs the client/orders.ts code above with authUrl: "/api/ably-token". When markShipped("store-17", "ORD-789") runs, every open dashboard receives a status-update message whose data is { orderId: "ORD-789", status: "shipped" }. A client holding this token cannot publish to orders:*; an attempt is rejected with error code 40160 (capability denied).

Example 2: Migrate chat code written for a pre-1.0 @ably/chat

User request: "After updating @ably/chat the build fails: RoomOptionsDefaults is not exported and room.messages is undefined."

typescript
// Before (0.x)
const room = chatClient.rooms.get("support-room", RoomOptionsDefaults);
await room.typing.start();
await room.reactions.send({ type: "like" });

// After (1.x)
const room = await chatClient.rooms.get("support-room");   // returns a Promise; no options needed to enable features
await room.attach();
await room.typing.keystroke();
await room.reactions.send({ name: "like" });

Listeners change shape too: reactions arrive as event.reaction.name, and typing events carry event.currentTypers, an array of { clientId } objects (event.currentlyTyping is deprecated since 1.2). After the change tsc passes and messages sent with room.messages.send({ text }) are delivered to every attached client.

Show full SKILL.md (360 more words)Show less

Guidelines

  • Never ship the API key to a browser or mobile app. Use authUrl or authCallback with a server-issued token, scope x-ably-capability to the channels and operations that user needs, and set x-ably-clientId on the server so users cannot impersonate each other.
  • One Realtime client per page or process. Each instance opens its own connection and counts against the connection limit. In Next.js, create it inside useEffect and pass it to AblyProvider from ably/react, so that server rendering does not open connections that never close.
  • Servers publish with Ably.Rest. It is stateless HTTP; serverless platforms (Lambda, Cloud Functions, Workers) are not built for the persistent connection a Realtime client holds.
  • History is short unless you enable persistence. Two minutes by default; persisted messages count again toward the message quota when stored and when retrieved. Chat rooms persist for 30 days by default.
  • Presence requires clientId and the presence capability to enter; the subscribe capability is enough to watch the presence set.
  • Namespace channels (orders:, notifications:, support:). Channel rules and capabilities both match colon-delimited segments with * wildcards, so the prefix is what lets you grant orders:* or persist only support:*. A trailing * needs at least one segment: orders:* does not match a channel named orders.
  • Ordering and retries. Subscribers connected to one region see a single order; when publishers are in different regions, two near-simultaneous messages can reach subscribers in different regions in a different order, while history returns one canonical order. The SDK assigns message ids so its own REST retries are not duplicated (idempotentRestPublishing, on by default); set id yourself when your code may publish the same event twice.
  • ably.request() takes a protocol version as its third argument in v2 (request(method, path, version, params, body, headers)); prefer the typed methods such as batchPublish().
  • Cost and limits. Billing counts messages, connection minutes and channel minutes, and each plan has rate limits. One publish received by 10 subscribers counts as 11 messages. Check the account limits before a launch.
  • When not to use it. For a single server with a few hundred clients and no delivery guarantees needed, Server-Sent Events or a plain WebSocket is simpler and has no per-message cost.

© TerminalSkills, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in skills/ably of TerminalSkills/skills.

  • SKILL.md
  • _scores.json

Open the folder on GitHubat commit a021875

Compare with similar skills

Ably next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Ably compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Ably this skillTerminalSkills/skills163—~3.1kAutomated safety check: PassApache-2.0
Gemini Live API Devgoogle-gemini/gemini-skills4.3k—~4.6kAutomated safety check: PassApache-2.0
Gemini Live API DevJetBrains/skills366—~2.6kAutomated safety check: PassNone
Supabase Development and Debuggingsupabase/agent-skills2.7k3 repos~3.6kAutomated safety check: PassMIT
Qstash JSupstash/qstash-js269—~746Automated safety check: PassMIT
Sasjs Adaptersasjs/core132—~2.6kAutomated safety check: PassMIT

Similar skills

  • Gemini Live API Dev

    google-gemini/gemini-skills

    Official

    A skill your agent uses when building real-time, bidirectional streaming applications with the Gemini Live API, or migrating legacy Live models (2.0/2.5/3.1) to Gemini 3.8 Live.

    4.3k GitHub stars~4.6k tokensUpdated 3 days ago
    Backend & APIsAuto-check passed
  • Gemini Live API Dev

    JetBrains/skills

    Official

    A skill your agent uses when building real-time, bidirectional streaming applications with the Gemini Live API.

    366 GitHub stars~2.6k tokensUpdated 3 mo ago
    Backend & APIsAuto-check passed
  • Official

    General Supabase skill for database, auth, Edge Functions, Realtime and storage work, plus client libraries, migrations, security audits, debugging and reading logs.

    2.7k GitHub starsUsed in 3 repos~3.6k tokens
    Backend & APIsAuto-check passed
  • Qstash JS

    upstash/qstash-js

    Official

    Work with the QStash JavaScript/TypeScript SDK for serverless messaging, scheduling.

    269 GitHub stars~746 tokensUpdated 3 days ago
    Backend & APIsAuto-check passed
  • Sasjs Adapter

    sasjs/core

    Frontend/Node integration with SAS backends using @sasjs/adapter - configuring the SASjs class, the exact request() inputs and response shape, authentication, file upload, and session management.

    132 GitHub stars~2.6k tokensUpdated 4 days ago
    Backend & APIsAuto-check passed
  • Cb Realtime API

    BlkLeg/CircuitBreaker

    How Circuit Breaker moves data between backend and frontend — the NATS internal bus, Redis pub/sub, the WebSocket stream endpoints and their first-message JWT handshake, SSE log/event streams, and…

    201 GitHub stars~1.7k tokensUpdated 4 days ago
    Backend & APIsAuto-check passed

More from TerminalSkills/skills

All 10 skills in this repo
  • Blender Addon Dev

    TerminalSkills/skills

    Build custom Blender add-ons with Python. An agent skill from TerminalSkills/skills.

    163 GitHub stars~2k tokensUpdated 5 days ago
    Auto-check passed
  • Seog

    TerminalSkills/skills

    Run local SEO from your terminal via the SEOG MCP server — Google Business Profile management, map-pack rank tracking and geo-grid scans, review sync and replies published to Google, competitor…

    163 GitHub stars~3.4k tokensUpdated 5 days ago
    Auto-check passed
  • Stripe Connect

    TerminalSkills/skills

    Build marketplace and platform payment flows with Stripe Connect.

    163 GitHub stars~2.9k tokensUpdated 5 days ago
    Auto-check passed
  • 3dsmax Rendering

    TerminalSkills/skills

    Scripts and configures production rendering in Autodesk 3ds Max with the V-Ray and Corona renderers: output size and files, render elements, denoising, light mix, batch and command-line rendering…

    163 GitHub stars~3.8k tokensUpdated 5 days ago
    Auto-check passed
  • 3dsmax Scripting

    TerminalSkills/skills

    Covers scripting Autodesk 3ds Max, the 3D modeling and rendering application, with MAXScript and Python (pymxs): scene manipulation, object creation, material assignment, camera and light setup…

    163 GitHub stars~3.2k tokensUpdated 5 days ago
    Auto-check passed
  • 3proxy

    TerminalSkills/skills

    3proxy is a small open-source proxy server that runs HTTP/HTTPS, SOCKS4/5, SNI and TCP/UDP port-mapping proxies from one config file.

    163 GitHub stars~3.5k tokensUpdated 5 days ago
    Auto-check: notes

Works with

Categories

Questions about Ably

What does Ably do?

Ably is a hosted realtime messaging service: clients publish and subscribe to named channels over WebSockets, see who is present, replay message history, and resume after a dropped connection. Ably is an agent skill from TerminalSkills/skills. Ably is a hosted realtime messaging service: clients publish and subscribe to named channels over WebSockets, see who is present, replay message history, and resume after a dropped connection.

When should I use Ably?

Ably fits situations like: A user asks to add realtime updates; push live notifications to the browser; show who is online; add a chat room with typing indicators.

How do I install Ably in Claude Code?

Run `npx skills add TerminalSkills/skills --skill ably -a claude-code`. Or copy the skill folder (skills/ably in TerminalSkills/skills) into .claude/skills/ably in your project. Claude Code loads it when a task matches its description.

How do I install Ably in Codex?

Run `npx skills add TerminalSkills/skills --skill ably -a codex`. Or copy the skill folder (skills/ably in TerminalSkills/skills) into .agents/skills/ably in your project. Codex loads it when a task matches its description.

Can I use Ably in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add TerminalSkills/skills --skill ably -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ably, .gemini/skills/ably, .github/skills/ably and .opencode/skills/ably in your project.

What does Ably need to run?

Going by SKILL.md and its folder, Ably needs the command-line tools its instructions call (npm) and credentials named ABLY_API_KEY. Our summary lists: Node.js; A credential in ABLY_API_KEY. Compatibility (from SKILL.md): Requires an Ably account and API key. ably 2.x runs in browsers and Node.js 16+; @ably/chat 1.x needs Node.js 20+ and ably ^2.19..

Does Ably access the network?

SKILL.md contains no URLs. Its commands use npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Ably safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Ably use?

Ably is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Ably use?

About 3.1k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Ably?

Skills that share tags, products or a category with Ably: Gemini Live API Dev (google-gemini/gemini-skills, 4.3k stars), Gemini Live API Dev (JetBrains/skills, 366 stars), Supabase Development and Debugging (supabase/agent-skills, 2.7k stars) and Qstash JS (upstash/qstash-js, 269 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Ably?

TerminalSkills (a GitHub organization) maintains it in TerminalSkills/skills, which has 163 GitHub stars. The repository holds 10 skills in this directory. The repository was last updated on October 3, 2026.

Source: TerminalSkills/skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.