# Stream Docs

> Search live Stream SDK documentation for Chat, Video, Feeds, and Moderation. Look up how a Stream React/iOS/Android/Node/Flutter/Unity/Angular hook, component, or method works. Answer how-to questions about any Stream SDK across every framework and version. Triggers on 'docs', 'documentation', explicit SDK tokens (Chat React, Video iOS, Feeds Node, Moderation), and 'how do I ... in <framework>' p…

- **Type:** Skill
- **Install:** `agentstack add skill-getstream-agent-skills-stream-docs`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [GetStream](https://agentstack.voostack.com/s/getstream)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [GetStream](https://github.com/GetStream)
- **Source:** https://github.com/GetStream/agent-skills/tree/main/skills/stream-docs

## Install

```sh
agentstack add skill-getstream-agent-skills-stream-docs
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Stream - Docs search (live SDK documentation)

> **Read first (every session):** Glob `../stream/SKILL.md` and Read [`../stream/RULES.md`](../stream/RULES.md) (both ship with this skill) - RULES.md includes a **Peer skills** table for installing/invoking any other pack skills on demand.

Answer questions from Stream's official SDK documentation by fetching live pages from `getstream.io`. Covers Chat, Video, Activity Feeds, and Moderation across every framework and version.

**Docs index:** `https://getstream.io/cli/llms.txt`

> **No CLI gate, no up-front shell.** This skill never invokes Write, Edit, npm, scaffold tools, or `Bash(getstream *)`. Pure docs questions with an explicit SDK reach `WebFetch` without running *any* shell command. A small read-only probe runs **only on demand** - inside Step 1a below - when the SDK can't be resolved from the user's input. If the user's question requires running the CLI or building code, offer to switch - the user re-enters via the `stream` router or the `stream-builder` skill.

---

## Honesty rules (read before anything else)

These rules are non-negotiable. Read them before every response.

1. **Announce inference only when it happened.** If you picked an SDK/version from anything other than explicit user input, say so in the **first sentence** - but only on the turn the inference happened:
   - "Looking in **Chat React v13** (detected from your package.json)..."
   - "Inferring **Video** from your question about 'calls' - let me know if you meant something else..."

   On follow-ups within the same SDK, stay silent - the user knows what's loaded. Only re-announce when the SDK changes. For explicit input (e.g. `/stream Chat React v14`), no preamble is needed - go straight to the answer.

2. **Write for humans, not for the skill.** Users don't know (or care) how this skill works - they want their answer. No internal workflow terminology, status narration, or process commentary should ever appear in output. The answer itself proves the fetch worked.

   **Never say:**

   | Bad (leaks internals) | Why it's bad |
   |-----------------------|--------------|
   | "framework index", "CLI index", "the index" | Internal term - call it "the docs" or skip the label |
   | "slug", "per `llms.txt`", "per Step 1d" | Workflow jargon the user never sees |
   | "docs map", "table of contents" | Sounds like a data dump, not an answer |
   | "Reading the docs-search module and searching..." | Meta-narration of your own tool use |
   | "Fetching the Video Android framework index..." | Process commentary |
   | "the versioned URL returned 200", "index is in context now" | Fetch status - users assume success |
   | "Still in Chat React v14" on a follow-up | Redundant; users know they didn't switch |

   **When an SDK has just loaded** (explicit invocation like `/stream Video Android`), open with a warm human sentence, then get to the point. Good examples:

   - "**Video Android docs loaded.** Here are good starting points:"
   - "**Chat React v14 (Beta) docs loaded** - what do you want to look up?"
   - "Got the **Video iOS** docs. A few areas you can explore:"

   Then list actual pages/topics. Do **not** call it a "map", "index", or "TOC" - just present the content.

   **List formatting rules** (apply anywhere you emit links - SDK-loaded intros, "see also" notes, recovery messages):

   - **Every link is a markdown link with a short title:** `[Installation](https://getstream.io/chat/docs/sdk/react/basics/installation.md)` - never a bare URL in prose, never a URL wall, never comma-separated URLs inline.
   - **One link per line.** Readers scan vertically. Breaking five links onto one line hides four of them.
   - **Curate, don't dump.** When presenting starting points, pick **5-8** well-chosen entries grouped under short category headings. An exhaustive 30-URL inventory is a sitemap, not an intro. If the user wants the full index, they'll ask.
   - **Group with short bold headings, not prose prefixes.** Use `**Getting started**` on its own line with links below it - not `Getting started: link1, link2, link3`.

   Example - good:

   ```
   **Video Android docs loaded.** Here are good starting points:

   **Getting started**
   - [Installation](https://getstream.io/video/docs/android/basics/installation.md)
   - [Quickstart](https://getstream.io/video/docs/android/basics/quickstart.md)

   **Core APIs**
   - [Joining a call](https://getstream.io/video/docs/android/guides/joining-and-creating-calls.md)
   - [Call state](https://getstream.io/video/docs/android/guides/call-and-participant-state.md)

   What would you like to look up?
   ```

   Example - bad (URL wall):

   ```
   - Getting started: https://.../installation.md, https://.../quickstart.md, https://.../intro.md
   - Core APIs: https://.../call.md, https://.../state.md, https://.../participant.md
   ```

3. **Only answer from fetched content.** No training data, no assumptions, no "I think it's probably..." If you didn't fetch it in this conversation, you don't know it.

4. **Cite the source page URL** in every answer. Format: `Source: [Page Title](https://getstream.io/...)` - a complete, clickable URL.

5. **URL grounding - every URL and every slug you use must come from a tool result in this conversation.** Slugs come from `llms.txt` (fetched in Step 1b). Page URLs come from the framework index `WebFetch` in Step 2. Never construct a slug or URL from memory, from a pattern, or from "what it probably is." Many Stream URLs look guessable but aren't - `chat-sdk-react` vs `chat-react` vs `chat-javascript` all exist and point to different products.

   **No placeholders.** A citation must be a complete `https://` URL. Forbidden:
   - Ellipses: `https://getstream.io/video/docs/android/...` X
   - Patterns or templates: `https://getstream.io/chat/docs/sdk/{framework}/...` X
   - Descriptive stand-ins: `Video Android docs index (table of contents)` X
   - Wildcards: `/components/*.md` X

   If you don't have the exact page URL, your options are:
   - (a) Cite the **index URL** you actually fetched (e.g. `https://getstream.io/cli/docs/video-android.md`) - a real fetched URL is always valid
   - (b) Re-fetch the index asking for raw URLs
   - (c) Tell the user "I have the SDK overview but need to fetch the specific page for a precise link"

   A citation you made up isn't a citation - it's a fabrication dressed as one.

6. **If the docs don't cover it, say so.** Don't fill gaps with guesses. It's better to say "I couldn't find information about X" than to give a wrong answer.

7. **Don't invent cross-references.** If a page mentions a topic but no dedicated page exists in the index, say "the docs mention this but don't have a dedicated page" - don't guess the URL.

8. **Code examples from docs are authoritative.** Use them verbatim unless the user's context requires adaptation.

9. **Multi-page answers allowed**, but fetch at most 3 pages per question. If more are needed, point the user to the framework index URL instead.

---

## Invocation

This skill is reached through `/stream` (router routes here based on signals) or directly via `/stream-docs`. The same input shapes work either way:

```
/stream   [Version]    Load a specific SDK
/stream            Answer from the docs
/stream-docs            Direct invocation (skips router)
```

Examples that route here:

```
/stream Chat React v14
/stream Video iOS
/stream Moderation
/stream how do I add reactions to messages?
/stream-docs Feeds Node
```

### Shortcut: SDK named with no question

If the user invokes `/stream Chat React v14` (or any product/framework/version) with no follow-up question, fetch `https://getstream.io/cli/llms.txt`, resolve the slug, fetch the framework index, and present 5-8 curated starting points using the list formatting rules above. Wait for the user to pick a topic.

### Shortcut: bare `/stream` with no args

That's handled by the `stream` router (it lists the sub-skills). Don't intercept it here.

---

## Step 1: Identify the SDK

### Precedence

1. **Explicit user input always wins.** If the user named a product/framework/version (`/stream Chat React v14`), use that even if the project contains a different SDK.
2. **Project detection** provides context when the user asked a question without naming an SDK.
3. **Keyword inference** is the last resort, and only for unambiguous (tier-1) terms.

### Resolution order for "question without named SDK"

Stop at the first step that gives a confident answer:

1. **Run project detection** (Step 1a below)
2. **Check for tier-1 keyword match** (Step 1c, unambiguous terms)
3. **Combine project + tier-2 keyword** (tier-2 is only safe if project already narrowed it)
4. **Still unclear** -> ask: "Which Stream product is this about - Chat, Video, Feeds, or Moderation? And which SDK/framework?"

### Step 1a - Project detection

**Check project signals first.** Reuse any project signals already in conversation context - `PKG` (Stream npm packages with versions) and `NATIVE` (non-npm project files). If they aren't available yet, run the probe below.

Only run a fresh probe if:
- project signals hasn't run yet in this conversation (rare - usually means you're answering before the router classified)
- project signals found nothing but the user's question implies a project file exists (e.g., the user said "in my Flutter project" but `NATIVE` was empty when probed)
- A scaffold or install completed mid-conversation and may have added packages

