cometchat-features
Companion skills:
cometchat-corecovers initialization and the provider pattern;cometchat-customizationis the next step when a feature is enabled but needs visual customization;cometchat-troubleshootinghandles post-feature-enable failures.
Purpose
This skill teaches Claude how CometChat features are structured and what work is actually required to enable each one. Most features require zero code — they are either already built into the UI Kit, enabled via a dashboard toggle, or activated by a single npm install. Understanding which type a feature is prevents unnecessary work.
1. Use this skill when
The user wants to add a specific feature to an already-integrated CometChat project. Trigger phrases:
/cometchat features/cometchat features <name>(e.g./cometchat features reactions)/cometchat <feature>(e.g./cometchat polls,/cometchat calls)- "add reactions to my chat"
- "add video calling"
- "enable polls"
- "add file sharing"
- "enable smart replies"
- "add typing indicators"
2. Preconditions
The user must have an existing integration:
npx @cometchat/skills-cli info --json
If integrated is false, stop and tell the user to run /cometchat
first to create the integration.
3. Why features fall into each type
CometChat features split into 4 types based on their architecture:
-
Type 1 — Default (compiled-in): These are shipped inside the UI Kit component bundle unconditionally. CometChat builds reactions, typing indicators, mentions, etc. into
CometChatMessageListandCometChatMessageComposerat compile time. The feature is always present; the only question is whether the prop that surfaces it is enabled. No code or dashboard changes needed. -
Type 2 — Dashboard-toggle (backend extensions): These are backend services hosted by CometChat's infrastructure. The UI Kit polls which extensions are enabled via the app's init response. When you flip the dashboard toggle, the backend returns a different feature flag, and the UI Kit renders the corresponding UI automatically. No client code change is needed — the rendering logic is already in the UI Kit, just gated on the flag.
-
Type 3 — Package-install (separate SDK): Voice/video calling requires a separate WebRTC SDK (
@cometchat/calls-sdk-javascript) because it links against browser media APIs that would bloat every integration if bundled unconditionally. Once installed, the UI Kit detects it via dynamic import and enables the call UI. -
Type 4 — Component-swap (variant component): Some features require a different component variant because the base component has a hard-coded behavior that can't be toggled via props. The CLI does a safe word-boundary replace of the component name in your owned files. If CometChat adds new variant components in future SDK releases, they will follow this same pattern.
4. The feature catalog
Type 1 — Default features (~14, already enabled in UI Kit)
These are already part of the components your integration uses. The skill's job is to tell the user they're already there and point at the relevant component:
- Instant Messaging
- Media Sharing (file/image/audio/video)
- Read Receipts
- Mark as Unread
- Typing Indicator
- User Presence (online/offline)
- Reactions
- Mentions (incl. @all)
- Threaded Conversations
- Quoted Replies
- Group Chat
- Report Message
- Conversation/Advanced Search
For these: query the docs MCP for the feature's component/usage docs, show the user where it is in their integration. No code changes needed.
Type 2 — Dashboard-toggle features (~40+, no code needed)
These require flipping a toggle in the CometChat Dashboard. Once enabled, the UI Kit auto-integrates them. No code changes needed.
Note: The dashboard features page also shows the Type 1 features (Instant Messaging, Reactions, Mentions, etc.) as always-on toggles at the top. Those are already enabled — no action needed. The features below are the ones that actually require toggling on.
Note: Conversation and Advanced Search has its own toggle on the Features page. It is on by default but can be disabled. If a user reports that search is missing, check this toggle.
Extensions — User Experience: Avatar, Bitly, Link Preview, Message Shortcuts, Pin Message, Rich Media Preview, Save Message, Thumbnail Generation, TinyURL, Voice Transcription
Extensions — User Engagement: Broadcast, Giphy, Gfycat, Message Translation, Polls, Reminders, Stickers, Stipop, Tenor
Extensions — Collaboration: Collaborative Document, Collaborative Whiteboard
Extensions — Security: Disappearing Messages, E2E Encryption (Enterprise plan only)
Extensions — Moderation (on the separate Extensions page, not Features): Data Masking, Image Moderation, Profanity Filter, Sentiment Analysis, XSS Filter, Human Moderation, Report User, Slow Mode, Virus/Malware Scanner
Extensions — Notifications (on the separate Extensions page): Email Notification, Push Notification, SMS Notification
Extensions — Customer Support: Chatwoot, Intercom
Smart Chat Features (AI): Conversation Starter, Smart Replies, Conversation Summary (AI features are fetched dynamically from the API — the exact list depends on your plan and backend configuration.)
Exact dashboard path (give this to the user verbatim):
For most features (User Experience, User Engagement, Collaboration, Security, AI):
- Open https://app.cometchat.com
- Select your app
- In the left sidebar: Chat & Messaging → Features
- Find the feature and flip its Status toggle to ON
- Some extensions have a settings icon — click it if the feature needs configuration (e.g. API keys for Giphy)
- Changes take effect immediately — refresh the chat in the browser
For Moderation and Notification extensions: These are NOT on the Features page. Navigate to: Left sidebar → Extensions (the separate Extensions page) Find the extension and enable it there.
After enabling, run cometchat verify to ensure the existing
integration still passes. No code changes are needed — the UI Kit
picks up enabled features automatically.
Type 3 — Package-install features (4, calls)
These require installing @cometchat/calls-sdk-javascript. Once installed,
the UI Kit auto-detects it and surfaces the call UI in CometChatMessageHeader,
CometChatConversations, etc.
- Call Buttons (in message headers)
- Incoming Call notifications
- Outgoing Call interface
- Call Logs (call history)
For these, the user opting in IS consent — run the install directly:
npm install @cometchat/calls-sdk-javascript
npx @cometchat/skills-cli verify --json
The UI Kit's initiateAfterLogin() auto-calls enableCalling() after the
package is installed. No manual wiring needed for default call buttons in
CometChatMessageHeader. Restart the dev server.
Type 4 — Component-swap features (drop-in variant)
Some features require swapping one component for a variant that has
different default behavior. The CLI handles the swap automatically —
it walks state.files_owned, performs a word-boundary regex replace,
updates state.json checksums, and records the applied feature so
re-runs are no-ops. Idempotent.
Currently available:
rich-text-formatting— swapsCometChatMessageComposer→CometChatCompactMessageComposer(the compact variant enables rich text formatting by default; the regular composer hasenableRichTextEditor=falsebaked in)
npx @cometchat/skills-cli apply-feature rich-text-formatting
Do NOT hand-edit the swap. The CLI is the source of truth. If future
SDK releases add new variant components, they will follow this same
apply-feature <id> pattern.
4b. Deep patterns for three most-requested features
For calls, AI smart replies, and presence, the catalog above only says "install a package" or "toggle in dashboard." Here are the concrete compositional patterns so common requests don't require a docs MCP round-trip.
Calls (audio + video)
After npm install @cometchat/calls-sdk-javascript, call buttons auto-appear in CometChatMessageHeader and the call UI renders in place. No manual wiring needed for basic 1:1 audio/video calls.
For custom integration — e.g. putting a "Start video call" button outside the message header, or handling an incoming call notification in a custom way — use CometChatCallButtons + CometChatIncomingCall + CometChatOngoingCall:
import { useState, useEffect } from "react";
import {
CometChatCallButtons,
CometChatIncomingCall,
CometChatOngoingCall,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
export function CustomCallUI({ targetUser }: { targetUser: CometChat.User }) {
const [ongoingCall, setOngoingCall] = useState<CometChat.Call>();
useEffect(() => {
// Listen for call state changes
const listenerId = "custom-call-listener";
CometChat.addCallListener(
listenerId,
new CometChat.CallListener({
onOutgoingCallAccepted: (call: CometChat.Call) => setOngoingCall(call),
onIncomingCallCancelled: () => setOngoingCall(undefined),
onCallEnded: () => setOngoingCall(undefined),
}),
);
return () => CometChat.removeCallListener(listenerId);
}, []);
return (
<>
<CometChatCallButtons user={targetUser} />
<CometChatIncomingCall />
{ongoingCall && <CometChatOngoingCall call={ongoingCall} />}
</>
);
}
Common gotchas:
- Calls require a logged-in CometChat user on both sides. Test from two browsers (or incognito) logged in as different UIDs.
CometChatIncomingCallmust be mounted globally (e.g. in your provider or layout) so incoming calls ring on every page.- Group calls use
CometChat.Groupinstead ofCometChat.UseronCometChatCallButtons.
AI smart replies
Smart replies is a dashboard-toggle feature (Type 2). After enabling it in the dashboard (Extensions → Smart Replies → Toggle on), no code changes are required — the CometChatMessageComposer automatically renders suggested replies as chips above the input when there's a recent incoming message.
For a custom UI — e.g. showing smart replies inline instead of above the composer, or only for certain conversation types — you read the extension data from the incoming message and render your own chips:
function SmartReplyChips({ message }: { message: CometChat.BaseMessage }) {
const metadata = message.getMetadata() as Record<string, unknown> | undefined;
const extensions = (metadata?.["@injected"] as Record<string, unknown>)?.["extensions"] as
| Record<string, unknown>
| undefined;
const smartReply = extensions?.["smart-reply"] as { reply_positive?: string; reply_neutral?: string; reply_negative?: string } | undefined;
if (!smartReply) return null;
const replies = [smartReply.reply_positive, smartReply.reply_neutral, smartReply.reply_negative].filter(Boolean) as string[];
return (
<div style={{ display: "flex", gap: 8, padding: 8 }}>
{replies.map((r) => (
<button key={r} onClick={() => sendTextMessage(r)}>{r}</button>
))}
</div>
);
}
Smart replies are server-generated and attached to messages via the @injected.extensions.smart-reply metadata path — the AI feature runs on CometChat's backend, not in your code.
Presence (online / offline status)
Presence is a default feature (Type 1) — online status indicators appear automatically on user avatars in CometChatConversations, CometChatUsers, and CometChatGroupMembers. Nothing to install, nothing to enable.
For custom UI that needs to know a specific user's online state — e.g. a "Sold by Aria Chen · online now" label on a product page — subscribe to user events:
import { useEffect, useState } from "react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
export function useUserPresence(uid: string): "online" | "offline" | "unknown" {
const [status, setStatus] = useState<"online" | "offline" | "unknown">("unknown");
useEffect(() => {
// 1. Fetch initial state
CometChat.getUser(uid).then((u) => {
setStatus(u.getStatus() === "online" ? "online" : "offline");
});
// 2. Subscribe to live changes
const listenerId = `presence-${uid}`;
CometChat.addUserListener(
listenerId,
new CometChat.UserListener({
onUserOnline: (user: CometChat.User) => {
if (user.getUid() === uid) setStatus("online");
},
onUserOffline: (user: CometChat.User) => {
if (user.getUid() === uid) setStatus("offline");
},
}),
);
return () => CometChat.removeUserListener(listenerId);
}, [uid]);
return status;
}
Common gotchas:
- Presence events only fire for users the current user has interacted with (conversation exists, in same group, etc.). For arbitrary UIDs with no prior interaction, you may need to call
CometChat.getUser(uid)periodically instead. getStatus()returns"online"or"offline"— also checkgetLastActiveAt()for a "last seen X ago" timestamp.- "Last seen" is disabled by default on free-tier apps. Enable it in the dashboard (Settings → Chat → Last Seen).
5. Docs MCP contract
The CometChat docs MCP at cometchat-docs is a hard requirement for
this skill. It's the canonical source for:
- Per-feature SDK reference (props, callbacks, builders, events)
- Per-feature configuration details beyond the dashboard path above
- Feature compatibility notes (which features need backend setup,
which auto-wire, which require explicit
setExtensions([...]))
Hard rules:
- Always query the docs MCP first before answering any feature
question that's not in our local catalog (
cometchat features info). - If the docs MCP is not installed, STOP. Tell the user:
"I need the CometChat docs MCP to walk you through this feature.
Install it with
claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcpand re-run." - Use the dashboard path from this skill (Chat & Messaging → Features) for all toggle features. Query the docs MCP for per-feature configuration details beyond the basic toggle.
- Canonical reference URLs (use as starting points if the agent doesn't have an MCP query handy):
6. Steps
Step 1 — Read state
npx @cometchat/skills-cli info --json
If not integrated, stop. Otherwise note the framework + experience so you can find the right files.
Step 2 — Determine feature
If the user named a feature, use it. Otherwise list the categories above and ask which feature they want.
Step 3 — Classify the feature
Match the feature name against the 4 types in section 4. If you don't know the type, query the docs MCP first.
Step 4 — Execute the right sub-flow
-
Default: show the user it's already there. Point at the component. Use
npx @cometchat/skills-cli features info <id>to surface the walkthrough verbatim.- CRITICAL — if the user explicitly wants a UI element to surface
the default feature (e.g. "implement conversation search",
"add a search bar", "show typing indicators in the header",
"expose mentions in the composer"), do NOT add a new component
yet. Most default features are exposed via PROPS on the
components your integration already mounts:
- "search bar" →
showSearchBaronCometChatConversations(andonSearchBarClickedto swap in<CometChatSearch>for advanced dual-scope search if the user wants that) - "filter conversations / messages" →
conversationsRequestBuilder/messagesRequestBuilder - "custom empty / error / loading state" →
emptyStateView,errorStateView,loadingStateView - "custom message bubble" →
templatesprop onCometChatMessageList(NOT a custom bubble component) - "hide / disable a sub-feature" →
disable*boolean props - "click handler" →
onItemClick,onMessageClick,onSearchBarClicked,onBack - "custom subtitle / status / timestamp" →
subtitleView,statusView,timestampViewProcess before any code change:
- Read the files in
.cometchat/state.jsonfiles_ownedand grep for the<CometChat[A-Z]JSX components actually in use:grep -hoE '<CometChat[A-Z][a-zA-Z]*' \ $(jq -r '.files_owned[]' .cometchat/state.json 2>/dev/null) \ 2>/dev/null | sort -u - Query the docs MCP for
"<ComponentName> props"for each one. - If a prop matches the user's intent, add the prop and stop. No new components, no custom CSS, no new files.
- Only if no prop matches, route to the
cometchat-customizationskill for the full four-tier discovery.
- "search bar" →
- CRITICAL — if the user explicitly wants a UI element to surface
the default feature (e.g. "implement conversation search",
"add a search bar", "show typing indicators in the header",
"expose mentions in the composer"), do NOT add a new component
yet. Most default features are exposed via PROPS on the
components your integration already mounts:
-
Dashboard-toggle: prefer the CLI — it flips the toggle via the same API the dashboard UI uses, so the user doesn't leave the terminal:
npx @cometchat/skills-cli features enable <id> --json # to turn it off: npx @cometchat/skills-cli features disable <id> --jsonThe CLI reads the app id from
.cometchat/config.jsonand the bearer token from the OS keychain (requires a priorcometchat auth login). Response shape:"status": "enabled"/"disabled"→ done. Tell the user to hard-refresh (Cmd+Shift+R) the browser tab running their dev server."status": "no-op"→ already in the desired state."status": "not-logged-in"→ runcometchat auth loginfirst."status": "no-app"→ run/cometchatorcometchat provision setupfirst so.cometchat/config.jsonhas the app id."status": "error"→ surfacenext_stepsverbatim. Includes the dashboard URL as a manual fallback.
Only fall back to the dashboard walkthrough (app.cometchat.com → Chat & Messaging → Features → flip Status toggle) if the CLI returns
erroror isn't available. Runcometchat features info <id>for per-feature configuration details (Giphy API keys, translation languages, etc.) beyond the basic toggle.Note: if the feature has
auto_wired_in_uikit: falsein the catalog (most non-default extensions), the toggle alone isn't enough — you also need to register the extension viaUIKitSettingsBuilder.setExtensions([...])beforeinit. The CLI's success output flags this; query the docs MCP for the exact builder syntax. -
Package-install (calls): run
npm install @cometchat/calls-sdk-javascriptdirectly. The user opted in, that IS consent. -
Component-swap: run
npx @cometchat/skills-cli apply-feature <id>. The CLI handles the swap deterministically. Do NOT hand-edit.
Step 5 — Verify
npx @cometchat/skills-cli verify --json
Surface any failed checks verbatim. If anything looks off after enabling
a feature (drift, unexpected build error, env warning), run
cometchat doctor for combined drift + env + AST diagnostics with
per-issue fix instructions, or route to the cometchat-troubleshooting
skill for deeper triage.
Hard rules
- Never modify a project without an existing CometChat integration.
- Always query the docs MCP for SDK reference (do not invent function names).
- For component-swap features, always use
cometchat apply-feature <id>— the CLI is the source of truth, never hand-edit. - For package-install features (calls), the user opting in IS consent —
run
npm install <package>directly. - For dashboard-toggle features, walk the user through the dashboard
activation steps from
cometchat features info <id>— the dashboard flip is something only the human can do. - For dashboard-toggle features, always give the canonical path: app.cometchat.com → select app → Chat & Messaging → Features → toggle ON. Query the docs MCP for per-feature config details (e.g. Giphy API key, Translation language settings).
- Always use
npx @cometchat/skills-cli.