All workflows

Reach NPS detractors while the score is fresh

Pull low scores from your NPS survey, route each one to its account owner with the comment, and draft a reply that listens.

View on GitHub

nps-detractor-rescue.md

Reach NPS detractors while the score is fresh

Set up the tools below, then run the steps in order for the user, carrying each step's results into the next.

Inputs

Ask the user for these before you start.

  • form_id: the Typeform NPS survey
  • score_field: the ref of its 0 to 10 question, e.g. nps_score
  • comment_field: the ref of its open question, e.g. nps_reason
  • email_field: the ref of the email question, or the name of the hidden field that carries the email, e.g. email
  • lookback_days: how far back to read responses, e.g. 7
  • cs_channel: the Slack channel to post in, e.g. #customer-success

Set up

Retrieve responses (Typeform, tool:typeform/retrieve-responses)

Use the API.

Note: Forms with more than 1,000 responses need narrower since and until ranges or the before and after cursors. Responses from the last 30 minutes or so may be missing: use a webhook for real-time leads.

HubSpot (tool:hubspot/search-crm-records, tool:hubspot/create-note)

For each call, use the first option your agent supports that lists it.

Notes:

  • Search CRM records: The MCP tool takes up to five groups of six filters and returns up to 200 records per page.
  • Create a note: hs_timestamp is required; attach the note to existing records with an associations object.
MCP (official, remote)

Add this server to your agent's MCP settings, then sign in when asked.

{ "mcpServers": { "hubspot": { "url": "https://mcp.hubspot.com" } } }
  • Search CRM records: call the MCP tool search_crm_objects
API (official)
  • Base URL: https://api.hubapi.com
  • Search CRM records: POST /crm/objects/2026-09/{objectType}/search
  • Create a note: POST /crm/objects/2026-09/notes
  • Auth: send the header Authorization: Bearer $HUBSPOT_API_KEY

Note: Use a service key or an app's static access token with the CRM scopes the calls need; paths carry a dated version such as 2026-09.

Post a message (Slack, tool:slack/post-message)

Use the first option your agent supports.

Note: Needs the chat:write scope. Over MCP it posts as the signed-in user; the API and CLI post as the app's bot.

MCP (official, remote)

Add this server to your agent's MCP settings, then sign in when asked.

{ "mcpServers": { "slack": { "url": "https://mcp.slack.com/mcp" } } }

Call the MCP tool slack_send_message.

CLI (official)

Install the command, then confirm it runs.

curl -fsSL https://downloads.slack-edge.com/slack-cli/install.sh | bash
slack --version

Run slack api chat.postMessage.

Set $SLACK_BOT_TOKEN in your environment first (get a key: https://api.slack.com/apps).

Before step 1, confirm access to each service with its cheapest read-only call, like a list or a search. Never send or change anything to test access.

Steps

  1. Pull detractors with Retrieve responses (Typeform). Read the responses to form_id submitted in the last lookback_days. Keep those with a score_field of 6 or less, with the email from email_field, the score and the comment_field answer.
  2. Find their owner with Search CRM records (HubSpot). Search contacts by each email. Keep the contact ID, company name and hubspot_owner_id; note the emails with no contact.
  3. Route it with Post a message (Slack). Post one message per detractor to cs_channel with the score, the comment, the company and the owner ID.
  4. Write the reply yourself. Draft a short plain-text reply for each detractor's owner to send that thanks them, restates their comment in one line and asks for 15 minutes. Show the drafts to the user.
  5. Log it with Create a note (HubSpot). Add a note to each contact ID with the score, the comment and the approved reply.

Done when

  • Every detractor in the window has a Slack post and a drafted reply.
  • Each matched contact has a note, and the user has the emails with no contact.

Rules

  • Use only the services set up above. The read-only calls they need, like listing ids or polling for results, are fine.
  • Ask the user before anything that sends messages, costs money, or changes data, and say how many records it touches. One approval covers a batch the user has seen.
  • Never print API keys.