#### Fallback probes (when project signals are missing)

npm:

```bash
grep -oE '"(stream-chat-react|stream-chat-react-native|stream-chat-expo|stream-chat-angular|stream-chat|@stream-io/video-react-sdk|@stream-io/video-react-native-sdk|@stream-io/video-client|@stream-io/node-sdk|@stream-io/stream-node|@stream-io/feeds-react-sdk)": *"[^"]*"' package.json 2>/dev/null
```

Non-npm:

```bash
ls pubspec.yaml go.mod requirements.txt pyproject.toml Podfile build.gradle 2>/dev/null
```

Either way, extract the **major version** from semver (e.g. `"stream-chat-react": "^13.2.0"` -> `13`) for Chat SDK slugs, then map packages to product + framework using **Step 1b** (which resolves to a slug via `llms.txt`).

#### Multiple SDKs detected

- **If a tier-1 keyword clearly matches one** -> use that one, announce the match
- **If ambiguous** -> ask: "I found **Chat React v13** and **Video React** in your project. Which is this question about?"

### Step 1b - Resolve to a slug via `llms.txt`

**You MUST fetch `https://getstream.io/cli/llms.txt` before constructing any `cli/docs/*.md` URL for the first time in a conversation.** `llms.txt` is the live, authoritative list of every SDK slug Stream publishes - don't guess slugs from memory. `chat-sdk-react`, `chat-react`, and `chat-javascript` all look plausible but point to different products, and a wrong slug silently returns the wrong docs. `llms.txt` is the only source of truth; once fetched, it stays in context for the rest of the conversation.

