Skip to main content
Glama
gomessoaresemmanuel-cpu

linkedin-prospection-mcp

score_lead

Score LinkedIn leads by analyzing fit, intent, and urgency to prioritize prospects and recommend offers for sales teams.

Instructions

Score a LinkedIn lead based on fit (ICP match), intent (burnout signals), and urgency (crisis markers). Returns priority P1-P4 and recommended offer.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameYesLead's full name
titleNoJob title / headline
companyNoCompany name
post_snippetNoText from their LinkedIn post
linkedin_urlNoLinkedIn profile URL

Implementation Reference

  • Implementation of the scoreLead function which calculates scores based on fit, intent, and urgency signals.
    function scoreLead(lead: LeadInput): ScoredLead {
      const titleLower = (lead.title || "").toLowerCase();
      const postLower = (lead.post_snippet || "").toLowerCase();
      const companyLower = (lead.company || "").toLowerCase();
    
      // FIT (0-30)
      let fit = 0;
      if (ICP_ROLES.some((r) => titleLower.includes(r))) fit += 20;
      if (HIGH_RISK_INDUSTRIES.some((i) => titleLower.includes(i) || companyLower.includes(i))) fit += 7;
      if (titleLower.length > 10 && titleLower.includes("|")) fit += 3;
    
      // INTENT (0-40)
      let intent = 0;
      const personalBurnout = [
        "j'ai failli", "j'ai craque", "j'etais epuise", "j'ai tout arrete",
        "j'ai du m'arreter", "mon burnout", "mon epuisement",
      ];
      if (personalBurnout.some((s) => postLower.includes(s))) {
        intent += 30;
      } else if (BURNOUT_KEYWORDS.some((k) => postLower.includes(k))) {
        intent += 15;
      }
      if (postLower.includes("aide") || postLower.includes("besoin") || postLower.includes("solution")) {
        intent += 10;
      }
    
      // URGENCY (0-30)
      let urgency = 0;
      const urgentMarkers = ["en peux plus", "a bout", "craque", "urgence", "au bord", "insomnie"];
      if (urgentMarkers.some((m) => postLower.includes(m))) urgency += 20;
      if (["j'ai", "j'etais", "mon", "ma", "je"].some((p) => postLower.includes(p))) urgency += 10;
    
      const total = fit + intent + urgency;
      let priority: ScoredLead["priority"];
      let recommended_offer: string;
    
      if (total >= 60) {
        priority = "P1-hot";
        recommended_offer = "Coaching Decouverte 297€";
      } else if (total >= 35) {
        priority = "P2-warm";
        recommended_offer = "Kit Anti-Burnout 47€";
      } else if (total >= 20) {
        priority = "P3-nurture";
        recommended_offer = "Guide 7 Jours (gratuit)";
      } else {
        priority = "P4-cold";
        recommended_offer = "Newsletter";
      }
    
      const reasons: string[] = [];
      if (fit >= 20) reasons.push("ICP role match");
      if (intent >= 30) reasons.push("personal burnout signal");
      else if (intent >= 15) reasons.push("burnout keyword detected");
      if (urgency >= 20) reasons.push("urgent markers");
    
      return {
        ...lead,
        fit_score: fit,
        intent_score: intent,
        urgency_score: urgency,
        total_score: total,
        priority,
        recommended_offer,
        reasoning: reasons.length > 0 ? reasons.join(" + ") : "Low signals",
      };
    }
  • src/index.ts:302-338 (registration)
    Tool registration for 'score_lead', which invokes the scoreLead function and formats the result.
    server.registerTool(
      "score_lead",
      {
        title: "Score a Lead",
        description:
          "Score a LinkedIn lead based on fit (ICP match), intent (burnout signals), " +
          "and urgency (crisis markers). Returns priority P1-P4 and recommended offer.",
        inputSchema: {
          name: z.string().describe("Lead's full name"),
          title: z.string().optional().describe("Job title / headline"),
          company: z.string().optional().describe("Company name"),
          post_snippet: z.string().optional().describe("Text from their LinkedIn post"),
          linkedin_url: z.string().optional().describe("LinkedIn profile URL"),
        },
        annotations: { readOnlyHint: true, openWorldHint: false, destructiveHint: false },
      },
      async ({ name, title, company, post_snippet, linkedin_url }) => {
        const scored = scoreLead({ name, title, company, post_snippet, linkedin_url });
    
        const output = [
          `Lead: ${scored.name}`,
          `Title: ${scored.title || "N/A"}`,
          `Company: ${scored.company || "N/A"}`,
          "",
          `Fit Score: ${scored.fit_score}/30`,
          `Intent Score: ${scored.intent_score}/40`,
          `Urgency Score: ${scored.urgency_score}/30`,
          `TOTAL: ${scored.total_score}/100`,
          "",
          `Priority: ${scored.priority}`,
          `Recommended Offer: ${scored.recommended_offer}`,
          `Reasoning: ${scored.reasoning}`,
        ].join("\n");
    
        return { content: [{ type: "text" as const, text: output }] };
      },
    );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gomessoaresemmanuel-cpu/linkedin-prospection-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server