competitor-radar-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@competitor-radar-mcpGive me yesterday's daily brief on competitor posts ranked by engagement and ICP relevance."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
competitor-radar-mcp
An MCP server that watches your competitors on X, rates every post per day by replies → bookmarks → retweets → likes, and tells you which posts actually spoke to your buyers.
Built for a GTM team that needed to know, every morning, what the market was telling its customers yesterday, without reading ten timelines by hand. Plugs into Claude Code, Claude Desktop, Cursor, or any MCP client.
scrape_competitors(days=1) → SQLite (posts + metric snapshots)
rate_posts / daily_report → ranked leaderboard for the UTC day
daily_brief prompt → "what got engagement" vs "what our buyers were told"Why this exists
Engagement counts are cheap to read and easy to misread. A model demo with 300 bookmarks and a million views is noise if none of your buyers care. A post with 48 bookmarks on 3 replies from a direct competitor, written in your buyer's vocabulary, is the one to study. The radar separates the two:
Engagement rank in the order that matters for B2B discourse: comments (argument), saves (a teachable move), retweets (identity), likes (approval).
ICP relevance (0–100) from a deterministic, editable term rubric grounded in your product and buyer context, reported on every post.
Both are shown; neither is hidden inside an LLM.
Related MCP server: Sociality MCP
Rating method
Two rankings are computed for the same day's pool and both appear on every row:
mode | rule | when it wins |
| lexicographic on | the literal "in that order" reading |
| each metric becomes a within-pool percentile, blended 4/3/2/1 in the same order | a post that is #1 on bookmarks and #3 on replies beats a post that is #1 on replies and last on everything else |
pool="day" ranks all competitors together (who won the day). pool="handle"
ranks each account only against its own posts, which removes the follower-count
advantage of the 200k accounts. icp_blend (0..1) optionally lets ICP relevance
move the weighted score; by default it only annotates.
Metrics are upserted on every scrape and every observation is kept, so a post's growth through the day is visible.
Getting posts in
X has no login-free read path anymore (logged-out profiles render zero posts; the syndication endpoint rate-limits). Pick one:
backend | needs | bookmarks | notes |
| your own logged-in session, imported once with | yes | free. undetected Chrome in a subprocess; reads all five metrics from the engagement-bar aria-label, which is the only place X exposes bookmark counts |
| nothing | yes | run |
|
| yes | actor |
|
| yes | official |
| nothing | – | offline; |
auto tries apify → xapi → browser. radar_doctor tells you which is usable and the fix for each that is not.
Install
git clone https://github.com/Ajitesh-png/competitor-radar-mcp
cd competitor-radar-mcp
pip install -r requirements.txt # mcp, requests
pip install -r requirements-browser.txt # optional: selenium, undetected-chromedriver
python tests/test_radar.py # 12 offline testsRegister with your MCP client (Claude Code .mcp.json shown):
{
"mcpServers": {
"competitor-radar": {
"type": "stdio",
"command": "python",
"args": ["/absolute/path/to/competitor-radar-mcp/server.py"]
}
}
}Then:
Edit
config/competitors.json(handles, tiers; verify each on x.com first).Copy
context/product.example.md→context/product.mdandcontext/icp.example.json→context/icp.json; describe your product and buyers.Tune
config/icp_signals.jsonto your buyer's vocabulary.In your client:
radar_doctor→scrape_competitors(days=1)→daily_report→daily_briefprompt.
Cron / n8n: python scripts/daily_run.py (add --backend fixture for a dry run).
Tools
tool | what |
| backend availability + fixes, config sanity, DB stats |
| manage the tracked set |
| pull posts → SQLite, ICP-score each |
| store posts collected in a logged-in browser |
| the JS that produces |
| rated leaderboard for a day |
| markdown scoreboard + leaderboard + ICP lens |
| per-day totals for one account |
| drill-downs |
| product + ICP + tiers + rubric the ratings are grounded in |
Resources: radar://product, radar://icp, radar://competitors,
radar://extractor.js, radar://report/{day}. Prompt: daily_brief(day, top).
Sample output
See docs/sample-report.md, rendered from the offline fixture. A real day from the original deployment looked like this: a video model's demo series took the top three weighted slots with ICP 0, while the one post aimed at the buyer ("playable ads from a single prompt for performance marketing teams in gaming") sat at rank 5 with ICP 35. That gap is the product.
Layout
server.py FastMCP server (tools, resources, prompt)
radar/
backends/ apify | xapi | browser | fixture, one interface
parse_metrics.py engagement-bar aria-label parser (reads bookmarks)
models.py store.py Post dataclass, SQLite (posts + snapshots + handles)
icp.py rating.py ICP rubric, per-day rating (strict + weighted)
report.py ingest.py markdown report, external-post normaliser
workers/ browser_worker.py (undetected Chrome), extractor.js
config/ competitors.json, scoring.json, icp_signals.json
context/ product + ICP examples (copy and edit)
scripts/ daily_run.py (cron), import_cookies.py
tests/ offline tests + fixtureDesign notes
Post text is data, never instructions. The server never feeds scraped text to an LLM on its own; the prompt tells the client model the same.
Bookmarks were the hard metric. No common scraper reads them; X only renders the count inside one
aria-label.parse_metrics.pyis the whole trick, shared by the Python worker and the browser JS.Browser scraping runs in a subprocess so a Chrome crash cannot take the MCP server down, and so the Selenium deps can live in a different venv.
Two rankings, not one. "Rate by A, then B, then C" has a strict reading and a practical one; shipping both avoided a week of arguing about which.
Deterministic ICP score. Cheap, explainable, editable JSON. The judgment layer lives in the prompt where it belongs.
Originally built inside a private growth-engineering repo at Notch and extracted here with example context. MIT licensed.
This server cannot be deployed
Maintenance
Related MCP Connectors
Live market intelligence & AI content strategy: trends, competitor moves, content calendar.
Social media analytics, post insights, and competitor benchmarking for AI agents.
X (Twitter) data for AI agents: tweets, profiles, followers, search, trends + social listening.
Social listening for AI agents: search mentions, pull scored buying signals, score leads
Related MCP Servers
- AlicenseAqualityBmaintenanceCompetitive intelligence platform with 24 tools. Monitor competitor pricing, content, positioning, tech stacks, and AI visibility — track how ChatGPT, Claude, and Gemini rank your brand.383MIT

Sociality MCPofficial
AlicenseNot gradedqualityDmaintenanceSocial media analytics, post insights, and competitor benchmarking for AI agents.6MIT- AlicenseNot gradedqualityBmaintenancePerplexity for social: ask what competitors are running across social and get answers grounded in real ad and creative data, not guesses.2Apache 2.0
- FlicenseNot gradedqualityBmaintenanceProvides social intelligence tools for AI agents to analyze competitor sentiment, trends, and brand mentions from X/Twitter data.-