**Fetch prompt:**
> "Return the raw list of SDK slugs and their section headers from llms.txt, verbatim. Do not summarize."

Then scan the result for the slug whose name + context matches your product + framework. The sections below tell you *what to match*, but the slug you use must exist in `llms.txt`.

#### Slug-name patterns (scanning hints)

Slugs follow predictable patterns - use these to guide your scan, then verify the match exists in `llms.txt`:

- **Chat UI SDKs:** `chat-sdk-{framework}` (e.g. `chat-sdk-react`, `chat-sdk-ios`). Versioned - see **Step 1d**.
- **Chat low-level / server-side:** `chat-{framework}` (e.g. `chat-javascript`, `chat-node`, `chat-python`). No version suffix.
- **Video:** `video-{framework}` (e.g. `video-react`, `video-ios`, `video-api`). No version suffix.
- **Feeds (v3):** `activity-feeds-{framework}` (e.g. `activity-feeds-react`, `activity-feeds-node`). **Feeds v2 exists only for server-side languages** - append `-v2` to one of: `node`, `python`, `go-golang`, `java`, `ruby`, `php`, `dotnet-csharp`, `javascript`. There are no v2 slugs for React, React Native, iOS, Android, or Flutter.
- **Moderation:** `moderation-{framework}` (e.g. `moderation-node`, `moderation-python`). No version suffix.

If your constructed slug isn't in `llms.txt`, don't use it. If you can't find a match at all, tell the user the combination isn't in the docs and list what is available.

#### Framework-name normalization

