Rank Intercom and Zendesk feature requests by the revenue of the people asking

Monthly: 90 days of feature requests from support and Discord, ranked by the MRR of the customers asking and the open deals they hold up.

Runs
1st of the month at 9:00
Posts
Report card

From your apps to your board

How the skill works: your agent reads 90 days of requests from Intercom; customer support from Zendesk; add community requests from Discord; each requester's revenue and deals from Stripe; crm from HubSpot; feature list, with synonyms, feature request tag, discord requests channel id from What you tell it, 1st of the month at 9:00, and gives you report card and the report in the chat.

Reads

  • Intercom90 days of requests
  • ZendeskCustomer support
  • DiscordAdd community requests
  • StripeEach requester's revenue and deals
  • HubSpotCRM
  • What you tell itFeature list, with synonyms, Feature request tag, Discord requests channel ID
reads
Your agentClaude Code, Codex, Cursor or Gemini1st of the month at 9:00
posts

You get

  • Report cardOn your board, updated in place every run
  • The report in the chatEvery run, with or without Briefkin

What you get

  • Requests in 90 days: how many, from how many people, by source.
  • Ranked by MRR: each feature with unique requesters, count rank, MRR of paying requesters and open deals that mention it.
  • Where count and revenue disagree: features that rank much higher by MRR than by count.
  • Proposed new features from unmatched requests.
  • What to do first: the feature with the most MRR and open pipeline behind it, and the customers to tell when it ships.

The card on the right is a sample. Yours shows your own numbers and updates in place every run.

What lands on your board

AcmeFeature requests weighted by revenue: support, Stripe and CRM · Claude Code

SSO is 4th by requests but 1st by revenue

SSO came from 9 customers in 90 days, 4th by count, but they pay $3,100 MRR, more than any other request, and it holds up 2 open deals worth $40,000. Dark mode leads by count with $620 MRR behind it.

RequestRequestersCount rankMRROpen deals
SSO (SAML)94th$3,1002, $40,000
Bulk CSV import212nd$1,850None
Zapier integration173rd$1,4001, $8,000
Calendar sync85th$900None
Dark mode341st$620None

214 requests from 146 people: Intercom 128, Zendesk 61, Discord 25 (counted, not priced).

Woodgrove Bank ($28,000) and Relecloud ($12,000) list SSO as a blocker. When ENG-412 has a date, tell them and the 9 paying requesters.

Done
An example with made-up numbers. Your agent posts your real ones.

What it does

A feature request list sorted by count favors whoever writes in most: free users, small accounts, the regulars in Discord. The request that three of your biggest customers raised once each, and that two open deals mention, sits near the bottom of it.

Once a month the agent groups 90 days of requests from Intercom and Zendesk (and Discord, counted but not priced), matches each requester to their Stripe MRR and their open HubSpot deals, and ranks the requests both ways. Product managers see where count and revenue disagree; support and founders get a list they can answer customers from.

How it works

  1. 1Collect 90 days of requests

    Intercom: POST /conversations/search with created_at > the Unix time 90 days ago, plus tag_ids IN [<feature request tag>] if you tag them, and GET /conversations/{id} for the messages and source.author.email. Zendesk: GET /api/v2/search.json?query=type:ticket created>90days tags:feature_request (your tag), then GET /api/v2/users/show_many?ids=<requester_ids> for emails.

  2. 2Add community requests

    For a feature-requests forum channel, list threads with GET /channels/{channel.id}/threads/archived/public and GET /guilds/{guild.id}/threads/active, keep those started in the 90 days (the thread ID is a snowflake that encodes the time) and read each starter message. Discord does not give bots members' emails, so these are counted but carry no revenue unless you keep a username-to-email list.

  3. 3

    3Classify into features

    Map each request to one name on the feature list the person keeps, using its synonyms; read untagged conversations too, since many requests arrive inside a support question. Propose a new name only for a cluster of 3 or more unmatched requests. Count unique requesters per feature, not conversations, so a customer who wrote five times counts once.

  4. 4Look up each requester's revenue and deals

    Stripe: GET /v1/customers/search?query=email:"<email>", then the customer's active subscriptions for MRR (monthly, after discounts). HubSpot: POST /crm/v3/objects/contacts/search with email IN [...], then POST /crm/v4/associations/contacts/deals/batch/read and the deals' amount and hs_is_closed, keeping open ones.

  5. 5

    5Join and rank both ways

    Join on the lowercased requester email; when it misses, match the email domain to a Stripe customer or HubSpot company domain, never free-mail. A company with several requesters adds its MRR and each deal once per feature. Requesters with no Stripe customer count in the request total and add $0. Rank by MRR, show the count rank beside it, and call out any feature whose MRR rank is 3 or more places above its count rank.

  6. Post it to the board

    With BRIEFKIN_TOKEN set, the agent sends the result as one card that updates in place every run. Without it, you get the report in the chat.

