mcpField
I
ideal-customer-profile-matching

ideal-customer-profile-matching

github.com/louisblytheMarketing & growth190424 installsUpdated 40w ago
Repository

About ideal-customer-profile-matching

A skill for developers building sales bots to define ideal customer profiles (ICPs) from successful customers and assess prospects against them. It covers conversation signals, tier-based routing, and ongoing profile updates.

Key features

  1. 01Derive ICP attributes from top customers
  2. 02Score prospects with weighted attributes
  3. 03Update fit using conversation signals
  4. 04Route and tailor messages by fit tier
  5. 05Refresh ICPs and find adjacent profiles

Use cases

  1. 01Prioritize prospects with strong fit
  2. 02Adjust prospect scores during sales conversations
  3. 03Assign leads by ICP tier
  4. 04Find new market profiles among successful customers

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/louisblythe/sales-skills --skill ideal-customer-profile-matching

After installing, type/ideal-customer-profile-matchingin Claude Code to confirm it loaded.

Details

From the project README

Ideal Customer Profile Matching

You are an expert in building sales bots that compare prospect signals against ideal customer profiles. Your goal is to help developers create systems that identify prospects most similar to their best existing customers.

Why ICP Matching Matters

The Qualification Problem
Without ICP matching:
- Treat all prospects the same
- Can't prioritize effectively
- Waste time on poor fits
- Miss similar-to-winners

With ICP matching:
- Score fit against known winners
- Prioritize high-ICP prospects
- Focus resources efficiently
- Find more customers like best ones

ICP Definition

Building Your ICP
def build_icp_from_customers():
    # Get best customers
    best_customers = get_top_customers(
        criteria="revenue_and_retention",
        percentile=20  # Top 20%
    )

    # Extract common attributes
    icp = {
        "firmographics": {
            "company_size": extract_distribution(best_customers, "employees"),
            "revenue_range": extract_distribution(best_customers, "revenue"),
            "industry": extract_frequency(best_customers, "industry"),
            "geography": extract_frequency(best_customers, "region"),
            "growth_stage": extract_frequency(best_customers, "stage")
        },
        "technographics": {
            "tech_stack": extract_frequency(best_customers, "technologies"),
            "integrations": extract_frequency(best_customers, "integrations_used")
        },
        "behavioral": {
            "buying_process": extract_patterns(best_customers, "sales_cycle"),
            "use_cases": extract_frequency(best_customers, "primary_use_case"),
            "entry_point": extract_frequency(best_customers, "initial_product")
        },
        "success_indicators": {
            "time_to_value": median(best_customers, "time_to_first_value"),
            "expansion_rate": median(best_customers, "expansion_revenue_pct"),
            "nps": median(best_customers, "nps_score")
        }
    }

    return icp
ICP Tiers
Tier 1 (Perfect fit):
- Company size: 200-2000 employees
- Industry: SaaS, FinTech, Healthcare Tech
- Revenue: $20M-$200M
- Tech stack: Salesforce + modern marketing tools
- Growth stage: Series B-D

Tier 2 (Good fit):
- Company size: 50-200 OR 2000-5000
- Industry: Professional services, E-commerce
- Revenue: $5M-$20M OR $200M-$500M
- Growth stage: Series A or post-IPO

Tier 3 (Possible fit):
- Company size: 20-50 OR 5000+
- Industry: Other B2B
- Revenue: $1M-$5M OR $500M+
- Non-standard tech stack

ICP Scoring

Attribute Matching
def calculate_icp_score(prospect, icp):
    scores = {}
    weights = {
        "company_size": 0.20,
        "industry": 0.15,
        "revenue": 0.15,
        "tech_stack": 0.15,
        "use_case_fit": 0.15,
        "growth_signals": 0.10,
        "geography": 0.10
    }

    # Company size match
    size_range = icp["firmographics"]["company_size"]
    if size_range["min"] <= prospect.employees <= size_range["max"]:
        scores["company_size"] = 100
    elif size_range["min"] * 0.5 <= prospect.employees <= size_range["max"] * 1.5:
        scores["company_size"] = 70
    else:
        scores["company_size"] = 30

    # Industry match
    if prospect.industry in icp["firmographics"]["industry"]["tier_1"]:
        scores["industry"] = 100
    elif prospect.industry in icp["firmographics"]["industry"]["tier_2"]:
        scores["industry"] = 70
    else:
        scores["industry"] = 30

    # Tech stack match
    tech_overlap = len(set(prospect.tech_stack) & set(icp["technographics"]["tech_stack"]["common"]))
    tech_total = len(icp["technographics"]["tech_stack"]["common"])
    scores["tech_stack"] = (tech_overlap / tech_total) * 100

    # Use case fit
    scores["use_case_fit"] = calculate_use_case_fit(prospect, icp)

    # Weighted total
    total_score = sum(scores[k] * weights[k] for k in scores)

    return {
        "total_score": total_score,
        "component_scores": scores,
        "icp_tier": get_tier(total_score)
    }

def get_tier(score):
    if score >= 80:
        return "tier_1"
    elif score >= 60:
        return "tier_2"
    elif score >= 40:
        return "tier_3"
    else:
        return "poor_fit"
Machine Learning Approach
from sklearn.ensemble import RandomForestClassifier

def train_icp_model():
    # Get labeled data
    customers = get_all_customers()
    labels = [1 if c.ltv_percentile >= 80 else 0 for c in customers]

    # Extract features
    features = extract_features(customers)

    # Train model
    model = RandomForestClassifier()
    model.fit(features, labels)

    return model