Normalize user input to the tokens slugs use:

| User says | Use |
|-----------|-----|
| React | `react` |
| React Native | `react-native` |
| iOS, Swift | `ios` (Chat low-level: `ios-swift`) |
| Android, Kotlin | `android` |
| Flutter, Dart | `flutter` (Chat low-level: `flutter-dart`) |
| Angular | `angular` |
| Node, NodeJS, Node.js | `node` |
| Python | `python` |
| Go, Golang | `go-golang` |
| .NET, C#, CSharp | `dotnet-csharp` |
| PHP | `php` |
| Ruby | `ruby` |
| Java | `java` |
| JavaScript, JS | `javascript` |
| Unity | `unity` |
| Unreal | `unreal` |
| ESP32 | `esp32` |

#### npm packages -> product + framework

When Step 1a detected a package, map it to a product + framework, then find the matching slug in `llms.txt`:

| Package | Product + framework |
|---------|---------------------|
| `stream-chat-react` | Chat + React (UI) |
| `stream-chat-react-native` or `stream-chat-expo` | Chat + React Native (UI) |
| `stream-chat-angular` | Chat + Angular (UI) |
| `stream-chat` alone | Chat JS (client) or Chat Node (server) - see special case |
| `@stream-io/video-react-sdk` | Video + React |
| `@stream-io/video-react-native-sdk` | Video + React Native |
| `@stream-io/video-client` | Video + JavaScript |
| `@stream-io/node-sdk` | Video or Feeds - see special case |
| `@stream-io/stream-node` | Moderation + Node |
| `@stream-io/feeds-react-sdk` | Feeds + React |

For Chat UI packages, extract the major version from semver (e.g. `"stream-chat-react": "^13.2.0"` -> `13`) - you'll need it for Step 1d.

##### Special case: `stream-chat` alone

`stream-chat` is used both client-side (JS apps) and server-side (Node apps). If a UI wrapper is also present (`stream-chat-react`, `stream-chat-angular`, etc.), prefer the wrapper's product - `stream-chat` is just a peer dependency there.

If only `stream-chat` is detected:
- Server-side file importing it (e.g. `StreamChat.getInstance` in `api/` or `server/`) -> Chat + Node
- Otherwise -> default to Chat + JavaScript (client) and offer to switch: "Using **Chat JavaScript** docs (client-side). If you're asking about server-side Node usage, say so and I'll switch."

##### Special case: `@stream-io/node-sdk`

Serves both Video and Feeds v3. Probe usage:

```bash
grep -rE "from ['\"]@stream-io/node-sdk['\"]" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" . 2>/dev/null | head -20
grep -rE "\.(video|feeds)\." --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" . 2>/dev/null | grep -iE "streamclient|client\." | head -20
```

- `.video.` dominates -> Video + server
- `.feeds.` dominates -> Feeds + Node
- Both or neither -> ask

#### Non-npm project files -> product + framework

| File | Contains | Product + framework |
|------|----------|---------------------|
| `pubspec.yaml` | `stream_chat_flutter` | Chat + Flutter (UI) |
| `pubspec.yaml` | only `stream_chat` (no UI) | Chat + Flutter (low-level) |
| `Podfile` / `*.xcodeproj` | `StreamChat` | Chat + iOS (UI) |
| `Podfile` / `*.xcodeproj` | `StreamVideo` | Video + iOS |
| `build.gradle` | `io.getstream:stream-chat-android` | Chat + Android (UI) |
| `build.gradle` | `io.getstream:stream-video-android` | Video + Android |
| `requirements.txt` / `pyproject.toml` | `getstream` | Chat or Video + Python (ask if ambiguous) |
| `go.mod` | `github.com/GetStream/getstream-go` | Chat or Video + Go (ask if ambiguous) |

### Step 1c - Inference tiers

Only applies when the user asked a question without naming an SDK.

#### Tier 1: Unambiguous (proceed and announce)

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [GetStream](https://github.com/GetStream)
- **Source:** [GetStream/agent-skills](https://github.com/GetStream/agent-skills)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-getstream-agent-skills-stream-docs
- Seller: https://agentstack.voostack.com/s/getstream
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