Install and run it

Pick your agent, where the data comes from and how to schedule it; the commands below follow.

Agent
Data
Schedule
  1. Install the skill

    One command. It puts the SKILL.md in ~/.claude/skills and in ~/.agents/skills, which Codex, Cursor, Gemini CLI, Copilot CLI and OpenCode read too.

    shellcurl -fsSL https://briefkin.dev/skills/intercom-requests-weighted-by-revenue/install | sh
  2. Run it

    Ask Claude Code:

    promptRun the intercom-requests-weighted-by-revenue skill

    Or paste the prompt instead of installing:

    promptCollect feature requests from the last 90 days: Intercom conversations (tag "<feature request tag>" if set, plus untagged ones that ask for a feature), Zendesk tickets tagged feature_request, and threads in my Discord requests forum. Group them into features from my list: <feature: synonyms; ...>, and propose new names only for clusters of 3 or more. Count unique requesters per feature. Match each requester by lowercased email to a Stripe customer (MRR from active subscriptions, monthly, after discounts) and to HubSpot contacts with open deals; fall back to company email domain, never free-mail. Count a company's MRR and each deal once per feature; Discord requesters count but add no revenue. Rank features by MRR with the count rank beside it, flag features whose MRR rank is 3 or more places above their count rank, and give totals by source. End with the feature to prioritize first and the customers to tell when it ships.
  3. Put it on a schedule

    1st of the month at 9:00, from cron on any machine where Claude Code is signed in:

    crontab0 9 1 * * claude -p "Run the intercom-requests-weighted-by-revenue skill"

    Add it with crontab -e. A laptop asleep at that time runs it when it wakes if you use launchd or Task Scheduler instead; GitHub Actions works for the API route.

  4. Send it to your board

    Connect Briefkin once with curl -fsSL https://briefkin.dev/install | sh and every run lands on your board as a report card. How setup works

View the SKILL.mdRaw file
SKILL.md---
name: intercom-requests-weighted-by-revenue
description: "Monthly: 90 days of feature requests from support and Discord, ranked by the MRR of the customers asking and the open deals they hold up. Use when the user asks for this, or when it runs on a schedule."
---

# Feature requests weighted by revenue: support, Stripe and CRM

Monthly: 90 days of feature requests from support and Discord, ranked by the MRR of the customers asking and the open deals they hold up.

A feature request list sorted by count favors whoever writes in most: free users, small accounts, the regulars in Discord. The request that three of your biggest customers raised once each, and that two open deals mention, sits near the bottom of it.

Once a month the agent groups 90 days of requests from Intercom and Zendesk (and Discord, counted but not priced), matches each requester to their Stripe MRR and their open HubSpot deals, and ranks the requests both ways. Product managers see where count and revenue disagree; support and founders get a list they can answer customers from.

## Two ways to get the data

Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.

## Route A: API or MCP server

### What you need

- Read access to Intercom conversations or Zendesk tickets, and the feature-request tag if you use one; untagged requests are classified by the agent.
- The same customer email in Intercom or Zendesk, Stripe and HubSpot: each request is priced through its requester's email, or the company domain when that is all that matches.
- Read access to Stripe Customers and Subscriptions and to HubSpot contacts and deals; optionally a Discord bot with View Channels and Read Message History on the requests channel.

If something is missing, say what and stop; do not invent numbers.