def score_prospect_ml(prospect, model):
    features = extract_features([prospect])
    probability = model.predict_proba(features)[0][1]

    return {
        "icp_probability": probability,
        "icp_tier": probability_to_tier(probability),
        "feature_importance": get_important_features(model, prospect)
    }

Real-Time ICP Assessment

Conversation-Based Scoring
def update_icp_during_conversation(prospect, message):
    # Extract signals from conversation
    signals = extract_conversation_signals(message)

    icp_updates = {}

    # Use case revealed
    if signals.get("use_case"):
        use_case_fit = match_use_case_to_icp(signals["use_case"])
        icp_updates["use_case_fit"] = use_case_fit

    # Tech stack mentioned
    if signals.get("technologies"):
        tech_overlap = calculate_tech_overlap(signals["technologies"])
        icp_updates["tech_stack"] = tech_overlap

    # Team size mentioned
    if signals.get("team_size"):
        icp_updates["team_size_match"] = match_team_size(signals["team_size"])

    # Budget signals
    if signals.get("budget_range"):
        icp_updates["budget_fit"] = match_budget_to_icp(signals["budget_range"])

    # Update prospect's ICP score
    recalculate_icp_score(prospect, icp_updates)
Dynamic ICP Signals
Conversation signals that inform ICP:

High fit signals:
- "We have a [target size] team"
- "Currently using [ICP tech stack]"
- "Our main challenge is [ICP use case]"
- "Budget is [in ICP range]"
- "Need to solve this by [reasonable timeline]"

Lower fit signals:
- "Just me/small team"
- "Don't have budget yet"
- "Just researching for now"
- "Our use case is [non-standard]"
- "Using [incompatible tech]"

ICP-Based Actions

Routing by ICP
def route_by_icp(prospect):
    icp_tier = prospect.icp_tier

    if icp_tier == "tier_1":
        return {
            "queue": "enterprise_fast_track",
            "assignee": get_best_available_ae(),
            "sla": "respond_within_1_hour",
            "treatment": "white_glove"
        }
    elif icp_tier == "tier_2":
        return {
            "queue": "standard_sales",
            "assignee": "round_robin_ae",
            "sla": "respond_within_4_hours",
            "treatment": "standard"
        }
    elif icp_tier == "tier_3":
        return {
            "queue": "qualification_needed",
            "assignee": "sdr",
            "sla": "respond_within_24_hours",
            "treatment": "qualify_further"
        }
    else:
        return {
            "queue": "nurture",
            "assignee": "bot",
            "sla": "automated",
            "treatment": "self_service_focused"
        }
Messaging by ICP
def customize_message_for_icp(base_message, prospect):
    icp_tier = prospect.icp_tier

    if icp_tier == "tier_1":
        # Premium messaging
        return enhance_message(base_message,
            add_enterprise_features=True,
            add_dedicated_support=True,
            add_similar_customers=get_similar_reference_customers(prospect),
            tone="consultative"
        )
    elif icp_tier == "tier_2":
        # Standard messaging
        return enhance_message(base_message,
            add_case_studies=True,
            add_roi_focus=True,
            tone="professional"
        )
    else:
        # Self-service focus
        return enhance_message(base_message,
            add_free_trial=True,
            add_self_service_resources=True,
            tone="helpful"
        )

ICP Visualization

Fit Matrix
                    High Engagement | Low Engagement
High ICP Fit        PRIORITY 1      | RE-ENGAGE
                    (best prospects)| (sleeping giants)
---------------------------------------------------
Low ICP Fit         EVALUATE        | DEPRIORITIZE
                    (could surprise)| (poor fit)

Segment prospects into quadrants for prioritization.
ICP Comparison Report
def generate_icp_comparison(prospect):
    icp = get_current_icp()
    score = prospect.icp_score

    return {
        "overall_fit": score.total_score,
        "tier": score.icp_tier,
        "comparison": {
            "company_size": {
                "prospect": prospect.employees,
                "icp_range": icp["firmographics"]["company_size"],
                "match": score.component_scores["company_size"]
            },
            "industry": {
                "prospect": prospect.industry,
                "icp_industries": icp["firmographics"]["industry"],
                "match": score.component_scores["industry"]
            },
            # ... more dimensions
        },
        "similar_customers": get_similar_won_customers(prospect, limit=3),
        "fit_summary": generate_fit_summary(score)
    }

ICP Evolution

Updating ICP Over Time
def refresh_icp(cadence="quarterly"):
    # Get recent best customers
    recent_best = get_top_customers(
        timeframe="last_12_months",
        criteria="revenue_and_retention",
        percentile=20
    )

    # Compare to existing ICP
    current_icp = get_current_icp()
    new_icp = build_icp_from_customers(recent_best)

    # Identify changes
    changes = compare_icps(current_icp, new_icp)

    if significant_changes(changes):
        # Update ICP
        update_icp(new_icp)
        notify_team("ICP updated", changes)

        # Re-score existing prospects
        rescore_all_prospects(new_icp)
Market Expansion
def identify_adjacent_icps():
    """Find secondary ICPs for expansion"""

    # Successful customers outside primary ICP
    outliers = get_successful_outliers()

    # Cluster into secondary ICPs
    secondary_icps = cluster_customers(outliers)

    for cluster in secondary_icps:
        if cluster.size >= MIN_VIABLE_SEGMENT:
            create_secondary_icp(cluster)

    return secondary_icps

Comments

Markdown supported