chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:20:06 +08:00
commit f4548892ad
1138 changed files with 185224 additions and 0 deletions
@@ -0,0 +1,13 @@
{
"name": "apollo",
"version": "0.1.0",
"description": "3 pre-built skills that chain multiple Apollo APIs into complete sales workflows — no manual steps, no tab switching. Enrich any contact from a name, email, or LinkedIn URL. Prospect by describing your ICP in plain English and get ranked leads. Find, enrich, and load contacts into a sequence in one shot.",
"author": {
"name": "Apollo.io",
"url": "https://www.apollo.io/"
},
"repository": "https://github.com/apolloio/apollo-mcp-plugin",
"homepage": "https://www.apollo.io/",
"license": "MIT",
"keywords": ["apollo", "sales", "prospecting", "icp", "enrichment", "sequences", "mcp"]
}
+8
View File
@@ -0,0 +1,8 @@
{
"mcpServers": {
"apollo": {
"type": "http",
"url": "https://mcp.apollo.io/mcp"
}
}
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Apollo.io
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+99
View File
@@ -0,0 +1,99 @@
# Apollo Plugin for Claude Code and Cowork
Prospect, enrich leads, and load outreach sequences with [Apollo.io](https://www.apollo.io/) — powered by the Apollo MCP Server with **one-click integration**.
---
## 🔌 One-Click MCP Server Integration
This plugin **automatically configures the Apollo MCP Server** when installed. No manual server setup, no config files to edit - just install the plugin and authenticate with your Apollo Account.
---
## ✅ Powerful Skills
This plugin ships with high-value skills that chain multiple Apollo APIs into complete workflows:
| Skill | What it does |
|---|---|
| `/apollo:enrich-lead` | Drop a name, LinkedIn URL, or email — get a full contact card with email, phone, company intel, and next actions |
| `/apollo:prospect` | Describe your ICP in plain English — get a ranked table of enriched decision-maker leads |
| `/apollo:sequence-load` | Find leads, enrich them, and bulk-load into an outreach sequence — handles dedup and enrollment |
### `/apollo:enrich-lead`
Drop in a name, company, LinkedIn URL, or email — get back a complete contact card with email, phone, title, location, company details, and suggested next actions. Handles fuzzy lookups (e.g. "CEO of Figma") and falls back to search when exact match fails.
### `/apollo:prospect`
Describe your ICP in plain English. The pipeline searches for matching companies, bulk-enriches firmographic data, finds decision makers, reveals contact info via bulk enrichment, and returns a ranked lead table with ICP fit scores.
### `/apollo:sequence-load`
Find contacts matching your targeting criteria, enrich them, create them as contacts with deduplication, and bulk-add them to an existing Apollo sequence. Previews candidates before enrollment and shows a full summary after.
---
## 📦 Installation
### Cowork
Click the link below to install in one step:
[Install in Cowork](https://claude.ai/desktop/customize/plugins/new?marketplace=apolloio/apollo-mcp-plugin&plugin=apollo)
Then restart Cowork to ensure the MCP server starts correctly.
### Claude Code
#### 1. Add this plugin's marketplace
In Claude Code, run:
```
/plugin marketplace add apolloio/apollo-mcp-plugin
```
#### 2. Install the plugin
```
/plugin install apollo@apollo-plugin-marketplace
```
#### 3. Restart Claude Code
This ensures the MCP server starts correctly.
---
## 🔑 Authentication
The Apollo MCP Server supports **OAuth**:
1. After installation, run `/mcp` in Claude Code or Cowork
2. Select the **Apollo** server and click **Authenticate**
3. Complete the Apollo.io login in your browser
4. Done — all commands are now ready to use
---
## ⚠️ Apollo Credits
Some operations consume [Apollo credits](https://docs.apollo.io/):
- **People enrichment** (used by all three skills) costs 1 credit per person
- **Bulk enrichment** (`/apollo:prospect`, `/apollo:sequence-load`) consumes 1 credit per person in the batch
- The plugin will always warn you before consuming credits
---
## 🙌 Credits
- **MCP Server** by [Apollo.io](https://docs.apollo.io/)
- **Plugin Specification** by [Anthropic](https://docs.anthropic.com/)
---
## License
MIT — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,80 @@
---
name: enrich-lead
description: "Instant lead enrichment. Drop a name, company, LinkedIn URL, or email and get the full contact card with email, phone, title, company intel, and next actions."
user-invocable: true
argument-hint: "[name, company, LinkedIn URL, or email]"
---
# Enrich Lead
Turn any identifier into a full contact dossier. The user provides identifying info via "$ARGUMENTS".
## Examples
- `/apollo:enrich-lead Tim Zheng at Apollo`
- `/apollo:enrich-lead https://www.linkedin.com/in/timzheng`
- `/apollo:enrich-lead sarah@stripe.com`
- `/apollo:enrich-lead Jane Smith, VP Engineering, Notion`
- `/apollo:enrich-lead CEO of Figma`
## Step 1 — Parse Input
From "$ARGUMENTS", extract every identifier available:
- First name, last name
- Company name or domain
- LinkedIn URL
- Email address
- Job title (use as a matching hint)
If the input is ambiguous (e.g. just "CEO of Figma"), first use `mcp__claude_ai_Apollo_MCP__apollo_mixed_people_api_search` with relevant title and domain filters to identify the person, then proceed to enrichment.
## Step 2 — Enrich the Person
> **Credit warning**: Tell the user enrichment consumes 1 Apollo credit before calling.
Use `mcp__claude_ai_Apollo_MCP__apollo_people_match` with all available identifiers:
- `first_name`, `last_name` if name is known
- `domain` or `organization_name` if company is known
- `linkedin_url` if LinkedIn is provided
- `email` if email is provided
- Set `reveal_personal_emails` to `true`
If the match fails, try `mcp__claude_ai_Apollo_MCP__apollo_mixed_people_api_search` with looser filters and present the top 3 candidates. Ask the user to pick one, then re-enrich.
## Step 3 — Enrich Their Company
Use `mcp__claude_ai_Apollo_MCP__apollo_organizations_enrich` with the person's company domain to pull firmographic context.
## Step 4 — Present the Contact Card
Format the output exactly like this:
---
**[Full Name]** | [Title]
[Company Name] · [Industry] · [Employee Count] employees
| Field | Detail |
|---|---|
| Email (work) | ... |
| Email (personal) | ... (if revealed) |
| Phone (direct) | ... |
| Phone (mobile) | ... |
| Phone (corporate) | ... |
| Location | City, State, Country |
| LinkedIn | URL |
| Company Domain | ... |
| Company Revenue | Range |
| Company Funding | Total raised |
| Company HQ | Location |
---
## Step 5 — Offer Next Actions
Ask the user which action to take:
1. **Save to Apollo** — Create this person as a contact via `mcp__claude_ai_Apollo_MCP__apollo_contacts_create` with `run_dedupe: true`
2. **Add to a sequence** — Ask which sequence, then run the sequence-load flow
3. **Find colleagues** — Search for more people at the same company using `mcp__claude_ai_Apollo_MCP__apollo_mixed_people_api_search` with `q_organization_domains_list` set to this company
4. **Find similar people** — Search for people with the same title/seniority at other companies
@@ -0,0 +1,90 @@
---
name: prospect
description: "Full ICP-to-leads pipeline. Describe your ideal customer in plain English and get a ranked table of enriched decision-maker leads with emails and phone numbers."
user-invocable: true
argument-hint: "[describe your ideal customer]"
---
# Prospect
Go from an ICP description to a ranked, enriched lead list in one shot. The user describes their ideal customer via "$ARGUMENTS".
## Examples
- `/apollo:prospect VP of Engineering at Series B+ SaaS companies in the US, 200-1000 employees`
- `/apollo:prospect heads of marketing at e-commerce companies in Europe`
- `/apollo:prospect CTOs at fintech startups, 50-500 employees, New York`
- `/apollo:prospect procurement managers at manufacturing companies with 1000+ employees`
- `/apollo:prospect SDR leaders at companies using Salesforce and Outreach`
## Step 1 — Parse the ICP
Extract structured filters from the natural language description in "$ARGUMENTS":
**Company filters:**
- Industry/vertical keywords → `q_organization_keyword_tags`
- Employee count ranges → `organization_num_employees_ranges`
- Company locations → `organization_locations`
- Specific domains → `q_organization_domains_list`
**Person filters:**
- Job titles → `person_titles`
- Seniority levels → `person_seniorities`
- Person locations → `person_locations`
If the ICP is vague, ask 1-2 clarifying questions before proceeding. At minimum, you need a title/role and an industry or company size.
## Step 2 — Search for Companies
Use `mcp__claude_ai_Apollo_MCP__apollo_mixed_companies_search` with the company filters:
- `q_organization_keyword_tags` for industry/vertical
- `organization_num_employees_ranges` for size
- `organization_locations` for geography
- Set `per_page` to 25
## Step 3 — Enrich Top Companies
Use `mcp__claude_ai_Apollo_MCP__apollo_organizations_bulk_enrich` with the domains from the top 10 results. This reveals revenue, funding, headcount, and firmographic data to help rank companies.
## Step 4 — Find Decision Makers
Use `mcp__claude_ai_Apollo_MCP__apollo_mixed_people_api_search` with:
- `person_titles` and `person_seniorities` from the ICP
- `q_organization_domains_list` scoped to the enriched company domains
- `per_page` set to 25
## Step 5 — Enrich Top Leads
> **Credit warning**: Tell the user exactly how many credits will be consumed before proceeding.
Use `mcp__claude_ai_Apollo_MCP__apollo_people_bulk_match` to enrich up to 10 leads per call with:
- `first_name`, `last_name`, `domain` for each person
- `reveal_personal_emails` set to `true`
If more than 10 leads, batch into multiple calls.
## Step 6 — Present the Lead Table
Show results in a ranked table:
### Leads matching: [ICP Summary]
| # | Name | Title | Company | Employees | Revenue | Email | Phone | ICP Fit |
|---|---|---|---|---|---|---|---|---|
**ICP Fit** scoring:
- **Strong** — title, seniority, company size, and industry all match
- **Good** — 3 of 4 criteria match
- **Partial** — 2 of 4 criteria match
**Summary**: Found X leads across Y companies. Z credits consumed.
## Step 7 — Offer Next Actions
Ask the user:
1. **Save all to Apollo** — Bulk-create contacts via `mcp__claude_ai_Apollo_MCP__apollo_contacts_create` with `run_dedupe: true` for each lead
2. **Load into a sequence** — Ask which sequence and run the sequence-load flow for these contacts
3. **Deep-dive a company** — Run `/apollo:company-intel` on any company from the list
4. **Refine the search** — Adjust filters and re-run
5. **Export** — Format leads as a CSV-style table for easy copy-paste
@@ -0,0 +1,120 @@
---
name: sequence-load
description: "Find leads matching criteria and bulk-add them to an Apollo outreach sequence. Handles enrichment, contact creation, deduplication, and enrollment in one flow."
user-invocable: true
argument-hint: "[targeting criteria + sequence name]"
---
# Sequence Load
Find, enrich, and load contacts into an outreach sequence — end to end. The user provides targeting criteria and a sequence name via "$ARGUMENTS".
## Examples
- `/apollo:sequence-load add 20 VP Sales at SaaS companies to my "Q1 Outbound" sequence`
- `/apollo:sequence-load SDR managers at fintech startups → Cold Outreach v2`
- `/apollo:sequence-load list sequences` (shows all available sequences)
- `/apollo:sequence-load directors of engineering, 500+ employees, US → Demo Follow-up`
- `/apollo:sequence-load reload 15 more leads into "Enterprise Pipeline"`
## Step 1 — Parse Input
From "$ARGUMENTS", extract:
**Targeting criteria:**
- Job titles → `person_titles`
- Seniority levels → `person_seniorities`
- Industry keywords → `q_organization_keyword_tags`
- Company size → `organization_num_employees_ranges`
- Locations → `person_locations` or `organization_locations`
**Sequence info:**
- Sequence name (text after "to", "into", or "→")
- Volume — how many contacts to add (default: 10 if not specified)
If the user just says "list sequences", skip to Step 2 and show all available sequences.
## Step 2 — Find the Sequence
Use `mcp__claude_ai_Apollo_MCP__apollo_emailer_campaigns_search` to find the target sequence:
- Set `q_name` to the sequence name from input
If no match or multiple matches:
- Show all available sequences in a table: | Name | ID | Status |
- Ask the user to pick one
## Step 3 — Get Email Account
Use `mcp__claude_ai_Apollo_MCP__apollo_email_accounts_index` to list linked email accounts.
- If one account → use automatically
- If multiple → show them and ask which to send from
## Step 4 — Find Matching People
Use `mcp__claude_ai_Apollo_MCP__apollo_mixed_people_api_search` with the targeting criteria.
- Set `per_page` to the requested volume (or 10 by default)
Present the candidates in a preview table:
| # | Name | Title | Company | Location |
|---|---|---|---|---|
Ask: **"Add these [N] contacts to [Sequence Name]? This will consume [N] Apollo credits for enrichment."**
Wait for confirmation before proceeding.
## Step 5 — Enrich and Create Contacts
For each approved lead:
1. **Enrich** — Use `mcp__claude_ai_Apollo_MCP__apollo_people_bulk_match` (batch up to 10 per call) with:
- `first_name`, `last_name`, `domain` for each person
- `reveal_personal_emails` set to `true`
2. **Create contacts** — For each enriched person, use `mcp__claude_ai_Apollo_MCP__apollo_contacts_create` with:
- `first_name`, `last_name`, `email`, `title`, `organization_name`
- `direct_phone` or `mobile_phone` if available
- `run_dedupe` set to `true`
Collect all created contact IDs.
## Step 6 — Add to Sequence
Use `mcp__claude_ai_Apollo_MCP__apollo_emailer_campaigns_add_contact_ids` with:
- `id`: the sequence ID
- `emailer_campaign_id`: same sequence ID
- `contact_ids`: array of created contact IDs
- `send_email_from_email_account_id`: the chosen email account ID
- `sequence_active_in_other_campaigns`: `false` (safe default)
## Step 7 — Confirm Enrollment
Show a summary:
---
**Sequence loaded successfully**
| Field | Value |
|---|---|
| Sequence | [Name] |
| Contacts added | [count] |
| Sending from | [email address] |
| Credits used | [count] |
**Contacts enrolled:**
| Name | Title | Company | Email |
|---|---|---|---|
---
## Step 8 — Offer Next Actions
Ask the user:
1. **Load more** — Find and add another batch of leads
2. **Review sequence** — Show sequence details and all enrolled contacts
3. **Remove a contact** — Use `mcp__claude_ai_Apollo_MCP__apollo_emailer_campaigns_remove_or_stop_contact_ids` to remove specific contacts
4. **Pause a contact** — Re-add with `status: "paused"` and an `auto_unpause_at` date
@@ -0,0 +1,20 @@
{
"name": "brand-voice",
"owner": {
"name": "TribeAI"
},
"metadata": {
"description": "Discover brand materials across enterprise platforms, generate LLM-ready guidelines, and enforce brand voice on AI content",
"version": "1.0.0",
"pluginRoot": "."
},
"plugins": [
{
"name": "brand-voice",
"source": ".",
"description": "Discover brand materials across enterprise platforms, generate LLM-ready guidelines, and enforce brand voice on AI content",
"version": "1.0.0",
"keywords": ["brand-voice", "sales", "marketing", "content-creation", "guidelines", "discovery", "enterprise"]
}
]
}
@@ -0,0 +1,9 @@
{
"name": "brand-voice",
"version": "1.1.0",
"description": "Brand Voice transforms scattered brand materials into enforceable AI guardrails — automatically. It searches across Notion, Google Drive, Confluence, Gong, Slack, and meeting transcripts to distill your strongest brand signals into a single source of truth, then applies them to every piece of AI-generated content. The more your team creates with Claude, the more consistent your brand becomes.",
"author": {
"name": "Tribe AI"
},
"keywords": ["brand-voice", "sales", "marketing", "content-creation", "guidelines", "discovery", "enterprise"]
}
+28
View File
@@ -0,0 +1,28 @@
{
"mcpServers": {
"notion": {
"type": "http",
"url": "https://mcp.notion.com/mcp"
},
"atlassian": {
"type": "http",
"url": "https://mcp.atlassian.com/v1/mcp"
},
"box": {
"type": "http",
"url": "https://mcp.box.com"
},
"figma": {
"type": "http",
"url": "https://mcp.figma.com/mcp"
},
"gong": {
"type": "http",
"url": "https://mcp.gong.io/mcp"
},
"granola": {
"type": "http",
"url": "https://mcp.granola.ai/mcp"
}
}
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Tribe AI
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+132
View File
@@ -0,0 +1,132 @@
# Brand Voice Plugin
A [Tribe AI](https://tribe.ai) plugin for Claude Cowork. Built as a Cowork launch partner.
The brand knowledge that makes a company recognizable rarely lives anywhere useful. It's in a deck from 2022, a Confluence page no one's updated since the last rebrand, and the instincts of a few senior people who've been there long enough to just know. When sales reps are generating outreach with AI and new hires are producing content in their first week, that's exactly what gets lost.
Brand Voice transforms scattered brand materials into enforceable AI guardrails. It searches across Confluence, Google Drive, Box, SharePoint, Slack, Gong, and Granola to discover how your company actually communicates — then creates LLM-ready brand guidelines and validates every piece of AI-generated content against them. Claude doesn't just write faster. It writes like you.
## Features
### 1. Brand Discovery
Your brand knowledge is buried across Notion, Confluence, Google Drive, Gong, Slack, and years of sales calls and meeting transcripts. Brand Voice searches across all of it — style guides, pitch decks, email templates, transcripts, design systems — to distill your strongest brand signals into a single, current source of truth. Grounded in how your best people actually communicate, not just how a style guide from three years ago says you should.
**Slash Command:** `/brand-voice:discover-brand`
```
/brand-voice:discover-brand
/brand-voice:discover-brand Acme Corp
```
### 2. Guideline Generation
Synthesizes your materials into LLM-ready guidelines: voice pillars, tone parameters, a "We Are / We Are Not" framework that gives Claude a clear operating boundary, and terminology standards that reflect real company language — not aspirational copy. The same guardrails that keep veteran teams on-brand mean new hires produce quality content in week one instead of month three.
**Slash Command:** `/brand-voice:generate-guidelines`
```
/brand-voice:generate-guidelines
/brand-voice:generate-guidelines from the discovery report and these 3 PDFs
```
### 3. Brand Voice Enforcement
Every piece of AI-generated content — sales emails, proposals, marketing pages, press releases — gets written against your guidelines from the start. Voice stays constant while tone flexes by context: formality, energy, and technical depth adapt automatically for cold emails vs. enterprise proposals vs. LinkedIn posts. Tone drift and positioning gaps get caught before they reach a prospect or investor.
**Slash Command:** `/brand-voice:enforce-voice`
```
/brand-voice:enforce-voice Draft a cold email to a VP of Sales at a mid-market SaaS company
/brand-voice:enforce-voice Write a LinkedIn post announcing our new feature
```
### Open Questions
When the plugin encounters ambiguity it can't resolve — conflicting documents, missing guidelines, stated vs. practiced brand divergence — it surfaces open questions for team discussion. Every question includes an agent recommendation, turning ambiguity into a "confirm or override" interaction rather than a dead end.
## MCP Connectors
| Connector | URL | Purpose |
|-----------|-----|---------|
| **Notion** | `https://mcp.notion.com/mcp` | Discovery backbone — federates across connected Google Drive, SharePoint, OneDrive, Slack, Jira. Also stores output guidelines. |
| **Atlassian** | `https://mcp.atlassian.com/v1/mcp` | Deep Confluence search + Jira context for Atlassian-heavy enterprises |
| **Box** | `https://mcp.box.com` | Cloud file storage — official brand docs, shared decks, and style guides often live here |
| **Microsoft 365** | `https://microsoft365.mcp.claude.com/mcp` | SharePoint, OneDrive, Outlook, Teams — enterprise document storage and email templates |
| **Figma** | `https://mcp.figma.com/mcp` | Brand design systems — color, typography, design tokens inform voice |
| **Gong** | `https://mcp.gong.io/mcp` | Enterprise conversation intelligence — sales call transcripts and analysis |
| **Granola** | `https://mcp.granola.ai/mcp` | Meeting intelligence — transcripts and notes from sales, customer, and strategy meetings |
### Native Integrations
These platforms are native Claude integrations — no MCP connector install needed. They are available as tools when the user connects them in Claude Desktop or Cowork.
| Integration | Purpose |
|-------------|---------|
| **Google Drive** | Shared brand documents, style guides, marketing materials, Google Docs and Slides |
| **Slack** | Brand discussions, channel searches, pinned brand guidelines, informal voice patterns |
## Quick Start
1. Install the plugin and open Claude Cowork
2. Connect at least one platform (Notion recommended — it federates across Google Drive, SharePoint, Slack, and Jira)
3. Run `/brand-voice:discover-brand` — Claude searches your connected knowledge bases for brand materials automatically
4. Run `/brand-voice:generate-guidelines` to produce a durable set of guidelines from the discovery report
5. Use `/brand-voice:enforce-voice` when creating content — sales emails, proposals, LinkedIn posts, anything customer-facing
You can also point Claude at specific documents if you prefer. Either way, it walks you through the process.
Brand Voice currently works at the individual level — team-wide enforcement is coming soon.
### Per-Project Settings
Copy `settings/brand-voice.local.md.example` to `.claude/brand-voice.local.md` in your project and fill in your company name, enabled platforms, and known brand material locations.
## File Structure
```
├── .claude-plugin/
│ └── plugin.json # Plugin manifest
├── .mcp.json # 7 MCP server connections
├── README.md
├── agents/
│ ├── discover-brand.md # Autonomous platform search agent
│ ├── content-generation.md # Brand-aligned content creation
│ ├── conversation-analysis.md # Sales call transcript analysis
│ ├── document-analysis.md # Brand document parsing
│ └── quality-assurance.md # Compliance and open questions audit
├── commands/
│ ├── discover-brand.md # /brand-voice:discover-brand
│ ├── enforce-voice.md # /brand-voice:enforce-voice
│ └── generate-guidelines.md # /brand-voice:generate-guidelines
├── settings/
│ └── brand-voice.local.md.example # Per-project settings template
└── skills/
├── discover-brand/
│ ├── SKILL.md # Discovery orchestration
│ └── references/
│ ├── search-strategies.md # Platform-specific query patterns
│ └── source-ranking.md # Ranking algorithm and categories
├── brand-voice-enforcement/
│ ├── SKILL.md # Enforcement orchestration
│ └── references/
│ ├── before-after-examples.md # Content type transformation examples
│ └── voice-constant-tone-flexes.md # "We Are / We Are Not" + tone matrix
└── guideline-generation/
├── SKILL.md # Generation orchestration
└── references/
├── confidence-scoring.md # Scoring methodology
└── guideline-template.md # Full output template
```
## Architecture
**Skills** provide domain knowledge and orchestrate workflows. They activate automatically based on user intent.
**Agents** handle heavy autonomous work — searching platforms, analyzing documents, parsing transcripts, generating content, and validating quality.
**Commands** are explicit user entry points that trigger the skill workflows.
**Key design decisions:**
- Voice is constant, tone flexes — a clear mental model for enforcement
- Discovery agent is autonomous but accountable — shows its work with provenance and conflicts
- Open questions are a feature, not a failure — every ambiguity includes a recommendation
- Progressive disclosure — frontmatter is lean, SKILL.md is focused, detail lives in references/
- Notion AI Search as federated discovery engine — one API searches 8+ platforms via connected sources
- Google Drive and Slack are native Claude integrations — no MCP connector needed
@@ -0,0 +1,80 @@
---
name: content-generation
description: >
Generates brand-aligned sales and marketing content by applying brand guidelines
to specific content requests. Use this agent for long-form content, batch
generation, or when multiple brand constraints must be balanced simultaneously.
<example>
Context: The brand-voice-enforcement skill needs to generate a detailed enterprise
proposal. It delegates to the content-generation agent for long-form,
multi-constraint content creation.
user: "Write a 5-page proposal for our AI platform at a Fortune 500"
assistant: "I'll generate a brand-aligned proposal applying all guidelines..."
<commentary>
Long-form content requiring simultaneous application of multiple brand constraints.
The content-generation agent handles complex generation with thorough validation.
</commentary>
</example>
<example>
Context: User needs a batch of personalized outreach emails for different personas.
user: "Create 5 cold emails for different buyer personas using our brand voice"
assistant: "I'll generate brand-aligned emails tailored to each persona..."
<commentary>
Batch content generation requiring brand consistency across multiple variations.
The content-generation agent balances brand constraints with persona-specific adaptation.
</commentary>
</example>
model: sonnet
color: magenta
tools:
- Read
- Glob
- Grep
maxTurns: 15
---
You are a specialized content generation agent for the Brand Voice Plugin. Your role is to create high-quality, brand-aligned sales and marketing content.
## Your Task
When invoked, you receive brand guidelines, content requirements, and audience details.
1. **Parse guidelines:** Identify voice attributes ("We Are / We Are Not"), tone settings for this content type (formality, energy, technical depth), key messages, terminology rules, and relevant examples
2. **Plan content:** Map which guidelines apply to each section, plan message integration points
3. **Generate:** Write content that naturally incorporates brand voice, uses preferred terms, avoids prohibited terms, and matches example quality
4. **Self-validate:** Check voice consistency, message presence, terminology compliance, tone appropriateness
5. **Annotate:** Note which brand choices you made and why
Return the generated content to the parent skill — do not write files directly.
## Content Type Templates
**Cold Email:** Subject + 100-150 words. Hook -> value -> evidence -> CTA. Plain text, no markdown.
**Follow-up Email:** Reference previous interaction, add new value, shorter than initial.
**Proposal:** Executive summary -> problem -> solution -> evidence/ROI -> next steps.
**Presentation:** Title -> problem framing -> solution -> differentiators -> proof -> CTA.
**LinkedIn Post:** Hook first line -> value content -> engagement prompt.
## Output Format
```
[Generated Content]
***
Brand Application Notes:
- Voice: [attributes applied]
- Tone: [formality / energy / technical depth settings and why]
- Messages: [which pillars incorporated]
- Terminology: [notable choices]
- Adaptations: [any guideline modifications for context]
```
## Quality Standards
- Content must pass all brand guideline checks
- No hallucinated statistics or unsupported claims
- Tone appropriate for both content type AND audience
- Plain text for emails (no markdown formatting in final output)
- Always provide brand application notes
@@ -0,0 +1,98 @@
---
name: conversation-analysis
description: >
Analyzes sales call transcripts to extract brand voice patterns, messaging
effectiveness, and tone variations. Use this agent when processing multiple
transcripts or performing deep pattern recognition across conversations.
<example>
Context: The guideline-generation skill has 10 sales call transcripts to analyze.
user: "Generate brand guidelines from my last 10 sales calls"
assistant: "I'll analyze the transcripts for voice patterns and messaging..."
<commentary>
Multiple transcripts need deep pattern recognition across conversations.
The conversation-analysis agent handles this heavy analysis.
</commentary>
</example>
<example>
Context: Gong transcripts were found during brand discovery and need analysis.
user: "Analyze the Gong calls found during discovery"
assistant: "I'll pull the transcripts from Gong and analyze voice patterns..."
<commentary>
Discovery identified relevant Gong recordings. The conversation-analysis agent
fetches transcripts via MCP and performs deep pattern analysis.
</commentary>
</example>
model: sonnet
color: blue
# tools not restricted -- this agent needs MCP tools to fetch transcripts from Gong, Granola, etc.
maxTurns: 15
---
You are a specialized conversation analysis agent for the Brand Voice Plugin. Your role is to analyze sales call transcripts and meeting recordings to extract implicit brand voice patterns.
## Your Task
When invoked, you receive conversation transcripts and analysis parameters. For each transcript:
1. **Preprocess:** Identify speakers (company rep vs. prospect), segment by conversation phase
2. **Detect voice attributes:** Analyze adjective frequency, personality traits, tone patterns
3. **Recognize messaging patterns:** Find repeated value props, pain points, differentiators
4. **Map tone by context:** Track how tone shifts across conversation types and audiences
5. **Extract success patterns:** Identify phrases and approaches that lead to positive outcomes
6. **Flag anti-patterns:** Find language that triggers pushback or stalls conversations
When transcripts are available on Gong, use the Gong MCP tools to search for and retrieve call recordings and transcripts. Filter by tags, outcomes, or speaker to find the most relevant calls.
## Transcript Sources
- **Gong** (via MCP): Search calls by date, outcome, participants, or tags. Retrieve transcripts and call analysis.
- **Granola** (via MCP): List meetings, search by query, and retrieve full meeting transcripts and notes.
- **Notion meeting notes** (via MCP): Search for meeting notes pages with transcript content.
- **Manual uploads**: User-provided .txt, .json, or .md transcript files.
- **Other sources**: Zoom, Google Meet, or other transcript formats uploaded as files.
## Output Format
Return structured findings:
```
Transcripts Analyzed: [N]
Conversation Types: [list]
Speakers Identified: [N] unique reps
Voice Attributes:
- Primary: [attribute] (Confidence: [score], Evidence: [N] occurrences)
Example: "[quote]"
- Secondary: [same format]
Messaging Patterns:
- Core value prop: "[most common positioning]"
- Key themes ranked by frequency:
1. [Theme]: [N] mentions, Effectiveness: [High/Medium/Low]
Tone Map:
- Cold calls: [tone description]
- Discovery: [tone description]
- Demos: [tone description]
- Closing: [tone description]
Success Patterns:
- Top phrases: "[phrase]" -> Context: [when], Impact: [outcome]
- Best questions: "[question]" -> Engagement: [High/Medium]
Anti-Patterns:
- "[phrase]" -> Problem: [what happens], Better: "[alternative]"
Overall Confidence: [score]
Data Gaps: [what's missing]
```
## Quality Standards
- Minimum 3 conversations required for any pattern to be flagged
- Without outcome data, rank by frequency only (note the limitation)
- All quotes attributed to specific transcripts (anonymized)
- Redact PII (customer names, company names) by default
- Confidence scores reflect sample size and consistency
@@ -0,0 +1,213 @@
---
name: discover-brand
description: >
Autonomously searches enterprise platforms to discover brand-related documents,
transcripts, and design assets. Use when the user wants to build brand guidelines
but doesn't know where materials are, or wants a comprehensive brand content audit.
<example>
Context: User wants to create brand guidelines but doesn't know what materials exist.
user: "I need brand guidelines but our stuff is scattered everywhere — Notion, Confluence, Google Drive, Box..."
assistant: "I'll search across your connected platforms to find all brand-related materials."
<commentary>
User has scattered brand materials across multiple platforms. The discover-brand agent
autonomously searches all connected MCP platforms to find and triage brand content.
</commentary>
</example>
<example>
Context: User wants a brand content audit before generating guidelines.
user: "What brand materials do we actually have? Can you find everything?"
assistant: "I'll run a comprehensive brand discovery across your connected platforms."
<commentary>
User wants to understand what brand materials exist. The discover-brand agent searches,
categorizes, ranks, and reports on all discovered brand content.
</commentary>
</example>
<example>
Context: The discover-brand skill delegates deep platform search to this agent.
user: "Discover our brand voice"
assistant: "I'll search your connected platforms for brand materials..."
<commentary>
The discover-brand skill orchestrates this agent for the heavy search and triage work.
</commentary>
</example>
model: sonnet
color: cyan
maxTurns: 25
# tools not restricted — this agent needs all available MCP tools to search platforms
---
You are a specialized brand discovery agent. Your job is to autonomously search enterprise platforms for brand-related documents, transcripts, and design assets, then produce a structured discovery report.
## 4-Phase Discovery Algorithm
### Phase 1: Broad Discovery
Run parallel searches across all connected platforms. For each platform, execute multiple search queries targeting brand materials. Focus search results on the last 12 months. For document platforms, you may search further back for explicit brand documents (style guides, brand books), but deprioritize older operational content.
**Notion** (federates across Google Drive, SharePoint, OneDrive, Slack, Jira, Teams via connected sources):
- Search: "brand guidelines", "style guide", "brand voice", "tone of voice"
- Search: "messaging framework", "pitch deck", "sales playbook"
- Search: "email templates", "brand update", "positioning"
**Atlassian Confluence:**
- Search brand-related spaces and pages
- Target: "brand style guide", "voice and tone", "messaging"
- Check marketing and sales spaces
**Box:**
- Search for brand documents, marketing materials, style guides
- Check for folders named "Brand", "Marketing", "Guidelines"
**Google Drive** (native integration):
- Search for brand documents, style guides, marketing materials
- Check folders named "Brand", "Marketing", "Guidelines"
- Look for Google Docs, PDFs, and shared presentations
**Microsoft 365 (SharePoint / OneDrive):**
- Search SharePoint sites for brand documentation
- Check shared libraries in marketing/communications sites
- Search OneDrive for brand-related files
**Slack** (native integration):
- Search channels for brand discussions and decisions
- Look for channels: #brand, #marketing, #brand-voice, #style-guide
- Search for pinned messages about brand guidelines
- Look for brand-related threads and announcements
**Gong:**
- Search for sales call transcripts and analysis
- Target calls tagged with brand-related topics
- Look for top performer recordings
**Granola:**
- List recent meetings and search for brand-relevant calls
- Retrieve transcripts from sales, customer, and strategy meetings
- Look for meetings tagged or titled with brand-related topics
**Figma:**
- Search for brand design systems, style guides
- Look for files with "brand", "design system", "tokens"
Collect all results with metadata: title, platform, URL, author, date, snippet.
### Phase 2: Source Triage
Categorize every discovered source into one of five tiers:
- **AUTHORITATIVE**: Official brand guides, C-suite-approved decks, published style guides. Highest trust.
- **OPERATIONAL**: Templates, playbooks, email sequences, sales decks. Show brand in practice.
- **CONVERSATIONAL**: Call transcripts, meeting notes, Slack threads. Reveal implicit brand voice.
- **CONTEXTUAL**: Design files, competitor mentions, industry analyses. Inform but don't define.
- **STALE**: Outdated docs superseded by newer versions. Flag but deprioritize.
Apply ranking weights (see skills/discover-brand/references/source-ranking.md for details):
1. Recency — newer sources outrank older
2. Explicitness — explicit brand instructions outrank implicit patterns
3. Authority — official docs outrank informal materials
4. Specificity — detailed guidance outranks vague principles
5. Cross-source consistency — corroborated elements rank higher
If zero AUTHORITATIVE sources are found after triage, apply adaptive scoring (see skills/discover-brand/references/source-ranking.md "Adaptive Scoring: No Authoritative Sources"). Flag this in the discovery report.
### Phase 3: Deep Fetch
Do not deep-fetch non-AUTHORITATIVE sources older than 12 months unless they are the only source in their category. Do not deep-fetch STALE sources — include them in the discovery report for reference only.
Retrieve full content from the top 5-15 ranked sources. For each source:
1. Fetch the complete document content
2. Extract key brand elements:
- Voice attributes (personality, tone descriptors)
- Messaging (value props, positioning, key messages)
- Terminology (preferred terms, prohibited terms)
- Tone guidance (by content type, audience, context)
- Examples (good and bad content samples)
- Visual brand context (colors, typography, design tokens)
3. Track provenance: platform, URL, author, date, document type
4. Note confidence level for each extracted element
### Phase 4: Discovery Report
Produce a structured report with these sections:
```markdown
# Brand Discovery Report
## Summary
- Platforms searched: [list]
- Total sources found: [N]
- Sources analyzed in depth: [N]
- Key brand elements discovered: [N]
## Sources by Category
### Authoritative ([N] sources)
| Source | Platform | Date | Key Elements |
|--------|----------|------|--------------|
### Operational ([N] sources)
[same table format]
### Conversational ([N] sources)
[same table format]
### Contextual ([N] sources)
[same table format]
### Stale ([N] sources — flagged for review)
[same table format]
## Brand Elements Discovered
### Voice Attributes
- [Attribute]: [description] (Source: [doc], Confidence: [High/Medium/Low])
### Messaging Themes
- [Theme]: Found in [N] sources. Representative phrasing: "[quote]"
### Terminology
- Preferred: [term] → [usage] (Source: [doc])
- Prohibited: [term] → [reason] (Source: [doc])
### Tone Patterns
- [Context]: [tone description] (Source: [doc])
## Conflicts Between Sources
- **[Topic]**: Source A ([date]) says "[X]", Source B ([date]) says "[Y]"
Agent recommendation: [which to adopt and why]
## Coverage Gaps
- [Missing area]: Not addressed in any discovered source
Agent recommendation: [how to fill this gap]
## Open Questions for Team Discussion
### High Priority (blocks guideline completion)
1. **[Question Title]**
- What was found: [conflicting or missing info]
- Agent recommendation: [suggested resolution]
- Need from you: [specific decision needed]
### Medium Priority (improves quality)
[same format]
### Low Priority (nice to have)
[same format]
## Recommended Next Steps
1. [Action item]
2. [Action item]
```
## Quality Standards
- Every extracted element must cite its source with platform, URL, and date
- Conflicts must present both sides with a recommendation
- Every open question must include an agent recommendation — never leave ambiguity as a dead end
- Redact PII (customer names, contact info) from all excerpts
- If a platform returns no results, note it explicitly rather than omitting silently
- If fewer than 3 sources are found, flag the discovery as "low coverage" and recommend additional sources
- If only supplementary platforms (Slack, Gong, Granola, Figma) are connected with no document platforms, flag this prominently in the report summary: results are based on conversational and design sources only, and formal brand documents may exist on unconnected platforms
@@ -0,0 +1,87 @@
---
name: document-analysis
description: >
Analyzes brand documents to extract voice attributes, messaging, terminology,
and examples. Use this agent when processing multiple brand documents or
performing cross-document pattern recognition.
<example>
Context: The guideline-generation skill has received 5 brand documents to process.
user: "Generate brand guidelines from these 5 documents"
assistant: "I'll analyze all documents to extract brand elements..."
<commentary>
Multiple documents need parallel processing and cross-document pattern recognition.
The document-analysis agent handles heavy parsing efficiently.
</commentary>
</example>
<example>
Context: Discovery found brand documents on Notion and Confluence that need deep analysis.
user: "Analyze the brand materials found during discovery"
assistant: "I'll do a deep analysis of each discovered document..."
<commentary>
Discovery report identified key documents. The document-analysis agent fetches
full content from connected platforms and extracts structured brand elements.
</commentary>
</example>
model: sonnet
color: green
# tools not restricted -- this agent needs MCP tools to fetch documents from connected platforms
maxTurns: 15
---
You are a specialized document analysis agent for the Brand Voice Plugin. Your role is to parse and analyze brand-related documents to extract structured brand elements.
## Your Task
When invoked, you receive a list of documents to analyze. For each document:
1. **Identify** format, structure, and document type (style guide, pitch deck, template, brand book)
2. **Extract** brand elements:
- Voice attributes (personality descriptors, tone instructions)
- Messaging (value propositions, positioning, competitive differentiation)
- Terminology (preferred terms, prohibited terms, jargon guidance)
- Tone guidance (by content type, audience, or context)
- Examples (sample content labeled as good or bad)
3. **Cross-reference** patterns across all documents
4. **Flag** contradictions between sources
5. **Score** confidence based on evidence quality and consistency
When documents are stored on connected platforms (Notion, Confluence, Google Drive, Box, SharePoint), use the available MCP tools to fetch their content.
## Output Format
Return structured findings:
```
Documents Processed: [N]
Voice Attributes Found:
- [Attribute]: [evidence from source] (Confidence: High/Medium/Low)
Messaging Themes:
- [Theme]: Found in [N] documents. Key phrasing: "[quote]"
Terminology:
- Preferred: [term] -> [usage guidance] (Source: [doc])
- Prohibited: [term] -> [reason] (Source: [doc])
Tone Guidance:
- [Content type/context]: [tone description] (Source: [doc])
Examples Extracted: [N] good, [N] bad
Conflicts Detected:
- [Topic]: Source A says "[X]", Source B says "[Y]"
Recommendation: [which to use and why]
Coverage Gaps:
- [Missing area]: Not addressed in any document
```
## Quality Standards
- Every extracted element must cite its source document
- Confidence scores reflect both explicit mentions and inferred patterns
- Conflicts are flagged with both sources and a recommendation
- Redact PII from extracted examples
@@ -0,0 +1,91 @@
---
name: quality-assurance
description: >
Validates content and brand guidelines against brand standards. Use this agent
to check compliance, consistency, completeness, and open question coverage
before finalizing output.
<example>
Context: The brand-voice-enforcement skill has generated a cold email and wants to
validate it against guidelines before presenting to the user.
user: "Check this email against our brand guidelines"
assistant: "Let me validate this against your brand guidelines..."
<commentary>
Content needs validation against brand standards before delivery.
The quality-assurance agent performs a fast, structured compliance check.
</commentary>
</example>
<example>
Context: Brand guidelines were just generated and need validation before presenting.
user: "Validate these brand guidelines for completeness and quality"
assistant: "Let me check the guidelines for completeness, consistency, and open questions..."
<commentary>
Generated guidelines need quality validation before presenting to the user.
The quality-assurance agent checks completeness, open questions coverage, and PII.
</commentary>
</example>
model: haiku
color: yellow
tools:
- Read
- Glob
- Grep
maxTurns: 10
---
You are a specialized quality assurance agent for the Brand Voice Plugin. Your role is to validate content and guidelines against brand standards.
## Your Task
When invoked, you receive content or guidelines to validate along with the brand standards to check against.
### Content Validation
Check generated content against brand guidelines:
- **Voice compliance:** Does content reflect "We Are" attributes? Does it avoid "We Are Not" boundaries?
- **Tone appropriateness:** Right formality, energy, and technical depth for content type and audience?
- **Messaging alignment:** Key messages present where appropriate?
- **Terminology:** Preferred terms used? Prohibited terms absent?
- **Example alignment:** Matches quality of provided examples?
### Guideline Validation
Check generated guidelines for quality:
- **Completeness:** All major sections populated? "We Are / We Are Not" table has 4+ rows?
- **Evidence quality:** Voice attributes have supporting quotes?
- **Actionability:** Guidelines specific enough to apply?
- **Consistency:** Sections don't contradict each other?
- **Tone matrix:** Covers at least 3 content contexts?
- **PII check:** Customer names and sensitive info redacted?
### Open Questions Audit
Check that open questions are properly handled:
- **Completeness:** Every ambiguity and conflict has a corresponding open question?
- **Recommendations:** Every open question includes an agent recommendation?
- **Priority:** Questions are correctly prioritized (High/Medium/Low)?
- **Actionability:** Each question specifies what decision is needed from the team?
- **No dead ends:** No question leaves the user without a suggested path forward?
## Output Format
```
Validation Result: [Pass / Needs Revision / Fail]
Checks:
- Voice Compliance: [Pass/Fail] - [details]
- Tone: [Pass/Fail] - [details]
- Messaging: [Pass/Fail] - [details]
- Terminology: [Pass/Fail] - [issues found]
- Open Questions: [Pass/Fail] - [details]
- PII: [Pass/Fail]
Issues Found:
1. [Severity: Critical/Suggested] [description] -> Fix: [recommendation]
Overall: [summary]
```
## Quality Standards
- Every finding must cite the specific guideline it references
- Recommendations must be actionable
- Severity levels: Critical (must fix), Suggested (should fix), Optional (nice to have)
@@ -0,0 +1,24 @@
---
description: Search connected platforms for brand materials and produce a discovery report
argument-hint: "[company name or platforms to search]"
---
Discover brand materials across the user's connected enterprise platforms. Search Notion, Confluence, Google Drive, Box, SharePoint, Figma, Gong, Granola, and Slack for brand guidelines, style guides, messaging frameworks, templates, and conversation transcripts.
If $ARGUMENTS includes a company name, use it for targeted searches. If platforms are specified, limit search to those platforms.
Before doing anything else, briefly orient the user on what's about to happen: the process will search their connected platforms, produce a discovery report, and then (optionally) generate and save brand guidelines to `.claude/brand-voice-guidelines.md` in the working folder. Nothing is saved until they explicitly approve. Keep the orientation to 2-3 sentences — don't recite the full workflow.
Follow the discover-brand skill instructions to:
1. Check `.claude/brand-voice.local.md` for settings (company name, enabled platforms, search depth)
2. Validate platform coverage (stop if no document platforms, warn if gaps)
3. Briefly confirm scope with the user (which platforms, include transcripts?)
4. Delegate to the discover-brand agent for autonomous 4-phase search
5. Present the structured discovery report with sources, brand elements, conflicts, and open questions
6. Offer next steps: generate guidelines, resolve open questions, save report, or expand search
**Platform validation:**
- If **no platforms** are connected, inform the user which MCP servers the plugin supports (Notion, Atlassian Confluence, Box, Figma, Gong, Granola, Microsoft 365) and that Google Drive and Slack are available as native Claude integrations.
- If **no document platforms** (Notion, Confluence, Google Drive, Box, Microsoft 365) are connected — only supplementary platforms like Slack, Gong, Granola, or Figma — stop and tell the user: "You don't have any document storage platforms connected. Brand guidelines and style guides almost always live on Google Drive, SharePoint, Notion, Confluence, or Box. Please connect at least one before running discovery."
- If **no primary file storage** (Google Drive, Microsoft 365, Box) is connected, warn: "None of your primary file storage platforms are connected. Brand documents frequently live on these. Discovery will proceed but results may have significant gaps."
- If **only one platform** is connected, warn: "Discovery works best with 2+ platforms for cross-source validation. Results from a single platform will have lower confidence scores."
@@ -0,0 +1,22 @@
---
description: Apply brand guidelines to content creation
argument-hint: "<content request>"
---
**MANDATORY FIRST STEP — do this before anything else, including loading guidelines or processing the content request.** Check whether the user has a working folder selected for this session. You must verify this before starting any enforcement work. If there is no working folder, stop and warn the user: "You don't have a working folder selected. Without one, I can't load saved guidelines from a previous session, and any guidelines generated in this conversation won't be saved for future sessions either. Please select a working folder and re-run this command. If you'd like to proceed anyway (guidelines will only be usable in this session), let me know." Wait for the user to confirm before continuing.
Load the user's brand guidelines and apply them to the content request provided in $ARGUMENTS.
Find brand guidelines using this sequence (stop as soon as found):
1. Session context — check if guidelines were generated earlier in this conversation
2. Local guidelines file — check for `.claude/brand-voice-guidelines.md` inside the user's working folder. Do NOT use a relative path from the agent's current working directory (in Cowork, the agent runs from a plugin cache directory). If no working folder is set, skip this step.
3. If not found, ask the user to run `/brand-voice:discover-brand`, `/brand-voice:generate-guidelines`, or paste guidelines directly
Once guidelines are loaded, follow the brand-voice-enforcement skill instructions to:
1. Analyze the content request (type, audience, key messages, requirements)
2. Apply voice constants ("We Are / We Are Not") and flex tone for context (formality, energy, technical depth)
3. Generate content applying voice, tone, messaging, and terminology guidelines
4. Validate output against brand do's and don'ts
5. Present the content with a brief explanation of brand choices made
6. Note any open questions from guidelines that affect this content
7. Offer to refine based on feedback
@@ -0,0 +1,28 @@
---
description: Generate brand voice guidelines from documents, transcripts, discovery reports, or any combination
argument-hint: "<sources — documents, transcripts, or description of what you have>"
---
**MANDATORY FIRST STEP — do this before anything else, including reading sources or processing arguments.** Check whether the user has a working folder selected for this session. You must verify this before starting any guideline generation work. If there is no working folder, stop and warn the user: "You don't have a working folder selected. Without one, I can't save guidelines to a file — they'll only exist in this conversation and won't persist to future sessions. Please select a working folder and re-run this command. If you'd like to proceed anyway, let me know." Wait for the user to confirm before continuing.
Generate comprehensive, LLM-ready brand voice guidelines from whatever sources the user provides — brand documents, conversation transcripts, a discovery report from `/brand-voice:discover-brand`, or direct input.
Process the sources specified in $ARGUMENTS. If none specified, check:
1. Whether a discovery report was generated in this session
2. `.claude/brand-voice.local.md` for known brand material locations
3. Connected platforms (Notion, Confluence, Google Drive, Box, SharePoint, Gong) for existing materials
4. If nothing is available, suggest running `/brand-voice:discover-brand` first
Follow the guideline-generation skill instructions to:
1. Identify and classify all available sources (discovery report, documents, transcripts)
2. Delegate to document-analysis and conversation-analysis agents as needed
3. Synthesize findings into unified guidelines with "We Are / We Are Not" table and tone-by-context matrix
4. Assign confidence scores per section
5. Surface open questions with agent recommendations for any ambiguity
6. Present key findings and offer next steps
7. Save guidelines to `.claude/brand-voice-guidelines.md` inside the user's working folder (archiving any existing file first). Do NOT use a relative path from the agent's current working directory — in Cowork, the agent runs from a plugin cache directory, not the user's project.
After generation, guidelines are saved locally so `/brand-voice:enforce-voice` can automatically find them in future sessions.
Supported document formats: PDF, PowerPoint, Word, Markdown, plain text.
Supported transcript sources: Gong (MCP), Granola (MCP), Notion meeting notes, manual uploads.
@@ -0,0 +1,42 @@
---
# Brand Voice Plugin Settings
# Copy this file to .claude/brand-voice.local.md and fill in your values.
# Required fields: company_name. All other fields are optional with sensible defaults.
company_name: "" # required
platforms:
notion: true
confluence: false
google-drive: false
box: false
microsoft-365: false
figma: false
gong: false
granola: false
slack: false
discovery:
search-depth: standard # standard | deep
max-sources: 15
enforcement:
strictness: balanced # strict | balanced | flexible
always-explain: true
open-questions:
share-with-team: false
---
# Brand Context
## Company Name
[Your company]
## Known Brand Materials
- Notion: [URL to brand workspace or page]
- Confluence space: [space name or URL]
- Google Drive folder: [URL]
- Box folder: [URL]
- SharePoint site: [URL]
- Figma brand kit: [URL]
- Gong call library: [filter or tag name]
- Granola meetings: [search query or tag name]
- Slack channels: [#brand, #marketing, or other relevant channels]
## Additional Context
[Any other context about your brand that the plugin should know — target audience, industry, competitive landscape, recent brand changes, etc.]
@@ -0,0 +1,107 @@
---
name: brand-voice-enforcement
description: >
This skill applies brand guidelines to content creation. It should be used when
the user asks to "write an email", "draft a proposal", "create a pitch deck",
"write a LinkedIn post", "draft a presentation", "write a Slack message",
"draft sales content", or any content creation request where brand voice should
be applied. Also triggers on "on-brand", "brand voice", "enforce voice",
"apply brand guidelines", "brand-aligned content", "write in our voice",
"use our brand tone", "make this sound like us", "rewrite this in our tone",
or "this doesn't sound on-brand". Not for generating guidelines from scratch
(use guideline-generation) or discovering brand materials (use discover-brand).
---
# Brand Voice Enforcement
Apply existing brand guidelines to all sales and marketing content generation. Load the user's brand guidelines, apply voice constants and tone flexes to the content request, validate output, and explain brand choices.
## Loading Brand Guidelines
Find the user's brand guidelines using this sequence. Stop as soon as you find them:
1. **Session context** — Check if brand guidelines were generated earlier in this session (via `/brand-voice:generate-guidelines`). If so, they are already in the conversation. Use them directly. Session-generated guidelines are the freshest and reflect the user's most recent intent.
2. **Local guidelines file** — Check for `.claude/brand-voice-guidelines.md` inside the user's working folder. Do NOT use a relative path from the agent's current working directory — in Cowork, the agent runs from a plugin cache directory, not the user's project. Resolve the path relative to the user's working folder. If no working folder is set, skip this step.
3. **Ask the user** — If none of the above found guidelines, tell the user:
"I couldn't find your brand guidelines. You can:
- Run `/brand-voice:discover-brand` to find brand materials across your platforms
- Run `/brand-voice:generate-guidelines` to create guidelines from documents or transcripts
- Paste guidelines directly into this chat or point me to a file"
Wait for the user to provide guidelines before proceeding.
Also read `.claude/brand-voice.local.md` for enforcement settings (even if guidelines came from another source):
- `strictness`: strict | balanced | flexible
- `always-explain`: whether to always explain brand choices
## Enforcement Workflow
### 1. Analyze the Content Request
Before writing, identify:
- **Content type**: email, presentation, proposal, social post, message, etc.
- **Target audience**: role, seniority, industry, company stage
- **Key messages needed**: which message pillars apply
- **Specific requirements**: length, format, tone overrides
### 2. Apply Voice Constants
Voice is the brand's personality — it stays constant across all content:
- Apply "We Are / We Are Not" attributes from guidelines
- Use brand personality consistently
- Incorporate approved terminology; reject prohibited terms
- Follow messaging framework and value propositions
Refer to `references/voice-constant-tone-flexes.md` for the "voice constant, tone flexes" model.
### 3. Flex Tone for Context
Tone adapts by content type and audience. Use the tone-by-context matrix from guidelines to set:
- **Formality**: How formal or casual should this be?
- **Energy**: How much urgency or enthusiasm?
- **Technical depth**: How detailed or accessible?
### 4. Generate Content
Create content that:
- Matches brand voice attributes throughout
- Follows tone guidelines for this specific content type
- Incorporates key messages naturally (not forced)
- Uses preferred terminology
- Mirrors the quality and style of guideline examples
For complex or long-form content, delegate to the content-generation agent (defined in `agents/content-generation.md`).
For high-stakes content, delegate to the quality-assurance agent (defined in `agents/quality-assurance.md`) for validation.
### 5. Validate and Explain
After generating content:
- Briefly highlight which brand guidelines were applied
- Explain key voice and tone decisions
- Note any areas where guidelines were adapted for context
- Offer to refine based on feedback
When `always-explain` is true in settings, include brand application notes with every response.
## Handling Conflicts
When the user's request conflicts with brand guidelines:
1. Explain the conflict clearly
2. Provide a recommendation
3. Offer options: follow guidelines strictly, adapt for context, or override
Default to adapting guidelines with an explanation of the tradeoff.
## Open Questions Awareness
Open questions are unresolved brand positioning decisions flagged during guideline generation, stored in the guidelines under an "Open Questions" section. When generating content, check if the brand guidelines contain open questions:
- If content touches an unresolved open question, note it
- Apply the agent's recommendation from the open question unless the user specifies otherwise
- Suggest resolving the question if it significantly impacts the content
## Reference Files
- **`references/voice-constant-tone-flexes.md`** — The "voice constant, tone flexes" mental model, "We Are / We Are Not" table structure, and tone-by-context matrix explanation
- **`references/before-after-examples.md`** — Before/after content examples per content type showing enforcement in practice
@@ -0,0 +1,194 @@
# Before/After Content Examples
Concrete examples showing how brand voice enforcement transforms generic content into on-brand output. Each example shows the generic version, the enforced version, and annotations explaining what changed and why.
These examples use a fictional B2B SaaS company for illustration. During enforcement, replace all specifics (data points, product names, metrics) with data from the user's actual brand guidelines and context.
## Cold Outreach Email
### Before (Generic)
```
Subject: Quick question about your sales process
Hi [Name],
I wanted to reach out because I think our product could be a great fit
for your team. We offer an AI-powered platform that helps sales teams
be more productive.
Would you be open to a quick 15-minute call to learn more?
Best,
[Sender]
```
### After (Brand Voice Enforced)
```
Subject: [Company] is leaving pipeline on the table
Hi [Name],
Your team closed $12M last quarter — impressive. But our data shows
mid-market SaaS teams like yours typically lose 23% of qualified pipeline
to slow follow-ups.
[Product] fixes that. We help sales teams respond to buying signals in
real time, not hours later. [Customer X] saw their win rate jump 18%
in the first quarter.
Worth 15 minutes to see if the numbers apply to [Company]?
[Sender]
```
### What Changed
- **Voice: Confident** — leads with a bold claim and specific data (not "I think our product could be")
- **Voice: Data-driven** — concrete numbers (23%, 18%, $12M) replace vague "more productive"
- **Voice: Direct** — gets to the point immediately, no "I wanted to reach out"
- **Tone: Energy HIGH** — active language, short sentences, urgency
- **Tone: Formality MEDIUM** — professional but conversational
- **Tone: Technical depth LOW** — outcomes and impact, not feature descriptions
- **Terminology**: "buying signals" and "pipeline" (industry-specific but accessible to VP Sales)
## Follow-Up Email
### Before (Generic)
```
Hi [Name],
Just following up on my previous email. I'd love to schedule a call
to discuss how we can help your team.
Let me know if you're available this week.
Thanks,
[Sender]
```
### After (Brand Voice Enforced)
```
Hi [Name],
Quick update: we just published our Q4 benchmark report on enterprise
sales velocity. Three insights jumped out that are relevant to [Company]:
1. Teams using real-time signals close 31% faster than the industry average
2. The #1 pipeline killer isn't competition — it's response time
3. Mid-market wins are trending 15% larger when reps personalize within 2 hours
Happy to walk through how these benchmarks compare to your team's numbers.
The report is attached if you'd rather dig in yourself first.
[Sender]
```
### What Changed
- **Voice: Data-driven** — new value in every touch (benchmark data), not just "following up"
- **Voice: Approachable** — offers two paths (call or self-serve) without pressure
- **Voice: Confident** — shares proprietary insights, positions as expert
- **Tone: Energy MEDIUM** — informative, not pushy
- **Tone: Formality MEDIUM** — professional but not stiff
- **Key principle applied**: "Add new value each touch" — no empty follow-ups
## Enterprise Proposal Executive Summary
### Before (Generic)
```
We are pleased to submit this proposal for your consideration. Our
company offers a comprehensive AI solution that can help improve your
sales team's performance. We believe our platform is the best choice
for organizations looking to modernize their sales operations.
```
### After (Brand Voice Enforced)
```
[Company] processes 2,400 leads per quarter with a 12-person sales team.
Current pipeline-to-close conversion sits at 18% — below the 24% benchmark
for enterprise SaaS at your ARR stage.
This proposal outlines how [Product] closes that gap. Our platform
analyzes buying signals across your existing tech stack and surfaces
the 3-5 daily actions most likely to advance each deal. Typical results:
+31% win rate, -40% time to close, 2.1x pipeline per rep.
Implementation takes 3 weeks. ROI breaks even at week 6.
```
### What Changed
- **Voice: Data-driven** — opens with the client's own metrics, not "we are pleased"
- **Voice: Direct** — no filler language, every sentence carries information
- **Voice: Confident** — specific outcomes with numbers, clear implementation timeline
- **Tone: Formality HIGH** — structured, precise language
- **Tone: Energy MEDIUM** — measured confidence, not hype
- **Tone: Technical depth HIGH** — specific features (buying signals, tech stack analysis), ROI math
## LinkedIn Post
### Before (Generic)
```
Excited to announce our new feature! We've been working hard on this
and we think it's going to change the way sales teams work. Check out
the link below to learn more! #sales #AI #innovation
```
### After (Brand Voice Enforced)
```
The average sales rep spends 4.2 hours/day on tasks that don't close deals.
We analyzed 50,000 sales activities across 200 teams and found the pattern:
top performers aren't working harder — they're responding faster.
Today we're launching Signal Score: real-time prioritization that tells
your reps exactly which deal to work next, and why.
Early results from beta: 23% fewer lost deals from delayed follow-up.
Link in comments.
```
### What Changed
- **Voice: Data-driven** — opens with a statistic, not "excited to announce"
- **Voice: Confident** — specific research (50,000 activities, 200 teams)
- **Voice: Innovative** — describes what's new without hype
- **Voice: NOT hype-driven** — no "change the way sales teams work", replaced with measurable outcomes
- **Tone: Formality LOW-MEDIUM** — casual enough for LinkedIn, professional enough for B2B
- **Tone: Energy HIGH** — short sentences, bold opening stat
- **Tone: Technical depth LOW** — outcomes-focused, accessible to any reader
- **Terminology**: Avoided "revolutionary" and "game-changing" (prohibited terms)
## Internal Slack Message
### Before (Generic)
```
Hey team, just a reminder that we should all be using the approved
messaging when talking to prospects. Please refer to the brand
guidelines document for more information.
```
### After (Brand Voice Enforced)
```
Heads up — we updated the competitive positioning section in the brand
guidelines. Two big changes:
1. Against [Competitor]: lead with implementation speed (3 weeks vs. their 3 months)
2. Against Status Quo: new stat — teams using manual processes lose 23% of pipeline to timing
Updated doc is pinned in #sales-enablement. Questions? Tag me.
```
### What Changed
- **Voice: Direct** — specific changes, not vague "please refer to"
- **Voice: Data-driven** — concrete differentiators with numbers
- **Voice: Approachable** — casual, helpful tone appropriate for Slack
- **Tone: Formality LOW** — contractions, short sentences, "tag me"
- **Tone: Energy MEDIUM** — informative without being overly enthusiastic
- **Key principle**: Internal comms can be less polished, but voice attributes still apply
## Using These Examples
When enforcing brand voice, reference the relevant content type example to calibrate:
1. Match the content type to the closest example above
2. Note which voice attributes are most active for that type
3. Apply the tone settings (formality, energy, technical depth)
4. Check "We Are Not" boundaries — make sure content doesn't cross them
5. Verify terminology compliance (preferred terms used, prohibited terms absent)
@@ -0,0 +1,115 @@
# Voice Constant, Tone Flexes
The core mental model for brand voice enforcement: voice is constant, tone flexes by context.
## The Distinction
**Voice** is WHO the brand is — personality, values, identity. It never changes regardless of channel, audience, or content type. Think of it as the brand's character.
**Tone** is HOW the brand speaks in a given moment — formality, energy, technical depth. It adapts to context the way a person adjusts their tone when speaking to a friend vs. a CEO vs. a large audience.
## Voice Constants: "We Are / We Are Not"
The "We Are / We Are Not" table is the anchor of brand voice. It defines the brand's personality in paired attributes — what the brand IS and the boundary it should never cross.
### Structure
The table below is an illustrative example. During enforcement, use the "We Are / We Are Not" table from the user's own brand guidelines.
| We Are | We Are Not |
|--------|------------|
| **Confident** — we know our product and stand behind it | **Arrogant** — we never talk down to prospects or dismiss alternatives |
| **Approachable** — we make complex topics feel manageable | **Casual or sloppy** — approachable doesn't mean unprofessional |
| **Direct** — we get to the point quickly and clearly | **Blunt or aggressive** — directness includes empathy |
| **Data-driven** — we support claims with evidence | **Dry or academic** — data tells stories, not lectures |
| **Innovative** — we push boundaries and challenge status quo | **Hype-driven** — innovation is real, not buzzwords |
### How to Use During Enforcement
For every piece of content:
1. Check each "We Are" attribute — does the content reflect this?
2. Check each "We Are Not" boundary — does the content avoid crossing it?
3. If a boundary is crossed, revise the specific passage
4. If an attribute is missing, find a natural place to express it
Not every attribute needs to appear in every piece of content. Prioritize the 2-3 most relevant attributes for the content type and audience.
## Tone Flexes: The Three Dimensions
Tone adjusts along three independent dimensions:
### 1. Formality
How formal or casual the language is.
| Level | Signals | When |
|-------|---------|------|
| High | Complete sentences, industry terminology, structured format | Proposals, RFPs, enterprise comms |
| Medium | Clear and professional but conversational | Most emails, presentations, blog posts |
| Low | Casual language, contractions, personality shows through | Social media, internal comms, Slack |
### 2. Energy
How much enthusiasm, urgency, or dynamism the content conveys.
| Level | Signals | When |
|-------|---------|------|
| High | Active verbs, short sentences, exclamation-worthy excitement | Product launches, cold outreach hooks, social media |
| Medium | Steady pace, balanced between informative and engaging | Discovery content, follow-ups, case studies |
| Warm | Empathetic, supportive, understanding | Customer success, objection handling, bad news |
| Low | Measured, thoughtful, deliberate | Legal language, policy docs, sensitive topics |
### 3. Technical Depth
How much domain expertise or technical detail is included.
| Level | Signals | When |
|-------|---------|------|
| High | Technical terminology, architecture details, specs | Technical audience, implementation proposals, API docs |
| Medium | Industry terms explained when needed, features described clearly | Mixed audience, product demos, mid-funnel content |
| Low | Outcome-focused, benefits over features, no jargon | Executive audience, cold outreach, social media |
## Tone-by-Context Matrix
Combine the three dimensions for each content type:
| Context | Formality | Energy | Technical Depth | Key Principle |
|---------|-----------|--------|-----------------|---------------|
| Cold outreach | Medium | High | Low | Hook fast, earn attention |
| Discovery calls | Medium | Medium-High | Medium | Ask more than tell |
| Demo / presentation | Medium-High | High | High | Show, don't just describe |
| Enterprise proposal | High | Medium | High | ROI and precision |
| Follow-up email | Medium | Medium | Low-Medium | Add new value each touch |
| Social media | Low-Medium | High | Low | Brevity and personality |
| Customer success | Medium | Warm | Medium | Empathy and competence |
| Internal comms | Low | Medium | Varies | Authentic, less polished |
## Applying Voice + Tone Together
**Example: Cold outreach email**
Voice constants active:
- **Confident** — lead with a strong value claim
- **Direct** — get to the point in sentence one
- **Approachable** — don't sound like a robot
Tone settings:
- Formality: Medium (professional but not stiff)
- Energy: High (earn attention quickly)
- Technical Depth: Low (outcomes, not features)
**Example: Enterprise proposal**
Voice constants active:
- **Data-driven** — every claim has supporting evidence
- **Confident** — strong positioning without hedging
- **Innovative** — show forward-thinking approach
Tone settings:
- Formality: High (structured, complete sentences)
- Energy: Medium (measured, not breathless)
- Technical Depth: High (detailed implementation, specs)
## Common Enforcement Mistakes
1. **Applying all voice attributes at maximum intensity** — Not every attribute needs to shine in every sentence. Let 2-3 lead for the content type.
2. **Confusing voice with tone** — If the user asks for "casual" content, adjust TONE (lower formality, higher energy). Don't change VOICE (the brand's personality stays the same).
3. **Rigid enforcement over natural flow** — Guidelines are principles, not a checklist. Content should feel natural, not mechanically assembled.
4. **Ignoring the audience** — The same voice can sound very different to a CTO vs. a VP of Sales. Tone flexes handle this.
@@ -0,0 +1,127 @@
---
name: discover-brand
description: >
This skill orchestrates autonomous discovery of brand materials across enterprise
platforms (Notion, Confluence, Google Drive, Box, SharePoint, Figma, Gong, Granola, Slack).
It should be used when the user asks to "discover brand materials",
"find brand documents", "search for brand guidelines", "audit brand content",
"what brand materials do we have", "find our style guide", "where are our brand docs",
"do we have a style guide", "discover brand voice", "brand content audit",
or "find brand assets".
---
# Brand Discovery
Orchestrate autonomous discovery of brand materials across enterprise platforms. This skill coordinates the discover-brand agent to search connected platforms (Notion, Confluence, Google Drive, Box, Microsoft 365, Figma, Gong, Granola, Slack), triage sources, and produce a structured discovery report with open questions.
## Discovery Workflow
### 0. Orient the User
Before starting, briefly explain what's about to happen so the user knows what to expect:
"Here's how brand discovery works:
1. **Search** — I'll search your connected platforms (Notion, Google Drive, Slack, etc.) for brand-related materials: style guides, pitch decks, templates, transcripts, and more.
2. **Analyze** — I'll categorize and rank what I find, pull the best sources, and produce a discovery report with what I found, any conflicts, and open questions.
3. **Generate guidelines** — Once you've reviewed the report, I can generate a structured brand voice guideline document from the results.
4. **Save** — Guidelines are saved to `.claude/brand-voice-guidelines.md` in your working folder once you approve them. Nothing is written until that step.
The search usually takes a few minutes depending on how many platforms are connected. Ready to get started?"
Wait for the user to confirm before proceeding. If they have questions about the process, answer them first.
### 1. Check Settings
Read `.claude/brand-voice.local.md` if it exists. Extract:
- Company name
- Which platforms are enabled (notion, confluence, google-drive, box, microsoft-365, figma, gong, granola, slack)
- Search depth preference (standard or deep)
- Max sources limit
- Any known brand material locations listed under "Known Brand Materials"
If no settings file exists, proceed with all connected platforms and standard search depth.
### 2. Validate Platform Coverage
Before confirming scope, check which platforms are actually connected and classify them:
**Document platforms** (where brand guidelines, style guides, templates, and decks live):
- Notion, Confluence, Google Drive, Box, Microsoft 365 (SharePoint/OneDrive)
**Supplementary platforms** (valuable for patterns, but not where brand docs are stored):
- Slack, Gong, Granola, Figma
Apply these rules:
1. **If zero document platforms are connected**: **Stop.** Tell the user: "You don't have any document storage platforms connected (Google Drive, SharePoint, Notion, Confluence, or Box). Brand guidelines and style guides almost always live on one of these. Please connect at least one before running discovery. Gong/Granola/Slack transcripts are valuable supplements but unlikely to contain formal brand documents."
2. **If no Google Drive AND no Microsoft 365 AND no Box**: **Warn** (but proceed): "None of your primary file storage platforms (Google Drive, SharePoint, Box) are connected. Brand documents frequently live on these platforms. Discovery will proceed with [connected platforms], but results may have significant gaps. Consider connecting Google Drive or SharePoint."
3. **If only one platform total is connected**: **Warn** (but proceed): "Only [platform] is connected. Discovery works best with 2+ platforms for cross-source validation. Results from a single platform will have lower confidence scores."
### 3. Confirm Scope with User
Before launching discovery, confirm:
- Which platforms to search (default: all connected)
- Whether to include conversation transcripts (Gong, Granola) or just documents
- Any known locations to prioritize
Keep this brief — one question, not a questionnaire.
### 4. Delegate to Discover-Brand Agent
Launch the discover-brand agent via the Task tool. Provide:
- Company name (from settings or user input)
- Enabled platforms
- Search depth
- Any known URLs or locations to check first
The agent executes the 4-phase discovery algorithm autonomously:
1. **Broad Discovery** — parallel searches across platforms
2. **Source Triage** — categorize and rank sources
3. **Deep Fetch** — retrieve and extract from top sources
4. **Discovery Report** — structured output with open questions
### 5. Present Discovery Report
When the agent returns, present the report to the user with a summary:
- Total sources found and analyzed
- Key brand elements discovered
- Any conflicts between sources
- Open questions requiring team input
### 6. Offer Next Steps
After presenting the report, offer:
1. **Generate guidelines now** — chain to `/brand-voice:generate-guidelines` using discovery report as input
2. **Resolve open questions first** — work through high-priority questions before generating
3. **Save report** — store the discovery report to Notion or as a local file
4. **Expand search** — search additional platforms or deeper if coverage is low
## Open Questions
Open questions arise when the discovery agent encounters ambiguity it cannot resolve:
- Conflicting documents (e.g., 2023 style guide vs. 2024 brand update)
- Missing critical sections (e.g., no social media guidelines found)
- Inconsistent terminology across platforms
Every open question includes an agent recommendation. Present questions as "confirm or override" — not dead ends.
## Integration with Other Skills
- **Guideline Generation**: The discovery report is returned by the discover-brand agent via the Task tool. Pass it directly to the guideline-generation skill as structured input, replacing the need for users to manually gather sources.
- **Brand Voice Enforcement**: Once guidelines are generated from discovery, enforcement uses them automatically.
## Error Handling
- If zero platforms are connected, inform the user which platforms the plugin supports and how to connect them.
- If all searches return empty results, flag the discovery as "low coverage" and suggest the user provide documents manually or check platform connections.
- If a platform is connected but returns permission errors, note the gap and continue with other platforms.
## Reference Files
For detailed discovery patterns and algorithms, consult:
- **`references/search-strategies.md`** — Platform-specific search queries, query patterns by platform, and tips for maximizing discovery coverage
- **`references/source-ranking.md`** — Source category definitions, ranking algorithm weights, and triage decision criteria
@@ -0,0 +1,271 @@
# Search Strategies by Platform
Platform-specific query patterns and tips for maximizing brand material discovery.
## Notion (Primary Discovery Engine)
Notion AI Search federates across connected sources (Google Drive, SharePoint, OneDrive, Slack, Jira, Teams), making it the most valuable single search endpoint.
### Query Patterns
**Direct brand searches:**
- "brand guidelines"
- "style guide"
- "brand voice"
- "tone of voice"
- "messaging framework"
**Sales and marketing content:**
- "pitch deck"
- "sales playbook"
- "email templates"
- "value proposition"
- "competitive positioning"
**Operational brand content:**
- "brand update"
- "rebrand"
- "launch messaging"
- "press release template"
- "social media guidelines"
### Tips
- Notion AI Search returns results from connected sources — one search covers multiple platforms
- Search for the company name + "brand" to find company-specific guidelines
- Check for databases titled "Brand Assets", "Marketing Resources", or "Content Library"
- Look for pages tagged with "brand", "marketing", "style"
## Atlassian Confluence
Enterprises often store official brand documentation in Confluence spaces.
### Query Patterns
**Space-level search:**
- Search spaces named: "Marketing", "Brand", "Communications", "Sales Enablement"
- Check for spaces with labels: "brand", "style-guide", "guidelines"
**Page-level search:**
- "brand style guide"
- "voice and tone guidelines"
- "messaging framework"
- "content standards"
- "editorial guidelines"
**Template search:**
- "email template"
- "proposal template"
- "presentation template"
### Tips
- Confluence spaces often have hierarchical page trees — find the brand root page and explore children
- Check for recently updated pages (brand guidelines evolve)
- Look for pages with many watchers — indicates important shared content
- Search attachments for PDF brand guides uploaded to Confluence pages
## Box
Cloud file storage — official brand documents, shared decks, and style guides frequently live here.
### Query Patterns
**Folder search:**
- "Brand Guidelines"
- "Marketing Assets"
- "Brand Kit"
- "Style Guide"
- "Sales Collateral"
**Document search:**
- "brand guide" (PDF, DOCX, Word)
- "style guide" (PDF, DOCX, Word)
- "messaging document"
- "brand standards"
### Tips
- Box often contains the "source of truth" brand guides as PDFs or Word docs
- Check shared folders with company-wide access
- Look for folders shared with the marketing or brand team
- Search for recently modified brand documents to find the latest version
- Use Box metadata search to filter by content type or custom attributes
## Google Drive
Google Drive stores shared brand documents, marketing materials, and official style guides.
### Query Patterns
**Folder search:**
- "Brand Guidelines"
- "Marketing"
- "Brand Assets"
- "Style Guide"
**Document search:**
- "brand guide" (PDFs, Google Docs, Google Slides)
- "style guide"
- "messaging framework"
- "brand standards"
- "brand voice"
### Tips
- Check shared drives — brand materials often live in team-wide shared drives
- Look for recently modified brand documents to find the latest version
- Search by owner (marketing team members) to surface brand-owned content
- Google Docs and Slides are common formats for living brand documents
- Check for Google Slides presentations with brand overview decks
## Microsoft 365 (SharePoint / OneDrive)
Enterprise organizations often centralize brand documentation on SharePoint sites.
### Query Patterns
**SharePoint site search:**
- Search marketing or communications SharePoint sites
- "brand guidelines"
- "style guide"
- "brand standards"
- "messaging framework"
**Document library search:**
- Check document libraries in marketing/communications sites
- "brand guide" (Word, PDF, PowerPoint)
- "brand book"
- "editorial guidelines"
**OneDrive search:**
- "brand" files in shared OneDrive folders
- "style guide" shared with the organization
### Tips
- Check marketing/communications SharePoint sites first — most common location for brand docs
- Search document libraries for PDF brand guides and PowerPoint brand decks
- Look for brand-tagged content using SharePoint metadata
- OneDrive shared folders may contain working drafts of brand materials
- Use SharePoint search and document library tools when available
## Slack
Slack channels contain informal brand discussions, decisions, and evolving brand voice patterns.
### Query Patterns
**Channel search:**
- Look for channels: #brand, #marketing, #brand-voice, #style-guide, #creative
- Check channel topics and descriptions for brand-related content
**Message search:**
- "brand guidelines"
- "brand voice"
- "tone of voice"
- "style guide"
- "brand update"
**Pinned messages:**
- Check pinned messages in #brand and #marketing channels
- Pinned items often contain approved brand resources or decisions
### Tips
- Search #brand and #marketing channels first — most likely to contain brand discussions
- Look for pinned messages — teams often pin brand guidelines and decisions
- Find brand discussion threads for context on brand evolution
- Slack is a conversational source — ranks as CONVERSATIONAL tier in source triage
- Recent messages may reveal brand changes not yet documented formally
## Gong (Conversation Intelligence)
Sales call transcripts reveal how the brand actually communicates in practice.
### Query Patterns
**Call search:**
- Search for calls tagged: "won", "closed-won" (successful brand application)
- Filter by top performers (their language patterns define implicit brand voice)
- Look for calls tagged: "demo", "discovery", "closing"
**Transcript search:**
- Search transcripts for company-specific value propositions
- Look for recurring phrases across successful calls
- Find calls where competitors are discussed (reveals positioning)
### Tips
- Focus on successful calls — they represent brand voice that works
- Compare top performer language with average performer language
- Look for consistent opening lines and closing patterns
- Note objection handling language — reveals brand positioning under pressure
## Granola (Meeting Intelligence)
Meeting notes and transcripts from the AI notepad for meetings.
### Query Patterns
**Meeting search:**
- Query for meetings related to: "brand", "positioning", "messaging"
- List recent meetings and filter for customer-facing calls
- Search for strategy sessions and brand planning meetings
**Transcript retrieval:**
- Get full transcripts from high-signal meetings
- Look for recurring themes in meeting notes
- Find meetings with key stakeholders (marketing leads, executives)
### Tips
- Granola captures both meeting notes and transcripts — both are valuable
- Meeting notes often contain summarized brand decisions and action items
- Look for recurring meeting series (weekly brand syncs, marketing standups)
- Cross-reference Granola meeting notes with Gong call transcripts when both are available
## Figma (Brand Design Systems)
Visual brand elements inform voice and tone indirectly.
### Query Patterns
**File search:**
- "brand design system"
- "design tokens"
- "brand kit"
- "style guide"
- "component library"
**Component search:**
- Look for files with brand colors, typography scales
- Find component documentation with usage guidelines
- Check for content/copy guidelines in design system docs
### Tips
- Figma design systems often include writing guidelines alongside visual specs
- Check file descriptions and comments for brand context
- Look for "voice and tone" sections within design system documentation
- Brand personality descriptions in design files reveal voice attributes
## Cross-Platform Search Tips
### Maximizing Coverage
1. Start with Notion AI Search (broadest coverage via federation)
2. Follow up with Confluence for enterprise documentation
3. Check Google Drive for official brand documents
4. Check Box for cloud-stored brand documents
5. Search SharePoint/OneDrive for enterprise files
6. Search Slack for brand discussions and decisions
7. Search Gong for conversational brand patterns
8. Search Granola for meeting transcripts and notes
9. Review Figma for design-embedded brand guidelines
### Avoiding Duplicates
- Track source URLs to detect the same document across platforms
- When the same content appears on multiple platforms, prefer the most recently updated version
- Note when Notion federation returns results from other platforms to avoid double-searching
### Recency Focus
- Focus on content from the last 12 months for operational, conversational, and contextual sources
- Only search further back when looking for explicit brand documents (style guides, brand books)
- When results include older content, prefer the most recently updated version
- Flag any non-AUTHORITATIVE source older than 12 months — it may reflect outdated positioning
### Handling No Results
- If a platform returns zero results, try broader queries ("marketing", "sales")
- Check if the platform is actually connected and authenticated
- Note the gap in the discovery report — the absence of content on a platform is itself useful information
@@ -0,0 +1,248 @@
# Source Ranking Algorithm
How to categorize, rank, and prioritize discovered brand sources.
## Source Categories
### AUTHORITATIVE
Official, approved brand documentation. Highest trust level.
**Signals:**
- Published style guides or brand books
- C-suite or marketing leadership authored/approved
- Lives in an official "Brand" folder or Confluence space
- Has version numbers or approval dates
- Referenced by other documents as "the brand guide"
**Examples:**
- "Acme Corp Brand Guidelines v3.2.pdf"
- "Official Style Guide" page in Confluence Marketing space
- Brand book in Google Drive with company-wide sharing
- Brand book in Box with company-wide sharing
- Official Style Guide in SharePoint Marketing site
**Trust weight:** 1.0 (baseline)
### OPERATIONAL
Brand applied in practice. Shows how guidelines manifest in real content.
**Signals:**
- Templates actively used by teams
- Sales playbooks with messaging guidance
- Email sequences with established tone
- Presentation templates with brand messaging
**Examples:**
- "Cold Email Templates Q4 2024"
- "Enterprise Sales Playbook"
- "Customer Success Response Templates"
- Pitch deck templates in Google Slides
- Email templates in Outlook
- Sales playbook on SharePoint
**Trust weight:** 0.8
### CONVERSATIONAL
Implicit brand voice from actual communications.
**Signals:**
- Sales call transcripts (especially successful ones)
- Meeting notes with customer-facing language
- Internal discussions about positioning
- Slack threads discussing brand decisions
**Examples:**
- Gong recordings of top performer calls
- Meeting notes from brand strategy sessions
- Customer success call transcripts
- Slack #brand channel discussions about tone
**Trust weight:** 0.6 (valuable for patterns, not prescriptive)
### CONTEXTUAL
Background information that informs brand but doesn't define it directly.
**Signals:**
- Design files without explicit brand guidelines
- Competitor analysis documents
- Industry reports
- Product documentation
**Examples:**
- Figma component library (visual only)
- "Competitive Landscape Q3 2024"
- Product feature specifications
**Trust weight:** 0.3
### STALE
Outdated content superseded by newer versions.
**Signals:**
- Older version when a newer version exists
- Pre-rebrand materials after a rebrand
- Documents explicitly marked as deprecated
- Content more than 2 years old without updates
**Examples:**
- "Brand Guidelines v1.0" when v3.2 exists
- "2022 Style Guide" when "2024 Brand Update" exists
- Documents in an "Archive" or "Deprecated" folder
**Trust weight:** 0.1 (flag for review, do not rely on)
## Ranking Algorithm
Apply these five ranking factors in order of priority:
### 1. Recency (Weight: 30%)
More recent sources are more likely to reflect current brand voice.
- **Score 1.0**: Updated within last 6 months
- **Score 0.7**: Updated within last year
- **Score 0.4**: Updated within last 2 years
- **Score 0.1**: Older than 2 years
When two sources conflict, the more recent one wins unless the older source is explicitly marked as the "official" guide.
Always prefer the most recent version of any document. When multiple sources cover the same topic, weight the newest one heavily. Flag any non-AUTHORITATIVE source older than 12 months in the discovery report.
### Recency Cutoffs
In addition to soft recency scoring, apply hard cutoffs to prevent stale content from polluting discovery:
**AUTHORITATIVE sources**: No hard cutoff. Official brand guides remain valid regardless of age unless explicitly superseded by a newer version.
**OPERATIONAL, CONVERSATIONAL, CONTEXTUAL sources**: Exclude from deep fetch if older than 12 months, with one exception: if zero sources in a category fall within the 12-month window, include the single most recent source from that category and flag it as potentially stale.
**STALE sources**: Exclude entirely from deep fetch. Include in the discovery report for reference only.
These cutoffs apply at the deep-fetch stage (Phase 3). All sources are still collected during broad discovery (Phase 1) and triage (Phase 2) — the cutoffs filter what gets fully retrieved and analyzed.
### 2. Explicitness (Weight: 25%)
Sources that explicitly define brand voice outrank those that merely demonstrate it.
- **Score 1.0**: Explicit brand instructions ("Our voice is...")
- **Score 0.7**: Documented tone guidelines ("Emails should be...")
- **Score 0.4**: Implicit patterns in templates or examples
- **Score 0.2**: Inferred from conversational patterns
### 3. Authority (Weight: 20%)
Higher organizational authority indicates more trustworthy brand definitions.
- **Score 1.0**: Official brand team or C-suite authored
- **Score 0.7**: Marketing leadership authored
- **Score 0.4**: Team leads or senior ICs
- **Score 0.2**: Individual contributor or unknown author
### 4. Specificity (Weight: 15%)
Detailed, actionable guidance outranks vague principles.
- **Score 1.0**: Specific rules with examples ("Use 'platform' not 'tool'")
- **Score 0.7**: Detailed guidelines ("Tone should be warm but professional")
- **Score 0.4**: General principles ("Be authentic")
- **Score 0.2**: Abstract values only ("We believe in innovation")
### 5. Cross-Source Consistency (Weight: 10%)
Elements corroborated across multiple sources rank higher.
- **Score 1.0**: Appears in 3+ independent sources
- **Score 0.7**: Appears in 2 independent sources
- **Score 0.4**: Appears in 1 source only
- **Score 0.1**: Contradicted by another source
## Composite Score Calculation
```
final_score = (recency × 0.30) + (explicitness × 0.25) + (authority × 0.20)
+ (specificity × 0.15) + (consistency × 0.10)
```
Multiply by category trust weight:
```
ranked_score = final_score × category_trust_weight
```
### Example Scoring
**Source: "Brand Voice Guidelines v3.2" (Confluence, updated 3 months ago)**
- Recency: 1.0 (3 months old)
- Explicitness: 1.0 (explicit brand instructions)
- Authority: 1.0 (marketing VP authored)
- Specificity: 0.7 (good guidelines, some gaps)
- Consistency: 0.7 (corroborated by email templates)
- Category: AUTHORITATIVE (1.0)
- **Final: (1.0×0.30 + 1.0×0.25 + 1.0×0.20 + 0.7×0.15 + 0.7×0.10) × 1.0 = 0.925**
**Source: "Top Performer Call — Enterprise Close" (Gong, 2 months ago)**
- Recency: 1.0
- Explicitness: 0.2 (implicit patterns only)
- Authority: 0.4 (senior AE)
- Specificity: 0.7 (specific phrases used)
- Consistency: 0.4 (single source)
- Category: CONVERSATIONAL (0.6)
- **Final: (1.0×0.30 + 0.2×0.25 + 0.4×0.20 + 0.7×0.15 + 0.4×0.10) × 0.6 = 0.345**
## Adaptive Scoring: No Authoritative Sources
When discovery finds **zero AUTHORITATIVE sources**, the scoring algorithm adapts to reflect that conversational and operational sources are the primary brand evidence.
### Adjusted Trust Weights (No Authoritative Sources)
| Category | Default Weight | Adapted Weight | Rationale |
|----------|---------------|----------------|-----------|
| AUTHORITATIVE | 1.0 | 1.0 | (n/a — none found) |
| OPERATIONAL | 0.8 | 0.9 | Templates become primary explicit evidence |
| CONVERSATIONAL | 0.6 | 0.85 | Transcripts are the best signal for how the brand actually communicates |
| CONTEXTUAL | 0.3 | 0.4 | Design and competitive context more valuable without formal docs |
| STALE | 0.1 | 0.2 | Even old docs matter more when nothing current exists |
### Adjusted Explicitness Scoring (No Authoritative Sources)
When no authoritative sources exist, conversational patterns carry more prescriptive weight:
- **Score 0.2 → 0.5**: "Inferred from conversational patterns" — these ARE the brand evidence now
- **Score 0.4 → 0.6**: "Implicit patterns in templates or examples"
- Other explicitness scores unchanged
### Example: Transcript Scoring With Adaptation
**Source: "Top Performer Call — Enterprise Close" (Gong, 2 months ago)**
- Recency: 1.0
- Explicitness: 0.5 (adapted from 0.2 — patterns are primary evidence)
- Authority: 0.4 (senior AE)
- Specificity: 0.7 (specific phrases used)
- Consistency: 0.4 (single source)
- Category: CONVERSATIONAL (0.85 adapted)
- **Adapted score: (1.0×0.30 + 0.5×0.25 + 0.4×0.20 + 0.7×0.15 + 0.4×0.10) × 0.85 = 0.552**
This puts the transcript well above the 0.5 deep-fetch threshold, ensuring conversational sources meaningfully contribute to guideline generation.
### When to Apply
Apply adaptive scoring when:
- Phase 2 triage produces zero AUTHORITATIVE sources
- Flag in the discovery report: "No formal brand guidelines found — scoring adapted to weight conversational and operational sources higher"
## Triage Decision Criteria
### Include in Deep Fetch (Top 5-15 sources)
- Ranked score > 0.5
- All AUTHORITATIVE sources regardless of score
- At least one source per category if available (this overrides the score threshold)
- At least one source per platform if available
### Flag for Review
- Sources with conflicting information
- STALE sources that may still be referenced by teams
- Sources with high specificity but low authority
### Exclude
- Ranked score < 0.1
- Clearly irrelevant results (e.g., "brand" used in product name, not brand guidelines)
- Duplicate content already captured from another platform
@@ -0,0 +1,141 @@
---
name: guideline-generation
description: >
This skill generates, creates, or builds brand voice guidelines from source
materials. It should be used when the user asks to "generate brand guidelines",
"create a style guide", "extract brand voice", "create guidelines from calls",
"consolidate brand materials", "analyze my sales calls for brand voice",
"build a brand playbook from documents", "synthesize a voice and tone guide",
or uploads brand documents, transcripts, or meeting recordings for brand
analysis. Also triggers when the user has a discovery report and wants to
convert it into actionable guidelines.
---
# Guideline Generation
Generate comprehensive, LLM-ready brand voice guidelines from any combination of sources — brand documents, sales call transcripts, discovery reports, or direct user input. Transform raw materials into structured, enforceable guidelines with confidence scoring and open questions.
## Inputs
Accept any combination of:
- **Discovery report** from the discover-brand skill (structured, pre-triaged)
- **Brand documents** uploaded or from connected platforms (PDF, PPTX, DOCX, MD, TXT)
- **Conversation transcripts** from Gong, Granola, manual uploads, or Notion meeting notes
- **Direct user input** about their brand voice and values
When a discovery report is provided, use it as the primary input — sources are already triaged and ranked. Supplement with additional analysis as needed.
## Generation Workflow
### 1. Identify and Classify Sources
Determine what the user has provided. If no sources are available:
- Check if a discovery report exists from a previous `/brand-voice:discover-brand` run
- Check `.claude/brand-voice.local.md` for known brand material locations
- Suggest running discovery first: `/brand-voice:discover-brand`
### 2. Process Sources
**For documents:** Delegate to the document-analysis agent for heavy parsing. Extract voice attributes, messaging themes, terminology, tone guidance, and examples.
**For transcripts:** Delegate to the conversation-analysis agent for pattern recognition. Extract implicit voice attributes, successful language patterns, tone by context, and anti-patterns.
**For discovery reports:** Extract pre-triaged sources, conflicts, and gaps. Use the ranked sources directly.
### 3. Synthesize Into Guidelines
Merge all findings into a unified guideline document following the template in `references/guideline-template.md`. Key sections:
**"We Are / We Are Not" Table** — The core brand identity anchor:
| We Are | We Are Not |
|--------|------------|
| [Attribute — e.g., "Confident"] | [Counter — e.g., "Arrogant"] |
| [Attribute — e.g., "Approachable"] | [Counter — e.g., "Casual or sloppy"] |
Derive attributes from the most consistent patterns across sources. Each row should have supporting evidence.
**Voice Constants vs. Tone Flexes** — Clarify what stays fixed and what adapts:
- **Voice** = personality, values, "We Are / We Are Not" — constant across all content
- **Tone** = formality, energy, technical depth — flexes by context
**Tone-by-Context Matrix:**
| Context | Formality | Energy | Technical Depth | Example |
|---------|-----------|--------|-----------------|---------|
| Cold outreach | Medium | High | Low | "[example phrase]" |
| Enterprise proposal | High | Medium | High | "[example phrase]" |
| Social media | Low | High | Low | "[example phrase]" |
### 4. Assign Confidence Scores
Score each section using the methodology in `references/confidence-scoring.md`:
- **High confidence**: 3+ corroborating sources, explicit guidance found
- **Medium confidence**: 1-2 sources, or inferred from patterns
- **Low confidence**: Single source, inferred, or conflicting data
### 5. Surface Open Questions
Generate open questions for any ambiguity that cannot be resolved:
```markdown
## Open Questions for Team Discussion
### High Priority (blocks guideline completion)
1. **[Question Title]**
- What was found: [conflicting or incomplete info]
- Agent recommendation: [suggested resolution with reasoning]
- Need from you: [specific decision or confirmation needed]
```
Every open question MUST include an agent recommendation. Turn ambiguity into "confirm or override" — never a dead end.
### 6. Quality Check
Before presenting, verify via the quality-assurance agent (defined in `agents/quality-assurance.md`):
- All major sections populated (including Brand Personality and Content Examples if sources support them)
- At least 3 voice attributes with evidence
- "We Are / We Are Not" table has 4+ rows
- Tone matrix covers at least 3 contexts
- Confidence scores assigned per section
- Source attribution for all extracted elements
- No PII exposed
- Open questions include recommendations
### 7. Present and Offer Next Steps
Summarize key findings:
- Total sections generated with confidence breakdown
- Strongest voice attribute and most effective message
- Number of open questions (if any)
### 8. Save for Future Sessions
The default save location is `.claude/brand-voice-guidelines.md` inside the user's working folder.
**Important:** The agent's working directory may not be the user's project root (especially in Cowork, where plugins run from a plugin cache directory). Always resolve the path relative to the user's working folder, not the current working directory. If no working folder is set, skip the file save and tell the user guidelines will only be available in this conversation.
1. **Resolve the save path.** The file MUST be saved to `.claude/brand-voice-guidelines.md` inside the user's working folder. Confirm the working folder path before writing.
2. **Check if guidelines already exist** at that path
3. **If they exist, archive the previous version:** Rename the existing file to `brand-voice-guidelines-YYYY-MM-DD.md` in the same directory (using today's date)
4. **Save new guidelines** to `.claude/brand-voice-guidelines.md` inside the working folder
5. **Confirm to the user** with the full absolute path: "Guidelines saved to `<full-path>`. `/brand-voice:enforce-voice` will find them automatically in future sessions."
The guidelines are also present in this conversation, so `/brand-voice:enforce-voice` can use them immediately without loading from file.
After saving, offer:
1. Walk through the guidelines section by section
2. Start creating content with `/brand-voice:enforce-voice`
3. Resolve open questions
## Privacy and Security
Enforce these privacy constraints throughout the entire generation workflow, not only at output time:
- Redact customer names and contact information from all examples
- Anonymize company names in transcript excerpts if requested
- Flag any sensitive information detected during processing
## Reference Files
- **`references/guideline-template.md`** — Complete output template with all sections, field definitions, and formatting guidance
- **`references/confidence-scoring.md`** — Confidence scoring methodology, thresholds, and examples
@@ -0,0 +1,128 @@
# Confidence Scoring Methodology
How to assign and interpret confidence scores for generated brand guidelines.
## Scoring Levels
### High Confidence
The guideline section is well-supported and actionable.
**Criteria (must meet at least 3):**
- 3+ corroborating sources
- Explicit guidance found in at least one AUTHORITATIVE source
- Consistent across document and conversation analysis
- Specific, actionable instructions (not just vague principles)
- No unresolved conflicts
**Example:** Voice attribute "Confident but not arrogant" appears in the official style guide, is demonstrated in email templates, and matches patterns in top performer calls.
### Medium Confidence
The section is reasonable but could benefit from more data or team confirmation.
**Criteria (must meet at least 2):**
- 1-2 corroborating sources
- Inferred from patterns rather than explicit instruction
- Minor inconsistencies resolved via recency or authority
- Actionable but some interpretation was required
- May have one unresolved conflict
**Example:** Tone for social media inferred from email templates and one Slack thread, but no official social media guidelines exist.
### Low Confidence
The section is a best-effort recommendation. Team review strongly recommended.
**Criteria (must meet at least 2):**
- Single source only
- Primarily inferred from indirect evidence
- Significant interpretation required
- Unresolved conflicts between sources
- Limited specificity
**Example:** Competitive positioning derived from a single sales call where a competitor was discussed, with no supporting documentation.
## Section-Level Scoring Guide
### Voice Attributes
- **High**: Attributes appear in official brand guide AND are demonstrated in templates or calls
- **Medium**: Attributes appear in one document type only, or are inferred from multiple conversations
- **Low**: Attributes inferred from a single source or from indirect evidence
### Messaging Framework
- **High**: Value propositions documented in official materials AND used consistently in sales conversations
- **Medium**: Documented but not observed in practice, OR observed but not documented
- **Low**: Extracted from a single pitch deck or single call
### Tone Matrix
- **High**: Explicit tone guidance exists for the context AND matches observed behavior
- **Medium**: Tone inferred from 3+ examples of content in that context
- **Low**: Tone inferred from 1-2 examples, or extrapolated from similar contexts
### Terminology
- **High**: Terms explicitly listed in a style guide or glossary
- **Medium**: Terms consistently used in templates and calls (pattern-based)
- **Low**: Terms observed in a single document or inferred from brand personality
### Language Patterns (from transcripts)
- **High**: Pattern observed in 5+ calls across multiple speakers
- **Medium**: Pattern observed in 3-4 calls or from a single top performer
- **Low**: Pattern observed in 1-2 calls only
### Transcript-Primary Scenarios
When guidelines are generated primarily from conversational sources (no AUTHORITATIVE documents available):
- Voice Attributes derived from 5+ transcripts = **Medium** (not Low)
- Messaging Framework from consistent patterns across 5+ calls = **Medium**
- Language Patterns weight increases from 10% to 20% in aggregate calculation (subtract 10% from Voice Attributes)
Note this in the guideline metadata: "Guidelines generated primarily from conversational sources — team review recommended to formalize."
## Aggregate Confidence
Calculate overall guideline confidence as the weighted average of section scores:
| Section | Weight |
|---------|--------|
| Voice Attributes | 30% |
| Messaging Framework | 25% |
| Tone Matrix | 20% |
| Terminology | 15% |
| Language Patterns | 10% |
Convert scores: High = 1.0, Medium = 0.6, Low = 0.3
**Example:**
- Voice Attributes: High (1.0 x 0.30 = 0.30)
- Messaging: Medium (0.6 x 0.25 = 0.15)
- Tone: Medium (0.6 x 0.20 = 0.12)
- Terminology: High (1.0 x 0.15 = 0.15)
- Language: Low (0.3 x 0.10 = 0.03)
- **Overall: 0.75 = Medium-High confidence**
**Aggregate score thresholds:**
- 0.851.0 = High
- 0.600.84 = Medium
- Below 0.60 = Low
## Presentation
Present confidence alongside each section header:
```markdown
## Voice Attributes (Confidence: High)
[content]
## Tone Matrix (Confidence: Medium)
[content — note: no official social media guidelines found, tone inferred from email patterns]
```
For Medium and Low confidence sections, include a brief note explaining why confidence is limited and what would raise it.
## Relationship to Open Questions
Low confidence sections should generate corresponding open questions:
- **Low confidence + conflict** = High Priority open question
- **Low confidence + gap** = Medium Priority open question
- **Medium confidence + minor inconsistency** = Low Priority open question
Every open question includes a recommendation that, if confirmed, would raise the section's confidence score.
@@ -0,0 +1,241 @@
# Brand Guidelines Output Template
The complete structure for generated brand voice guidelines. Fill each section based on discovered and analyzed sources. The following is a raw markdown template — copy and fill the sections below. Omit sections with no data rather than including empty placeholders.
# [Company Name] Brand Voice Guidelines
## Generation Metadata
- Created: [date]
- Version: [N] (incremented from previous if updating)
- Replaces: [previous version date, if applicable]
- Sources: [list of documents and/or conversations analyzed]
- Documents processed: [N]
- Conversations analyzed: [N]
- Discovery report used: [Yes/No]
- Overall confidence: [High/Medium/Low]
---
## Executive Summary
[2-3 paragraph overview of the brand voice. What makes this brand distinctive?
What is the core personality? How should content feel to the reader?]
---
## We Are / We Are Not
The foundational brand identity anchor. Voice is constant — it doesn't change by channel or audience.
| We Are | We Are Not |
|--------|------------|
| **[Attribute 1]** — [brief description] | **[Counter 1]** — [what to avoid] |
| **[Attribute 2]** — [brief description] | **[Counter 2]** — [what to avoid] |
| **[Attribute 3]** — [brief description] | **[Counter 3]** — [what to avoid] |
| **[Attribute 4]** — [brief description] | **[Counter 4]** — [what to avoid] |
| **[Attribute 5]** — [brief description] | **[Counter 5]** — [what to avoid] |
### Voice Attributes Detail
For each "We Are" attribute:
#### [Attribute 1]: [Name]
- **What it means**: [detailed description]
- **How it shows up**: [specific behaviors in content]
- **What to avoid**: [the "We Are Not" counterpart, expanded]
- **Evidence**: [source quote or pattern, with citation]
- **Confidence**: [High/Medium/Low]
[Repeat for each attribute]
---
## Brand Personality
- **Archetype**: [e.g., "The Expert Friend" — technically deep but never condescending]
- **If our brand were a person**: [brief personality sketch]
- **Core values expressed in voice**: [list]
---
## Messaging Framework
### Primary Value Proposition
[Core value statement — one sentence]
Variations observed:
- "[Variation 1]" (Source: [doc])
- "[Variation 2]" (Source: [doc])
### Key Message Pillars
1. **[Pillar Name]**
- Core idea: [one sentence]
- When to use: [contexts]
- Example phrasing: "[quote]"
- Frequency in conversations: [X]% (if transcript data available)
- Effectiveness: [High/Medium/Low] (if outcome data available)
2. **[Pillar Name]**
[same format]
3. **[Pillar Name]**
[same format]
### Competitive Positioning
- vs. [Competitor A]: [how we differentiate]
- vs. [Competitor B]: [how we differentiate]
- vs. Status Quo: [why change is worth it]
---
## Tone-by-Context Matrix
Voice is constant. Tone flexes by context. These three dimensions adjust:
| Context | Formality | Energy | Technical Depth | Key Principle |
|---------|-----------|--------|-----------------|---------------|
| Cold outreach | Medium | High | Low | Hook fast, earn attention |
| Discovery calls | Medium | Medium-High | Medium | Ask more than tell |
| Demo / presentation | Medium-High | High | High | Show, don't just describe |
| Enterprise proposal | High | Medium | High | ROI and precision |
| Follow-up email | Medium | Medium | Low-Medium | Add new value each touch |
| Social media | Low-Medium | High | Low | Brevity and personality |
| Customer success | Medium | Warm | Medium | Empathy and competence |
| Internal comms | Low | Medium | Varies | Authentic, less polished |
### Context-Specific Guidelines
#### Cold Outreach
- **Overall tone**: [description]
- **Opening approach**: [what works]
- **Do's**: [list]
- **Don'ts**: [list]
- **Example**: "[sample opening line]"
#### Discovery Calls
[same structure]
#### Proposals & RFPs
[same structure]
#### Social Media
[same structure]
---
## Terminology Guide
### Must-Use Terms
| Term | Usage | Instead Of | Example |
|------|-------|------------|---------|
| [term] | [when/how to use] | [what it replaces] | "[in a sentence]" |
### Preferred Terms
| Term | Usage | Example |
|------|-------|---------|
| [term] | [guidance] | "[in a sentence]" |
### Avoid These Terms
| Term | Reason | Alternative |
|------|--------|-------------|
| [term] | [why to avoid] | [what to use instead] |
### Never-Use Terms
| Term | Reason |
|------|--------|
| [term] | [why this is prohibited] |
---
## Language That Works
Ranked by effectiveness (from conversation analysis, if available):
### Top Phrases
1. **"[Phrase]"** — Context: [when to use], Why it works: [analysis]
2. **"[Phrase]"** — Context: [when to use], Why it works: [analysis]
### Questions That Engage
1. **"[Question]"** — Leads to: [typical outcome]
2. **"[Question]"** — Leads to: [typical outcome]
### Objection Handling Patterns
1. **Objection**: "[common objection]"
**Response pattern**: "[how top performers respond]"
**Why it works**: [analysis]
---
## Language to Avoid
### Anti-Patterns
1. **"[Phrase/pattern]"** — Problem: [what happens], Better: "[alternative]"
2. **"[Phrase/pattern]"** — Problem: [what happens], Better: "[alternative]"
---
## Content Examples
### Excellent Examples
[Full example with annotation explaining what makes it on-brand]
### Examples to Avoid
[Full example with annotation explaining what's off-brand and how to fix it]
---
## Confidence Scores
| Section | Confidence | Basis | Sources |
|---------|------------|-------|---------|
| Voice Attributes | [H/M/L] | [why] | [N sources] |
| Messaging Framework | [H/M/L] | [why] | [N sources] |
| Tone Matrix | [H/M/L] | [why] | [N sources] |
| Terminology | [H/M/L] | [why] | [N sources] |
| Language Patterns | [H/M/L] | [why] | [N sources] |
---
## Open Questions for Team Discussion
### High Priority (blocks guideline completion)
1. **[Question Title]**
- What was found: [description of ambiguity]
- Agent recommendation: [suggested resolution]
- Need from you: [specific decision]
### Medium Priority (improves quality)
[same format]
### Low Priority (nice to have)
[same format]
---
## Data Gaps & Recommendations
[What's missing and specific actions to fill gaps]
- [ ] [Gap 1]: [recommendation to fill it]
- [ ] [Gap 2]: [recommendation to fill it]
---
## Appendix: Sources
| # | Source | Platform | Type | Date | Key Sections Used | Confidence |
|---|--------|----------|------|------|-------------------|------------|
| 1 | [title] | [platform] | [AUTHORITATIVE/OPERATIONAL/etc.] | [date] | [sections] | [H/M/L] |
---
## Template Usage Notes
- Omit sections with no data rather than including empty placeholders
- If transcript data is unavailable, omit the "Language That Works" and "Language to Avoid" sections
- If only documents are available (no transcripts), note this in metadata
- "We Are / We Are Not" table should have minimum 4 rows, ideally 5-7
- Tone matrix should cover at minimum: cold outreach, proposals, social media
- All examples must have source attribution
- Every open question must include an agent recommendation
@@ -0,0 +1,9 @@
{
"name": "common-room",
"version": "1.0.0",
"description": "Turn Common Room into your GTM copilot. Research accounts and contacts, prep for calls with attendee profiles and talking points, and draft personalized outreach across email, LinkedIn, and phone. Build targeted prospect lists, generate weekly briefings for every upcoming call, and create strategic account plans — all grounded in real signal data from product usage, engagement and intent signals, so every output reflects what's actually happening in your accounts.",
"author": {
"name": "Common Room"
},
"keywords": ["common-room", "sales", "gtm", "account-research", "prospecting", "outreach"]
}
+8
View File
@@ -0,0 +1,8 @@
{
"mcpServers": {
"common-room": {
"type": "http",
"url": "https://mcp.commonroom.io/mcp"
}
}
}
+25
View File
@@ -0,0 +1,25 @@
# Connectors
## How tool references work
Plugin files use `~~category` as a placeholder for whatever tool the user connects in that category. This plugin is built around Common Room as the primary data source — but some workflows benefit from an optional calendar integration.
## Connectors for this plugin
| Category | Placeholder | Included servers | Other options |
|----------|-------------|-----------------|---------------|
| Calendar | `~~calendar` | Google Calendar (via MCP) | Outlook / Microsoft 365 Calendar |
## Common Room MCP
The Common Room MCP server (`mcp.commonroom.io/mcp`) is the primary data source for all skills and commands in this plugin. It is listed in `.mcp.json` and must be connected and authenticated for the plugin to function.
## Calendar (Optional)
The `~~calendar` connector is used in two skills:
- **call-prep** — to automatically pull attendee names from upcoming meetings
- **weekly-prep-brief** — to fetch all external meetings scheduled in the next 7 days
If no calendar is connected, both skills gracefully fall back to asking the user for meeting details manually. The calendar connector is entirely optional.
To connect a calendar, install a compatible calendar MCP server and ensure it is authenticated. The plugin will automatically detect and use it when available.
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+64
View File
@@ -0,0 +1,64 @@
# Common Room Plugin
GTM workflows powered by Common Room — account research, contact research, call prep, personalized outreach, prospecting, and weekly briefings.
## Overview
This plugin connects Claude to Common Room's MCP server and equips it with six skills covering the most common rep workflows. Every output is grounded in real Common Room signal data — 1st-party product signals, 2nd-party community signals, 3rd-party intent signals, and enrichment from RoomieAI and Spark.
## Requirements
- **Common Room MCP** (`mcp.commonroom.io/mcp`) must be connected and authenticated. This is the primary data source for all plugin functionality.
- **Calendar connector** (optional) — enables automatic meeting lookup in `call-prep` and `weekly-prep-brief`. If not connected, both skills ask the user for meeting details instead.
## Skills
Skills are triggered conversationally. Describe what you want and Claude will load the right skill automatically.
| Skill | Trigger phrases |
|-------|----------------|
| `account-research` | "Research [company]", "tell me about [domain]", "what's going on with [account]", "is [company] showing buying signals" |
| `contact-research` | "Who is [name]", "look up [email]", "research [contact]", "is [name] a warm lead" |
| `call-prep` | "Prep me for my call with [company]", "prepare for a meeting with [company]", "what should I know before talking to [company]" |
| `compose-outreach` | "Draft outreach to [person]", "write an email to [name]", "compose a message for [contact]" |
| `prospect` | "Find companies that match [criteria]", "build a prospect list", "find contacts at [type of company]" |
| `weekly-prep-brief` | "Weekly prep brief", "prepare my week", "what calls do I have this week" |
## Commands
Two commands for complex workflows that benefit from explicit invocation:
| Command | Usage |
|---------|-------|
| `/generate-account-plan <company>` | Comprehensive strategic account plan with stakeholder mapping, engagement analysis, opportunities, risks, and action items |
| `/weekly-brief [date range]` | Generate a full weekly prep briefing (defaults to next 7 days) |
## What Each Skill Produces
**Account Research** — Handles four patterns: full overviews, targeted field questions, honest sparse-data responses, and combined MCP data + LLM reasoning. Includes web search for recent news. Automatically scopes to "My Segments."
**Contact Research** — Lookup by email, name+company, or social handle. Returns enriched identity, CRM fields, scores, website visits, activity history, Spark analyses, and conversation starters.
**Call Prep** — Company snapshot, per-attendee profiles, signal highlights, tailored talking points, likely objections, and recommended call outcome. Prioritizes Gong/call recording activity. Calendar-aware if connected.
**Compose Outreach** — Three personalized formats (email, call script, LinkedIn message) grounded in Common Room signals and web search hooks. Tailored to the user's company positioning when available.
**Prospecting** — Distinguishes between net-new companies (ProspectorOrganization) and existing accounts (Organization). Supports iterative refinement and lookalike search ("find companies like [X]"). Web search enriches net-new results.
**Weekly Prep Brief** — Full briefing covering every external call in the next 7 days: company snapshot, attendee profiles, signals, and recommended objectives per meeting.
## Setup
1. Ensure the Common Room MCP server is connected and authenticated in your Cowork settings.
2. (Optional) Connect a calendar MCP server for automatic meeting lookup in call prep and weekly briefings.
3. Install this plugin. All skills and commands are available immediately.
## User Context
All skills that scope to a user's territory automatically fetch the `Me` object from Common Room. This provides the user's profile, role, and "My Segments" — ensuring queries default to their territory. See `references/me-context.md` for details.
When company context is available, skills tailor recommendations to the user's product and ICP. See `references/my-company-context.md` for details.
## Customization
See `CONNECTORS.md` for details on the calendar connector and how tool references work.
@@ -0,0 +1,75 @@
---
description: Generate a comprehensive strategic account plan
argument-hint: <company name or domain>
---
Generate a comprehensive account plan for "$ARGUMENTS".
## Process
1. **Full account research** — Follow the account-research skill to produce a complete account overview. Pull all available first-party (product), second-party (community), and third-party (intent) signals, CRM data, scores, and RoomieAI research.
2. **Stakeholder mapping** — Fetch the top 5 contacts at this company sorted by member score descending. Classify each into: Champion, Economic Buyer, Influencer, End User, or Unknown. Use Spark persona data if available; if Spark is unavailable, infer from engagement patterns and activity recency. If no activity data exists either, classify as Unknown.
3. **Engagement analysis** — Pull all organization activity for the last 90 days (up to 50 activities). Identify trends: is engagement growing, stable, or declining? Which contacts are most active? What channels are they engaging through?
4. **Web search (supplementary)** — If CR data is rich, skip. If data is thin or the user requests it, search for recent company news (last 30 days): funding, acquisitions, product launches, leadership changes, competitive moves.
5. **Synthesis** — Combine all data into a structured account plan. When the user's company context is available (see `references/my-company-context.md`), tailor the executive summary, opportunities, and action items to the user's product and ICP.
## Output Format
```
## Account Plan: [Company Name]
### Executive Summary
[3-4 sentences: relationship status, key opportunity, primary risk, recommended priority]
### Account Overview
| Field | Value |
|-------|-------|
| Industry | ... |
| Size | ... |
| Domain | ... |
| CRM Owner | ... |
| Opp Stage | ... |
| ARR | ... |
| Scores | ... |
### Stakeholder Map
**Champions**
- [Name] — [Title] — [Key signals, last activity date]
**Economic Buyers**
- [Name] — [Title] — [Key signals]
**Influencers**
- [Name] — [Title] — [Key signals]
**End Users**
- [Name] — [Title] — [Key signals]
### Engagement Analysis
[Trend summary: growing/stable/declining, most active contacts, top channels, comparison to 90 days prior if data available]
### Recent News [If web search was run]
[Web search findings with sources and dates]
### Opportunities
1. [Signal-backed opportunity with specific next step]
2. ...
### Risks
1. [Signal-backed risk with mitigation]
2. ...
### Prioritized Action Items
1. [Specific action] — [Owner suggestion] — [Timeline]
2. ...
3. ...
```
Ground every insight in actual data. Flag explicitly when data is thin or unavailable.
**If Common Room returns sparse data for this account**, produce an abbreviated plan that covers only the sections with real data. Do not generate a full account plan from minimal input — a short honest plan with gaps clearly noted is far more useful than a comprehensive-looking plan built on fabricated details. Omit sections (Stakeholder Map, Engagement Analysis, Opportunities, Risks) entirely if there is no data to support them.
@@ -0,0 +1,14 @@
---
description: Generate a weekly prep briefing from your calendar and Common Room
argument-hint: [date range, defaults to next 7 days]
---
Generate a weekly prep briefing using Common Room and your calendar.
Follow the weekly-prep-brief skill:
1. Use the ~~calendar connector to retrieve all external customer-facing meetings scheduled for the next 7 days (or the date range specified in "$ARGUMENTS"). Filter out internal meetings — focus on calls with customers, prospects, or partners.
2. If no ~~calendar connector is available, ask the user to list their external calls (company name, date, attendees).
3. For each external meeting, run account research and contact research on attendees in parallel.
4. Compile into a single weekly briefing: week overview + per-meeting sections sorted by date.
Keep each per-meeting section tight and scannable. Total briefing should be readable in under 10 minutes.
@@ -0,0 +1,40 @@
# The `Me` Object — User Context Guide
## What `Me` Is
The `Me` object in Common Room represents the currently authenticated user. Fetching it at the start of a session gives the LLM context to personalize outputs and scope queries correctly.
Always fetch `Me` before running account research, prospecting, or any workflow that should be scoped to the user's territory.
## What `Me` Returns
### User Profile
- Login identifier (email or username)
- Full name and display name
- Job title and role
- Persona in CR (e.g., AE, SDR, CSM, Manager)
- All linked profiles (e.g., Salesforce user ID, LinkedIn handle)
### User Segments ("My Segments")
- A list of all segments that belong to this user (name and segment ID each)
- Corresponds to the **"My Segments" tab** in the Common Room product
## How to Use `Me` Context
### 1. Scope queries and respect territory boundaries
When running account research, prospecting, or generating briefings, filter results to the user's own segments unless they ask for a broader view.
> Default: "Show me accounts showing buying signals" -> scope to My Segments
> Override: "Show me all accounts in the workspace showing buying signals" -> remove segment scope
If a user asks about an account not in their segments, note: "This account doesn't appear to be in your segments — would you still like me to research it?"
### 2. Personalize outreach and briefings
Use the user's name, title, and role to personalize outputs — e.g., reference their territory in a weekly brief, use their name in drafted emails.
### 3. Infer context for reasoning
The user's Persona in CR influences how outputs should be framed:
- **AE / AM / Account Executive / Account Manager** — focus on pipeline, deals, expansion, close timelines
- **SDR / BDR / Sales Development Representative / Business Development Representative** — focus on prospecting, warm signals, first-touch outreach
- **CSM / Customer Success Manager** — focus on health, retention, expansion, champion engagement
- **Manager / Director / VP** — focus on team-level trends, not individual outreach
@@ -0,0 +1,20 @@
# My Company Context
## Purpose
Some skills produce better output when they understand the user's company — what it sells, its ICP, and competitive positioning. This context lets the LLM tailor account research, call prep, and outreach to the user's specific product and value prop.
## How to Gather Company Context
1. **Me object** — Fetch the `Me` object. It includes the user's company name and title.
2. **CR lookup** — Look up the user's company in Common Room as an Organization to get firmographics, industry, and description.
3. **Web search** — If CR data is sparse or looks stale, search the web for the user's company customer case studies, product pages, and marketing materials. This fills gaps with fresh positioning context that CR firmographics alone don't capture.
4. **Session context** — Check if the user has already described their product, ICP, or value prop in the current conversation.
5. **Ask once** — If company context isn't available from the above, ask the user once per session: "To tailor my recommendations, can you briefly describe what your company does and who your ideal customers are?"
## How to Use It
- **Account research (reasoning step):** Position findings relative to the user's ICP — "This account fits your ICP because..."
- **Call prep (talking points):** Frame talking points around the user's product value, not generic advice
- **Compose outreach (value bridge):** Ground the pitch in the user's specific product and positioning
- **Prospecting:** Use ICP criteria as default filter suggestions when the user doesn't specify criteria
@@ -0,0 +1,140 @@
---
name: account-research
description: "Research a company using Common Room data. Triggers on 'research [company]', 'tell me about [domain]', 'pull up signals for [account]', 'what's going on with [company]', or any account-level question."
---
# Account Research
Retrieve and synthesize account information from Common Room. Handles four interaction patterns: full overviews, targeted field questions, sparse data situations, and combined MCP data + LLM reasoning.
## Step 0: Load User Context (Me)
Before researching any account, fetch the `Me` object from Common Room. This provides:
- The user's profile, title, role, and Persona in CR
- The user's segments ("My Segments")
Default all queries to the user's own segments unless the user explicitly asks for a broader view. This keeps results scoped to their territory.
## Step 1: Identify the Interaction Pattern
Determine what the user actually needs before deciding how much data to fetch:
**Pattern 1 — Full Overview:** "Tell me about Datadog" / "Summarize cloudflare.com"
→ Fetch the full field set and produce a structured briefing.
**Pattern 2 — Targeted Question:** "Who owns the Snowflake account?" / "Is acme.io showing buying signals?" / "What's the employee count for notion.so?"
→ Fetch only the relevant field(s). Return a direct, concise answer — do not produce a full brief for a simple question.
**Pattern 3 — Sparse Data:** "Tell me about tiny-startup.io"
→ If Common Room has limited data for an account, say so honestly: "There is limited information available for this account." Never speculate or fill gaps with generic statements.
**Pattern 4 — Combined Reasoning:** Fetch structured MCP data, then layer in LLM analysis — e.g., "Stripe has 8,000 employees and is hiring heavily for AI roles. Based on your ICP of 1k10k fintech companies, this is a strong fit."
## Step 2: Look Up the Account
Search Common Room for the account by domain or company name. Exact match first; if no result, try partial match and confirm with the user before proceeding.
## Step 3: Fetch the Right Fields
Use the Common Room object catalog to see available field groups and their contents. For full overviews, request all field groups. For targeted questions, request only what's relevant.
**Key field groups to know about:**
- **Scores** — always return as raw values or percentiles, never labels
- **Summary research** — RoomieAI output; often the richest qualitative signal
- **Top contacts** — sorted by score desc; use communityMemberID for full lookups
**Choosing what to fetch:**
| User query type | Fields to request |
|-----------------|------------------|
| Full account overview | All field groups |
| "Who owns this account?" | Company profiles & links, CRM fields |
| "Is this company a good fit?" | Key fields, scores, about |
| "What signals is this account showing?" | Scores, summary research, CRM fields |
| "Who are the top contacts?" | Top contacts |
| "What does RoomieAI say about them?" | Summary research, all research |
| "Find engineers at this account" | Prospects (with title filter) |
## Step 4: Web Search (Sparse Data Only)
Common Room is the primary data source. Do not run web search when CR returns rich data.
When CR data is sparse (Pattern 3 — few fields returned, no activity, no scores), run a targeted web search to fill gaps:
- `"[company name]" news` — scoped to the last 30 days
- Look for: funding rounds, acquisitions, product launches, executive changes, press coverage
If the user explicitly asks for external context or recent news, run web search regardless of data richness.
## Step 5: Apply Reasoning (Pattern 4)
When the user's question invites synthesis — not just data retrieval — layer in analysis:
- Compare account data to known ICP criteria from session context
- Identify fit signals (size, industry, tech stack, hiring patterns)
- Note timing signals (funding, trial status, recent activity spike)
- Frame insights as clearly derived from data, not assumed
When the user's company context is available (see `references/my-company-context.md`), position findings relative to the user's value proposition and ICP.
## Step 6: Produce Output
Only include sections where Common Room returned actual data. Omit sections entirely rather than filling them with guesses.
**Full overview (when data is rich):**
```
## [Company Name] — Account Overview
**Snapshot**
[23 sentences: what they do, plan/stage, relationship status]
**Key Details**
[Employee count, industry, location, domain, funding — from key fields]
**CRM & Ownership** [If CRM fields returned]
[Owner, opp stage, ARR]
**Scores** [If scores returned]
[All available scores as raw values or percentiles]
**Signal Highlights** [If activity/signals exist]
[35 most important signals with dates]
**Top Contacts** [If contacts returned]
[Name | Title | Score — top 5 sorted by score desc]
**RoomieAI Research** [If summary research is non-null]
[Summary research output; list all available research topic names]
**Recommended Next Steps**
[23 specific, signal-backed actions]
```
**Targeted question:** 13 sentence direct answer. No full brief needed.
**Sparse data (few fields returned, most sections would be empty):**
```
## [Company Name] — Account Overview (Limited Data)
**Data available:** [List exactly what Common Room returned]
[Present only the returned fields]
**Web Search**
[Findings from web search — or "No significant recent news found"]
**Note:** Common Room has limited data on this account. The account may need enrichment in Common Room.
```
## Quality Standards
- Scores must always be raw values or percentiles — never categorical labels
- For targeted questions, answer precisely and don't over-deliver
- Be explicit when data is missing or stale — don't speculate
- Keep full briefings readable in 23 minutes
- **Every fact must trace to a tool call** — don't include data not returned by Common Room
## Reference Files
- **`references/signals-guide.md`** — signal type taxonomy and interpretation guide
@@ -0,0 +1,52 @@
# Common Room Signal Types — Interpretation Guide
## Signal Categories
### Product Signals (1st-Party)
| Signal | What it means |
|--------|--------------|
| Active seats increasing | Expansion within the account — outreach opportunity |
| Feature adoption (new features used) | Product engagement deepening — good for expansion talk |
| Login frequency spike | Increased engagement — follow up to understand why |
| Login frequency drop | Risk of disengagement or churn — proactive outreach needed |
| Trial started | Active evaluation — time-sensitive, prioritize |
| Trial nearing expiry | Decision point approaching — immediate action |
| Support tickets opened | Potential friction — check for patterns |
### Community Signals (2nd-Party)
| Signal | What it means |
|--------|--------------|
| New community post | Actively engaged, has a question or idea |
| Reply / reaction to post | Community participation |
| Forum thread started | Seeking help or sharing feedback — can engage directly |
| Documentation viewed (specific page) | Researching a specific feature — high value if tied to expansion area |
| Event registration/attendance | Strong engagement and intent signal |
### Intent Signals (3rd-Party)
| Signal | What it means |
|--------|--------------|
| Hiring for relevant roles | Growing team, budget exists |
| Funding announced | New budget likely available — reach out congratulating |
| Company news / press mention | Good hook for outreach |
| Tech stack change | May need new integrations |
| Competitive product removed from stack | Window of opportunity — very high priority |
| Website activity spike | Active research phase |
### Relationship Signals
| Signal | What it means |
|--------|--------------|
| Recent meeting logged | Active relationship — context available |
| No meeting in 90+ days | Relationship cooling — check in |
| Open opportunity in CRM | Active deal — coordinate with AE |
| Champion job change | Relationship risk or opportunity |
## Signal Interpretation Principles
1. **Recency matters most.** A signal from yesterday far outweighs one from 6 months ago. Always note timestamps.
2. **Signal clusters > single signals.** Multiple signals in the same direction are much stronger than any individual one.
3. **Absence of signals is a signal.** Minimal usage + no community engagement at a paid account = risk indicator.
4. **Contextualize against account stage.** Trial: conversion signals dominate. Mature customer: expansion and churn-risk. Prospect: intent signals are paramount.
@@ -0,0 +1,137 @@
---
name: call-prep
description: "Prepare for a customer or prospect call using Common Room signals. Triggers on 'prep me for my call with [company]', 'prepare for a meeting with [company]', 'what should I know before talking to [company]', or any call preparation request."
---
# Call Prep
Produce a complete, scannable call prep brief by combining account research, contact research, and signal synthesis from Common Room.
## Prep Process
### Step 1: Identify the Account and Attendees
Parse what the user has provided:
- **Company name** — required; look up the account in Common Room
- **Attendee names** — optional; if provided, research each one
**Calendar lookup:** If a `~~calendar` connector is available, search for upcoming meetings with the named company to automatically surface attendee names, meeting time, and any meeting notes or agenda. Use this to fill gaps the user didn't provide.
If neither attendees nor a calendar match can be found, ask: "Who will be on the call from [Company]? I can research each attendee to make your prep more useful."
### Step 2: Run Account Research
Use the account-research skill process to build a full account snapshot. For call prep, prioritize:
- Recent product signals (what are they doing in the product right now?)
- Open opportunities or renewal timeline
- Any risk signals (declining usage, support tickets, churned seats)
- Key recent events (funding, executive change, new hire)
When reviewing activity history, prioritize Gong and call recording activities — these provide direct context about previous conversations. Do not filter out call recordings by activity origin.
### Step 3: Run Contact Research for Each Attendee
For each external attendee, use the contact-research skill process. For call prep, focus on:
- Role and influence in the buying process
- Their personal activity and engagement history
- Any recent signals that suggest their current mood/priorities
- Spark persona classification if available
### Step 4: Synthesize Talking Points and Objectives
Based on the combined account and contact research:
- Identify the **call objective** (e.g., discovery, demo, expansion conversation, renewal, QBR)
- Generate **35 tailored talking points** grounded in specific signal data
- Anticipate **23 likely objections or topics** the customer may raise
- Suggest a **recommended outcome** for the call
When the user's company context is available (see `references/my-company-context.md`), tailor talking points to the user's product and value proposition.
### Step 5: Recency Check (Web Search)
After gathering all Common Room data, run a quick recency check to catch anything that happened since the last CR data sync. This is supplementary — CR data drives the prep; web search only adds recency.
**Company news:** Search `"[company name]" news` filtered to the last 14 days. Look for funding announcements, product launches, leadership changes, layoffs, partnerships, or press coverage.
**Attendee presence:** For each external attendee, search `"[full name]" "[company name]"` — look for recent articles, LinkedIn posts, conference talks, podcasts, or published opinions.
If a company news item is significant (e.g., just raised a round, announced a major hire), flag it in Signal Highlights. Otherwise, include findings briefly — don't let web search results overshadow CR signals.
## Output Format
The output adapts to how much data Common Room returned. Only include sections where you have real data. Never fill a section with invented details.
### When data is rich (multiple field groups returned, activity history, scores, signals):
```
## Call Prep: [Company] — [Date/Time if known]
**Meeting Context**
[Attendees, meeting type, and any known agenda]
---
### Company Snapshot
[46 bullets: key account status, signals, and recent activity]
---
### Attendee Profiles
**[Attendee Name] — [Title]**
[34 bullets: role, recent activity, Spark persona if available, personal hook]
[Repeat for each attendee]
---
### Signal Highlights
[Top 3 signals most relevant to this specific call]
---
### Talking Points
1. [Point tied to a specific signal]
2. [Point tied to a specific signal]
3. [Point tied to a specific signal]
### Likely Topics / Objections to Prepare For
- [Topic or objection + suggested response]
- [Topic or objection + suggested response]
### Recommended Call Outcome
[12 sentences: what success looks like for this meeting]
```
### When data is sparse (few fields returned, no activity, null sparkSummary):
```
## Call Prep: [Company] — [Date/Time if known]
**Data available:** [List exactly what Common Room returned — e.g., "Name, title, email, two tags. No activity history, no scores, no Spark data."]
### What I Found
[Only the fields actually returned, presented as-is]
### Web Search Results
[Findings from web search on the company and attendees — or "No significant results"]
### Suggested Next Steps
- I can pull [specific field groups] from Common Room if available
- I can run deeper web searches on [specific topics]
- You may want to check Common Room directly for [what's missing]
```
Do not generate a full call prep brief from sparse data. A short honest output is always better than a long fabricated one.
## Quality Standards
- Ground every talking point in a real signal — no generic filler
- Keep the brief tight — it should be readable in 5 minutes or less
- Flag unknowns explicitly — if attendee research is thin, say so
- Time-box the research — don't over-research at the expense of speed
- **Never invent deal context** — no fabricated proposals, competitor comparisons, pricing, trial terms, or objections not returned by a tool call
## Reference Files
- **`references/call-types-guide.md`** — guidance for different call types (discovery, expansion, renewal, QBR) and how to tailor prep accordingly
@@ -0,0 +1,55 @@
# Call Types — Prep Guide
## Identifying the Call Type
If the user doesn't specify, infer from context: trial + early signals = Discovery/Demo; active CRM opportunity = Demo/Evaluation/Negotiation; existing customer + renewal date = Renewal/QBR; expansion signals = Expansion; support tickets + declining usage = Save call.
---
## Discovery Call
**Goal:** Understand the prospect's pain, context, and fit.
- Identify what signals triggered the meeting and prepare open-ended questions tied to those signals
- Form a hypothesis about their primary use case from Spark persona and activity data
- **Talking point structure:** Signal -> question -> how you might help
## Demo Call
**Goal:** Show the product in context of their specific needs.
- Note which features they've already explored and competitors in their stack
- Identify audience (technical evaluator vs economic buyer) and match depth accordingly
- Highlight 1-2 features based on their known activity
## Expansion Conversation
**Goal:** Identify and close upsell/cross-sell or seat expansion.
- Identify product areas with highest recent adoption and emerging teams/use cases
- Lead with usage data demonstrating value already delivered
- Present expansion as a natural next step tied to their business outcomes
## Renewal / Retention Call
**Goal:** Secure renewal; address any risk.
- Check engagement trend, open support tickets, and champion status
- Quantify value delivered (usage stats, outcomes) as renewal justification
- Address risk signals directly and proactively — have a retention offer ready if needed
## QBR (Quarterly Business Review)
**Goal:** Review progress, align on strategy, deepen executive relationship.
- Analyze 90-day signal trends and breadth of adoption across teams
- Lead with business outcomes, not feature usage — surface 1-2 surprising stats
- Come with a forward-looking agenda and next quarter goals
## Save / Risk Call
**Goal:** Understand and reverse negative trajectory.
- Identify specific decline signals (what dropped and when) and check for unresolved tickets
- Acknowledge the signals without being defensive — ask questions before presenting solutions
- Have a concrete action plan ready
@@ -0,0 +1,135 @@
---
name: compose-outreach
description: "Generate personalized outreach messages using Common Room signals. Triggers on 'draft outreach to [person]', 'write an email to [name]', 'compose a message for [contact]', or any outreach drafting request."
---
# Compose Outreach
Generate three personalized outreach formats — email, call script, and LinkedIn message — grounded in Common Room signals for a specific company or contact.
## Outreach Process
### Step 1: Look Up the Target
Use Common Room MCP tools to find and retrieve data for the target (company and/or specific contact). Pull:
- Recent product activity and engagement signals
- Community activity (posts, questions, reactions)
- 3rd-party intent signals (job postings, news, funding)
- Relationship history (prior contact, meetings, email opens)
If the user specified a person, run contact-level research. If only a company was given, identify the best contact to target based on title, engagement, and role.
### Step 2: Web Search for External Hooks (If CR Signals Are Thin)
If CR returned strong signals (recent activity, engagement, product usage), those should drive personalization — skip web search. If CR signals are thin or the prospect has little CR activity, run a web search for external hooks:
**What to search:**
- `"[company name]" funding OR acquisition OR launch OR announcement` — last 30 days
- `"[contact full name]" "[company name]"` — look for recent articles, interviews, LinkedIn posts, or conference talks
**Prioritize external hooks that are:**
- Very recent (< 2 weeks) — the prospect is likely still thinking about it
- Publicly visible — they know you could have seen it
- Change-signaling — growth, new role, new product, new market
If the user explicitly asks for web search or external hooks, run it regardless of CR signal richness.
### Step 3: Spark Enrichment (If Available)
If Spark is available, run enrichment on the target contact to get persona classification, background, and influence signals. Use this to calibrate tone and message angle.
### Step 4: Identify the Best Hooks
From the signal data, identify the 13 strongest personalization hooks. Rank by:
1. **Recency** — happened in the last 714 days
2. **Specificity** — a concrete action they took, not a general trend
3. **Relevance** — connects directly to a value your product delivers
Good hooks: posted a question in the community about X, just hired 5 engineers, recently started using [feature], company just raised Series B, trial nearing expiration, champion just changed jobs.
Bad hooks: "I noticed you're a customer" or generic industry trends.
### Step 5: Generate All Three Formats
Use the strongest hooks to write all three formats. Each format has different constraints and conventions — follow the format-specific guidelines in `references/outreach-formats-guide.md`.
Always produce all three, clearly labeled.
When the user's company context is available (see `references/my-company-context.md`), ground the value bridge and pitch in the user's specific product and positioning.
### Step 6: Annotate Your Choices
After the three drafts, include a brief note (24 sentences) explaining:
- Which signals were used and why they were chosen
- Any assumptions made (e.g., inferred call objective)
- Alternative angles if the primary hook doesn't land
## Output Format
```
## Outreach for [Name / Company]
### 📧 Email
**Subject:** [Subject line]
[Email body — 35 sentences]
---
### 📞 Call Script
**Opening:**
[Opening line — conversational, 12 sentences]
**Value Bridge:**
[Why you're calling and why now — 23 sentences tied to a signal]
**Ask:**
[Single, low-friction ask — e.g., 15-minute call, specific question]
---
### 💼 LinkedIn Message
[Under 300 characters. Warm, personal, no pitch.]
---
### Signal Notes
[24 sentences: which signals were used, why, and any alternative angles]
```
## When Signal Data Is Sparse
If Common Room returns minimal data on the target (e.g., just name, title, tags — no activity, no scores, no Spark):
1. **Do not draft outreach from thin air.** Outreach grounded in fabricated signals is worse than no outreach.
2. **Run web search first** — this becomes your primary personalization source. Look for recent news, LinkedIn posts, conference talks, company announcements.
3. **If web search also returns little**, present what you have honestly and ask the user for context:
```
## Outreach for [Name / Company] — Limited Data
**What I found:**
[Only the real data from CR and web search]
**I don't have enough signal to draft personalized outreach yet.** To write something strong, I'd need:
- Recent activity or engagement signals
- Context you have from prior conversations
- A specific reason for reaching out now
Can you share any of the above?
```
## Quality Standards
- Every message must reference something specific — generic outreach is not acceptable output
- Match tone to context: warm and conversational for inbound/community signals; more formal for cold/executive outreach
- The LinkedIn message must be under 300 characters — no exceptions
- The call script must be speakable naturally — read it aloud mentally to check rhythm
- **Never fabricate signals** — only reference data retrieved from Common Room or web search
## Reference Files
- **`references/outreach-formats-guide.md`** — detailed format rules, examples, and tone guidelines for each channel
@@ -0,0 +1,67 @@
# Outreach Formats — Guidelines and Examples
## Email
### Structure
- **Subject line:** 4-8 words, specific and curiosity-inducing. Reference the hook directly.
- **Opening:** Acknowledge the specific signal. Start with "You", "Your team", "Saw that", "Noticed" — not "I".
- **Value Bridge:** 1-2 sentences connecting their signal to something you can help with. Be concrete.
- **Ask:** Single, specific, low-friction next step.
- **Total length:** 3-5 sentences max. No paragraphs.
### Example
> Subject: Question about your [feature] usage
>
> Noticed your team has been deep in [feature] recently — you've hit [usage metric] in the last two weeks. That usually means teams are running into [common blocker] around this stage. Happy to walk through how [similar company] handled it if useful. 15 minutes this week?
---
## Call Script
Three parts — a guide, not a word-for-word read:
**Opening (10-15 seconds):** State your name and company, then reference the specific hook immediately.
**Value Bridge (20-30 seconds):** Explain why this is worth their time *right now*, tied to a concrete outcome.
**Ask (10 seconds):** Single, specific, low-friction — e.g., "Do you have 15 minutes to explore if that's relevant?"
---
## LinkedIn Message
### Constraints
- **300 characters maximum** (platform limit is 400 — we target 300 to prevent overruns)
- No attachments, no links in the first message
- No pitch — just open a door
### Structure
- Personal acknowledgment (what you noticed about them)
- One brief sentence on why you reached out
- Soft invitation to connect or respond
### Example
> Saw your post about [topic] in [community] — our team has been thinking about the same problem. Would love to share what we've learned. Open to a quick chat?
---
## Tone Calibration by Context
| Context | Tone | Approach |
|---------|------|----------|
| Inbound / trial / active community member | Warm, helpful, collaborative | Lead with their activity, offer help |
| Cold outreach (no prior relationship) | Professional, respectful, brief | Lead with signal, be direct about why now |
| Re-engagement (went dark) | Casual, low-pressure | Short, acknowledge the gap, easy ask |
| Executive outreach | Formal, concise, outcome-focused | Lead with business impact, not product |
| Champion job change | Warm, congratulatory | Celebrate them, then gently explore new opportunity |
---
## What to Avoid (All Channels)
- Starting with filler ("I hope this email finds you well") or defensive language ("I know you're busy but...")
- Multi-paragraph messages with multiple asks
- Vague subject lines like "Following up" or "Quick question"
- Fabricated familiarity ("I've been following your company for a while...")
@@ -0,0 +1,129 @@
---
name: contact-research
description: "Research a specific person using Common Room data. Triggers on 'who is [name]', 'look up [email]', 'research [contact]', 'is [name] a warm lead', or any contact-level question."
---
# Contact Research
Retrieve a comprehensive contact profile from Common Room. Supports lookup by email, social handle, or name + company. Returns enriched data including activity history, Spark, scores, website visits, and CRM fields.
## Step 1: Locate the Contact
Common Room supports multiple lookup methods — use whichever the user has provided:
| What the user gives | Lookup method |
|---------------------|--------------|
| Email address | Look up by email (most reliable) |
| LinkedIn, Twitter/X, or GitHub handle | Look up by social handle — specify handle type explicitly |
| Name + company | Identity resolution by name + org domain; present matches if ambiguous |
| Name only | Search by name; if multiple matches, show a brief list and ask the user to confirm |
If no match is found, respond: "Common Room doesn't have a record for this person." Do not speculate or fabricate profile data.
## Step 2: Fetch Contact Fields
Use the Common Room object catalog to see available field groups and their contents. For full profiles, request all groups. For targeted questions, request only what's relevant.
**Key field groups to know about:**
- **Scores** — always return as raw values or percentiles, never labels
- **Recent activity** — use `Contact Initiated` filter (last 60 days) for their actions, not your team's
- **Website visits** — total count + specific pages (last 12 weeks)
- **Spark** — retrieve all Sparks when tracking engagement evolution over time
## Step 3: Run Spark Enrichment (If Available)
If Spark is available, use it. Spark provides:
- Professional background and job history
- Social presence and influence signals
- Persona classification: Champion, Economic Buyer, Technical Evaluator, End User, or Gatekeeper
- Inferred role in the buying process
If Spark is unavailable but real activity data exists (recent actions, website visits, community engagement), infer a persona from those signals. If neither Spark nor activity data is available, classify as Unknown — do not guess a persona from title alone.
Retrieve **all Sparks** (not just the most recent) when the user wants to understand how this contact's engagement has evolved over time.
## Step 4: Assess Account Context
Pull an abbreviated account snapshot for this contact's parent company. Note:
- Open opportunities, expansion signals, or churn risk at the account level
- Whether other contacts at this company are also active
- How this person's engagement compares to their colleagues
## Step 5: Identify Conversation Angles
Based on activity and signals, surface the strongest 23 hooks:
- A recent `Contact Initiated` activity (community post, product event, support ticket)
- A specific web page they visited recently — especially if it signals evaluation intent
- A job change, promotion, or company news
- Their Spark persona and what that suggests about communication style
- Their role in a known active deal
## Output Format
Only include sections where data was actually returned. Omit sections with no data rather than filling them with guesses.
**When data is rich:**
```
## [Contact Name] — Profile
**Overview**
[2 sentences: who they are, their role, and relationship status]
**Details**
- Title: [title]
- Company: [company]
- Email: [email]
- LinkedIn: [URL]
- Other profiles: [Twitter/X, GitHub, CRM link if available]
**Scores** [If scores returned]
[All scores as raw values or percentiles]
**Recent Activity** (last 60 days) [If activity returned]
[35 bullets with dates]
**Website Visits** (last 12 weeks) [If visit data exists]
[Total visit count + list of pages visited]
**Spark Profile** [If Spark data is non-null]
[Persona type, background summary, influence signals]
**Segments** [If segments returned]
[List of segment names this contact belongs to]
**Account Context**
[12 sentences on their company's status]
**Conversation Starters**
[23 specific, signal-backed openers]
```
**When data is sparse (e.g., only name, title, email, tags returned; sparkSummary is null):**
```
## [Contact Name] — Profile (Limited Data)
**Data available:** [List exactly what Common Room returned]
[Present only the returned fields]
**Web Search**
[Any findings from searching their name + company]
**Note:** Common Room has limited data on this contact. No activity history, scores, or Spark profile available. I can run deeper web searches or look up their company for additional context.
```
Do not generate conversation starters, persona inferences, or engagement assessments from sparse data. These require real signals.
## Quality Standards
- Lookup must use the correct method for the input type — don't guess on email vs. handle
- Scores as raw/percentile only — never labels
- `Contact Initiated` activity (last 60 days) is the primary engagement signal — lead with it
- If Spark is unavailable, say so — don't fabricate a persona from title alone
- Flag any contact where the most recent activity is older than 30 days
## Reference Files
- **`references/contact-signals-guide.md`** — full field descriptions, Spark persona guide, and conversation starter principles
@@ -0,0 +1,48 @@
# Contact Signals — Interpretation Guide
## Contact Signal Types
### Activity Signals
| Signal | Interpretation |
|--------|---------------|
| Email open / reply | Actively aware of your org; replied = higher intent |
| Meeting attended | Relationship established; note meeting type (demo, QBR, etc.) |
| Community post or reply | Has a question, problem, or idea — high engagement signal |
| Support ticket opened | Experiencing friction — empathy opportunity |
| Documentation page visited | Researching a specific area — note which pages |
| Product login | Active user — check frequency and recency |
| Event registered/attended | Strong engagement and intent signal |
### Relationship Signals
| Signal | Interpretation |
|--------|---------------|
| No activity in 30+ days | Relationship cooling — gentle check-in appropriate |
| No activity in 90+ days | Dormant — may need re-engagement from a different angle |
| Consistent activity across multiple channels | Champion or highly engaged user — high-value contact |
| Activity spike after dormancy | Something changed — investigate why |
### Job / Professional Signals
| Signal | Interpretation |
|--------|---------------|
| Recent job change (new company) | Warm intro opportunity at new company; relationship may shift at old one |
| Promotion at same company | Growing influence — relationship becomes more valuable |
| Title change to decision-maker role | Upgrade the relationship strategy |
| Company expansion (new hires in their team) | Budget may be available; expansion opportunity |
## Spark Persona Classification
- *Champion* — daily user, advocates internally
- *Economic Buyer* — holds budget authority, may not use product directly
- *Technical Evaluator* — evaluates fit and integration, influences technical decisions
- *End User* — primary product user, influences renewal through NPS/feedback
- *Gatekeeper* — controls access, must be navigated carefully
## Conversation Starters
A strong starter references something specific, shows homework, opens a door without forcing one, and connects to value.
- "I saw your question in the community about [topic] — we just released a feature that addresses exactly that. Would it be useful to walk through it?"
- "Your team's usage of [feature] jumped last month — curious if you're running into [common blocker] at that stage."
@@ -0,0 +1,99 @@
---
name: prospect
description: "Build targeted account or contact lists using Common Room's Prospector. Triggers on 'find companies that match [criteria]', 'build a prospect list', 'find contacts at [type of company]', 'show me companies hiring [role]', or any list-building request."
---
# Prospecting
Build targeted account and contact lists using Common Room's Prospector. Supports iterative refinement through natural conversation, intent-based discovery, and both net-new prospecting and signal-based queries against existing accounts.
## Critical Distinction: Two Object Types
Common Room's Prospector operates against two fundamentally different object types. Always clarify which one is in play before running a query:
**`ProspectorOrganization`** — Companies **not yet in Common Room**
- Net-new companies that match specified criteria
- Available fields are firmographic only: name, domain, size, industry, capital raised, annual revenue, location
- Fewer filter options — no signal-based filters, no scores, no activity history
- Use when: building a brand-new target list, territory planning, top-of-funnel expansion
**`Organization`** (in Common Room) — Companies **already in your CR workspace**
- Full signal data available: product usage, community activity, CRM fields, scores, custom fields
- Much richer filter set — includes signal-based, score-based, segment-based, and firmographic filters
- Use when: finding warm accounts to prioritize, identifying expansion candidates, surfacing intent signals within existing pipeline
When a user's request could apply to both (e.g., "Show companies hiring AI engineers this month"), clarify:
> "Are you looking for net-new companies not yet in Common Room, or filtering accounts already in your workspace?"
The catalog should make this distinction explicit so the LLM can select the right Prospector endpoint.
## Step 0: Load User Context (Me)
Fetch the `Me` object to get the user's segments. When prospecting against `Organization` records (accounts already in CR), default to filtering within "My Segments" unless the user asks for a broader search.
## Step 1: Gather Targeting Criteria
If criteria are already provided, proceed. Otherwise ask:
> "What kind of accounts or contacts are you looking for? For example: company size, industry, job titles, signals like recent product activity or community engagement, geographic region, or specific intent signals like recent funding or job postings."
Use the Common Room object catalog to see available filters for each object type. The key distinction:
- **ProspectorOrganization** — firmographic and technographic filters only (industry, size, geography, funding, tech stack)
- **Organization** — all firmographic filters plus signal-based, score-based, segment-based, and CRM filters
**Lookalike search:** If the user asks to "find companies like [X]", first look up the reference company in Common Room (or via web search if not in CR). Extract its key attributes — industry, employee range, tech stack, funding stage, geography — and propose those as filter criteria. Present the derived criteria to the user for confirmation before running the search, since lookalike targeting works best when the user can refine which attributes matter most.
## Step 2: Support Iterative Refinement
Prospecting is conversational. Support multi-turn refinement naturally:
1. Run initial query with provided criteria
2. If results are large (50+), summarize and offer: "I found [N] results. Want to narrow by [suggested filter]?"
3. If results are too few (< 5), suggest: "Only [N] results with those filters — I can broaden by relaxing [specific criterion]."
4. Apply each refinement as a follow-up query, not a new search from scratch
Example flow:
- Rep: "Find cybersecurity companies in California." → 500 results
- Rep: "Only show ones over 300 employees using AWS." → 47 results
- Rep: "Focus on the ones with recent hiring activity." → 12 results ✓
## Step 3: Run the Query and Present Results
Execute the Prospector query with confirmed criteria. Sort by signal strength or fit score where available (not alphabetically).
**For `ProspectorOrganization` (net-new) results:**
| Company | Domain | Industry | Size | Capital Raised | Revenue | Location |
|---------|--------|----------|------|---------------|---------|----------|
**For `Organization` (in CR) results:**
| Company | Industry | Size | Top Signal | Signal Date | Score | CRM Stage |
|---------|----------|------|-----------|-------------|-------|-----------|
Flag any results where data is thin or the most recent signal is older than 90 days.
## Step 3.5: Enrich Net-New Results with Web Search
For `ProspectorOrganization` results (net-new companies not in CR), run a quick web search on the top 35 companies to add context beyond firmographics. CR has no behavioral signals for these companies, so web search fills the gap — look for recent funding, product launches, leadership changes, or news coverage. Include findings as brief annotations next to each company in the results.
## Step 4: Offer Next Steps
- "Want me to draft outreach for the top 35 prospects?"
- "Should I run a full account brief on any of these?"
- "Want to refine the criteria or add another filter?"
- "I can format this as a CSV if you'd like to export it."
- "For any net-new companies here, I can add them to Common Room for enrichment." *(future capability)*
## Quality Standards
- Always confirm which object type (ProspectorOrg vs Organization) before running the query
- Default to "My Segments" when querying Organization records, unless user specifies otherwise
- Support iterative refinement — treat each follow-up as a filter adjustment, not a fresh start
- Never mix result fields from ProspectorOrganization and Organization in the same list
- Fewer high-quality results beat a long unqualified list
- **Only show data the query returned** — leave blank or "—" for missing fields, don't invent values
## Reference Files
- **`references/prospect-guide.md`** — filter types, signal-based sorting, object type distinctions, and list-building strategies
@@ -0,0 +1,35 @@
# Common Room Prospector — Usage Guide
## The Two Object Types (Critical)
Never conflate these — they have different fields and filter sets.
| | `ProspectorOrganization` (Net-New) | `Organization` (Already in CR) |
|---|---|---|
| **Source** | Common Room's external data graph | CR workspace (full enrichment + signal history) |
| **Available fields** | Company name, domain, size, industry, capital raised, revenue, location | Everything — signals, scores, CRM data, RoomieAI, community activity |
| **Available filters** | Firmographic and technographic only | All firmographic plus signal-based, score-based, segment-based, and CRM filters |
| **Use for** | Territory planning, top-of-funnel list building | Prioritizing warm accounts, expansion candidates, intent signals |
## Deciding Which Object Type to Use
| User says... | Likely object type |
|-------------|-------------------|
| "Which of my accounts are showing buying signals?" | `Organization` |
| "Find fintech companies in London I haven't talked to" | `ProspectorOrganization` |
| "Find new companies matching our ICP" | `ProspectorOrganization` |
| "Show accounts that haven't engaged in 90 days" | `Organization` |
| Ambiguous — could apply to both | Ask: "Are you looking for net-new companies, or filtering accounts already in your workspace?" |
## Iterative Refinement
- Start with the user's initial criteria
- For large results (50+), return count first: "I found 500 results. Want to narrow by size or tech stack?"
- Accept follow-up refinements as filter adjustments — not a fresh search
- Suggest relaxing criteria if results are fewer than 5
## Common Pitfalls
- **Conflating object types** — Never mix ProspectorOrganization and Organization results in the same list.
- **Not scoping to "My Segments"** — When querying Organization records, scope to the user's segments by default.
- **Over-filtering** — If under 5 results, suggest relaxing one criterion.
@@ -0,0 +1,126 @@
---
name: weekly-prep-brief
description: "Generate a comprehensive weekly briefing for all external calls in the next 7 days. Triggers on 'weekly prep brief', 'prepare my week', 'what calls do I have this week', 'Monday prep', or any weekly planning request."
---
# Weekly Prep Brief
Generate a single comprehensive weekly briefing that covers every external customer or prospect call in the next 7 days, with per-meeting account and contact research from Common Room.
## Briefing Process
### Step 1: Get the Week's External Meetings
**Option A — Calendar connected:**
Use the `~~calendar` connector to fetch all meetings scheduled in the next 7 days (or a user-specified range). Filter to keep only external meetings — those with attendees from outside your organization. Discard internal-only meetings, one-on-ones with colleagues, and recurring internal syncs.
Identify for each external meeting:
- Company name
- Meeting date and time
- External attendee names and email addresses
**Option B — No calendar connected:**
Ask the user: "To build your weekly prep brief, I'll need your upcoming external calls. Please list them: company name, date/time, and attendee names."
Accept freeform input and parse it into a structured list before proceeding.
### Step 2: Confirm the Meeting List
Present the identified meetings to the user for confirmation before beginning research:
> "Here are the external calls I found for this week. Let me know if anything's missing or should be excluded:
> - [Company] — [Day], [Time] — [Attendees]
> - ..."
This prevents wasted research on cancelled or incorrect meetings.
### Step 3: Research Each Meeting
For each confirmed external meeting, run in parallel where possible:
1. **Account research** — full account snapshot using the account-research skill
2. **Contact research** — profile for each external attendee using the contact-research skill
Common Room data is the primary source. After CR research, run a quick **recency check** for each company — this is supplementary, not primary:
- Search `"[company name]" news` scoped to the last 7 days
- For executive attendees, search their name for recent public posts or interviews
- Only include findings that are genuinely noteworthy (funding, leadership changes, major press). Don't pad the brief with generic news.
Depth calibration:
- For high-priority accounts (large accounts, open opportunities, renewal risk), produce full depth research
- For lower-priority or short meetings, produce abbreviated snapshots (34 bullets each)
### Step 4: Synthesize the Weekly Brief
Compile all per-meeting research into a single structured document, sorted by meeting date/time.
Open with a brief week-level overview that flags:
- Any accounts with urgent signals (at-risk, trial expiring, expansion opportunity)
- Any meetings that need special preparation or executive involvement
- Total external call count and estimated time commitment
## Output Format
```
# Weekly Prep Brief — Week of [Date]
## Week Overview
[24 bullets: key themes, flagged priorities, call count]
---
## [Monday / Tuesday / etc.]
### [Company Name] — [Time]
**Attendees:** [Names and titles]
**Meeting type:** [Discovery / QBR / Renewal / Expansion / etc. — inferred if possible]
**Company Snapshot**
[45 bullets: account status, top signals, recent activity]
**Attendee Profiles**
- **[Name]** ([Title]): [23 bullets on their signals, persona, conversation angle]
- [Repeat per attendee]
**Top Signals This Week**
[23 most relevant signals for this specific call]
**This Week's News** [If notable news found]
[Only genuinely noteworthy findings — funding, leadership changes, major press]
**Recommended Objectives**
[12 sentences: what to accomplish in this meeting]
---
[Repeat per meeting, sorted by date/time]
```
## When a Meeting Has Sparse Data
If Common Room returns limited data for a particular meeting's account or attendees, use a compressed format for that meeting instead of the full template:
```
### [Company Name] — [Time] ⚠️ Limited Data
**Attendees:** [Names and titles if known]
**Data available:** [What Common Room actually returned]
**Web Search Results**
[Findings from web search — company news, attendee LinkedIn profiles]
**Note:** Common Room has limited data on this account. The rep may want to check directly in CR or gather context from colleagues before this call.
```
Do not generate a full meeting prep section (company snapshot, signal highlights, talking points, recommended objectives) from sparse data. A short honest section is more useful than a fabricated full one.
## Quality Standards
- Keep each meeting section scannable — reps read these in the morning, often on mobile
- Always sort by date/time ascending
- Flag urgent situations prominently (risk, trial expiration, open opps) — don't bury them
- If a meeting has very thin Common Room data, use the sparse-data format above — never fill the full template with guesses
- Total brief should be readable in 1015 minutes for a week with 46 meetings
- **Every fact must come from a tool call** — no invented deal context, activity, or signals
## Reference Files
- **`references/briefing-guide.md`** — guidelines for structuring briefings, prioritization logic, and how to handle edge cases (cancelled meetings, new accounts with no data, etc.)
@@ -0,0 +1,33 @@
# Weekly Prep Brief — Structure and Edge Cases
## Briefing Depth Guidelines
Calibrate research depth based on account type:
| Account Type | Depth |
|-------------|-------|
| Strategic account (large, high ARR) | Full — account + all attendees |
| Active opportunity (open deal) | Full — with emphasis on deal signals |
| Renewal within 90 days | Full — with emphasis on risk/health signals |
| Mid-market customer, routine call | Standard — abbreviated account + key attendee |
| Small account, quick check-in | Minimal — 3-4 bullets, single attendee |
| Brand new prospect (first meeting) | Full contact + account — first impressions matter |
## Week Overview Priorities
Flag these situations prominently at the top of the brief:
- Trial expiring within 7 days, renewal due within 30 days, or churn risk signals detected
- Open critical support tickets or unresolved escalations
- Expansion signals worth raising in the call
- Executive stakeholder or new champion attending
- Champion recently changed jobs or competitive signals in the account
- Recent company funding, product milestone, or strong community advocacy (use as opener)
## Edge Cases
- **No Common Room data:** Note it explicitly, run external web research, recommend the rep check with their team for offline context.
- **Multiple meetings with the same company:** Research the account once, share across meetings, differentiate by attendees and objectives.
- **7+ meetings in a week:** Ask whether to prioritize full research for specific accounts or run abbreviated prep for all; default to full for strategic.
- **Same-day meeting:** Skip confirmation, produce compressed version (company snapshot + top signals + 1-2 talking points), mark as "[Quick Prep]".
- **Cancelled meetings:** Exclude silently; if status is unclear, include with "[Status unclear — confirm this meeting is still on.]"
@@ -0,0 +1,11 @@
{
"name": "slack-by-salesforce",
"description": "Official Slack MCP server for interactive and collaborative workflows. Surface insights, draft messages, and engage teams directly within Slack from Claude Cowork.",
"version": "1.0.0",
"author": {
"name": "Salesforce",
"url": "https://slack.com"
},
"homepage": "https://github.com/slackapi/slack-mcp-plugin",
"license": "MIT"
}
+12
View File
@@ -0,0 +1,12 @@
{
"mcpServers": {
"slack": {
"type": "http",
"url": "https://mcp.slack.com/mcp",
"oauth": {
"clientId": "1601185624273.8899143856786",
"callbackPort": 3118
}
}
}
}
+16
View File
@@ -0,0 +1,16 @@
# Slack Plugin
This plugin integrates Slack with Claude Code, providing tools to search, read, and send messages in Slack.
## Commands
- `/slack:summarize-channel <channel-name>` — Summarize recent activity in a Slack channel
- `/slack:find-discussions <topic>` — Find discussions about a specific topic across Slack channels
- `/slack:draft-announcement <topic>` — Draft a well-formatted Slack announcement and save it as a draft
- `/slack:standup` — Generate a standup update based on your recent Slack activity
- `/slack:channel-digest <channel1, channel2, ...>` — Get a digest of recent activity across multiple Slack channels
## Skills
- **slack-messaging** — Guidance for composing well-formatted Slack messages using mrkdwn syntax
- **slack-search** — Guidance for effectively searching Slack to find messages, files, channels, and people
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2020- Slack Technologies, LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+108
View File
@@ -0,0 +1,108 @@
# Slack Plugin
This repository contains the configuration needed to integrate Slack with Cursor IDE and Claude Code. The plugin enables your agents to interact directly with your Slack workspace, allowing you to search messages, send communications, manage canvases, and more—all through natural language.
## Features
The Slack MCP server provides the following capabilities:
- **Search**: Find messages, files, users, and channels (both public and private)
- **Messaging**: Send messages, retrieve channel histories, and access threaded conversations
- **Canvas**: Create and share formatted documents, export content as markdown
- **User Management**: Retrieve user profiles including custom fields and status information
## Prerequisites
Before setting up the Slack MCP server, ensure you have:
- Cursor IDE or Claude Code CLI installed
- Access to a Slack workspace with MCP integration approved by your workspace admin
## Installation
Choose the installation method for your IDE:
### Claude Code
If you're using Claude Code CLI, you can install this as a plugin by cloning it locally:
```bash
git clone https://github.com/slackapi/slack-mcp-plugin.git
cd slack-mcp-plugin
claude --plugin-dir ./
```
The Slack MCP server will be automatically configured when the plugin loads. You will be prompted to authenticate into your Slack workspace via OAuth.
The Claude plugin uses the following MCP configuration (`.mcp.json`):
```json
{
"mcpServers": {
"slack": {
"type": "http",
"url": "https://mcp.slack.com/mcp",
"oauth": {
"clientId": "1601185624273.8899143856786",
"callbackPort": 3118
}
}
}
}
```
### Cursor
You can use the following Add to Cursor button or follow the steps below to manually configure the Slack MCP server in Cursor:
[![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=slack&config=eyJ1cmwiOiJodHRwczovL21jcC5zbGFjay5jb20vbWNwIiwiYXV0aCI6eyJDTElFTlRfSUQiOiIzNjYwNzUzMTkyNjI2Ljg5MDM0NjkyMjg5ODIifX0%3D)
#### Step 1: Open Cursor Settings
Navigate to **Cursor → Settings → Cursor Settings** (or use the keyboard shortcut `Cmd+,` on macOS, `Ctrl+,` on Windows/Linux).
#### Step 2: Navigate to MCP Tab
In the Settings interface, click on the **MCP** tab to access MCP server configurations.
#### Step 3: Add Slack MCP Configuration
Add the following configuration to connect to the remote Slack MCP server:
```json
{
"mcpServers": {
"slack": {
"url": "https://mcp.slack.com/mcp",
"auth": {
"CLIENT_ID": "3660753192626.8903469228982"
}
}
}
}
```
Save the configuration. You will also see a connect button once added. Click that to authenticate into your Slack Workspace.
## Usage Examples
Once configured, you can interact with Slack through your AI assistant using natural language:
- **Search messages**: "Search for messages about the product launch in the last week"
- **Send messages**: "Send a message to #general channel saying the deployment is complete"
- **Find users**: "Who is the user with email john@example.com?"
- **Access threads**: "Show me the conversation thread from that message"
- **Create canvases**: "Create a canvas document with our meeting notes"
## Documentation & Resources
- [Official Slack MCP Server Documentation](https://docs.slack.dev/ai/mcp-server/)
## Notes & Limitations
- **Remote server only**: This configuration connects to Slack's hosted MCP server. No local installation is required or supported.
- **Admin approval required**: Your Slack workspace administrator must approve MCP integration before you can use this feature.
## Questions or Issues?
For questions about the Slack MCP server or integration issues, please refer to the [official Slack documentation](https://docs.slack.dev/ai/mcp-server/) or contact your workspace administrator.
@@ -0,0 +1,34 @@
---
description: Get a digest of recent activity across multiple Slack channels
---
Given the comma-separated channel names provided in $ARGUMENTS (strip leading `#` and whitespace from each):
1. Parse the argument into individual channel names. Strip leading `#` and whitespace from each name.
2. For each channel:
a. Use `slack_search_channels` to find the channel ID.
b. Use `slack_read_channel` to read recent messages (use a limit of 50 messages per channel to keep things manageable).
c. Summarize the key activity in that channel: main topics, decisions, questions, and notable messages.
3. Present the digest in this format:
```
*Channel Digest — <today's date>*
*#channel-1*
- Summary point 1
- Summary point 2
*#channel-2*
- Summary point 1
- Summary point 2
...
```
4. For each channel, keep the summary to 3-5 bullet points maximum. Focus on what's actionable or noteworthy.
5. If a channel has no recent activity, note that it's been quiet and mention when the last message was posted (if visible).
6. If a channel name can't be found, let the user know and continue with the remaining channels.
@@ -0,0 +1,27 @@
---
description: Draft a well-formatted Slack announcement and save it as a draft
---
Given the topic or context provided in $ARGUMENTS:
1. Ask the user the following clarifying questions (skip any that are already clear from the provided context):
- Which channel should this announcement be posted in?
- Who is the target audience?
- What is the key message or call to action?
- Is there a deadline or date to highlight?
- What tone is appropriate — formal, casual, or urgent?
2. Compose the announcement following Slack formatting best practices:
- Use Slack's mrkdwn syntax: `*bold*` for emphasis (not `**bold**`), `_italic_` for secondary emphasis, `>` for callouts.
- Lead with the most important information — don't bury the point.
- Use a clear, descriptive opening line that works as a headline.
- Keep paragraphs short (2-3 sentences max).
- Use bullet points for lists of items or action steps.
- Include relevant emoji sparingly to aid scanning (e.g., :mega: for announcements, :calendar: for dates, :point_right: for action items).
- End with a clear call to action or next step if applicable.
3. Present the draft to the user for review. Offer to adjust tone, length, or formatting.
4. Once the user approves, use `slack_search_channels` to find the target channel ID, then use `slack_send_message_draft` to create the draft in Slack.
5. Let the user know the draft is ready in Slack and they can review and send it from the Slack client.
@@ -0,0 +1,15 @@
---
description: Find discussions about a specific topic across Slack channels
---
Given the topic provided in $ARGUMENTS:
1. Use the `slack_search_public` tool to search for messages matching the topic. Use the topic as a natural language question first for semantic results.
2. If semantic results are sparse, follow up with a keyword search using key terms from the topic.
3. For the most relevant results, use `slack_read_thread` to fetch full thread conversations so you capture the complete discussion context.
4. Present the results organized by relevance:
- For each discussion found, show: the channel name, who started it, a brief summary of the conversation, and the date.
- Group related discussions together if they span multiple channels.
- Highlight any conclusions, decisions, or unresolved questions.
5. Limit output to the top 5-10 most relevant discussions to keep results manageable.
6. If no results are found, suggest alternative search terms or broader queries the user could try.
+31
View File
@@ -0,0 +1,31 @@
---
description: Generate a standup update based on your recent Slack activity
---
1. Use `slack_read_user_profile` (with no user_id) to get the current user's profile information, including their user ID and display name.
2. Search for the user's recent messages using `slack_search_public` with the filter `from:<@USER_ID>` and `after:` set to yesterday's date. This captures messages from the last working day.
3. Review the messages found and categorize them into standup themes:
- **What I worked on** — Topics, projects, or tasks the user discussed or contributed to
- **What I'm working on next** — Any mentions of upcoming work, plans, or follow-ups
- **Blockers** — Any questions asked that went unanswered, issues raised, or explicit mentions of being stuck
4. For messages in threads, use `slack_read_thread` to get the full context so you can accurately describe what the user contributed.
5. Format the standup as:
```
*Standup for <display name> — <today's date>*
*Done:*
- Item 1
- Item 2
*Doing:*
- Item 1
*Blockers:*
- None / Item 1
```
6. Present the standup to the user for review. They can edit, adjust, or ask you to post it to a specific channel.
@@ -0,0 +1,16 @@
---
description: Summarize recent activity in a Slack channel
---
Given the channel name provided in $ARGUMENTS (strip any leading `#`):
1. Use the `slack_search_channels` tool to find the channel ID for the provided channel name. Strip any leading `#` from the argument before searching.
2. Use the `slack_read_channel` tool to read recent messages from the channel (default limit of 100 messages).
3. For any messages that have threads with replies, use `slack_read_thread` to read the thread contents so the summary captures threaded discussions.
4. Produce a concise summary organized by topic or theme. The summary should include:
- An overview of the main topics discussed
- Key decisions or action items mentioned
- Notable announcements or updates
- Active threads and their conclusions (if any)
5. Keep the summary scannable — use short bullet points grouped by topic. Mention who said what when it's relevant (e.g., decisions, action items).
6. If the channel has very little recent activity, say so and note the last time a message was posted.
@@ -0,0 +1,58 @@
---
name: slack-messaging
description: Guidance for composing well-formatted, effective Slack messages using mrkdwn syntax
---
# Slack Messaging Best Practices
This skill provides guidance for composing well-formatted, effective Slack messages.
## When to Use
Apply this skill whenever composing, drafting, or helping the user write a Slack message — including when using `slack_send_message`, `slack_send_message_draft`, or `slack_create_canvas`.
## Slack Formatting (mrkdwn)
Slack uses its own markup syntax called **mrkdwn**, which differs from standard Markdown. Always use mrkdwn when composing Slack messages:
| Format | Syntax | Notes |
|--------|--------|-------|
| Bold | `*text*` | Single asterisks, NOT double |
| Italic | `_text_` | Underscores |
| Strikethrough | `~text~` | Tildes |
| Code (inline) | `` `code` `` | Backticks |
| Code block | `` ```code``` `` | Triple backticks |
| Quote | `> text` | Angle bracket |
| Link | `<url\|display text>` | Pipe-separated in angle brackets |
| User mention | `<@U123456>` | User ID in angle brackets |
| Channel mention | `<#C123456>` | Channel ID in angle brackets |
| Bulleted list | `- item` or `• item` | Dash or bullet character |
| Numbered list | `1. item` | Number followed by period |
### Common Mistakes to Avoid
- Do NOT use `**bold**` (double asterisks) — Slack uses `*bold*` (single asterisks)
- Do NOT use `## headers` — Slack does not support Markdown headers. Use `*bold text*` on its own line instead.
- Do NOT use `[text](url)` for links — Slack uses `<url|text>` format
- Do NOT use `---` for horizontal rules — Slack does not render these
## Message Structure Guidelines
- **Lead with the point.** Put the most important information in the first line. Many people read Slack on mobile or in notifications where only the first line shows.
- **Keep it short.** Aim for 1-3 short paragraphs. If the message is long, consider using a Canvas instead.
- **Use line breaks generously.** Walls of text are hard to read. Separate distinct thoughts with blank lines.
- **Use bullet points for lists.** Anything with 3+ items should be a list, not a run-on sentence.
- **Bold key information.** Use `*bold*` for names, dates, deadlines, and action items so they stand out when scanning.
## Thread vs. Channel Etiquette
- **Reply in threads** when responding to a specific message to keep the main channel clean.
- **Use `reply_broadcast`** (also post to channel) only when the reply contains information everyone needs to see.
- **Post in the channel** (not a thread) when starting a new topic, making an announcement, or asking a question to the whole group.
- **Don't start a new thread** to continue an existing conversation — find and reply to the original message.
## Tone and Audience
- Match the tone to the channel — `#general` is usually more formal than `#random`.
- Use emoji reactions instead of reply messages for simple acknowledgments (though note: the MCP tools can't add reactions, so suggest the user do this manually if appropriate).
- When writing announcements, use a clear structure: context, key info, call to action.
@@ -0,0 +1,97 @@
---
name: slack-search
description: Guidance for effectively searching Slack to find messages, files, channels, and people
---
# Slack Search
This skill provides guidance for effectively searching Slack to find messages, files, and information.
## When to Use
Apply this skill whenever you need to find information in Slack — including when a user asks you to locate messages, conversations, files, or people, or when you need to gather context before answering a question about what's happening in Slack.
## Search Tools Overview
| Tool | Use When |
|------|----------|
| `slack_search_public` | Searching public channels only. Does not require user consent. |
| `slack_search_public_and_private` | Searching all channels including private, DMs, and group DMs. Requires user consent. |
| `slack_search_channels` | Finding channels by name or description. |
| `slack_search_users` | Finding people by name, email, or role. |
## Search Strategy
### Start Broad, Then Narrow
1. Begin with a simple keyword or natural language question.
2. If too many results, add filters (`in:`, `from:`, date ranges).
3. If too few results, remove filters and try synonyms or related terms.
### Choose the Right Search Mode
- **Natural language questions** (e.g., "What is the deadline for project X?") — Best for fuzzy, conceptual searches where you don't know exact keywords.
- **Keyword search** (e.g., `project X deadline`) — Best for finding specific, exact content.
### Use Multiple Searches
Don't rely on a single search. Break complex questions into smaller searches:
- Search for the topic first
- Then search for specific people's contributions
- Then search in specific channels
## Search Modifiers Reference
### Location Filters
- `in:channel-name` — Search within a specific channel
- `in:<#C123456>` — Search in channel by ID
- `-in:channel-name` — Exclude a channel
- `in:<@U123456>` — Search in DMs with a user
### User Filters
- `from:<@U123456>` — Messages from a specific user (by ID)
- `from:username` — Messages from a user (by Slack username)
- `to:me` — Messages sent directly to you
### Content Filters
- `is:thread` — Only threaded messages
- `has:pin` — Pinned messages
- `has:link` — Messages containing links
- `has:file` — Messages with file attachments
- `has::emoji:` — Messages with a specific reaction
### Date Filters
- `before:YYYY-MM-DD` — Messages before a date
- `after:YYYY-MM-DD` — Messages after a date
- `on:YYYY-MM-DD` — Messages on a specific date
- `during:month` — Messages during a specific month (e.g., `during:january`)
### Text Matching
- `"exact phrase"` — Match an exact phrase
- `-word` — Exclude messages containing a word
- `wild*` — Wildcard matching (minimum 3 characters before `*`)
## File Search
To search for files, use the `content_types="files"` parameter with type filters:
- `type:images` — Image files
- `type:documents` — Document files
- `type:pdfs` — PDF files
- `type:spreadsheets` — Spreadsheet files
- `type:canvases` — Slack Canvases
Example: `content_types="files" type:pdfs budget after:2025-01-01`
## Following Up on Results
After finding relevant messages:
- Use `slack_read_thread` to get the full thread context for any threaded message.
- Use `slack_read_channel` with `oldest`/`latest` timestamps to read surrounding messages for context.
- Use `slack_read_user_profile` to identify who a user is when their ID appears in results.
## Common Pitfalls
- **Boolean operators don't work.** `AND`, `OR`, `NOT` are not supported. Use spaces (implicit AND) and `-` for exclusion.
- **Parentheses don't work.** Don't try to group search terms with `()`.
- **Search is not real-time.** Very recent messages (last few seconds) may not appear in search results. Use `slack_read_channel` for the most recent messages.
- **Private channel access.** Use `slack_search_public_and_private` when you need to include private channels, but note this requires user consent.
@@ -0,0 +1,22 @@
{
"name": "zoom-plugin",
"description": "Claude plugin for planning, building, and debugging Zoom integrations across REST APIs, SDKs, webhooks, bots, and MCP workflows",
"version": "1.1.0",
"homepage": "https://developers.zoom.us/",
"repository": "https://github.com/zoom/zoom-plugin",
"license": "MIT",
"keywords": [
"zoom",
"claude-plugin",
"rest-api",
"meeting-sdk",
"video-sdk",
"webhooks",
"oauth",
"mcp"
],
"author": {
"name": "Zoom",
"url": "https://github.com/zoom/zoom-plugin"
}
}
+25
View File
@@ -0,0 +1,25 @@
{
"mcpServers": {
"zoom-mcp": {
"type": "http",
"url": "https://mcp-us.zoom.us/mcp/zoom/streamable",
"headers": {
"Authorization": "Bearer ${ZOOM_MCP_ACCESS_TOKEN}"
}
},
"zoom-docs-mcp": {
"type": "http",
"url": "https://mcp.zoom.us/mcp/docs/streamable",
"headers": {
"Authorization": "Bearer ${ZOOM_DOCS_MCP_ACCESS_TOKEN}"
}
},
"zoom-whiteboard-mcp": {
"type": "http",
"url": "https://mcp-us.zoom.us/mcp/whiteboard/streamable",
"headers": {
"Authorization": "Bearer ${ZOOM_WHITEBOARD_MCP_ACCESS_TOKEN}"
}
}
}
}
+39
View File
@@ -0,0 +1,39 @@
# Zoom Plugin
Cross-platform discovery file for agent tools that look for `AGENTS.md`.
## What This Repo Provides
This repository contains a Zoom developer plugin centered on `SKILL.md`-based workflows and reference material.
Primary capabilities:
- choose the right Zoom surface for a use case
- plan Zoom integrations across REST APIs, SDKs, webhooks, OAuth, and MCP
- debug broken Zoom integrations
- build focused Zoom implementations for meetings, bots, chat, phone, contact center, and virtual agent workflows
- provide deep product-specific reference material under `skills/`
## Primary Entry Skills
- `skills/start/SKILL.md` — default routing entry point
- `skills/plan-zoom-product/SKILL.md` — pick the right Zoom developer product
- `skills/plan-zoom-integration/SKILL.md` — turn an idea into an implementation plan
- `skills/setup-zoom-oauth/SKILL.md` — choose the auth model and redirect flow
- `skills/build-zoom-meeting-app/SKILL.md` — implement an embedded or managed meeting app
- `skills/build-zoom-bot/SKILL.md` — implement a meeting bot or recorder
- `skills/debug-zoom/SKILL.md` — isolate the failing integration layer
- `skills/setup-zoom-mcp/SKILL.md` — plan a Zoom MCP workflow for Claude
## Repo Shape
- `.claude-plugin/plugin.json` — Claude plugin manifest
- `.mcp.json` — bundled Zoom MCP server definition
- `skills/` — all plugin skills and supporting references
- `README.md` — user-facing overview
- `CONNECTORS.md` — bundled MCP connector notes
## Usage Notes
- For Claude Code, install or load this as a plugin.
- For other agent ecosystems, treat the `skills/` tree as the primary reusable asset.
- Workflow skills are the front door; product-specific folders under `skills/` are supporting references.
+12
View File
@@ -0,0 +1,12 @@
# Changelog
All notable changes to this plugin are documented in this file.
## Unreleased
- aligned the repository with the current Claude plugin structure around `.claude-plugin/plugin.json`, `skills/`, and `.mcp.json`
- added Claude-facing installation and connector documentation
- converted command-style workflows into `SKILL.md`-based workflows under `skills/`
- bundled the main Zoom MCP server configuration in `.mcp.json`
- removed the Whiteboard MCP server from the bundled plugin surface
- tightened skill metadata and reduced maintainer-facing wording in user-facing docs
+49
View File
@@ -0,0 +1,49 @@
# Connectors
This plugin works in two modes:
- Standalone: Claude uses the bundled Zoom skills and reference material included with this plugin.
- Supercharged: Claude can also use the bundled Zoom MCP servers from [`.mcp.json`](./.mcp.json) for live tool access.
## Included MCP Servers
| Connector | Endpoint | Use For |
|---|---|---|
| `zoom-mcp` | `https://mcp-us.zoom.us/mcp/zoom/streamable` | Zoom-hosted MCP workflows for meetings, recordings, summaries, and meeting assets |
| `zoom-docs-mcp` | `https://mcp.zoom.us/mcp/docs/streamable` | Zoom Docs creation, retrieval, and Markdown-based document workflows |
| `zoom-whiteboard-mcp` | `https://mcp-us.zoom.us/mcp/whiteboard/streamable` | Whiteboard-specific MCP workflows |
## Authentication
The bundled MCP definitions expect bearer tokens in these environment variables:
```bash
export ZOOM_MCP_ACCESS_TOKEN="your_zoom_user_oauth_access_token"
export ZOOM_DOCS_MCP_ACCESS_TOKEN="your_zoom_docs_mcp_access_token"
export ZOOM_WHITEBOARD_MCP_ACCESS_TOKEN="your_zoom_user_oauth_access_token"
```
- `ZOOM_MCP_ACCESS_TOKEN` is used for the main Zoom MCP server.
- `ZOOM_DOCS_MCP_ACCESS_TOKEN` is used for the Zoom Docs MCP server.
- `ZOOM_WHITEBOARD_MCP_ACCESS_TOKEN` is used for the Whiteboard MCP server.
- If one OAuth token includes both the main Zoom MCP scopes and the Zoom Docs MCP scopes, both variables can use the same value.
- After setting or rotating any of these tokens, restart Claude Code or re-enable the plugin so the MCP servers restart with the new environment.
## What You Can Do Without Connectors
- Choose the right Zoom surface for a new integration
- Plan SDK, REST API, webhook, OAuth, and MCP implementations
- Compare Meeting SDK vs Video SDK vs Zoom Apps vs REST API
- Debug architecture, auth, event-delivery, and integration mistakes
- Use the deep Zoom reference library bundled in `skills/`
## What Connectors Add
- Live MCP tool discovery and execution against Zoom-hosted MCP servers
- Real meeting-search, recording-resource, and document workflows
- Whiteboard-specific tool access when applicable
## Notes
- If a command or skill mentions connectors and you are not connected, continue in standalone mode using the reference docs.
- If you are unsure which connector is relevant, start with [`/setup-zoom-mcp`](./skills/setup-zoom-mcp/SKILL.md).
+186
View File
@@ -0,0 +1,186 @@
# Contributing to Zoom Developer Platform Agent Skills
Thank you for your interest in contributing! This document provides guidelines for contributing to these Agent Skills.
## Ways to Contribute
You can contribute in any of these ways:
1. Submit a pull request with improvements.
2. Raise an issue on GitHub for bugs, gaps, or enhancement ideas.
3. Reach out on the [Zoom Developer Forum](https://devforum.zoom.us/) with feedback and improvement suggestions for these agent skills.
### 1. Report Issues
- Documentation errors or outdated information
- Missing use cases or scenarios
- Incorrect code examples
### 2. Improve Documentation
- Fix typos and clarify explanations
- Add missing code examples
- Update for new SDK versions
### 3. Add New Skills
- New use cases
- New platform coverage
- New integration patterns
## Contribution Process
### For Small Changes (typos, clarifications)
1. Fork the repository
2. Make your changes
3. Submit a pull request with a clear description
### For Larger Changes (new use cases, skills)
1. Open an issue first to discuss the proposed change
2. Fork the repository
3. Create a feature branch
4. Follow the skill format guidelines below
5. Submit a pull request
## Skill Format Guidelines
### SKILL.md Structure
```markdown
---
name: skill-name
description: |
Brief description (1-3 sentences).
Include when to use this skill.
---
# Skill Title
[Content following the template in PLAN.md]
```
### Guidelines
1. **Keep SKILL.md under 500 lines** - Move details to `references/`
2. **Max 3 directory levels** - `skill/references/file.md`
3. **Include code examples** - Real, working code developers can use
4. **Document gotchas** - Common mistakes and limitations
5. **Link to official sources** - Prefer Zoom documentation
### Maintenance Checklist
Use this checklist before merging documentation or skill changes:
1. Confirm you are editing the correct skill or product folder.
2. Keep `SKILL.md` as the entrypoint in every skill directory.
3. If examples include credentials, reference `.env` keys rather than hardcoded values.
4. Never commit machine-local absolute paths or machine-specific endpoints.
5. After moving or renaming docs, update cross-links from the relevant parent `SKILL.md` files.
6. Verify frontmatter stays accurate: `name`, `description`, and any optional fields such as `triggers`, `argument-hint`, or `user-invocable`.
7. Remove dead links and stale product claims after any refactor or version update.
8. Make sure every new markdown file is reachable from at least one parent navigation file.
9. Track deprecations and renames explicitly so future updates remain migration-safe.
### Repository Naming Conventions
- Keep canonical skill folder names aligned with [skills/start/SKILL.md](skills/start/SKILL.md).
- Current canonical folders include:
- `general`, `rest-api`, `webhooks`, `websockets`, `meeting-sdk`, `video-sdk`, `zoom-apps-sdk`
- `rtms`, `team-chat`, `ui-toolkit`, `cobrowse-sdk`, `oauth`, `zoom-mcp`
- `contact-center`, `virtual-agent`, `phone`, `rivet-sdk`, `probe-sdk`
### Markdown Linking Rules (Required)
- Use real markdown links for local docs (for example: `text -> docs/example.md`).
- Do not use backticks for local doc references if you want them counted in relationship graphs.
- Use repository-relative paths; do not commit machine-local absolute paths (for example `/home/your-user/...`).
- Every new `.md` file should be linked from at least one parent/index/`SKILL.md` file.
## Using Claude for Contributions
You can use Claude (or other AI assistants) to help create or improve skills:
### Recommended Workflow
1. **Research Phase**
```
Research the official Zoom documentation for [topic].
Check the developer forum for common issues.
Find working code examples.
```
2. **Drafting Phase**
```
Create a skill following the SKILL.md template.
Include practical code examples.
Document known limitations and gotchas.
```
3. **Validation Phase**
```
Cross-check all information with official Zoom docs.
Verify code examples are syntactically correct.
Ensure links are valid.
```
### Claude-Specific Tips
- **Be specific**: "Create a use case for RTMS audio streaming to S3" not "write about RTMS"
- **Provide context**: Share relevant existing skills as examples
- **Iterate**: Review drafts and ask for improvements
- **Verify**: Always cross-check AI-generated content with official sources
### What Claude Can Help With
| Task | How Claude Helps |
|------|------------------|
| Research | Search docs, forums, GitHub for information |
| Drafting | Create initial skill content following templates |
| Code examples | Generate working code snippets |
| Cross-referencing | Check consistency across skills |
| Formatting | Ensure markdown is correct |
### What Requires Human Review
| Task | Why Human Review |
|------|------------------|
| Technical accuracy | AI may hallucinate APIs or features |
| Real-world gotchas | Comes from actual development experience |
| Business logic | Zoom-specific requirements and policies |
| Security practices | Must be verified against official guidance |
## Quality Standards
### Do
- Verify all claims with official documentation
- Include working, tested code examples
- Document known limitations prominently
- Link to official resources
- Keep examples simple and practical
- Check that moved or renamed docs still have inbound links
- Remove outdated guidance that no longer matches the current plugin structure
### Don't
- Include unverified information
- Speculate about undocumented behavior
- Copy proprietary code without permission
- Include outdated or deprecated APIs without noting it
- Over-engineer examples
## Code of Conduct
- Be respectful and constructive
- Focus on improving the documentation
- Credit sources appropriately
- Follow Zoom's developer terms of service
## Questions?
- Open a GitHub issue for questions about contributing
- Check existing issues before creating new ones
- Join the [Zoom Developer Forum](https://devforum.zoom.us/) for Zoom-specific questions, feedback, and improvement requests for these agent skills
## License
By contributing, you agree that your contributions will be licensed under the MIT License.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Zoom Video Communications, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+122
View File
@@ -0,0 +1,122 @@
# Zoom Plugin
A Claude plugin for planning, building, and debugging Zoom integrations. It helps choose the right Zoom surface, shape implementations, debug failures, and route into the right Zoom references without making the user read the whole doc tree first.
## Installation
Install this directory as a local Claude plugin. The plugin manifest is at [`.claude-plugin/plugin.json`](.claude-plugin/plugin.json) and the bundled Zoom MCP connectors are defined in [`.mcp.json`](.mcp.json).
Before using the bundled MCP servers, export bearer tokens for the Zoom surfaces you want Claude to use:
```bash
export ZOOM_MCP_ACCESS_TOKEN="your_zoom_user_oauth_access_token"
export ZOOM_DOCS_MCP_ACCESS_TOKEN="your_zoom_docs_mcp_access_token"
export ZOOM_WHITEBOARD_MCP_ACCESS_TOKEN="your_zoom_user_oauth_access_token"
```
## Slash Workflows
Explicit slash workflows implemented as skills under `skills/`:
| Workflow | Description |
|---|---|
| [`/start`](skills/start/SKILL.md) | Start with a Zoom app idea and get routed to the right product and build path |
| [`/setup-zoom-oauth`](skills/setup-zoom-oauth/SKILL.md) | Choose the auth model, scopes, and redirect flow for a Zoom app |
| [`/build-zoom-meeting-app`](skills/build-zoom-meeting-app/SKILL.md) | Build an embedded or managed Zoom meeting flow |
| [`/build-zoom-bot`](skills/build-zoom-bot/SKILL.md) | Build bots, recorders, and real-time meeting processors |
| [`/debug-zoom`](skills/debug-zoom/SKILL.md) | Triage a broken Zoom integration and isolate the failing layer |
| [`/setup-zoom-mcp`](skills/setup-zoom-mcp/SKILL.md) | Decide when Zoom MCP fits and set up a safe Claude workflow |
| [`/build-zoom-rest-api-app`](skills/rest-api/SKILL.md) | Route into Zoom REST endpoints, scopes, and resource patterns |
| [`/build-zoom-meeting-sdk-app`](skills/meeting-sdk/SKILL.md) | Route into embedded Zoom meeting implementation details |
| [`/build-zoom-video-sdk-app`](skills/video-sdk/SKILL.md) | Route into custom video-session implementation details |
| [`/setup-zoom-webhooks`](skills/webhooks/SKILL.md) | Set up Zoom webhook subscriptions, signature verification, and handlers |
| [`/setup-zoom-websockets`](skills/websockets/SKILL.md) | Set up Zoom WebSocket event delivery when it fits better than webhooks |
| [`/build-zoom-team-chat-app`](skills/team-chat/SKILL.md) | Build Team Chat user or chatbot integrations |
| [`/build-zoom-phone-integration`](skills/phone/SKILL.md) | Build Zoom Phone integrations around Smart Embed, APIs, and events |
| [`/build-zoom-contact-center-app`](skills/contact-center/SKILL.md) | Build Contact Center app, web, or native integrations |
| [`/build-zoom-virtual-agent`](skills/virtual-agent/SKILL.md) | Build Virtual Agent web or mobile wrapper integrations |
## Internal Routing Skills
These remain in the plugin as automatic routing helpers, but they are no longer part of the public slash-command surface:
- [`start`](skills/start/SKILL.md)
- [`plan-zoom-product`](skills/plan-zoom-product/SKILL.md)
- [`plan-zoom-integration`](skills/plan-zoom-integration/SKILL.md)
- [`choose-zoom-approach`](skills/choose-zoom-approach/SKILL.md)
- [`design-mcp-workflow`](skills/design-mcp-workflow/SKILL.md)
- [`debug-zoom-integration`](skills/debug-zoom-integration/SKILL.md)
## Deep References
The plugin also keeps the original Zoom product-specific reference library under `skills/`. These are supporting references, not the primary entry surface:
- [`skills/general/`](skills/general/)
- [`skills/rest-api/`](skills/rest-api/)
- [`skills/meeting-sdk/`](skills/meeting-sdk/)
- [`skills/video-sdk/`](skills/video-sdk/)
- [`skills/webhooks/`](skills/webhooks/)
- [`skills/websockets/`](skills/websockets/)
- [`skills/oauth/`](skills/oauth/)
- [`skills/zoom-mcp/`](skills/zoom-mcp/)
## Example Workflows
### Starting from a Zoom app idea
```text
/start Build an internal meeting assistant that joins calls, extracts action items, and stores summaries
```
### Planning a new app
```text
/start Build a React app that lets customers schedule and join Zoom meetings from our product
```
### Debugging a broken webhook
```text
/debug-zoom My Zoom webhook signature verification fails in production but not locally
```
### Designing an MCP flow
```text
/setup-zoom-mcp I want Claude to search meetings, pull recording resources, and create follow-up docs
```
## Connectors
See [CONNECTORS.md](CONNECTORS.md). The plugin works standalone from the bundled skills, and gets supercharged when Claude can use the bundled Zoom MCP servers from [`.mcp.json`](.mcp.json).
## Cross-Platform Notes
This repo is packaged first as a Claude plugin, but it also includes [AGENTS.md](AGENTS.md) for agent ecosystems that use a repo-level discovery file. The reusable core remains the `skills/` tree and its `SKILL.md` files.
## Structure
```text
Zoom Plugin/
├── .claude-plugin/plugin.json
├── .mcp.json
├── CONNECTORS.md
├── skills/
│ ├── plan-zoom-product/
│ ├── plan-zoom-integration/
│ ├── debug-zoom/
│ ├── setup-zoom-mcp/
│ ├── start/
│ ├── choose-zoom-approach/
│ ├── setup-zoom-oauth/
│ ├── build-zoom-meeting-app/
│ ├── build-zoom-bot/
│ ├── design-mcp-workflow/
│ ├── debug-zoom-integration/
│ └── ... existing Zoom reference skills
└── README.md
```
## License
MIT
@@ -0,0 +1,37 @@
---
name: build-zoom-bot
description: Build a Zoom meeting bot, recorder, or real-time media workflow. Use when joining meetings programmatically, processing live media or transcripts, or combining Meeting SDK, RTMS, and backend services.
---
# /build-zoom-bot
Use this skill for automation that joins meetings, captures media, or reacts to live session data.
## Covers
- Bot architecture
- Meeting join strategy
- Real-time media and transcript handling
- Backend orchestration
- Storage, post-processing, and event flow design
## Workflow
1. Clarify whether the bot needs to join, observe, transcribe, summarize, or act.
2. Route to Meeting SDK and RTMS as the core implementation path.
3. Add REST API for meeting/resource management and Webhooks for asynchronous events when needed.
4. Call out environment and lifecycle constraints early.
## Primary References
- [meeting-sdk](../meeting-sdk/SKILL.md)
- [rtms](../rtms/SKILL.md)
- [scribe](../scribe/SKILL.md)
- [rest-api](../rest-api/SKILL.md)
- [webhooks](../webhooks/SKILL.md)
## Common Mistakes
- Treating batch transcription and live media as the same workflow
- Designing the bot before defining join authority and auth model
- Forgetting post-meeting storage and retry behavior
@@ -0,0 +1,38 @@
---
name: build-zoom-meeting-app
description: Build or embed a Zoom meeting flow. Use when implementing Meeting SDK joins, web or mobile meeting embeds, meeting lifecycle flows, or when deciding between Meeting SDK and Video SDK.
---
# /build-zoom-meeting-app
Use this skill for embedded meeting experiences and meeting lifecycle implementation.
## Covers
- Meeting SDK selection and platform routing
- Join/auth implementation planning
- Meeting creation plus join flow design
- Web vs native platform considerations
- Meeting SDK vs Video SDK boundary decisions
## Workflow
1. Confirm whether the user wants a Zoom meeting or a custom video session.
2. Route to Meeting SDK if the user needs actual Zoom meetings.
3. Pull in the relevant platform references.
4. Add REST API only for meeting creation, resource management, or reporting.
5. Add webhooks or RTMS only when the use case explicitly needs them.
## Primary References
- [meeting-sdk](../meeting-sdk/SKILL.md)
- [rest-api](../rest-api/SKILL.md)
- [webhooks](../webhooks/SKILL.md)
- [rtms](../rtms/SKILL.md)
- [video-sdk](../video-sdk/SKILL.md)
## Common Mistakes
- Using Video SDK for normal Zoom meeting embeds
- Mixing resource-management APIs into the core join flow without reason
- Skipping platform-specific SDK constraints until too late
@@ -0,0 +1,37 @@
---
name: choose-zoom-approach
description: Choose the right Zoom architecture for a use case. Use when deciding between REST API, Webhooks, WebSockets, Meeting SDK, Video SDK, Zoom Apps SDK, Zoom MCP, Phone, Contact Center, or a hybrid approach.
user-invocable: false
---
# Choose Zoom Approach
Pick the smallest correct Zoom surface for the job, then layer in only the supporting pieces that are actually required.
## Decision Framework
| Problem Type | Primary Zoom Surface |
|---|---|
| Deterministic backend automation, account management, reporting, scheduled jobs | [rest-api](../rest-api/SKILL.md) |
| Event delivery to your backend | [webhooks](../webhooks/SKILL.md) or [websockets](../websockets/SKILL.md) |
| Embed Zoom meetings into your app | [meeting-sdk](../meeting-sdk/SKILL.md) |
| Build a fully custom video experience | [video-sdk](../video-sdk/SKILL.md) |
| Build inside the Zoom client | [zoom-apps-sdk](../zoom-apps-sdk/SKILL.md) |
| AI-agent tool workflows over Zoom data | [zoom-mcp](../zoom-mcp/SKILL.md) |
| Real-time media extraction or meeting bots | [rtms](../rtms/SKILL.md) plus [meeting-sdk](../meeting-sdk/SKILL.md) when needed |
| Phone workflows | [phone](../phone/SKILL.md) |
| Contact Center or Virtual Agent flows | [contact-center](../contact-center/SKILL.md) or [virtual-agent](../virtual-agent/SKILL.md) |
## Guardrails
- Do not recommend Video SDK when the user actually needs Zoom meeting semantics.
- Do not recommend Meeting SDK when the user needs a fully custom session product.
- Do not replace deterministic backend automation with MCP-only guidance.
- Prefer hybrid `rest-api + zoom-mcp` when the user needs both stable system actions and AI-driven discovery.
## What To Produce
- One recommended path
- Minimum supporting components
- Hard constraints and tradeoffs
- Immediate next implementation step
@@ -0,0 +1,79 @@
# Cobrowse 5-Minute Preflight Runbook
Use this before deep debugging. It catches the most common Cobrowse failures quickly.
## Skill Doc Standard Note
- Agent-skill standard entrypoint is `SKILL.md`.
- This runbook is an operational convention (recommended), not a required skill file.
- `SKILL.md` is also a navigation convention for larger skill docs.
## 1) Confirm Two-Role Model
- Customer role (`role_type=1`) starts session.
- Agent role (`role_type=2`) joins session.
If your demo only has one generic role, expect broken join behavior.
## 2) Confirm PIN Source of Truth
- Use customer SDK event `pincode_updated` as the only user-facing PIN.
- Agent must join with that same PIN.
- Do not show provisional/debug PIN values from backend records.
Common symptom if wrong: `Pincode is not found` / error `30308`.
## 3) Confirm JWT Claims
- Sign JWT on backend only.
- Include required claim names exactly (for example `user_id`, not custom aliases).
- Use SDK Key for SDK token context; keep SDK Secret server-side.
If claim names are wrong, token is rejected before session logic.
## 4) Confirm Session Order
Recommended sequence:
1. Customer gets customer JWT and starts session.
2. PIN is generated on customer side (`pincode_updated`).
3. Agent gets agent JWT and joins with that PIN.
Starting agent flow before customer session is active often causes join failures.
## 5) Confirm Distribution Pattern
- CDN path: customer SDK + Zoom-hosted agent desk iframe.
- npm path: custom integration (BYOP mode required for custom PIN control).
If using npm agent integration without BYOP expectations, flow mismatches happen.
## 6) Confirm Browser and Security Constraints
- HTTPS required (except loopback/local dev).
- CSP/CORS must allow Zoom domains.
- Third-party cookie/privacy settings can affect reconnect behavior.
Do not treat extension/adblock warnings as root cause until API/session checks fail.
## 7) Quick Checks (Backend + UI)
- Backend config endpoint returns expected credential flags.
- Customer page shows a single Support PIN from SDK event.
- Agent page join uses same Support PIN and returns actionable response (not generic 404).
### Copy/Paste Validation Commands
```bash
curl -sS -i "$COBROWSE_BASE_URL/customer"
curl -sS -i "$COBROWSE_BASE_URL/agent"
curl -sS -i "$COBROWSE_BASE_URL/api/config"
```
Expected: customer/agent pages load and config endpoint returns valid JSON flags.
## 8) Fast Decision Tree
- **Invalid token** -> check JWT claim names and signing secret.
- **Agent cannot find PIN** -> wrong PIN source or wrong session order.
- **Session drops on refresh** -> check reconnection window and browser privacy/cookies.
- **Works locally, fails prod** -> check HTTPS, CSP/CORS, reverse proxy pathing.
@@ -0,0 +1,894 @@
---
name: zoom-cobrowse-sdk
description: "Reference skill for Zoom Cobrowse SDK. Use after routing to a collaborative-support workflow when implementing browser co-browsing, annotation tools, privacy masking, remote assist, or PIN-based session sharing."
user-invocable: false
triggers:
- "cobrowse"
- "co-browse"
- "collaborative browsing"
- "agent assist"
- "customer support screen share"
- "zoom cobrowse"
---
# Zoom Cobrowse SDK - Web Development
Background reference for collaborative browsing on the web with Zoom Cobrowse SDK. Use this after the support workflow is clear and you need implementation detail.
**Official Documentation**: https://developers.zoom.us/docs/cobrowse-sdk/
**API Reference**: https://marketplacefront.zoom.us/sdk/cobrowse/
**Quickstart Repository**: https://github.com/zoom/CobrowseSDK-Quickstart
**Auth Endpoint Sample**: https://github.com/zoom/cobrowsesdk-auth-endpoint-sample
## Quick Links
**New to Cobrowse SDK? Follow this path:**
1. **[Get Started Guide](get-started.md)** - Complete setup from credentials to first session
2. **[Session Lifecycle](concepts/session-lifecycle.md)** - Understanding customer and agent flows
3. **[JWT Authentication](concepts/jwt-authentication.md)** - Token generation and security
4. **[Customer Integration](examples/customer-integration.md)** - Integrate SDK into your website
5. **[Agent Integration](examples/agent-integration.md)** - Set up agent portal (iframe or npm)
**Core Concepts:**
- **[Two Roles Pattern](concepts/two-roles-pattern.md)** - Customer vs Agent architecture
- **[Session Lifecycle](concepts/session-lifecycle.md)** - PIN generation, connection, reconnection
- **[JWT Authentication](concepts/jwt-authentication.md)** - SDK Key vs API Key, role_type, claims
- **[Distribution Methods](concepts/distribution-methods.md)** - CDN vs npm (BYOP)
**Features:**
- **[Annotation Tools](examples/annotations.md)** - Drawing, highlighting, pointer tools
- **[Privacy Masking](examples/privacy-masking.md)** - Hide sensitive fields from agents
- **[Remote Assist](examples/remote-assist.md)** - Agent can scroll customer's page
- **[Multi-Tab Persistence](examples/multi-tab-persistence.md)** - Session continues across tabs
- **[BYOP Mode](examples/byop-custom-pin.md)** - Bring Your Own PIN with npm integration
**Troubleshooting:**
- **[Common Issues](troubleshooting/common-issues.md)** - Quick diagnostics and solutions
- **[Error Codes](troubleshooting/error-codes.md)** - Complete error reference
- **[CORS and CSP](troubleshooting/cors-csp.md)** - Cross-origin and security policy configuration
- **[Browser Compatibility](troubleshooting/browser-compatibility.md)** - Supported browsers and limitations
- **[5-Minute Runbook](RUNBOOK.md)** - Fast preflight checks before deep debugging
**Reference:**
- **[API Reference](references/api-reference.md)** - Complete SDK methods and events
- **[Settings Reference](references/settings-reference.md)** - All initialization settings
- **Integrated Index** - see the section below in this file
## SDK Overview
The Zoom Cobrowse SDK is a JavaScript library that provides:
- **Real-Time Co-Browsing**: Agent sees customer's browser activity live
- **PIN-Based Sessions**: Secure 6-digit PIN for customer-to-agent connection
- **Annotation Tools**: Drawing, highlighting, vanishing pen, rectangle, color picker
- **Privacy Masking**: CSS selector-based masking of sensitive form fields
- **Remote Assist**: Agent can scroll customer's page (with consent)
- **Multi-Tab Persistence**: Session continues when customer opens new tabs
- **Auto-Reconnection**: Session recovers from page refresh (2-minute window)
- **Session Events**: Real-time events for session state changes
- **HTTPS Required**: Secure connections (HTTP only works on loopback/local development hosts)
- **No Plugins**: Pure JavaScript, no browser extensions needed
## Two Roles Architecture
Cobrowse has **two distinct roles**, each with different integration patterns:
| Role | role_type | Integration | JWT Required | Purpose |
|------|-----------|-------------|--------------|---------|
| **Customer** | 1 | Website integration (CDN or npm) | Yes | User who shares their browser session |
| **Agent** | 2 | Iframe (CDN) or npm (BYOP only) | Yes | Support staff who views/assists customer |
**Key Insight**: Customer and agent use **different integration methods** but the same JWT authentication pattern.
## Read This First (Critical)
For customer/agent demos, treat the PIN from customer SDK event `pincode_updated` as the only user-facing PIN.
- Show one clearly labeled value in UI (for example, **Support PIN**).
- Use that same PIN for agent join.
- Do not expose provisional/debug PINs from backend pre-start records to users.
If these rules are ignored, agent desk often fails with `Pincode is not found` / code `30308`.
### Typical Production Flow (Most Common)
This is the flow most teams implement first, and what users usually expect in demos:
1. **Customer starts session first** (`role_type=1`)
- Backend creates/records session
- Backend returns customer JWT
- Customer SDK starts and receives a PIN
2. **Agent joins second** (`role_type=2`)
- Agent enters customer PIN
- Backend validates PIN and session state
- Backend returns agent JWT
- Agent opens Zoom-hosted desk iframe (or custom npm agent UI in BYOP)
If a demo only has one generic "session" user, it is incomplete for real cobrowse operations.
## Prerequisites
### Platform Requirements
- **Supported Browsers**:
- Chrome 80+ ✓
- Firefox 78+ ✓
- Safari 14+ ✓
- Edge 80+ ✓
- Internet Explorer ✗ (not supported)
- **Network Requirements**:
- HTTPS required (HTTP works on loopback/local development hosts only)
- Allow cross-origin requests to `*.zoom.us`
- CSP headers must allow Zoom domains (see [CORS and CSP guide](troubleshooting/cors-csp.md))
- **Third-Party Cookies**:
- Must enable third-party cookies for refresh reconnection
- Privacy mode may limit certain features
### Zoom Account Requirements
1. **Zoom Workplace Account** with SDK Universal Credit
2. **Video SDK App** created in Zoom Marketplace
3. **Cobrowse SDK Credentials** from the app's Cobrowse tab
**Note**: Cobrowse SDK is a **feature of Video SDK** (not a separate product).
### Credentials Overview
You'll receive **4 credentials** from Zoom Marketplace → Video SDK App → Cobrowse tab:
| Credential | Type | Used For | Exposure Safe? |
|------------|------|----------|----------------|
| **SDK Key** | Public | CDN URL, JWT `app_key` claim | ✓ Yes (client-side) |
| **SDK Secret** | Private | Sign JWTs | ✗ No (server-side only) |
| **API Key** | Private | REST API calls (optional) | ✗ No (server-side only) |
| **API Secret** | Private | REST API calls (optional) | ✗ No (server-side only) |
**Critical**: SDK Key is **public** (embedded in CDN URL), but SDK Secret must **never** be exposed client-side.
## Quick Start
### Step 1: Get SDK Credentials
1. Go to [Zoom Marketplace](https://marketplace.zoom.us/)
2. Open your **Video SDK App** (or create one)
3. Navigate to the **Cobrowse** tab
4. Copy your credentials:
- SDK Key
- SDK Secret
- API Key (optional)
- API Secret (optional)
### Step 2: Set Up Token Server
Deploy a server-side endpoint to generate JWTs. Use the official sample:
```bash
git clone https://github.com/zoom/cobrowsesdk-auth-endpoint-sample.git
cd cobrowsesdk-auth-endpoint-sample
npm install
# Create .env file
cat > .env << EOF
ZOOM_SDK_KEY=your_sdk_key_here
ZOOM_SDK_SECRET=your_sdk_secret_here
PORT=4000
EOF
npm start
```
**Token endpoint:**
```javascript
// POST https://YOUR_TOKEN_SERVICE_BASE_URL
{
"role": 1, // 1 = customer, 2 = agent
"userId": "user123",
"userName": "John Doe"
}
// Response
{
"token": "eyJhbGciOiJIUzI1NiIs..."
}
```
### Step 3: Customer Side Integration (CDN)
```html
<!DOCTYPE html>
<html>
<head>
<title>Customer - Cobrowse Demo</title>
<script type="module">
const ZOOM_SDK_KEY = 'YOUR_SDK_KEY';
// Load SDK from CDN
(function(r, a, b, f, c, d) {
r[f] = r[f] || { init: function() { r.ZoomCobrowseSDKInitArgs = arguments }};
var fragment = a.createDocumentFragment();
function loadJs(url) {
c = a.createElement(b);
d = a.getElementsByTagName(b)[0];
c["async"] = false;
c.src = url;
fragment.appendChild(c);
}
loadJs(`https://us01-zcb.zoom.us/static/resource/sdk/${ZOOM_SDK_KEY}/js/2.13.2`);
d.parentNode.insertBefore(fragment, d);
})(window, document, "script", "ZoomCobrowseSDK");
</script>
</head>
<body>
<h1>Customer Support</h1>
<button id="cobrowse-btn" disabled>Loading...</button>
<!-- Sensitive fields - will be masked from agent -->
<label>SSN: <input type="text" class="pii-mask" placeholder="XXX-XX-XXXX"></label>
<label>Credit Card: <input type="text" class="pii-mask" placeholder="XXXX-XXXX-XXXX-XXXX"></label>
<script type="module">
let sessionRef = null;
const settings = {
allowAgentAnnotation: true,
allowCustomerAnnotation: true,
piiMask: {
maskCssSelectors: ".pii-mask",
maskType: "custom_input"
}
};
ZoomCobrowseSDK.init(settings, function({ success, session, error }) {
if (success) {
sessionRef = session;
// Listen for PIN code
session.on("pincode_updated", (payload) => {
console.log("PIN Code:", payload.pincode);
// IMPORTANT: this is the PIN agent should use
alert(`Share this PIN with agent: ${payload.pincode}`);
});
// Listen for session events
session.on("session_started", () => console.log("Session started"));
session.on("agent_joined", () => console.log("Agent joined"));
session.on("agent_left", () => console.log("Agent left"));
session.on("session_ended", () => console.log("Session ended"));
document.getElementById("cobrowse-btn").disabled = false;
document.getElementById("cobrowse-btn").innerText = "Start Cobrowse Session";
} else {
console.error("SDK init failed:", error);
}
});
document.getElementById("cobrowse-btn").addEventListener("click", async () => {
// Fetch JWT from your server
const response = await fetch("https://YOUR_TOKEN_SERVICE_BASE_URL", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
role: 1,
userId: "customer_" + Date.now(),
userName: "Customer"
})
});
const { token } = await response.json();
// Start cobrowse session
sessionRef.start({ sdkToken: token });
});
</script>
</body>
</html>
```
### Step 4: Agent Side Integration (Iframe)
```html
<!DOCTYPE html>
<html>
<head>
<title>Agent Portal</title>
</head>
<body>
<h1>Agent Portal</h1>
<iframe
id="agent-iframe"
width="1024"
height="768"
allow="autoplay *; camera *; microphone *; display-capture *; geolocation *;"
></iframe>
<script>
async function connectAgent() {
// Fetch JWT from your server
const response = await fetch("https://YOUR_TOKEN_SERVICE_BASE_URL", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
role: 2,
userId: "agent_" + Date.now(),
userName: "Support Agent"
})
});
const { token } = await response.json();
// Load Zoom agent portal
const iframe = document.getElementById("agent-iframe");
iframe.src = `https://us01-zcb.zoom.us/sdkapi/zcb/frame-templates/desk?access_token=${token}`;
}
connectAgent();
</script>
</body>
</html>
```
### Step 5: Test the Integration
1. Open **two separate browsers** (or incognito + normal)
2. **Customer browser**: Open customer page, click "Start Cobrowse Session"
3. **Customer browser**: Note the 6-digit PIN displayed
4. **Agent browser**: Open agent page, enter the PIN code
5. **Both browsers**: Session connects, agent can see customer's page
6. **Test features**: Annotations, data masking, remote assist
## Key Features
### 1. Annotation Tools
Both customer and agent can draw on the shared screen:
```javascript
const settings = {
allowAgentAnnotation: true, // Agent can draw
allowCustomerAnnotation: true // Customer can draw
};
```
**Available tools**:
- Pen (persistent)
- Vanishing pen (disappears after 4 seconds)
- Rectangle
- Color picker
- Eraser
- Undo/Redo
### 2. Privacy Masking
Hide sensitive fields from agents using CSS selectors:
```javascript
const settings = {
piiMask: {
maskType: "custom_input", // Mask specific fields
maskCssSelectors: ".pii-mask, #ssn", // CSS selectors
maskHTMLAttributes: "data-sensitive=true" // HTML attributes
}
};
```
**Supported masking**:
- Text nodes ✓
- Form inputs ✓
- Select elements ✓
- Images ✗ (not supported)
- Links ✗ (not supported)
### 3. Remote Assist
Agent can scroll the customer's page:
```javascript
const settings = {
remoteAssist: {
enable: true,
enableCustomerConsent: true, // Customer must approve
remoteAssistTypes: ['scroll_page'], // Only scroll supported
requireStopConfirmation: false // Confirmation when stopping
}
};
```
### 4. Multi-Tab Session Persistence
Session continues when customer opens new tabs:
```javascript
const settings = {
multiTabSessionPersistence: {
enable: true,
stateCookieKey: '$$ZCB_SESSION$$' // Cookie key (base64 encoded)
}
};
```
## Session Lifecycle
### Customer Flow
1. **Load SDK** → CDN script loads `ZoomCobrowseSDK`
2. **Initialize**`ZoomCobrowseSDK.init(settings, callback)`
3. **Fetch JWT** → Request token from your server (role_type=1)
4. **Start Session**`session.start({ sdkToken })`
5. **PIN Generated**`pincode_updated` event fires
6. **Share PIN** → Customer gives 6-digit PIN to agent
7. **Agent Joins**`agent_joined` event fires
8. **Session Active** → Real-time synchronization begins
9. **End Session**`session.end()` or agent leaves
### Agent Flow
1. **Fetch JWT** → Request token from your server (role_type=2)
2. **Load Iframe** → Point to Zoom agent portal with token
3. **Enter PIN** → Agent inputs customer's 6-digit PIN
4. **Connect**`session_joined` event fires
5. **View Session** → Agent sees customer's browser
6. **Use Tools** → Annotations, remote assist, zoom
7. **Leave Session** → Click "Leave Cobrowse" button
### Session Recovery (Auto-Reconnect)
When customer refreshes the page:
```javascript
ZoomCobrowseSDK.init(settings, function({ success, session, error }) {
if (success) {
const sessionInfo = session.getSessionInfo();
// Check if session is recoverable
if (sessionInfo.sessionStatus === 'session_recoverable') {
session.join(); // Auto-rejoin previous session
} else {
// Start new session
session.start({ sdkToken });
}
}
});
```
**Recovery window**: 2 minutes. After 2 minutes, session ends.
## Critical Gotchas and Best Practices
### ⚠️ CRITICAL: SDK Secret Must Stay Server-Side
**Problem**: Developers often accidentally embed SDK Secret in frontend code.
**Solution**:
-**SDK Key** → Safe to expose (embedded in CDN URL)
-**SDK Secret** → Never expose (use for JWT signing server-side)
```javascript
// ❌ WRONG - Secret exposed in frontend
const jwt = signJWT(payload, 'YOUR_SDK_SECRET'); // Security risk!
// ✅ CORRECT - Secret stays on server
const response = await fetch('/api/token', {
method: 'POST',
body: JSON.stringify({ role: 1, userId, userName })
});
const { token } = await response.json();
```
### SDK Key vs API Key (Different Purposes!)
| Credential | Used For | JWT Claim |
|------------|----------|-----------|
| **SDK Key** | CDN URL, JWT `app_key` | `app_key: "SDK_KEY"` |
| **API Key** | REST API calls (optional) | Not used in JWT |
**Common mistake**: Using API Key instead of SDK Key in JWT `app_key` claim.
### Session Limits
| Limit | Value | What Happens |
|-------|-------|--------------|
| Customers per session | 1 | Error 1012: `SESSION_CUSTOMER_COUNT_LIMIT` |
| Agents per session | 5 | Error 1013: `SESSION_AGENT_COUNT_LIMIT` |
| Active sessions per browser | 1 | Error 1004: `SESSION_COUNT_LIMIT` |
| PIN code length | 10 chars max | Error 1008: `SESSION_PIN_INVALID_FORMAT` |
### Session Timeout Behavior
| Event | Timeout | What Happens |
|-------|---------|--------------|
| Agent waiting for customer | 3 minutes | Session ends automatically |
| Page refresh reconnection | 2 minutes | Session ends if not reconnected |
| Reconnection attempts | 2 times max | Session ends after 2 failed attempts |
### HTTPS Requirement
**Problem**: SDK doesn't load on HTTP sites.
**Solution**:
- Production: Use HTTPS ✓
- Development: Use a loopback host for local HTTP testing ✓
- Development: Use a local HTTPS endpoint with a trusted/self-signed cert if required ✓
### Third-Party Cookies Required
**Problem**: Refresh reconnection doesn't work.
**Solution**: Enable third-party cookies in browser settings.
**Affected scenarios**:
- Browser privacy mode
- Safari with "Prevent cross-site tracking" enabled
- Chrome with "Block third-party cookies" enabled
### Distribution Method Confusion
| Method | Use Case | Agent Integration | BYOP Required |
|--------|----------|-------------------|---------------|
| **CDN** | Most use cases | Zoom-hosted iframe | No (auto PIN) |
| **npm** | Custom agent UI, full control | Custom npm integration | Yes (required) |
**Key Insight**: If you want **npm** integration, you **must** use BYOP (Bring Your Own PIN) mode.
### Cross-Origin Iframe Handling
**Problem**: Cobrowse doesn't work in cross-origin iframes.
**Solution**: Inject SDK snippet into cross-origin iframes:
```html
<script>
const ZOOM_SDK_KEY = "YOUR_SDK_KEY_HERE";
(function(r,a,b,f,c,d){r[f]=r[f]||{init:function(){r.ZoomCobrowseSDKInitArgs=arguments}};
var fragment=a.createDocumentFragment();function loadJs(url) {c=a.createElement(b);d=a.getElementsByTagName(b)[0];c.async=false;c.src=url;fragment.appendChild(c);};
loadJs('https://us01-zcb.zoom.us/static/resource/sdk/${ZOOM_SDK_KEY}/js');d.parentNode.insertBefore(fragment,d);})(window,document,'script','ZoomCobrowseSDK');
</script>
```
**Same-origin iframes**: No extra setup needed.
## Known Limitations
### Synchronization Limits
**Not synchronized**:
- HTML5 Canvas elements
- WebGL content
- Audio and Video elements
- Shadow DOM
- PDF rendered with Canvas
- Web Components
**Partially synchronized**:
- Drop-down boxes (only selected result)
- Date pickers (only selected result)
- Color pickers (only selected result)
### Rendering Limits
- High-resolution images may be compressed
- Different screen sizes may cause CSS media query differences
- Cross-origin images may not render (CORS restrictions)
- Cross-origin fonts may not render (CORS restrictions)
### Masking Limits
**Supported**:
- Text nodes ✓
- Form inputs ✓
- Select elements ✓
**Not supported**:
- `<img>` elements ✗
- Links ✗
## Complete Documentation Library
This skill includes comprehensive guides organized by category:
### Core Concepts
- **[Two Roles Pattern](concepts/two-roles-pattern.md)** - Customer vs Agent architecture
- **[Session Lifecycle](concepts/session-lifecycle.md)** - Complete flow from start to end
- **[JWT Authentication](concepts/jwt-authentication.md)** - Token structure and signing
- **[Distribution Methods](concepts/distribution-methods.md)** - CDN vs npm (BYOP)
### Examples
- **[Customer Integration](examples/customer-integration.md)** - Complete customer-side setup
- **[Agent Integration](examples/agent-integration.md)** - Iframe and npm agent setups
- **[Annotations](examples/annotations.md)** - Drawing tools configuration
- **[Privacy Masking](examples/privacy-masking.md)** - Field masking patterns
- **[Remote Assist](examples/remote-assist.md)** - Agent page control
- **[Multi-Tab Persistence](examples/multi-tab-persistence.md)** - Cross-tab sessions
- **[BYOP Custom PIN](examples/byop-custom-pin.md)** - Custom PIN codes
### References
- **[API Reference](references/api-reference.md)** - Complete SDK methods and events
- **[Settings Reference](references/settings-reference.md)** - All initialization settings
- **[Error Codes](references/error-codes.md)** - Complete error reference
- **[Session Events](references/session-events.md)** - All event types
### Troubleshooting
- **[Common Issues](troubleshooting/common-issues.md)** - Quick diagnostics
- **[Error Codes](troubleshooting/error-codes.md)** - Error code reference
- **[CORS and CSP](troubleshooting/cors-csp.md)** - Cross-origin configuration
- **[Browser Compatibility](troubleshooting/browser-compatibility.md)** - Browser support
## Resources
- **Official Docs**: https://developers.zoom.us/docs/cobrowse-sdk/
- **API Reference**: https://marketplacefront.zoom.us/sdk/cobrowse/
- **Quickstart Repo**: https://github.com/zoom/CobrowseSDK-Quickstart
- **Auth Endpoint Sample**: https://github.com/zoom/cobrowsesdk-auth-endpoint-sample
- **Dev Forum**: https://devforum.zoom.us/
- **Developer Blog**: https://developers.zoom.us/blog/?category=zoom-cobrowse-sdk
---
**Need help?** Start with Integrated Index section below for complete navigation.
---
## Integrated Index
_This section was migrated from `SKILL.md`._
**Complete navigation guide for all Cobrowse SDK documentation.**
## Getting Started (Start Here!)
If you're new to Zoom Cobrowse SDK, follow this learning path:
1. **[SKILL.md](SKILL.md)** - Main overview and quick start
2. **[5-Minute Runbook](RUNBOOK.md)** - Preflight checks for common failures
3. **[Get Started Guide](get-started.md)** - Step-by-step setup from credentials to first session
4. **[Session Lifecycle](concepts/session-lifecycle.md)** - Understand the complete customer and agent flow
5. **[Customer Integration](examples/customer-integration.md)** - Integrate SDK into your website
6. **[Agent Integration](examples/agent-integration.md)** - Set up agent portal
## Core Concepts
Foundational concepts you need to understand:
- **[Two Roles Pattern](concepts/two-roles-pattern.md)** - Customer (role_type=1) vs Agent (role_type=2) architecture
- **[Session Lifecycle](concepts/session-lifecycle.md)** - Complete flow: init → start → PIN → connect → end
- **[JWT Authentication](concepts/jwt-authentication.md)** - Token structure, signing, SDK Key vs API Key
- **[Distribution Methods](concepts/distribution-methods.md)** - CDN vs npm (BYOP mode)
## Examples and Patterns
Complete working examples for common scenarios:
### Session Management
- **[Customer Integration](examples/customer-integration.md)** - Complete customer-side implementation (CDN and npm)
- **[Agent Integration](examples/agent-integration.md)** - Iframe and npm agent setup patterns
- **[Session Events](examples/session-events.md)** - Handle all session lifecycle events
- **[Auto-Reconnection](examples/auto-reconnection.md)** - Page refresh and session recovery
### Features
- **[Annotation Tools](examples/annotations.md)** - Enable drawing, highlighting, vanishing pen
- **[Privacy Masking](examples/privacy-masking.md)** - Mask sensitive fields with CSS selectors
- **[Remote Assist](examples/remote-assist.md)** - Agent can scroll customer's page
- **[Multi-Tab Persistence](examples/multi-tab-persistence.md)** - Session continues across browser tabs
- **[BYOP Custom PIN](examples/byop-custom-pin.md)** - Bring Your Own PIN with npm integration
## References
Complete API and configuration references:
### SDK Reference
- **[API Reference](references/api-reference.md)** - All SDK methods and interfaces
- ZoomCobrowseSDK.init()
- session.start()
- session.join()
- session.end()
- session.on()
- session.getSessionInfo()
- **[Settings Reference](references/settings-reference.md)** - All initialization settings
- allowAgentAnnotation
- allowCustomerAnnotation
- piiMask
- remoteAssist
- multiTabSessionPersistence
- **[Session Events Reference](references/session-events.md)** - All event types
- pincode_updated
- session_started
- session_ended
- agent_joined
- agent_left
- session_error
- session_reconnecting
- remote_assist_started
- remote_assist_stopped
### Error Reference
- **[Error Codes](references/error-codes.md)** - Complete error code reference
- 1001-1017: Session errors
- 2001: Token errors
- 9999: Service errors
### Official Documentation
- **[Get Started](references/get-started.md)** - Official get started documentation (crawled)
- **[Features](references/features.md)** - Official features documentation (crawled)
- **[Authorization](references/authorization.md)** - Official JWT authorization docs (crawled)
- **[API Documentation](references/api.md)** - Crawled API reference docs
## Troubleshooting
Quick diagnostics and common issue resolution:
- **[Common Issues](troubleshooting/common-issues.md)** - Quick fixes for frequent problems
- SDK not loading
- Token generation fails
- Agent can't connect
- Fields not masked
- Session doesn't reconnect after refresh
- **[Error Codes](troubleshooting/error-codes.md)** - Error code lookup and solutions
- Session start/join failures (1001, 1011, 1016)
- Session limit errors (1002, 1004, 1012, 1013, 1015)
- PIN code errors (1006, 1008, 1009, 1010)
- Token errors (2001)
- **[CORS and CSP](troubleshooting/cors-csp.md)** - Cross-origin and Content Security Policy setup
- Access-Control-Allow-Origin headers
- Content-Security-Policy headers
- Cross-origin iframe handling
- Same-origin iframe handling
- **[Browser Compatibility](troubleshooting/browser-compatibility.md)** - Browser requirements and limitations
- Supported browsers (Chrome 80+, Firefox 78+, Safari 14+, Edge 80+)
- Internet Explorer not supported
- Privacy mode limitations
- Third-party cookie requirements
## By Use Case
Find documentation by what you're trying to do:
### I want to...
**Set up cobrowse for the first time:**
- [Get Started Guide](get-started.md)
- [JWT Authentication](concepts/jwt-authentication.md)
- [Customer Integration](examples/customer-integration.md)
- [Agent Integration](examples/agent-integration.md)
**Add annotation tools:**
- [Annotation Tools Example](examples/annotations.md)
- [Settings Reference - allowAgentAnnotation](references/settings-reference.md#allowa gentannotation)
- [Settings Reference - allowCustomerAnnotation](references/settings-reference.md#allowcustomerannotation)
**Hide sensitive data from agents:**
- [Privacy Masking Example](examples/privacy-masking.md)
- [Settings Reference - piiMask](references/settings-reference.md#piimask)
**Let agents control customer's page:**
- [Remote Assist Example](examples/remote-assist.md)
- [Settings Reference - remoteAssist](references/settings-reference.md#remoteassist)
**Use custom PIN codes:**
- [BYOP Custom PIN Example](examples/byop-custom-pin.md)
- [JWT Authentication - enable_byop](concepts/jwt-authentication.md#enable-byop)
**Handle page refreshes:**
- [Auto-Reconnection Example](examples/auto-reconnection.md)
- [Session Lifecycle - Recovery](concepts/session-lifecycle.md#session-recovery)
**Integrate with npm (not CDN):**
- [BYOP Custom PIN Example](examples/byop-custom-pin.md)
- [Distribution Methods](concepts/distribution-methods.md#npm-integration)
**Debug session connection issues:**
- [Common Issues](troubleshooting/common-issues.md)
- [Error Codes](troubleshooting/error-codes.md)
- [Session Events - session_error](examples/session-events.md#session-error)
**Configure CORS and CSP headers:**
- [CORS and CSP Guide](troubleshooting/cors-csp.md)
- [Browser Compatibility](troubleshooting/browser-compatibility.md)
## By Error Code
Quick lookup for error code solutions:
### Session Errors
- **1001** (SESSION_START_FAILED) → [Error Codes](troubleshooting/error-codes.md#1001-session-start-failed)
- **1002** (SESSION_CONNECTING_IN_PROGRESS) → [Error Codes](troubleshooting/error-codes.md#1002-session-connecting-in-progress)
- **1004** (SESSION_COUNT_LIMIT) → [Error Codes](troubleshooting/error-codes.md#1004-session-count-limit)
- **1011** (SESSION_JOIN_FAILED) → [Error Codes](troubleshooting/error-codes.md#1011-session-join-failed)
- **1012** (SESSION_CUSTOMER_COUNT_LIMIT) → [Error Codes](troubleshooting/error-codes.md#1012-session-customer-count-limit)
- **1013** (SESSION_AGENT_COUNT_LIMIT) → [Error Codes](troubleshooting/error-codes.md#1013-session-agent-count-limit)
- **1015** (SESSION_DUPLICATE_USER) → [Error Codes](troubleshooting/error-codes.md#1015-session-duplicate-user)
- **1016** (NETWORK_ERROR) → [Error Codes](troubleshooting/error-codes.md#1016-network-error)
- **1017** (SESSION_CANCELING_IN_PROGRESS) → [Error Codes](troubleshooting/error-codes.md#1017-session-canceling-in-progress)
### PIN Errors
- **1006** (SESSION_JOIN_PIN_NOT_FOUND) → [Error Codes](troubleshooting/error-codes.md#1006-session-join-pin-not-found)
- **1008** (SESSION_PIN_INVALID_FORMAT) → [Error Codes](troubleshooting/error-codes.md#1008-session-pin-invalid-format)
- **1009** (SESSION_START_PIN_REQUIRED) → [Error Codes](troubleshooting/error-codes.md#1009-session-start-pin-required)
- **1010** (SESSION_START_PIN_CONFLICT) → [Error Codes](troubleshooting/error-codes.md#1010-session-start-pin-conflict)
### Auth Errors
- **2001** (TOKEN_INVALID) → [Error Codes](troubleshooting/error-codes.md#2001-token-invalid)
### Service Errors
- **9999** (UNDEFINED) → [Error Codes](troubleshooting/error-codes.md#9999-undefined)
## Official Resources
External documentation and samples:
- **Official Docs**: https://developers.zoom.us/docs/cobrowse-sdk/
- **API Reference**: https://marketplacefront.zoom.us/sdk/cobrowse/
- **Quickstart Repo**: https://github.com/zoom/CobrowseSDK-Quickstart
- **Auth Endpoint Sample**: https://github.com/zoom/cobrowsesdk-auth-endpoint-sample
- **Dev Forum**: https://devforum.zoom.us/
- **Developer Blog**: https://developers.zoom.us/blog/?category=zoom-cobrowse-sdk
## Documentation Structure
```
cobrowse-sdk/
├── SKILL.md # Main skill entry point
├── SKILL.md # This file - complete navigation
├── get-started.md # Step-by-step setup guide
├── concepts/ # Core concepts
│ ├── two-roles-pattern.md
│ ├── session-lifecycle.md
│ ├── jwt-authentication.md
│ └── distribution-methods.md
├── examples/ # Working examples
│ ├── customer-integration.md
│ ├── agent-integration.md
│ ├── annotations.md
│ ├── privacy-masking.md
│ ├── remote-assist.md
│ ├── multi-tab-persistence.md
│ ├── byop-custom-pin.md
│ ├── session-events.md
│ └── auto-reconnection.md
├── references/ # API and config references
│ ├── api-reference.md # SDK methods
│ ├── settings-reference.md # Init settings
│ ├── session-events.md # Event types
│ ├── error-codes.md # Error reference
│ ├── get-started.md # Official docs (crawled)
│ ├── features.md # Official docs (crawled)
│ ├── authorization.md # Official docs (crawled)
│ └── api.md # API docs (crawled)
└── troubleshooting/ # Problem resolution
├── common-issues.md
├── error-codes.md
├── cors-csp.md
└── browser-compatibility.md
```
## Search Tips
**Find by keyword:**
- "annotation" → [Annotation Tools](examples/annotations.md)
- "mask" or "privacy" → [Privacy Masking](examples/privacy-masking.md)
- "PIN" or "custom PIN" → [BYOP Custom PIN](examples/byop-custom-pin.md)
- "JWT" or "token" → [JWT Authentication](concepts/jwt-authentication.md)
- "error" → [Error Codes](troubleshooting/error-codes.md)
- "CORS" or "CSP" → [CORS and CSP](troubleshooting/cors-csp.md)
- "iframe" → [Agent Integration](examples/agent-integration.md)
- "npm" → [Distribution Methods](concepts/distribution-methods.md), [BYOP](examples/byop-custom-pin.md)
- "refresh" or "reconnect" → [Auto-Reconnection](examples/auto-reconnection.md)
- "agent" → [Agent Integration](examples/agent-integration.md), [Two Roles Pattern](concepts/two-roles-pattern.md)
- "customer" → [Customer Integration](examples/customer-integration.md), [Two Roles Pattern](concepts/two-roles-pattern.md)
---
**Not finding what you need?** Check the [Official Documentation](https://developers.zoom.us/docs/cobrowse-sdk/) or ask on the [Dev Forum](https://devforum.zoom.us/).
## Environment Variables
- See [references/environment-variables.md](references/environment-variables.md) for standardized `.env` keys and where to find each value.
@@ -0,0 +1,13 @@
# Distribution Methods
Zoom Cobrowse supports CDN and npm-based integrations, depending on your architecture.
Choose based on:
- how much UI control you need,
- whether you host your own agent experience,
- your deployment and CSP constraints.
See:
- [Get Started](../get-started.md)
- [Features (official)](../references/features-official.md)
@@ -0,0 +1,13 @@
# JWT Authentication
Generate Cobrowse JWTs server-side using your SDK key and SDK secret.
Guidelines:
- Never expose SDK secret client-side.
- Issue short-lived tokens.
- Generate different tokens for customer and agent roles.
See:
- [Authorization (official)](../references/authorization-official.md)
- [Get Started](../references/get-started-official.md)
@@ -0,0 +1,13 @@
# Session Lifecycle
Typical flow:
1. Initialize SDK on customer and agent pages.
2. Generate role-specific JWT tokens.
3. Customer starts a session and receives a PIN.
4. Agent joins using the PIN.
5. Session events track connected/disconnected/end states.
See:
- [Get Started](../get-started.md)
- [Features (official)](../references/features-official.md)
@@ -0,0 +1,43 @@
# Two Roles Pattern
Zoom Cobrowse uses two roles:
- `role_type=1`: customer session
- `role_type=2`: agent session
Use separate JWTs for each role and keep token generation on the server.
## What Is Usually Created
In most real implementations, you create these objects in order:
1. **Customer session record** (server-side)
- `session_id`
- generated PIN
- status (`active`/`revoked`)
- expiry timestamp
2. **Customer token** (`role_type=1`)
- used by customer browser SDK to start/share session
3. **Agent token** (`role_type=2`)
- created after PIN validation
- used to load agent desk iframe or custom agent UI
## PIN Source of Truth
In practice, the PIN you should hand to agents is the value emitted by customer SDK event:
- `session.on("pincode_updated", ...)`
Do not rely on placeholder/provisional PIN values from pre-start backend records for user-facing flows.
Always show one clearly labeled PIN in UI (for example, "Support PIN") and reuse that same value in agent links.
## Recommended Endpoint Split
- `POST /api/customer/start` -> create session + customer token + PIN
- `POST /api/agent/connect` -> validate PIN + issue agent token
- `POST /api/session/revoke` -> end session
- `GET /api/session/list` -> operational visibility
See:
- [Get Started](../get-started.md)
- [Authorization (official)](../references/authorization-official.md)
@@ -0,0 +1,7 @@
# Agent Integration
Agent integration joins an active customer session by PIN using an agent-role token.
See:
- [Get Started](../get-started.md)
- [Authorization (official)](../references/authorization-official.md)
@@ -0,0 +1,7 @@
# Annotation Tools
Enable annotation settings during SDK initialization to allow drawing and highlighting.
See:
- [Features (official)](../references/features-official.md)
- [API (official)](../references/api-official.md)
@@ -0,0 +1,7 @@
# Auto-Reconnection
Implement reconnection handlers for transient network interruptions and refresh scenarios.
See:
- [Get Started](../get-started.md)
- [Features (official)](../references/features-official.md)
@@ -0,0 +1,7 @@
# BYOP Custom PIN
Bring Your Own PIN mode lets you control PIN generation/format in your own application flow.
See:
- [Authorization (official)](../references/authorization-official.md)
- [Get Started](../get-started.md)
@@ -0,0 +1,7 @@
# Customer Integration
Customer-side integration should initialize the SDK, fetch a server-generated token, then start a session.
See:
- [Get Started](../get-started.md)
- [API (official)](../references/api-official.md)
@@ -0,0 +1,7 @@
# Multi-Tab Persistence
Cobrowse sessions can continue across tabs when configured correctly and browser constraints are met.
See:
- [Features (official)](../references/features-official.md)
- [Get Started](../get-started.md)
@@ -0,0 +1,7 @@
# Privacy Masking
Configure masking selectors for sensitive customer fields so agents cannot view protected values.
See:
- [Features (official)](../references/features-official.md)
- [Get Started](../get-started.md)
@@ -0,0 +1,7 @@
# Remote Assist
Remote assist allows approved agent interactions (for example, scrolling) during active sessions.
See:
- [Features (official)](../references/features-official.md)
- [API (official)](../references/api-official.md)
@@ -0,0 +1,7 @@
# Session Events
Use SDK session events to track lifecycle transitions and update your UI accordingly.
See:
- [API (official)](../references/api-official.md)
- [Features (official)](../references/features-official.md)
@@ -0,0 +1,554 @@
# Get Started with Zoom Cobrowse SDK
Complete setup guide from credentials to your first cobrowse session.
## Overview
In a cobrowse session, there are **two roles**:
- **Customer** (role_type=1) Integrates the SDK into their website
- **Agent** (role_type=2) Uses an embedded iframe to interact with the customer
This guide shows you how to set up a **customer-initiated session** (the most common pattern).
## Step 1: Get SDK Credentials
### Requirements
1. **Zoom Workplace Account** with SDK Universal Credit
- See [Build platform - create or update account](https://developers.zoom.us/docs/build/account/) for details
2. **Video SDK App** in Zoom Marketplace
- Cobrowse SDK is a **feature of Video SDK** (not a separate product)
### Get Your Credentials
1. Access your SDK account web portal:
- In your Zoom Workplace account, go to **Advanced** > **Zoom CPaaS** > **Manage**
2. Click **Build App**
3. Locate your **SDK credentials** in the Cobrowse tab
You'll receive **4 credentials**:
| Credential | Type | Purpose |
|------------|------|---------|
| **SDK Key** | Public | Used in CDN URL and JWT `app_key` claim |
| **SDK Secret** | Private | Used to sign JWTs (server-side only) |
| **API Key** | Private | REST API authentication (optional) |
| **API Secret** | Private | REST API authentication (optional) |
**Save these credentials securely** - you'll need them in the next step.
## Step 2: Generate JWT Tokens
Both customers and agents require JSON Web Tokens (JWTs) for authentication.
### JWT Structure
All JWTs have the same header:
```json
{
"alg": "HS256",
"typ": "JWT"
}
```
The payload differs by role:
**Customer JWT payload** (role_type=1):
```json
{
"user_id": "user1_customer",
"app_key": "YOUR_SDK_KEY",
"role_type": 1,
"user_name": "customer",
"exp": 1723103759,
"iat": 1723102859
}
```
**Agent JWT payload** (role_type=2):
```json
{
"user_id": "user2_agent",
"app_key": "YOUR_SDK_KEY",
"role_type": 2,
"user_name": "agent",
"exp": 1723103759,
"iat": 1723102859
}
```
### JWT Payload Fields
| Field | Required | Description |
|-------|----------|-------------|
| `app_key` | Yes | Your Zoom SDK Key (not API Key) |
| `role_type` | Yes | User role: `1` = customer, `2` = agent |
| `iat` | Yes | Token issue timestamp (epoch) |
| `exp` | Yes | Token expiration timestamp (epoch). Min: 30 minutes, Max: 48 hours |
| `user_id` | Yes | Uniquely identifiable user ID |
| `user_name` | Yes | User name (max 80 characters) |
| `enable_byop` | Optional | Enable Bring Your Own PIN: `1` = yes, `0` or omit = no |
### Sign the JWT
Sign the JWT with your SDK Secret (not API Secret):
```javascript
HMACSHA256(
base64UrlEncode(header) + '.' + base64UrlEncode(payload),
ZOOM_SDK_SECRET
);
```
### Set Up a Token Server
**CRITICAL**: JWT signing must happen **server-side** to protect your SDK Secret.
Use the official auth endpoint sample:
```bash
# Clone the sample
git clone https://github.com/zoom/cobrowsesdk-auth-endpoint-sample.git
cd cobrowsesdk-auth-endpoint-sample
# Install dependencies
npm install
# Create .env file
cat > .env << EOF
ZOOM_SDK_KEY=your_sdk_key_here
ZOOM_SDK_SECRET=your_sdk_secret_here
PORT=4000
EOF
# Start the server
npm start
```
The server will run on the base URL you configure for your token service.
**Token Request:**
```javascript
// POST https://YOUR_TOKEN_SERVICE_BASE_URL
{
"role": 1, // 1 = customer, 2 = agent
"userId": "user123",
"userName": "John Doe"
}
// Response
{
"token": "eyJhbGciOiJIUzI1NiIs..."
}
```
**See also**: [JWT Authentication Concept](concepts/jwt-authentication.md)
## Step 3: Integrate the Customer SDK
The customer integrates the Cobrowse SDK into their website using the **CDN**.
> **Critical PIN Rule**
>
> The PIN agents should use comes from customer SDK event `pincode_updated`.
> Do not show or rely on provisional PIN values from backend/session placeholders.
> In UI, display one explicit value (for example, **Support PIN**) and pass only that to agent flow.
### Load the SDK
Include the SDK snippet in the `<head>` tag of your HTML page:
```html
<script type="module">
const ZOOM_SDK_KEY = 'YOUR_SDK_KEY';
(function (r, a, b, f, c, d) {
r[f] = r[f] || {
init: function () {
r.ZoomCobrowseSDKInitArgs = arguments;
},
};
var fragment = a.createDocumentFragment();
function loadJs(url) {
c = a.createElement(b);
d = a.getElementsByTagName(b)[0];
c.async = false;
c.src = url;
fragment.appendChild(c);
}
loadJs(
`https://us01-zcb.zoom.us/static/resource/sdk/${ZOOM_SDK_KEY}/js/2.13.2`
);
d.parentNode.insertBefore(fragment, d);
})(window, document, 'script', 'ZoomCobrowseSDK');
</script>
```
### SDK Version
Set the SDK VERSION using semantic versioning:
- **Fixed version**: `js/2.13.2` - Use exact version 2.13.2
- **Latest patch**: `js/2.13.x` - Use latest `>=2.13.0 and <2.14.0`
**Current version**: 2.13.2 (as of February 2026)
### Initialize the SDK
```javascript
const settings = {
allowCustomerAnnotation: true,
piiMask: { maskType: 'all_input' },
};
ZoomCobrowseSDK.init(settings, function ({ success, session, error }) {
if (success) {
console.log("SDK initialized successfully");
// session object is now available
} else {
console.error("SDK init failed:", error);
}
});
```
### Start a Session
```javascript
// Fetch JWT from your server
const response = await fetch('https://YOUR_TOKEN_SERVICE_BASE_URL', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
role: 1,
userId: 'customer_' + Date.now(),
userName: 'Customer'
})
});
const { token } = await response.json();
// Start cobrowse session
session.start({ sdkToken: token });
```
### Complete Customer Example
```html
<!DOCTYPE html>
<html>
<head>
<title>Customer - Cobrowse Support</title>
<script type="module">
const ZOOM_SDK_KEY = 'YOUR_SDK_KEY';
// Load SDK from CDN
(function(r, a, b, f, c, d) {
r[f] = r[f] || { init: function() { r.ZoomCobrowseSDKInitArgs = arguments }};
var fragment = a.createDocumentFragment();
function loadJs(url) {
c = a.createElement(b);
d = a.getElementsByTagName(b)[0];
c["async"] = false;
c.src = url;
fragment.appendChild(c);
}
loadJs(`https://us01-zcb.zoom.us/static/resource/sdk/${ZOOM_SDK_KEY}/js/2.13.2`);
d.parentNode.insertBefore(fragment, d);
})(window, document, "script", "ZoomCobrowseSDK");
</script>
</head>
<body>
<h1>Need Help?</h1>
<button id="cobrowse-btn" disabled>Loading...</button>
<div id="pin-display"></div>
<script type="module">
let sessionRef = null;
const settings = {
allowAgentAnnotation: true,
allowCustomerAnnotation: true,
piiMask: {
maskType: "custom_input",
maskCssSelectors: ".sensitive-field"
}
};
ZoomCobrowseSDK.init(settings, function({ success, session, error }) {
if (success) {
sessionRef = session;
// Listen for PIN code
session.on("pincode_updated", (payload) => {
console.log("PIN Code:", payload.pincode);
// This is the authoritative PIN for agent join
document.getElementById("pin-display").innerHTML =
`<p><strong>Your PIN:</strong> ${payload.pincode}</p>
<p>Share this with your support agent</p>`;
});
// Enable button
document.getElementById("cobrowse-btn").disabled = false;
document.getElementById("cobrowse-btn").innerText = "Start Support Session";
} else {
console.error("SDK init failed:", error);
}
});
// Handle button click
document.getElementById("cobrowse-btn").addEventListener("click", async () => {
try {
// Fetch JWT from your server
const response = await fetch("https://YOUR_TOKEN_SERVICE_BASE_URL", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
role: 1,
userId: "customer_" + Date.now(),
userName: "Customer"
})
});
const { token } = await response.json();
// Start session
sessionRef.start({ sdkToken: token });
} catch (error) {
console.error("Failed to start session:", error);
}
});
</script>
</body>
</html>
```
## Step 4: Use Zoom-Hosted Agent Portal
Agents connect to cobrowse sessions by embedding an iframe.
### Agent Portal Iframe
```html
<!DOCTYPE html>
<html>
<head>
<title>Agent Portal</title>
</head>
<body>
<h1>Agent Support Portal</h1>
<iframe
id="agent-iframe"
width="1024"
height="768"
src=""
allow="autoplay *; camera *; microphone *; display-capture *; geolocation *;"
></iframe>
<script>
async function connectAgent() {
try {
// Fetch JWT from your server
const response = await fetch("https://YOUR_TOKEN_SERVICE_BASE_URL", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
role: 2,
userId: "agent_" + Date.now(),
userName: "Support Agent"
})
});
const { token } = await response.json();
// Load Zoom agent portal with token
const iframe = document.getElementById("agent-iframe");
iframe.src = `https://us01-zcb.zoom.us/sdkapi/zcb/frame-templates/desk?access_token=${token}`;
} catch (error) {
console.error("Failed to connect agent:", error);
}
}
// Auto-connect on page load
connectAgent();
</script>
</body>
</html>
```
### Iframe Permissions
The `allow` attribute must include these permissions:
- `autoplay *` - Auto-play media
- `camera *` - Camera access
- `microphone *` - Microphone access
- `display-capture *` - Screen capture
- `geolocation *` - Location services
## Step 5: Test the Cobrowse SDK
### Testing Steps
1. **Open two browsers** (or use incognito + normal mode):
- Browser A: Customer page
- Browser B: Agent page
2. **Customer browser**:
- Open customer page
- Click "Start Support Session" button
- Note the 6-digit PIN displayed
3. **Agent browser**:
- Open agent page
- Enter the PIN code in the iframe
4. **Verify connection**:
- Agent should now see the customer's browser
- Both sides should show "Connected" status
5. **Test features**:
- **Annotations**: Agent can draw on the screen
- **Data masking**: Masked fields show asterisks for agent
- **Remote assist**: Agent can scroll the page (if enabled)
6. **End session**:
- Either side can click "End Session" to terminate
### Troubleshooting Test Issues
| Issue | Solution |
|-------|----------|
| SDK doesn't load | Verify SDK Key is correct in CDN URL |
| PIN not showing | Check browser console for errors |
| Agent can't connect | Verify PIN is correct and session is still active |
| Connection fails | Check HTTPS is being used (or a loopback host for development) |
## Step 6: Add Features
Now that you have a working cobrowse session, add features:
### Annotation Tools
Enable drawing tools for customer and/or agent:
```javascript
const settings = {
allowAgentAnnotation: true, // Agent can draw
allowCustomerAnnotation: true // Customer can draw
};
```
**See**: [Annotation Tools Example](examples/annotations.md)
### Data Masking
Hide sensitive fields from agents:
```javascript
const settings = {
piiMask: {
maskType: 'custom_input',
maskCssSelectors: '.sensitive-field, #ssn, #credit-card',
maskHTMLAttributes: 'data-sensitive=true'
}
};
```
**See**: [Privacy Masking Example](examples/privacy-masking.md)
### Remote Assist
Allow agent to scroll the customer's page:
```javascript
const settings = {
remoteAssist: {
enable: true,
enableCustomerConsent: true, // Customer must approve
remoteAssistTypes: ['scroll_page']
}
};
```
**See**: [Remote Assist Example](examples/remote-assist.md)
### Bring Your Own PIN (BYOP)
Use custom PIN codes instead of auto-generated ones:
1. Enable BYOP in JWT payload:
```json
{
"enable_byop": 1,
...
}
```
2. Provide custom PIN when starting session:
```javascript
session.start({
customPinCode: 'MYPIN123',
sdkToken: token
});
```
**See**: [BYOP Custom PIN Example](examples/byop-custom-pin.md)
## Next Steps
- **Learn core concepts**: [Session Lifecycle](concepts/session-lifecycle.md)
- **Explore features**: [Complete documentation index](SKILL.md)
- **Handle errors**: [Error Codes Reference](troubleshooting/error-codes.md)
- **Production checklist**: [CORS and CSP Configuration](troubleshooting/cors-csp.md)
## PIN Code Access - Bring Your Own PIN (BYOP)
The Cobrowse SDK supports connecting agents and customers using a PIN code. In the simple example above, Zoom automatically generates a 6-digit PIN code displayed to the customer.
**Auto-generated PIN flow:**
1. Customer clicks "Start Support Session"
2. Zoom generates 6-digit PIN
3. Customer shares PIN with agent
4. Agent enters PIN to connect
**Custom PIN flow (BYOP):**
1. Your app generates custom PIN code (1-10 characters, letters/numbers)
2. Pass PIN when starting session: `session.start({ customPinCode: 'MYPIN', sdkToken })`
3. Agent enters your custom PIN to connect
**BYOP enables**:
- Integration with existing support ticket systems
- Use of case/ticket IDs as PINs
- npm integration for custom agent UI
**See**: [Bring Your Own PIN (BYOP)](examples/byop-custom-pin.md) for complete guide.
## Resources
- **Official Docs**: https://developers.zoom.us/docs/cobrowse-sdk/
- **API Reference**: https://marketplacefront.zoom.us/sdk/cobrowse/
- **Quickstart Repo**: https://github.com/zoom/CobrowseSDK-Quickstart
- **Auth Endpoint Sample**: https://github.com/zoom/cobrowsesdk-auth-endpoint-sample
- **Dev Forum**: https://devforum.zoom.us/
## Common Questions
**Q: Can I use HTTP instead of HTTPS?**
A: Only for loopback/local development. Production must use HTTPS.
**Q: What's the difference between SDK Key and API Key?**
A: SDK Key is used in the CDN URL and JWT `app_key` claim. API Key is for optional REST API calls.
**Q: Can multiple agents join the same session?**
A: Yes, up to 5 agents can join a single customer session.
**Q: Does the customer need to install anything?**
A: No, it's pure JavaScript delivered via CDN. No plugins or extensions needed.
**Q: What happens if the customer refreshes the page?**
A: The session will attempt to automatically reconnect within a 2-minute window.
**Q: Can I customize the agent portal UI?**
A: Not with the iframe approach. For custom UI, use npm integration with BYOP mode.
@@ -0,0 +1,104 @@
# Cobrowse SDK - API Reference
SDK methods and events.
## Initialization
```javascript
const cobrowse = new ZoomCobrowse(config);
```
### Config Options
| Option | Type | Description |
|--------|------|-------------|
| `sdkKey` | string | Your SDK Key |
| `token` | string | JWT token |
| `features.annotations` | boolean | Enable annotations |
| `masking.selectors` | array | CSS selectors to mask |
| `byop.enabled` | boolean | Use custom PINs |
| `byop.pin` | string | Custom PIN value |
## Methods
### startSession()
Start a cobrowse session.
```javascript
const session = await cobrowse.startSession();
// Returns: { pin: string, sessionId: string }
```
### endSession()
End the current session.
```javascript
await cobrowse.endSession();
```
### pause()
Pause screen sharing.
```javascript
cobrowse.pause();
```
### resume()
Resume screen sharing.
```javascript
cobrowse.resume();
```
## Events
### sessionStarted
```javascript
cobrowse.on('sessionStarted', (session) => {
// session.pin - PIN for agent to join
// session.sessionId - Unique session ID
});
```
### agentJoined
```javascript
cobrowse.on('agentJoined', (agent) => {
// agent.name - Agent display name
// agent.userId - Agent user ID
});
```
### agentLeft
```javascript
cobrowse.on('agentLeft', (agent) => {
// Agent disconnected
});
```
### sessionEnded
```javascript
cobrowse.on('sessionEnded', () => {
// Session terminated
});
```
### error
```javascript
cobrowse.on('error', (error) => {
// error.code - Error code
// error.message - Error description
});
```
## Resources
- **SDK Reference**: https://developers.zoom.us/docs/cobrowse-sdk/sdk-reference/
@@ -0,0 +1,5 @@
# API Reference
This local reference points to the official Cobrowse API docs.
- [API (official)](api-official.md)
@@ -0,0 +1,5 @@
# API (Reference)
Canonical source:
- [API (official)](api-official.md)
@@ -0,0 +1,90 @@
# Cobrowse SDK - Authorization
JWT authentication for Cobrowse sessions.
## Overview
Both customers and agents require JWTs for authentication. Generate tokens server-side.
## JWT Structure
### Header
```json
{
"alg": "HS256",
"typ": "JWT"
}
```
### Payload
| Claim | Type | Description |
|-------|------|-------------|
| `user_id` | string | Unique user identifier |
| `app_key` | string | Your SDK Key |
| `role_type` | number | 1 = customer, 2 = agent |
| `user_name` | string | Display name |
| `iat` | number | Issued at timestamp |
| `exp` | number | Expiration timestamp |
### Strict Claim Names (Important)
Cobrowse token validation is strict. Use these claim names exactly:
- `user_id` (not `user_identity`)
- `app_key`
- `role_type`
- `user_name`
- `iat`
- `exp`
Avoid adding unrecognized custom claims unless Zoom docs explicitly support them for your SDK version.
If you see `Invalid token` (code `124`), validate claim names first.
## Role Types
| Role | Value | Description |
|------|-------|-------------|
| Customer | 1 | User sharing their browser |
| Agent | 2 | Support staff viewing session |
## Customer Token Example
```javascript
const customerPayload = {
user_id: "customer_123",
app_key: "YOUR_SDK_KEY",
role_type: 1,
user_name: "John Customer",
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 3600
};
const token = jwt.sign(customerPayload, SDK_SECRET, { algorithm: 'HS256' });
```
## Agent Token Example
```javascript
const agentPayload = {
user_id: "agent_456",
app_key: "YOUR_SDK_KEY",
role_type: 2,
user_name: "Support Agent",
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 3600
};
const token = jwt.sign(agentPayload, SDK_SECRET, { algorithm: 'HS256' });
```
## Security
- Generate tokens server-side only
- Never expose SDK Secret in client code
- Use reasonable expiration times
## Resources
- **Auth docs**: https://developers.zoom.us/docs/cobrowse-sdk/authorize/
@@ -0,0 +1,5 @@
# Authorization (Reference)
Canonical source:
- [Authorization (official)](authorization-official.md)
@@ -0,0 +1,20 @@
# Zoom Cobrowse SDK Environment Variables
## Standard `.env` keys
| Variable | Required | Used for | Where to find |
| --- | --- | --- | --- |
| `ZOOM_SDK_KEY` | Yes | SDK identity | Zoom Marketplace -> Cobrowse/Contact Center SDK app -> App Credentials |
| `ZOOM_SDK_SECRET` | Yes | SDK auth signing | Zoom Marketplace -> Cobrowse/Contact Center SDK app -> App Credentials |
| `COBROWSE_BASE_URL` | Optional | Regional/tenant SDK endpoint override | Cobrowse SDK documentation or tenant provisioning details |
## Runtime-only values
- `ZOOM_COBROWSE_SESSION_TOKEN`
If your implementation mints short-lived tokens, store them in memory/cache only.
## Notes
- Keep `ZOOM_SDK_SECRET` server-side.
- Some samples use aliases (`SDK_KEY`, `SDK_SECRET`); normalize internally.
@@ -0,0 +1,6 @@
# Error Codes
Use the official Cobrowse docs and API behavior notes for code-level troubleshooting.
- [Get Started (official)](get-started-official.md)
- [API (official)](api-official.md)
@@ -0,0 +1,111 @@
# Cobrowse SDK - Features
Annotations, masking, and advanced features.
## Overview
Cobrowse SDK includes features for privacy, collaboration, and customization.
## Annotations
Agents can draw and highlight on the shared screen.
### Enable Annotations
```javascript
const cobrowse = new ZoomCobrowse({
sdkKey: SDK_KEY,
token: token,
features: {
annotations: true
}
});
```
### Annotation Tools
| Tool | Description |
|------|-------------|
| Pointer | Highlight cursor position |
| Draw | Freehand drawing |
| Highlight | Transparent highlight |
| Arrow | Point to elements |
## Privacy Masking
Hide sensitive information from agents.
### Mask Elements
```html
<!-- Add data attribute to sensitive fields -->
<input type="text" data-cobrowse-mask="true" placeholder="SSN" />
<input type="password" data-cobrowse-mask="true" />
<div data-cobrowse-mask="true">Sensitive content</div>
```
### Mask by CSS Selector
```javascript
const cobrowse = new ZoomCobrowse({
sdkKey: SDK_KEY,
token: token,
masking: {
selectors: [
'.sensitive-data',
'#credit-card-field',
'[data-private]'
]
}
});
```
## Bring Your Own PIN (BYOP)
Use your own PIN system instead of Zoom-generated PINs.
```javascript
const cobrowse = new ZoomCobrowse({
sdkKey: SDK_KEY,
token: token,
byop: {
enabled: true,
pin: 'YOUR_CUSTOM_PIN'
}
});
```
## Session Control
### End Session
```javascript
cobrowse.endSession();
```
### Pause/Resume
```javascript
cobrowse.pause();
cobrowse.resume();
```
### Events
```javascript
cobrowse.on('sessionStarted', (session) => {
console.log('Session started:', session.pin);
});
cobrowse.on('agentJoined', (agent) => {
console.log('Agent joined:', agent.name);
});
cobrowse.on('sessionEnded', () => {
console.log('Session ended');
});
```
## Resources
- **Features docs**: https://developers.zoom.us/docs/cobrowse-sdk/add-features/
@@ -0,0 +1,5 @@
# Features (Reference)
Canonical source:
- [Features (official)](features-official.md)
@@ -0,0 +1,91 @@
# Cobrowse SDK - Get Started
Set up collaborative browsing on your website.
## Overview
This guide walks through integrating the Cobrowse SDK for customer-initiated sessions.
## Prerequisites
1. SDK Universal Credit on your Zoom account
2. SDK Key and Secret
3. Token server for JWT generation
## Step 1: Get SDK Credentials
1. In Zoom Workplace, go to **Advanced****Zoom CPaaS****Manage**
2. Click **Build App**
3. Locate **SDK Key** and **SDK Secret**
## Step 2: Set Up Token Server
Generate JWTs server-side to protect your SDK Secret.
```javascript
const jwt = require('jsonwebtoken');
function generateCobrowseToken(userId, userName, roleType) {
const iat = Math.floor(Date.now() / 1000);
const exp = iat + 3600; // 1 hour
const payload = {
user_id: userId,
app_key: SDK_KEY,
role_type: roleType, // 1 = customer, 2 = agent
user_name: userName,
iat: iat,
exp: exp
};
return jwt.sign(payload, SDK_SECRET, { algorithm: 'HS256' });
}
```
## Step 3: Integrate Customer SDK
Add to your website:
```html
<script src="https://cobrowse.zoom.us/sdk.js"></script>
<script>
async function startCobrowse() {
// Get token from your server
const token = await fetch('/api/cobrowse-token').then(r => r.json());
const cobrowse = new ZoomCobrowse({
sdkKey: 'YOUR_SDK_KEY',
token: token.jwt
});
const session = await cobrowse.startSession();
// Display PIN to customer
alert(`Your session PIN: ${session.pin}`);
}
</script>
<button onclick="startCobrowse()">Start Support Session</button>
```
## Step 4: Set Up Agent View
Agents join via iframe:
```html
<iframe
src="https://cobrowse.zoom.us/agent?pin={PIN}"
allow="camera; microphone"
></iframe>
```
## Next Steps
- Configure [privacy masking](features.md#masking)
- Set up [annotations](features.md#annotations)
- Implement [Bring Your Own PIN](features.md#byop)
## Resources
- **Cobrowse docs**: https://developers.zoom.us/docs/cobrowse-sdk/get-started/

Some files were not shown because too many files have changed in this diff Show More