mcpField
M
multi-stakeholder-thread-management

multi-stakeholder-thread-management

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

About multi-stakeholder-thread-management

A skill for developers building sales bots to manage deals involving multiple decision-makers. It covers stakeholder mapping, per-person conversation tracking, coordinated outreach, and consensus monitoring.

Key features

  1. 01Discover and map deal stakeholders
  2. 02Track context and objections per person
  3. 03Check information consistency across conversations
  4. 04Tailor messages to stakeholder roles
  5. 05Monitor alignment and plan outreach

Use cases

  1. 01Map decision-makers mentioned in a sales conversation
  2. 02Track concerns across a buying committee
  3. 03Coordinate role-specific pre-demo messages

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/louisblythe/sales-skills --skill multi-stakeholder-thread-management

After installing, type/multi-stakeholder-thread-managementin Claude Code to confirm it loaded.

Details

From the project README

Multi-Stakeholder Thread Management

You are an expert in building sales bots that handle conversations involving multiple decision-makers. Your goal is to help developers create systems that track, coordinate, and advance conversations across buying committees.

Why Multi-Stakeholder Management Matters

The Complex Deal Reality
Modern B2B deals:
- Average 6-10 people in buying decision
- Multiple perspectives and priorities
- Different information needs
- Consensus often required

Single-threaded approach:
- Rely on one champion
- Miss other stakeholders
- Blind to objections elsewhere
- Deal stalls mysteriously
Multi-Threaded Approach
Managed stakeholder engagement:
- Map all decision participants
- Understand each person's priorities
- Address concerns individually
- Build consensus systematically

Result: Faster deals, fewer surprises

Stakeholder Mapping

Identifying Stakeholders
class StakeholderMap:
    def __init__(self, deal_id):
        self.deal_id = deal_id
        self.stakeholders = []

    def add_stakeholder(self, stakeholder):
        self.stakeholders.append({
            "id": generate_id(),
            "name": stakeholder["name"],
            "title": stakeholder["title"],
            "role": classify_role(stakeholder),  # champion, buyer, user, etc.
            "influence": stakeholder.get("influence", "unknown"),
            "sentiment": stakeholder.get("sentiment", "neutral"),
            "priorities": stakeholder.get("priorities", []),
            "objections": stakeholder.get("objections", []),
            "engagement_level": 0,
            "last_contact": None,
            "preferred_channel": stakeholder.get("channel", "email")
        })

def classify_role(stakeholder):
    title = stakeholder["title"].lower()

    if any(x in title for x in ["ceo", "cfo", "cto", "president", "owner"]):
        return "economic_buyer"
    elif any(x in title for x in ["vp", "director", "head of"]):
        return "decision_maker"
    elif any(x in title for x in ["manager", "lead"]):
        return "influencer"
    elif any(x in title for x in ["analyst", "specialist", "coordinator"]):
        return "user"
    else:
        return "unknown"
Stakeholder Discovery
def discover_stakeholders_from_conversation(message, existing_map):
    # Look for mentions of other people
    mentions = extract_person_mentions(message)

    for mention in mentions:
        # "My boss Sarah"
        # "Our CTO will need to review"
        # "The finance team"

        if mention not in existing_map:
            stakeholder = {
                "name": mention.get("name", "Unknown"),
                "title": mention.get("title", "Unknown"),
                "relationship": mention.get("relationship"),  # boss, colleague, etc.
                "mentioned_by": message.sender,
                "discovered_from": message.content
            }
            existing_map.add_stakeholder(stakeholder)

    return existing_map

Conversation Tracking

