Discovers influencers and partnership opportunities for brands using XPOZ MCP Twitter APIs. Classifies by tier (Mega/Macro/Micro/Nano), voice type, sentiment, and potential from user data.
How this skill is triggered — by the user, by Claude, or both
Slash command
/xpoz-social-intelligence:brand-influencersThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill provides comprehensive influencer discovery and partnership opportunity analysis. It fetches users discussing a brand, classifies them by reach tier, voice type, and sentiment, then identifies the best partnership candidates and rising stars.
This skill provides comprehensive influencer discovery and partnership opportunity analysis. It fetches users discussing a brand, classifies them by reach tier, voice type, and sentiment, then identifies the best partnership candidates and rising stars.
Activate this skill when the user asks about:
Expand the brand name to capture all mentions:
NVIDIA → "NVIDIA" OR "$NVDA"
Tesla → "Tesla" OR "$TSLA"
Use getTwitterUsersByKeywords with:
- query: Expanded brand query
- fields: ["id", "username", "name", "description", "followersCount", "relevantTweetsCount", "relevantTweetsLikesSum", "relevantTweetsRetweetsSum"]
- userPrompt: "Finding influencers discussing [BRAND]"
CRITICAL: Async Polling Pattern
operationIdcheckOperationStatus with that operationIdUse getTwitterPostsByKeywords with:
- query: Same expanded query
- fields: ["id", "text", "authorUsername", "createdAtDate", "likeCount", "retweetCount"]
- userPrompt: "Fetching sample tweets for influencer quotes"
Tier Classification (by follower count):
| Tier | Followers | Icon |
|---|---|---|
| Mega | 1M+ | Crown |
| Macro | 100K-1M | Star |
| Micro | 10K-100K | Sparkle |
| Nano | <10K | Dot |
Voice Type Classification:
| Voice Type | Indicators |
|---|---|
| analyst | "analysis", "research", financial terms |
| trader | "trade", "position", "calls", options language |
| news | media outlet, journalist, news in bio |
| official | brand account, verified brand |
| researcher | PhD, professor, research institution |
| influencer | creator, content, social media focus |
| founder | CEO, founder, co-founder, startup founder |
| interviewer | podcast host, show host, media interviewer |
| community | fan accounts, community managers, enthusiast groups |
Sentiment Classification:
Partnership Score (0-100):
Calculate based on:
CRITICAL RULE: Official brand accounts MUST have partnership_score = 0
Rising Star Detection:
{
"reportType": "influencers",
"brand": "NVIDIA",
"period": {
"days": 7,
"startDate": "2025-01-06",
"endDate": "2025-01-13"
},
"summary": {
"headline": "Strong Analyst Coverage Drives NVIDIA Discussion",
"insight": "Key insight about influencer landscape",
"partnership_strategy": "2-3 sentences on recommended partnership approach",
"risk_assessment": "Critical voices and potential PR risks to monitor"
},
"tier_counts": {
"mega": 2,
"macro": 8,
"micro": 15,
"nano": 25
},
"top_niches": ["Tech Analysis", "AI Research", "Trading", "News"],
"influencers": [
{
"username": "@tech_analyst",
"name": "Tech Analyst",
"followers": 125000,
"description": "Bio text here",
"tier": "Macro",
"voice_type": "analyst",
"niche": "Tech Analysis",
"sentiment": "positive",
"partnership_score": 85,
"is_rising_star": false,
"engagement_rate": 1.5,
"sample_tweet": {
"text": "Actual tweet quote...",
"likes": 500,
"retweets": 50
},
"why_partner": "High reach analyst with positive stance on NVIDIA"
}
],
"partnership_opportunities": ["@analyst1", "@creator2", "@trader3"],
"rising_stars": ["@rising1", "@rising2"],
"critical_voices": ["@critic1", "@skeptic2"]
}
Generate a standalone HTML report with:
Powered by XPOZ MCP Social Intelligence — visit xpoz.ai to see how you can use it (with link to https://xpoz.ai)import React, { useState } from 'react';
import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';
import { Crown, Star, Sparkles, Circle, Users, TrendingUp, AlertTriangle, Handshake } from 'lucide-react';
export default function BrandInfluencers() {
const [activeTab, setActiveTab] = useState('overview');
const [selectedTier, setSelectedTier] = useState('all');
// CLAUDE: Replace with actual analyzed data
const brand = 'NVIDIA';
const period = { days: 7 };
const summary = {
headline: 'Strong Analyst Coverage Drives NVIDIA Discussion',
insight: 'Tech analysts and traders dominate the conversation',
partnership_strategy: 'Focus on Macro-tier analysts with positive sentiment...',
risk_assessment: 'Monitor 3 critical voices raising valuation concerns'
};
const tierCounts = { mega: 2, macro: 8, micro: 15, nano: 25 };
const topNiches = ['Tech Analysis', 'AI Research', 'Trading', 'News'];
const influencers = [
{ username: '@tech_analyst', name: 'Tech Analyst', followers: 125000, tier: 'Macro', voice_type: 'analyst', niche: 'Tech Analysis', sentiment: 'positive', partnership_score: 85, is_rising_star: false, engagement_rate: 1.5 },
{ username: '@ai_investor', name: 'AI Investor', followers: 89000, tier: 'Micro', voice_type: 'trader', niche: 'AI Trading', sentiment: 'positive', partnership_score: 78, is_rising_star: false, engagement_rate: 2.1 },
{ username: '@chip_news', name: 'Chip News', followers: 450000, tier: 'Macro', voice_type: 'news', niche: 'Semiconductors', sentiment: 'neutral', partnership_score: 65, is_rising_star: false, engagement_rate: 0.8 },
{ username: '@nvidia', name: 'NVIDIA', followers: 2500000, tier: 'Mega', voice_type: 'official', niche: 'Official', sentiment: 'positive', partnership_score: 0, is_rising_star: false, engagement_rate: 0.5 },
{ username: '@rising_analyst', name: 'Rising Analyst', followers: 35000, tier: 'Micro', voice_type: 'analyst', niche: 'Tech Analysis', sentiment: 'positive', partnership_score: 72, is_rising_star: true, engagement_rate: 3.2 }
];
const partnershipOpportunities = influencers.filter(i => i.partnership_score >= 70 && i.voice_type !== 'official');
const risingStars = influencers.filter(i => i.is_rising_star);
const criticalVoices = influencers.filter(i => ['negative', 'leaning_negative'].includes(i.sentiment));
const tierStyles = {
Mega: { color: 'from-purple-500 to-pink-500', bg: 'bg-purple-500/10', border: 'border-purple-500/20', text: 'text-purple-400', icon: Crown },
Macro: { color: 'from-blue-500 to-cyan-500', bg: 'bg-blue-500/10', border: 'border-blue-500/20', text: 'text-blue-400', icon: Star },
Micro: { color: 'from-emerald-500 to-teal-500', bg: 'bg-emerald-500/10', border: 'border-emerald-500/20', text: 'text-emerald-400', icon: Sparkles },
Nano: { color: 'from-amber-500 to-orange-500', bg: 'bg-amber-500/10', border: 'border-amber-500/20', text: 'text-amber-400', icon: Circle }
};
const voiceTypeBadge = (type) => {
const styles = {
analyst: 'bg-blue-500/20 text-blue-400',
trader: 'bg-green-500/20 text-green-400',
news: 'bg-amber-500/20 text-amber-400',
official: 'bg-purple-500/20 text-purple-400',
researcher: 'bg-cyan-500/20 text-cyan-400',
influencer: 'bg-pink-500/20 text-pink-400'
};
return styles[type] || styles.influencer;
};
const sentimentBadge = (s) => {
const styles = {
positive: 'bg-green-500/20 text-green-400',
leaning_positive: 'bg-green-500/10 text-green-300',
neutral: 'bg-gray-500/20 text-gray-400',
leaning_negative: 'bg-red-500/10 text-red-300',
negative: 'bg-red-500/20 text-red-400'
};
return styles[s] || styles.neutral;
};
const formatFollowers = (n) => n >= 1000000 ? (n/1000000).toFixed(1) + 'M' : n >= 1000 ? (n/1000).toFixed(0) + 'K' : n;
const filteredInfluencers = selectedTier === 'all' ? influencers : influencers.filter(i => i.tier === selectedTier);
const tabs = [
{ id: 'overview', label: 'Overview', icon: Users },
{ id: 'partnerships', label: 'Partnership Opportunities', icon: Handshake },
{ id: 'rising', label: 'Rising Stars', icon: TrendingUp },
{ id: 'critical', label: 'Critical Voices', icon: AlertTriangle }
];
return (
<div className="w-full max-w-5xl mx-auto p-6 bg-slate-900 rounded-xl text-white">
{/* Header */}
<div className="flex items-center justify-between mb-6">
<div>
<h1 className="text-2xl font-bold">{brand} Influencer Discovery</h1>
<p className="text-slate-400 text-sm">{influencers.length} influencers • {period.days} days</p>
</div>
<div className="flex gap-4">
<div className="text-center">
<div className="text-2xl font-bold text-pink-400">{partnershipOpportunities.length}</div>
<div className="text-xs text-slate-500">Opportunities</div>
</div>
<div className="text-center">
<div className="text-2xl font-bold text-amber-400">{risingStars.length}</div>
<div className="text-xs text-slate-500">Rising Stars</div>
</div>
</div>
</div>
{/* Summary */}
<div className="bg-slate-800 rounded-lg p-4 mb-6">
<h2 className="text-xl font-bold mb-2">{summary.headline}</h2>
<p className="text-slate-300">{summary.insight}</p>
</div>
{/* Tier Distribution */}
<div className="grid grid-cols-4 gap-4 mb-6">
{Object.entries(tierCounts).map(([tier, count]) => {
const style = tierStyles[tier.charAt(0).toUpperCase() + tier.slice(1)];
const Icon = style?.icon || Circle;
return (
<div key={tier} className={`${style?.bg} rounded-lg p-4 ${style?.border} border`}>
<div className="flex items-center gap-2 mb-2">
<Icon className={`w-5 h-5 ${style?.text}`} />
<span className={`font-medium ${style?.text}`}>{tier.charAt(0).toUpperCase() + tier.slice(1)}</span>
</div>
<div className="text-3xl font-bold text-white">{count}</div>
</div>
);
})}
</div>
{/* Tabs */}
<div className="flex gap-2 mb-6 border-b border-slate-700 pb-2">
{tabs.map(tab => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`flex items-center gap-2 px-4 py-2 rounded-lg transition-colors ${
activeTab === tab.id
? 'bg-blue-500/20 text-blue-400 border border-blue-500/50'
: 'text-slate-400 hover:bg-slate-800'
}`}
>
<tab.icon className="w-4 h-4" />
{tab.label}
</button>
))}
</div>
{/* Tab Content */}
{activeTab === 'overview' && (
<div>
{/* Tier Filter */}
<div className="flex gap-2 mb-4">
<button
onClick={() => setSelectedTier('all')}
className={`px-3 py-1 rounded text-sm ${selectedTier === 'all' ? 'bg-indigo-500 text-white' : 'bg-slate-800 text-slate-400'}`}
>
All
</button>
{['Mega', 'Macro', 'Micro', 'Nano'].map(tier => (
<button
key={tier}
onClick={() => setSelectedTier(tier)}
className={`px-3 py-1 rounded text-sm ${selectedTier === tier ? 'bg-indigo-500 text-white' : 'bg-slate-800 text-slate-400'}`}
>
{tier}
</button>
))}
</div>
{/* Influencer Grid */}
<div className="grid grid-cols-2 gap-4">
{filteredInfluencers.map((inf, i) => {
const style = tierStyles[inf.tier];
const Icon = style?.icon || Circle;
return (
<div key={i} className="bg-slate-800 rounded-lg p-4 relative">
{inf.partnership_score >= 70 && inf.voice_type !== 'official' && (
<div className="absolute -top-2 -right-2 bg-gradient-to-r from-green-500 to-teal-500 text-white text-xs font-bold px-2 py-1 rounded-full">
{inf.partnership_score}
</div>
)}
<div className="flex items-start gap-3">
<div className={`w-10 h-10 rounded-full bg-gradient-to-br ${style?.color} flex items-center justify-center`}>
<Icon className="w-5 h-5 text-white" />
</div>
<div className="flex-1">
<div className="flex items-center gap-2">
<span className="font-medium">{inf.name}</span>
<span className={`text-xs px-2 py-0.5 rounded ${voiceTypeBadge(inf.voice_type)}`}>{inf.voice_type}</span>
</div>
<p className="text-slate-500 text-sm">{inf.username}</p>
<div className="flex items-center gap-3 mt-2 text-sm">
<span className="text-slate-400">{formatFollowers(inf.followers)}</span>
<span className={`px-2 py-0.5 rounded text-xs ${sentimentBadge(inf.sentiment)}`}>{inf.sentiment}</span>
{inf.is_rising_star && <span className="text-amber-400 text-xs">Rising Star</span>}
</div>
</div>
</div>
</div>
);
})}
</div>
</div>
)}
{activeTab === 'partnerships' && (
<div>
<div className="bg-green-500/10 rounded-lg p-4 mb-4 border border-green-500/20">
<h3 className="font-medium text-green-400 mb-2">Partnership Strategy</h3>
<p className="text-slate-300 text-sm">{summary.partnership_strategy}</p>
</div>
<div className="grid grid-cols-2 gap-4">
{partnershipOpportunities.map((inf, i) => (
<div key={i} className="bg-slate-800 rounded-lg p-4">
<div className="flex items-center justify-between mb-2">
<span className="font-medium">{inf.name}</span>
<span className="text-green-400 font-bold">{inf.partnership_score}/100</span>
</div>
<p className="text-slate-500 text-sm">{inf.username} • {formatFollowers(inf.followers)}</p>
</div>
))}
</div>
</div>
)}
{activeTab === 'rising' && (
<div className="grid grid-cols-2 gap-4">
{risingStars.length > 0 ? risingStars.map((inf, i) => (
<div key={i} className="bg-amber-500/10 rounded-lg p-4 border border-amber-500/20">
<div className="flex items-center gap-2 mb-2">
<TrendingUp className="w-5 h-5 text-amber-400" />
<span className="font-medium">{inf.name}</span>
</div>
<p className="text-slate-500 text-sm">{inf.username}</p>
<p className="text-amber-400 text-sm mt-2">{inf.engagement_rate.toFixed(1)}% engagement rate</p>
</div>
)) : <p className="text-slate-400 col-span-2">No rising stars detected in this period.</p>}
</div>
)}
{activeTab === 'critical' && (
<div>
<div className="bg-red-500/10 rounded-lg p-4 mb-4 border border-red-500/20">
<h3 className="font-medium text-red-400 mb-2">Risk Assessment</h3>
<p className="text-slate-300 text-sm">{summary.risk_assessment}</p>
</div>
{criticalVoices.length > 0 ? (
<div className="grid grid-cols-2 gap-4">
{criticalVoices.map((inf, i) => (
<div key={i} className="bg-slate-800 rounded-lg p-4 border border-red-500/20">
<span className="font-medium">{inf.name}</span>
<p className="text-slate-500 text-sm">{inf.username} • {formatFollowers(inf.followers)}</p>
</div>
))}
</div>
) : <p className="text-slate-400">No critical voices detected in this period.</p>}
</div>
)}
</div>
);
}
FETCH REAL USER DATA - You MUST call getTwitterUsersByKeywords and fetch real users. Do NOT generate fake influencer data.
USE EXPANDED QUERIES - Always expand brand names to include ticker symbols.
ASYNC POLLING - Poll checkOperationStatus until status is "completed".
OFFICIAL ACCOUNTS = 0 PARTNERSHIP SCORE - Any account that is an official brand account (voice_type: "official") MUST have partnership_score = 0. These are not partnership opportunities.
CALCULATE ENGAGEMENT RATE - Use formula: (likes + retweets) / followers * 100
DETECT RISING STARS - Flag accounts with engagement_rate > 2% AND followers < 50K
getTwitterUsersByKeywords with expanded querycheckOperationStatus until completegetTwitterPostsByKeywords for sample tweetscheckOperationStatus until completeEndpoint: https://mcp.xpoz.ai/mcp
Transport: HTTP Streamable (not SSE)
Auth: Bearer Token
Tools: getTwitterUsersByKeywords, getTwitterPostsByKeywords, checkOperationStatus
npx claudepluginhub xpozpublic/xpoz-claude-code-pluginsFinds and ranks influencers by niche, engagement, and authenticity across Twitter/X, Instagram, and Reddit using Xpoz. Activates on queries about influencer discovery, thought leaders, or KOL research.
Discovers and analyzes influencers across Instagram, Twitter/X, LinkedIn, YouTube, and Reddit using the anysite MCP server. Supports multi-platform search, engagement analysis, audience evaluation, and partnership identification.
Discovers and evaluates influencers for brand partnerships across Instagram, Facebook, YouTube, and TikTok using Apify Actors. Provides engagement metrics, authenticity checks, and shortlisted candidates.