### Steps

1. **Collect 90 days of requests** (Intercom): Intercom: `POST /conversations/search` with `created_at >` the Unix time 90 days ago, plus `tag_ids IN [<feature request tag>]` if you tag them, and `GET /conversations/{id}` for the messages and `source.author.email`. Zendesk: `GET /api/v2/search.json?query=type:ticket created>90days tags:feature_request` (your tag), then `GET /api/v2/users/show_many?ids=<requester_ids>` for emails.
2. **Add community requests** (Discord): For a feature-requests forum channel, list threads with `GET /channels/{channel.id}/threads/archived/public` and `GET /guilds/{guild.id}/threads/active`, keep those started in the 90 days (the thread ID is a snowflake that encodes the time) and read each starter message. Discord does not give bots members' emails, so these are counted but carry no revenue unless you keep a username-to-email list.
3. **Classify into features**: Map each request to one name on the feature list the person keeps, using its synonyms; read untagged conversations too, since many requests arrive inside a support question. Propose a new name only for a cluster of 3 or more unmatched requests. Count unique requesters per feature, not conversations, so a customer who wrote five times counts once.
4. **Look up each requester's revenue and deals** (Stripe): Stripe: `GET /v1/customers/search?query=email:"<email>"`, then the customer's active subscriptions for MRR (monthly, after discounts). HubSpot: `POST /crm/v3/objects/contacts/search` with `email IN [...]`, then `POST /crm/v4/associations/contacts/deals/batch/read` and the deals' `amount` and `hs_is_closed`, keeping open ones.
5. **Join and rank both ways**: Join on the lowercased requester email; when it misses, match the email domain to a Stripe customer or HubSpot company domain, never free-mail. A company with several requesters adds its MRR and each deal once per feature. Requesters with no Stripe customer count in the request total and add $0. Rank by MRR, show the count rank beside it, and call out any feature whose MRR rank is 3 or more places above its count rank.

## Route B: the browser

### What you need

- Signed in to Intercom or Zendesk as a teammate or agent, to the Stripe Dashboard (Analyst role or higher), to HubSpot with view access to contacts and deals, and to Discord as a member of the requests channel.

If something is missing, say what and stop; do not invent numbers.

### Steps

Start at https://app.intercom.com/. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.

1. **Collect requests in Intercom**: Open the inbox, search or filter by your feature-request tag and set the date to the last 90 days. For each conversation, note the requester's email and what they asked for. Read a sample of untagged conversations too, since requests often arrive inside support questions.
2. **Add Zendesk and Discord**: Zendesk: search `type:ticket created>90days tags:feature_request` and note requester and request. Discord: open the feature-requests forum channel, scroll through posts from the last 90 days and note each request and username.
3. **Group and count**: Map each request to a feature from the list, by name or synonym, and count unique requesters per feature. Propose a new feature only for 3 or more similar unmatched requests.
4. **Price the requesters**: In `https://dashboard.stripe.com/customers` search each email and read the active subscription amount per month. In HubSpot, open the contact (or company) and read the open deals in its **Deals** card. Count a company once per feature; Discord requesters add no revenue.
5. **Rank and report**: Rank features by MRR with the count rank beside it and the open deals, flag features 3 or more places higher by MRR than by count, give totals by source, and end with the feature to prioritize and the customers to tell when it ships.

Note: Looking up each requester by hand is slow past about 100 requests; the browser route then works best on the top features by count plus anything tagged by a paying account, and the API route covers the full set. Without a feature-request tag the browser route can only sample untagged conversations, so its counts run low.

## The report

- **Requests in 90 days**: how many, from how many people, by source.
- **Ranked by MRR**: each feature with unique requesters, count rank, MRR of paying requesters and open deals that mention it.
- **Where count and revenue disagree**: features that rank much higher by MRR than by count.
- **Proposed new features** from unmatched requests.
- What to do first: the feature with the most MRR and open pipeline behind it, and the customers to tell when it ships.

## Post it to Briefkin

When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.

