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.
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 surveyscore_field: the ref of its 0 to 10 question, e.g. nps_scorecomment_field: the ref of its open question, e.g. nps_reasonemail_field: the ref of the email question, or the name of the hidden field that carries the email, e.g. emaillookback_days: how far back to read responses, e.g. 7cs_channel: the Slack channel to post in, e.g. #customer-success
Set up
Retrieve responses (Typeform, tool:typeform/retrieve-responses)
Use the API.
- Base URL: https://api.typeform.com
- Endpoint:
GET /forms/{form_id}/responses - Auth: send the header
Authorization: Bearer $TYPEFORM_API_KEY - Get a key: https://admin.typeform.com/user/tokens
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_timestampis required; attach the note to existing records with anassociationsobject.
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
- Pull detractors with Retrieve responses (Typeform). Read the responses to
form_idsubmitted in the lastlookback_days. Keep those with ascore_fieldof 6 or less, with the email fromemail_field, the score and thecomment_fieldanswer. - 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. - Route it with Post a message (Slack). Post one message per detractor to
cs_channelwith the score, the comment, the company and the owner ID. - 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.
- 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.
