Closed Lost Revival logo

Closed Lost Revival

Organization
cognyai
closed-lost-revival

Re-read every lost deal in your CRM (HubSpot, Pipedrive or Upsales; Salesforce via the CRM layer) with its calls, meetings and notes, replace "not interested" with the real reason plus a reopen condition, then watch for those conditions — a shipped feature, a renewal date, a champion moving, the account coming back to your site — and draft a personal note that quotes the original conversation

Overview

Publishercognyai
Repositoryclaude-code-marketing-skills
Skill nameclosed-lost-revival
Stars
111
Forks
15
Bundled files
Instructions only
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by cognyai on GitHub. Read the source before you install it.

Installation

Install the Closed Lost Revival AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/cognyai/claude-code-marketing-skills/tree/main/skills/closed-lost-revival
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/cognyai/claude-code-marketing-skills.git /tmp/claude-code-marketing-skills
mkdir -p .claude/skills
cp -r /tmp/claude-code-marketing-skills/skills/closed-lost-revival .claude/skills/closed-lost-revival
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Closed Lost Revival in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Closed Lost Revival on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Closed Lost Revival is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Closed-Lost Revival

This is the agent that pays for all the others. "Not interested" is a lazy summary of a real conversation. Re-read each lost deal, record the actual reason and a reopen condition, and then watch for the condition:

  • "Needed SSO" → the day the changelog says SSO shipped, they get a personal note quoting their call.
  • "Went with a competitor, contract renews in March" → show up in January.
  • "Champion left the company" → congratulate them at the new company and reintroduce yourself.

Most companies have a pile of unfinished revenue sitting in their own CRM.

Requires: Cogny ($9/mo) with a CRM connected: HubSpot, Pipedrive or Upsales (Salesforce and others: see the CRM layer in /marketing-engineer). The steps below are written for HubSpot. "Pipedrive and Upsales" says what changes for those CRMs. Fibbler is optional and adds ad-engagement signals.

Step 0: Cogny check

If no mcp__cogny__* tools exist (no list_integrations, no cogny_status), print this and stop:

Closed-Lost Revival needs your marketing data through Cogny's MCP gateway.

1. Sign up at https://cogny.com and connect a CRM: HubSpot, Pipedrive or Upsales (Stripe and fibbler optional).
2. Add Cogny to .mcp.json in your project:
   {"mcpServers": {"cogny": {"type": "http", "url": "https://app.cogny.com/mcp"}}}
3. Restart Claude Code; it opens a browser for the OAuth login on first use.

Nothing to run without Cogny.