```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
  -H "authorization: Bearer $BRIEFKIN_TOKEN" \
  -H "content-type: application/json" \
  -d @- <<'JSON'
{
  "v": 1,
  "event_id": "intercom-requests-weighted-by-revenue/<date of this run, e.g. 2026-10-16>",
  "item_key": "intercom-requests-weighted-by-revenue",
  "project": "Acme",
  "source": "Feature requests weighted by revenue: support, Stripe and CRM skill",
  "kind": "update",
  "title": "SSO is 4th by requests but 1st by revenue",
  "summary": "**SSO** came from 9 customers in 90 days, 4th by count, but they pay **$3,100 MRR**, more than any other request, and it holds up **2 open deals worth $40,000**. Dark mode leads by count with $620 MRR behind it.",
  "widget": [
    {
      "type": "Table",
      "props": {
        "columns": [
          "Request",
          "Requesters",
          "Count rank",
          "MRR",
          "Open deals"
        ],
        "align": [
          "left",
          "right",
          "right",
          "right",
          "left"
        ],
        "rows": [
          [
            "SSO (SAML)",
            9,
            "4th",
            "$3,100",
            "2, $40,000"
          ],
          [
            "Bulk CSV import",
            21,
            "2nd",
            "$1,850",
            "None"
          ],
          [
            "Zapier integration",
            17,
            "3rd",
            "$1,400",
            "1, $8,000"
          ],
          [
            "Calendar sync",
            8,
            "5th",
            "$900",
            "None"
          ],
          [
            "Dark mode",
            34,
            "1st",
            "$620",
            "None"
          ]
        ]
      }
    },
    {
      "type": "Text",
      "props": {
        "text": "214 requests from 146 people: Intercom 128, Zendesk 61, Discord 25 (counted, not priced).",
        "variant": "muted"
      }
    },
    {
      "type": "Callout",
      "props": {
        "text": "Woodgrove Bank ($28,000) and Relecloud ($12,000) list SSO as a blocker. When ENG-412 has a date, tell them and the 9 paying requesters.",
        "tone": "info"
      }
    }
  ]
}
JSON
```

Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.

## Run it on a schedule

Suggested: 1st of the month at 9:00 (`0 9 1 * *`). From cron, with the agent signed in on that machine:

```bash
0 9 1 * * claude -p "Run the intercom-requests-weighted-by-revenue skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```

Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/intercom-requests-weighted-by-revenue#schedule

Source: https://briefkin.dev/skills/intercom-requests-weighted-by-revenue

What your agent needs

  • Read access to Intercom conversations or Zendesk tickets, and the feature-request tag if you use one; untagged requests are classified by the agent.

  • The same customer email in Intercom or Zendesk, Stripe and HubSpot: each request is priced through its requester's email, or the company domain when that is all that matches.

  • Read access to Stripe Customers and Subscriptions and to HubSpot contacts and deals; optionally a Discord bot with View Channels and Read Message History on the requests channel.

Connecting Intercom

  1. Intercom MCP server, Intercom's official remote server at https://mcp.intercom.com/mcp (https://mcp.eu.intercom.com/mcp for EU workspaces; Australian workspaces aren't supported yet). Intercom is in Claude's connector directory for US workspaces, and on Team and Enterprise plans an Owner adds it. Its tools search and fetch conversations and contacts (docs).
  2. REST API with an access token. Create an app in the Intercom Developer Hub, store its access token in INTERCOM_ACCESS_TOKEN, and call https://api.intercom.io (api.eu.intercom.io or api.au.intercom.io by region) with an Intercom-Version header. Give the app Read conversations and Read and list users and companies.

The MCP server includes a few write tools (internal notes, Help Center articles), so for unattended reports an app token with read permissions only is the tighter option.

Connecting Zendesk

  1. MCP server. Zendesk doesn't list an official one; community MCP servers exist, and they need the same subdomain, email and API token as a direct API call.
  2. API with an API token. An admin enables token access in Admin Center under Apps and integrations > APIs and creates a token. The skill reads ZENDESK_SUBDOMAIN, ZENDESK_EMAIL and ZENDESK_API_TOKEN and sends basic auth as {email}/token:{token}.
  3. OAuth client. For a narrower credential, register an OAuth client in Admin Center and request the read scope.