Per-Stakeholder Context
class StakeholderConversation:
    def __init__(self, stakeholder_id, deal_id):
        self.stakeholder_id = stakeholder_id
        self.deal_id = deal_id
        self.messages = []
        self.topics_discussed = []
        self.questions_asked = []
        self.objections_raised = []
        self.commitments_made = []
        self.information_shared = []

    def add_interaction(self, interaction):
        self.messages.append(interaction)

        # Extract context
        if interaction.get("questions"):
            self.questions_asked.extend(interaction["questions"])
        if interaction.get("objections"):
            self.objections_raised.extend(interaction["objections"])
        if interaction.get("commitments"):
            self.commitments_made.extend(interaction["commitments"])

    def get_state(self):
        return {
            "last_contact": self.messages[-1]["timestamp"] if self.messages else None,
            "engagement_count": len(self.messages),
            "open_questions": [q for q in self.questions_asked if not q.get("answered")],
            "unresolved_objections": [o for o in self.objections_raised if not o.get("resolved")],
            "sentiment_trend": calculate_sentiment_trend(self.messages)
        }
Cross-Stakeholder View
def get_deal_stakeholder_summary(deal_id):
    stakeholder_map = get_stakeholder_map(deal_id)

    summary = {
        "total_stakeholders": len(stakeholder_map.stakeholders),
        "by_role": {},
        "engagement": {},
        "risks": []
    }

    for stakeholder in stakeholder_map.stakeholders:
        role = stakeholder["role"]
        summary["by_role"][role] = summary["by_role"].get(role, 0) + 1

        conv = get_stakeholder_conversation(stakeholder["id"], deal_id)
        state = conv.get_state()

        summary["engagement"][stakeholder["name"]] = {
            "level": state["engagement_count"],
            "sentiment": stakeholder["sentiment"],
            "last_contact": state["last_contact"]
        }

        # Identify risks
        if state["unresolved_objections"]:
            summary["risks"].append({
                "stakeholder": stakeholder["name"],
                "type": "unresolved_objection",
                "details": state["unresolved_objections"]
            })

        if stakeholder["sentiment"] == "negative":
            summary["risks"].append({
                "stakeholder": stakeholder["name"],
                "type": "negative_sentiment"
            })

    return summary

Coordination Strategies

Information Consistency
def ensure_consistency(deal_id, message, recipient):
    """Ensure information is consistent across stakeholders"""

    # Get what we've told other stakeholders
    other_conversations = get_all_stakeholder_conversations(deal_id)

    # Check for potential conflicts
    for conv in other_conversations:
        if conv.stakeholder_id != recipient.id:
            conflicts = detect_information_conflicts(
                new_message=message,
                existing_conversation=conv
            )

            if conflicts:
                # Flag for review or auto-reconcile
                handle_conflict(conflicts, message, conv)

    return message
Role-Appropriate Messaging
def customize_for_role(base_message, stakeholder):
    role = stakeholder["role"]

    customizations = {
        "economic_buyer": {
            "focus": ["roi", "risk", "strategic_fit"],
            "detail_level": "executive_summary",
            "cta": "Worth a brief discussion on strategic fit?"
        },
        "decision_maker": {
            "focus": ["value", "implementation", "support"],
            "detail_level": "moderate",
            "cta": "Want to dive deeper into how this works?"
        },
        "influencer": {
            "focus": ["features", "workflow", "team_impact"],
            "detail_level": "detailed",
            "cta": "Would a demo for your team be helpful?"
        },
        "user": {
            "focus": ["usability", "training", "daily_workflow"],
            "detail_level": "practical",
            "cta": "Want to try it yourself?"
        }
    }

    config = customizations.get(role, customizations["influencer"])
    return adapt_message(base_message, config)
Stakeholder-Specific Objections
def track_and_address_objections(deal_id):
    stakeholder_map = get_stakeholder_map(deal_id)

    objection_matrix = {}
    for stakeholder in stakeholder_map.stakeholders:
        conv = get_stakeholder_conversation(stakeholder["id"], deal_id)
        objection_matrix[stakeholder["name"]] = conv.objections_raised

    # Identify common objections
    common = find_common_objections(objection_matrix)

    # Identify unique objections
    unique = find_unique_objections(objection_matrix)

    return {
        "common_objections": common,  # Address broadly
        "unique_objections": unique,   # Address individually
        "recommended_actions": generate_objection_actions(common, unique)
    }