Prerequisites

  1. Call list_integrations. This skill needs a CRM: HubSpot, Pipedrive or Upsales.

  2. Make one cheap read on the CRM: HubSpot get_user_details, Pipedrive list_users, Upsales list_users(limit: 1). If fibbler is connected, get_account_overview. A 401, Forbidden or "lacks scope" means 🔴 "reconnect in Cogny"; don't retry it. A broken fibbler only drops the ad-engagement signals; a broken CRM stops the run.

  3. If a CRM tool is missing, call refresh_mcp_discovery once. New tools only appear after the client reconnects, so tell the user to reconnect the Cogny MCP and stop this run.

  4. No CRM connected: print this and stop. Don't fall back to runcloser (not supported).

    Closed-lost revival needs a CRM. Connect HubSpot, Pipedrive or Upsales in Cogny
    (Integrations → Connect), then run /closed-lost-revival build again.

    Optional partial ledger from Stripe. If Stripe is connected, offer (don't run unasked) a "lost customers" ledger instead: stripe_api_read GetSubscriptions with status: "canceled", paged with starting_after and aggregated with jq (pages are large), reading canceled_at, cancellation_details (reason, feedback, comment) and the plan price. Skip trial-only cancellations (ended_at == trial_end). Write it to brain/evidence/closed-lost/ledger headed "Partial: Stripe cancellations only, no CRM", with comment as the only [verbatim] evidence. These are churned customers, not lost deals, so there is no conversation to re-read and no draft notes.

Usage

  • /closed-lost-revival build — first pass over lost deals (last 18 months), creates the ledger
  • /closed-lost-revival watch — weekly: check every open reopen condition
  • /closed-lost-revival shipped "SSO" — a feature just shipped, so find everyone who asked for it
  • /closed-lost-revival match BK014 — lost prospects that campaign BK014's offer answers

Steps — build

1. Pull lost deals

get_user_details to confirm read access. get_properties(deals, ["dealstage","closed_lost_reason","pipeline"]) to learn the pipelines and which stages are closed-lost, plus the options on closed_lost_reason (it's often free text, sometimes a dropdown).

search_crm_objects on deals, filters hs_is_closed = true AND hs_is_closed_won = false AND closedate ≥ 18 months ago. Properties: dealname, amount, deal_currency_code, closedate, closed_lost_reason, dealstage, pipeline, hubspot_owner_id, hs_analytics_source, hs_analytics_source_data_1, hs_analytics_source_data_2, notes_last_contacted. Page with after until done.

Exclude non-losses: reasons or names saying duplicate, test, merged, created in error, or "moved to another pipeline". Report excluded counts by reason. If more than half the rows are noise, file one ticket ("[ME:closed-lost-revival] Clean CRM: N of M lost deals are noise") and continue with the rest.

Amounts: use deal_currency_code. Never add amounts in different currencies together.

2. Re-read each deal

Cap at 50 deals per run, newest and largest first. For each deal:

  • Associated contacts and company (get_crm_objects with associations): name, jobtitle, company domain, industry, numberofemployees.
  • The conversation: search_crm_objects on calls, meetings and notes filtered by associations.deal = <dealId> (and by the main contact if the deal has none). Read hs_call_body, hs_meeting_body, hs_internal_meeting_notes, hs_note_body, and any transcript property (see /customer-language).
  • If fibbler is connected, get_influenced_deals (deal_filter: "lost", crm: "hubspot") shows which campaigns touched the deal.

closed_lost_reason is the rep's one-liner, written at close. The notes are where the real reason usually is. When they disagree, trust the notes and record both.

3. Record the real reason and a reopen condition

ReasonReopen condition typeExample condition
Missing featurefeature_shipped"SSO ships"
Timing / budget cycledate"after year-end close, 2027-01-15"
Chose competitordate (renewal) + signal"contract renews 2027-03; watch for competitor complaints"
Champion left / no championperson_moved"the champion lands somewhere new"
Priceoffer_change"a lower tier or annual discount exists"
Too small / bad fitnone — and add to customer-fit evidence—
Unknownnone — flag the notes as too thin to judge—

Keep the evidence: the note or quote it came from, with object type, id and date, labelled [verbatim] or [paraphrase]. Never invent a reason. If the record is too thin, say "unknown — notes too thin".

4. Write the ledger

write_context_node at brain/evidence/closed-lost/ledger:

markdown
# Closed-lost ledger — built YYYY-MM-DD
Lost deals (18 mo): N · real losses: R · excluded as noise: X · re-read: C (capped at 50)
| Deal (id) | Company | Lost | Amount (ccy) | CRM reason | Real reason | Evidence (object, id, date) | Reopen condition | Type | Watch until | Status |

Failures: <none, or what couldn't be read>

Also add brain/evidence/closed-lost/patterns: reasons ranked by count and by lost amount (per currency), plus the gap between the CRM reason and the real reason, which is a coaching finding in itself. If "too small" or "bad fit" leads the list, file a ticket proposing a customer-fit update. Don't make the edit yourself.

Optional: propose (as a ticket for a HubSpot admin) two custom deal properties, reopen_condition and reopen_date, so the team sees the conditions in the CRM. This skill never writes to the CRM.

Pipedrive and Upsales

StepPipedrive (Pipedrive)Upsales (Upsales)
Lost dealslist_deals(status: "lost", updated_since: <18 months ago>), cursor-paginated; get_deal for lost_reason, lost_time, value, currency, org_id, person_idlist_orders(filters=[{"field":"probability","comparator":"eq","value":0}], sort: "-date"); the loss-reason custom field comes from get_metadata
Company / peoplelist_organizations, list_persons(org_id)client.id → list_accounts, list_contacts(filters: client.id)
The conversationlist_activities(deal_id): subject, notelist_activities and list_appointments filtered by client.id: notes, description
Open deal now?list_deals(status: "open", org_id)list_opportunities(filters: client.id)
Last touchnewest list_activities(org_id, done: true)newest list_activities / list_appointments for client.id
Re-engagementfibbler get_warm_accounts with crm: "pipedrive"list_visits for client.id (Upsales web tracking)
Opt-outperson marketing_status when present; otherwise HOLDcontact unsubscribe/active fields from get_metadata; otherwise HOLD

Fibbler's get_influenced_deals takes crm: "hubspot" | "salesforce" | "copper" | "attio", with no Pipedrive or Upsales, so skip it there. Only get_warm_accounts accepts crm: "pipedrive". For Upsales, skip fibbler.

Steps — watch (weekly)

For each open row:

  • date: is it within 45 days? → due
  • feature_shipped: read brain/evidence/changelog (or WebFetch the changelog URL in START-HERE)
  • person_moved: brave_search for the person's name with their new title or company. Require a second identifier (old company, city, photo-free profile text) to match, because names collide.
  • offer_change: compare against brain/company/offers
  • Re-engagement (any row): re-read the company and contacts and look for hs_analytics_last_visit_timestamp in the last 14 days, a new recent_conversion_date (form fill), or hs_email_last_open_date/hs_email_last_click_date. If fibbler is connected, get_warm_accounts too. Any of these bumps the priority.

Before drafting, re-check the CRM (HubSpot fields below; Pipedrive/Upsales equivalents in the table above) and skip the row if:

  • the company has an open deal now (hs_is_closed = false), or has become a customer (lifecyclestage = customer, or a won deal under any name)
  • a contact was touched in the last 14 days (notes_last_contacted, hs_last_sales_activity_timestamp)
  • the contact has opted out: hs_email_optout = true, a "do not contact" hs_lead_status, or unsubscribed from sales email

Respecting opt-outs and contact preferences isn't optional.

Steps — shipped ""

search_context and the ledger for rows whose reason or evidence mentions the feature (and its synonyms). Each match is due now.

Drafting the note

For every due row, write a short personal note (≤100 words) that:

  1. References their original words: "Back in March you said the deal-breaker was SSO for your IT team." Only quote [verbatim] evidence as their words; paraphrase anything else.
  2. States what changed, specifically.
  3. Makes one low-friction ask.

Use brain/brand/voice. No claims outside offers. For person_moved, congratulate them first and lead with no pitch. Address it from the original deal owner (search_owners).

Bundle all drafts into one create_ticket ("[ME:closed-lost-revival] Approve: N closed-lost revival notes"), each with the deal link, the condition met, the evidence and the draft. Mark the rows drafted in the ledger. After the user sends, the next run sees the new engagement in HubSpot and marks the row sent.

Steps — match

Read brain/campaigns/<ID>. Select ledger rows whose real reason the campaign's offer answers (e.g. "maybe after year-end" for a year-end campaign). Draft as above and append the list to the campaign folder under ## Closed-lost matches. If there's no CRM or no ledger, write one line there instead: "skipped: ".

Recording findings

Detect the plan from the tools that exist: use create_ticket first when it exists (Cloud), and create_finding only when it doesn't (Solo). The fields differ; see section 2 of ../marketing-engineer/references/mcp-routing.md.

Critical rules

  1. Never invent a reason. "Unknown" is a valid answer.
  2. Quote only verbatim evidence as the prospect's words, with object id and date.
  3. Drafts only. Respect opt-outs. Skip open deals and customers.
  4. Read-only on the CRM. Proposed CRM fields go to a human as a ticket.
  5. Exclude CRM noise and report how much there was.

Frequently asked questions

What does the Closed Lost Revival AI skill do?

Re-read every lost deal in your CRM (HubSpot, Pipedrive or Upsales; Salesforce via the CRM layer) with its calls, meetings and notes, replace "not interested" with the real reason plus a reopen condition, then watch for those conditions — a shipped feature, a renewal date, a champion moving, the account coming back to your site — and draft a personal note that quotes the original conversation

Why use Closed Lost Revival on TypingMind?

Because you install it once and use it with any model. Closed Lost Revival is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Closed Lost Revival in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/cognyai/claude-code-marketing-skills/tree/main/skills/closed-lost-revival. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Closed Lost Revival?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Closed Lost Revival?

As many as you like. As long as a model supports skills, you can use Closed Lost Revival with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Closed Lost Revival AI skill free?

It is published on GitHub by cognyai. Check the repository for licensing terms. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