An API token acts as the user who made it, with that agent's full rights; an OAuth token with only read can't update, assign or close tickets.

Connecting Discord

  1. MCP server. Discord doesn't publish an official one. Community MCP servers exist and run on your own bot token; many include sending and moderation tools, so read what a server can do before you hand it a token.
  2. REST API with a bot. Create an application in the Discord Developer Portal, add a bot, turn on the Message Content intent, and invite the bot to your server with only the View Channels and Read Message History permissions. Store its token in DISCORD_BOT_TOKEN and send it as Authorization: Bot <token>; the skill also reads DISCORD_CHANNEL_IDS, the channels to watch.

Keep the bot out of every channel the report doesn't cover with channel permission overrides, and leave out Send Messages unless you want it to post the digest back into Discord.

Connecting Stripe

  1. Stripe MCP server, Stripe's official remote server at https://mcp.stripe.com. Add Stripe from Claude's connector directory, or run claude mcp add --transport http stripe https://mcp.stripe.com/, and sign in with OAuth; clients without OAuth can send a restricted key as a Bearer token.
  2. The Stripe CLI. Run stripe login once, then stripe subscriptions list --status active --limit 100 or stripe invoices list --status open. The CLI defaults to test mode, so add --live for real data.
  3. API with a restricted key. Create a restricted key (rk_live_...) in the Dashboard under Developers > API keys, store it in STRIPE_API_KEY, and give it Read on the resources the report touches: Subscriptions, Invoices, Charges, Customers, PaymentIntents, Balance and Disputes.

Never hand an agent the secret key (sk_live_...); a restricted key with Read where needed and None everywhere else can't refund, cancel or charge anything.

Connecting HubSpot

  1. HubSpot MCP server, HubSpot's remote server at https://mcp.hubspot.com. HubSpot also offers a Claude connector built on the same server; you sign in with your HubSpot user and it sees what that user can see (docs).
  2. API with a private app token. Create a private app in your HubSpot account settings, give it only the scopes the report reads (crm.objects.deals.read, crm.objects.contacts.read, crm.objects.companies.read, crm.objects.owners.read), and store its token in HUBSPOT_ACCESS_TOKEN.

The MCP server and connector can create and update records, so for unattended reports a private app with only .read scopes is the safer credential.

Questions

What about requests from people who are not in Stripe?

They count toward the number of requesters and add $0 MRR. They are usually free or trial users, or a colleague of a paying customer writing from another address; the domain fallback catches the second case for company domains. If a feature's requesters are mostly unmatched, the card says so rather than ranking it low.

Why 90 days, and does an old request still count?

Ninety days collects enough requests to rank and stays recent enough that the requester still cares. Each month's run covers a fresh 90-day window, so a request drops off three months after it was made. MRR is read on the day of the run, so a customer who has since churned adds nothing.

Do I need Briefkin to use the Feature requests weighted by revenue: support, Stripe and CRM skill?

No. The skill runs with your own agent and gives you the report in the chat. With a Briefkin token set, each run also posts it to your board as a report card, so you can glance at it instead of asking again.

Which agents can run it?

Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Windsurf and Amp all read SKILL.md files. The install command puts it in ~/.claude/skills and ~/.agents/skills, where they look. ChatGPT, the Claude app and Grok take the prompt instead. Pick your agent under "Install and run it" and the commands change to match.

Can it work without an API or MCP server, from my browser?

Yes. Switch the data source to "Your browser" and the steps change to the Intercom, Zendesk, Discord, Stripe and HubSpot pages themselves: the agent opens app.intercom.com in a browser you are signed in to and reads the numbers off the page. Claude Code, Codex, Cursor, Claude app and ChatGPT can drive a browser out of the box; Gemini CLI, Copilot CLI and OpenCode need a Playwright or Chrome DevTools MCP server first. It is slower than the API and needs you signed in, so it suits a report you run by hand or from a scheduler on your own computer.

Read this report on your board, not in a chat log

Skills are free to use with any agent. Briefkin is where their results land: one board for every report, number and question your agents send, with a ping when something needs you.

Free during the open beta. No card.