Consensus Building

Alignment Tracking
def assess_buying_committee_alignment(deal_id):
    stakeholder_map = get_stakeholder_map(deal_id)

    alignment = {
        "champions": [],
        "supporters": [],
        "neutral": [],
        "skeptics": [],
        "blockers": []
    }

    for stakeholder in stakeholder_map.stakeholders:
        sentiment = stakeholder["sentiment"]
        if sentiment == "very_positive":
            alignment["champions"].append(stakeholder)
        elif sentiment == "positive":
            alignment["supporters"].append(stakeholder)
        elif sentiment == "neutral":
            alignment["neutral"].append(stakeholder)
        elif sentiment == "negative":
            alignment["skeptics"].append(stakeholder)
        elif sentiment == "very_negative":
            alignment["blockers"].append(stakeholder)

    # Calculate alignment score
    weights = {"champions": 2, "supporters": 1, "neutral": 0, "skeptics": -1, "blockers": -2}
    score = sum(len(alignment[k]) * weights[k] for k in weights)

    return {
        "alignment": alignment,
        "score": score,
        "recommendation": get_alignment_recommendation(alignment)
    }

def get_alignment_recommendation(alignment):
    if alignment["blockers"]:
        return f"Address blockers: {[s['name'] for s in alignment['blockers']]}"
    elif alignment["skeptics"]:
        return f"Convert skeptics: {[s['name'] for s in alignment['skeptics']]}"
    elif not alignment["champions"]:
        return "Develop a champion"
    elif alignment["neutral"]:
        return f"Engage neutral stakeholders: {[s['name'] for s in alignment['neutral']]}"
    else:
        return "Ready to advance"

Communication Orchestration

When to Contact Which Stakeholder
def plan_stakeholder_outreach(deal_id):
    summary = get_deal_stakeholder_summary(deal_id)
    plan = []

    for stakeholder in summary["stakeholders"]:
        state = summary["engagement"][stakeholder["name"]]

        # Determine need for outreach
        days_since_contact = (now() - state["last_contact"]).days if state["last_contact"] else 999

        if days_since_contact > 14:
            plan.append({
                "stakeholder": stakeholder,
                "reason": "re-engagement",
                "priority": "medium"
            })

        if stakeholder["name"] in [r["stakeholder"] for r in summary["risks"]]:
            plan.append({
                "stakeholder": stakeholder,
                "reason": "risk_mitigation",
                "priority": "high"
            })

    # Sequence outreach appropriately
    return sequence_outreach_plan(plan)
Coordinated Multi-Touch
def execute_coordinated_outreach(deal_id, campaign_type):
    stakeholder_map = get_stakeholder_map(deal_id)

    campaign_configs = {
        "pre_demo": {
            "economic_buyer": {"message": "exec_summary", "timing": "day_before"},
            "decision_maker": {"message": "agenda_preview", "timing": "day_before"},
            "user": {"message": "feature_teaser", "timing": "2_days_before"}
        },
        "post_demo": {
            "economic_buyer": {"message": "roi_summary", "timing": "same_day"},
            "decision_maker": {"message": "detailed_followup", "timing": "same_day"},
            "user": {"message": "trial_invitation", "timing": "next_day"}
        }
    }

    config = campaign_configs.get(campaign_type, {})

    for stakeholder in stakeholder_map.stakeholders:
        role_config = config.get(stakeholder["role"])
        if role_config:
            schedule_message(
                stakeholder=stakeholder,
                message_type=role_config["message"],
                timing=role_config["timing"]
            )

Metrics

Multi-Stakeholder Health
Track:
- Stakeholders identified vs engaged
- Sentiment by stakeholder
- Objection resolution rate
- Consensus score trend
- Deal velocity by stakeholder count

Comments

Markdown supported