MCP Tools — Quick Reference
The Hypermass Media MCP exposes 30 read-only tools to any MCP-aware client (Claude Code, Claude Desktop, Cursor, Cline, custom agents). This is the "what can I ask?" reference. For protocol / auth / write tiers, see
mcp-spec.md.
Connect
- Mint a key: dashboard → workspace → Settings → MCP API keys → Mint key. Copy the raw
hyper_…value (shown once). - Add to your client config:
{
"mcpServers": {
"hypermass": {
"type": "http",
"url": "https://hypermass.media/api/mcp",
"headers": { "Authorization": "Bearer hyper_…" }
}
}
}
- Restart your client. You'll see 16 new tools prefixed by their domain (
workspace.*,metrics.*,posts.*, etc.).
Every call lands in Settings → MCP API keys → Recent calls for audit.
Tools
All tools accept an optional username arg to disambiguate when the workspace has multiple IG accounts. Default = first/oldest active account. Defaults shown in ().
Workspace
| Tool | What it returns |
|---|---|
workspace.get |
Workspace identity + connected IG accounts with followers/follows/media counts and last_synced_at. Always call first. |
workspace.listMembers |
(OWNER only) Every workspace member with role + email + join date. |
Account-level metrics
| Tool | Args | What it returns |
|---|---|---|
metrics.getCurrent |
username? |
The most-recent fully-synced day of all account-level metrics (followers, reach, views, interactions, follows/unfollows, profile views, etc.). |
metrics.getPeriod |
days (30), username? |
One row per day for the last N days (max 365). Use for charts / trend analysis. |
metrics.comparePeriods |
days (7), username? |
Last N days vs the N days before — sum + percent change for every core metric. |
Posts
| Tool | Args | What it returns |
|---|---|---|
posts.list |
limit (25), media_type?, media_product_type?, username? |
Recent posts with core metrics. Filter by IMAGE / VIDEO / CAROUSEL_ALBUM or FEED / REELS / STORY / AD. |
posts.get |
ig_media_id |
Full record for one post (long numeric Meta id). |
posts.top |
by ("engagement"), days (30), limit (10), username? |
Top performers ranked by engagement / reach / views / like_count. |
posts.byHashtag |
hashtag, limit (25), username? |
The workspace's own posts containing the hashtag. Leading # optional. |
Audience
| Tool | Args | What it returns |
|---|---|---|
audience.demographics |
metric (follower_demographics), breakdown (country), username? |
Latest snapshot for follower_demographics or engaged_audience_demographics, broken down by age / gender / city / country. Sorted desc by value. |
audience.onlineHours |
days (28), username? |
24-hour distribution of when followers are online, averaged over the period. Use for best-posting-time recommendations. |
Derived analytics
| Tool | Args | What it returns |
|---|---|---|
posting.bestTimes |
days (60), top_n (5), username? |
Cross-references when followers are online × historical engagement on Jay's posts. Ranks top hours-of-day by combined score. |
engagement.byContentType |
days (60), username? |
Avg likes / comments / shares / saves / reach / engagement-rate per format (REELS vs CAROUSEL vs FEED vs IMAGE). Answers "what format wins for me." |
audience.cities |
top_n (20), metric (follower_demographics), username? |
City-level demographic drill-down. Use when audience.demographics breakdown='country' is too coarse. |
posts.outliers |
metric ("engagement"), days (90), sigma (1.5), username? |
Posts >= N σ above/below the account's mean. Returns hits_above and hits_below with z-score + multiple-of-mean. Use for "why did this post pop / flop?" |
events.detectSpikes |
metric ("followers_count"), days (60), sigma (2), username? |
Unusual daily-metric jumps correlated with same-day posts + mentions. Surfaces "announcement day," viral reels, mention waves. For followers, uses day-over-day delta against last non-null snapshot (handles partial sync gaps). |
hashtags.myPerformance |
days (90), min_uses (2), username? |
For every hashtag the account has used in its own captions: usage count + avg engagement vs the account's overall average. Surfaces "your #X posts get K× your normal." |
Stories (captured by 30-min polling cron)
| Tool | Args | What it returns |
|---|---|---|
stories.list |
days (7), limit (50), username? |
Recent stories with media_type, permalink (only valid while live), timestamp, captured insights (reach, views, replies, exits, taps_forward, taps_back). |
stories.insights |
ig_media_id |
Full insights for one specific story. |
stories.summary |
days (7), username? |
Rollup: total stories, avg reach/views/replies, avg taps_forward (skip-rate proxy), top story by reach, completion-rate proxy (1 - exits/reach). |
Stories caveat: stories vanish from Instagram after 24h. We capture them via a polling cron every 30 min, so anything posted > ~30 min before the next poll is captured with its final-state insights. The first day after deploy will have empty results until the cron has run a few cycles.
Competitor sets (storage only)
| Tool | Args | What it returns |
|---|---|---|
competitors.listSets |
— | All named competitor sets for this workspace + their handles. |
competitors.set |
name, handles[], description? |
Save / replace a named competitor list (e.g. "actor-comedians"). Pure storage — competitor fetching via business_discovery is currently blocked by our IG Login auth stack. The set persists for when we unblock the lookup ops. |
Mentions, comments, brand, history
| Tool | Args | What it returns |
|---|---|---|
mentions.list |
limit (25), username? |
Recent mentions — posts where someone tagged this account. Includes tagger username, media url, like/comment counts. |
mentions.get |
id (uuid) |
Full record for one mention. |
comments.list |
ig_media_id, limit (50) |
Comments on one of your posts, oldest first. |
comments.threadOnMyPost |
ig_media_id, limit (100) |
Same as comments.list plus a pre-built thread_map (parent → children ids) so the agent can reconstruct conversation shape without scanning. |
mentions.summary |
days (30), username? |
Roll-up: total mentions, top-mentioning accounts by frequency, format breakdown, avg engagement on the mentioning post. |
posts.carouselChildren |
ig_media_id |
Individual slides of a carousel post — per-slide media_url, type, metrics. |
brand.get |
username? |
The workspace's BrandProfile: niche, voice, goals, off-limits topics, peer accounts, etc. Ground all recommendations in this. |
history.dailyFollowers |
days (90), username? |
Follower-count snapshot per day (max 365). Use for follower-trajectory analysis. |
Things to ask Claude
Once connected, natural questions work:
- "What's my engagement trend over the last 7 days vs the 7 before?"
- "Show me my top 5 reels from the last 90 days."
- "What countries are most of my followers in?"
- "What time of day are my followers online?"
- "Who's mentioning me lately?"
- "What's my brand profile so you can help me draft a caption?"
- "Find my posts with #yoga and tell me which one performed best."
Claude will pick the right tool. If a question needs multiple tools (e.g. "compare this to my brand goals"), it'll chain them.
Currently blocked (was on the wish list, but Meta won't let us)
We deliberately use Instagram Business Login (cleaner UX for celebs, no Facebook Page dependency). Meta restricts a handful of cross-account endpoints to apps on the older Facebook Login for Business path. Until we add a parallel auth stack, these are unreachable:
competitor.profile / posts / top / compare / heatmap— needsbusiness_discovery, returns code 100 on our auth.hashtag.top / hashtag.recent— needs/ig_hashtag_search, same.reel_audio_id— not exposed by any Meta API on any auth path.comments_liston third-party posts — Meta only exposes comments on posts you own or that tagged you.reels_trending(true trending) — no Meta API. Closest legit replacement iscompetitors.heatmap(blocked above) or hashtag-niche queries (blocked above).
Code for the doable-via-other-auth ones is preserved in src/lib/mcp/operations.ts inside /* DEAD */ blocks for fast revival.
Limits + safety
- Read-only. Nothing here writes to the DB or to Instagram. Write tiers (drafts, publish) are designed in
mcp-spec.mdand gated behind future approval flows. - Workspace-scoped. A key for workspace A can't see workspace B's data — enforced at the DB layer (RLS) and re-checked in every handler that takes an id (
posts.get,mentions.get,comments.list). - Rate-limited. 60 calls/min per key. Returns HTTP 429 with
Retry-Afterif you blast it. - Audit-logged. Every call (success or error) appears in Settings → Recent calls within seconds.
Adding a new tool
Append to OPERATIONS in src/lib/mcp/operations.ts. The route picks it up automatically — tools/list will include it, tools/call will dispatch to it. Include a description that helps the LLM choose it.