Creatordb MCP server agent

MCP server exposing the CreatorDB V3 API to Claude Code / Claude Desktop / Cursor

by CreatorDB·MIT license·★ 2 Stars on the repo·GitHub ↗

Inside this agent

README.md · the author's own words
# creatordb-mcp-server

A [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the [CreatorDB V3 API](https://apiv3.creatordb.app) to any…

**43 tools across six surfaces:**

- **Creator-side data** — profile, performance, audience demographics, contact, content-detail, performance history for YouTube, Instagram,…
- **Creator search** — natural-language search across all three platforms, plus structured filter search per platform (country, language, f…
- **Brand-side / sponsor intelligence** *(YouTube + Instagram only — TikTok brand data is not indexed)* — search CreatorDB's 10K+ indexed b…
- **Content search** — find individual TikTok videos by content-level filters (publish time window, view/like thresholds, hashtags, languag…
- **Topic + niche taxonomies** — paged, searchable catalogs (~470 YT topics, ~16K YT niches, ~40K each on IG/TT) for resolving the per-crea…
- **Account** — credit usage broken down by endpoint and platform.

Every tool returns the underlying V3 JSON plus a `Credits used: N | Remaining: M` footer line, so the AI knows exactly what it's spending.

Word-for-word excerpt, not a result. Read the full README.md ↓

Files of Creatordb MCP server

CreatorDB/main1 file
README.md
Show the full text482 lines

creatordb-mcp-server

A Model Context Protocol server that exposes the CreatorDB V3 API to any MCP-compatible client (Claude Code, Claude Desktop, Cursor, etc.).

43 tools across six surfaces:

  • Creator-side data — profile, performance, audience demographics, contact, content-detail, performance history for YouTube, Instagram, and TikTok
  • Creator search — natural-language search across all three platforms, plus structured filter search per platform (country, language, follower thresholds, niches, hashtags, audience demographics, etc.)
  • Brand-side / sponsor intelligence (YouTube + Instagram only — TikTok brand data is not indexed) — search CreatorDB's 10K+ indexed brands, pull a brand's full profile, list every creator a brand has sponsored, get aggregated audience demographics across a brand's sponsored creator pool, and cross-platform spend / CPM / CPE rollups. The heavier sponsor reads (get_sponsor_creators, get_sponsor_performance, get_sponsor_audience, get_sponsor_summary) cost 15 credits each — use deliberately. get_sponsor_information is 2, search_sponsors 2, list_sponsors 1.
  • Content search — find individual TikTok videos by content-level filters (publish time window, view/like thresholds, hashtags, language, etc.). Different from creator search — this returns posts, not channels. (YouTube and Instagram content search are temporarily unavailable while their search is optimized for lower credit consumption; TikTok remains.)
  • Topic + niche taxonomies — paged, searchable catalogs (~470 YT topics, ~16K YT niches, ~40K each on IG/TT) for resolving the per-creator topic/niche IDs returned in profile responses. Pass search to resolve a phrase to entry names rather than paging.
  • Account — credit usage broken down by endpoint and platform.

Every tool returns the underlying V3 JSON plus a Credits used: N | Remaining: M footer line, so the AI knows exactly what it's spending.

Working with Claude Code? Open this README in Claude Code (or paste the URL into a Claude session) and say "set up this MCP for me." The steps below are written so an AI assistant can follow them top to bottom.

Quick start

There are two ways to connect, depending on your client:

  • Local clients (Claude Code, Claude Desktop, Cursor) run the server as a subprocess via npx — see Install (local / stdio).
  • Web / desktop / mobile clients connect to the hosted endpoint, or add CreatorDB straight from Claude's connector directory — see Remote connector.

Both expose the same 43 tools. Both need a CreatorDB V3 API key.

  1. Prerequisites
    • For the local route: Node.js 22 or newer (node -v to check)
    • A CreatorDB V3 API key — get one from https://creatordb.app account settings, or ask your team admin
  2. Pick a connection method below
  3. Restart your MCP client so it picks up the new tools
  4. Verify by running /mcp in Claude Code — creatordb should appear with status connected

Install (local / stdio)

For Claude Code, Claude Desktop, and Cursor. The server reads one environment variable: CREATORDB_API_KEY (your V3 key).

The package is published to npm as @creatordbai/mcp-server. No local clone, no SSH key, no GitHub access required:

Claude Code:

claude mcp add creatordb -s user \
  -e CREATORDB_API_KEY=YOUR_CREATORDB_API_KEY \
  -- npx -y @creatordbai/mcp-server

Claude Desktop — edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "creatordb": {
      "command": "npx",
      "args": ["-y", "@creatordbai/mcp-server"],
      "env": { "CREATORDB_API_KEY": "YOUR_CREATORDB_API_KEY" }
    }
  }
}

If you have GitHub org access and want to track main instead of the npm release, swap the npm name for git+ssh://[email protected]/CreatorDB/creatordb-mcp-server.git — the repo's prepare script will build on install.

Method B — clone and build locally

Good if you want to read/modify the source, or if npx from git doesn't work in your environment.

git clone https://github.com/CreatorDB/creatordb-mcp-server.git
cd creatordb-mcp-server
npm install
npm run build

# Then register with Claude Code:
claude mcp add creatordb -s user \
  -e CREATORDB_API_KEY=YOUR_CREATORDB_API_KEY \
  -- node "$(pwd)/dist/index.js"

For Claude Desktop, use the same JSON as Method A but swap command + args:

"command": "node",
"args": ["/absolute/path/to/creatordb-mcp-server/dist/index.js"],
Method C — project-scoped via .mcp.json (best for teams)

Drop a .mcp.json into a CreatorDB project repo. Anyone who opens that repo in Claude Code gets prompted to enable the MCP — no per-person setup commands.

{
  "mcpServers": {
    "creatordb": {
      "command": "npx",
      "args": ["-y", "git+ssh://[email protected]/CreatorDB/creatordb-mcp-server.git"],
      "env": { "CREATORDB_API_KEY": "${CREATORDB_API_KEY}" }
    }
  }
}

${CREATORDB_API_KEY} reads from the user's shell environment, so the key stays out of git. Each teammate sets it once in their .zshrc/.bash_profile:

export CREATORDB_API_KEY=YOUR_CREATORDB_API_KEY

Remote connector (Claude web, desktop, mobile)

Claude clients that can't spawn a local subprocess connect to the hosted endpoint instead of running npx. There are two ways in.

From the connector directory (easiest). CreatorDB is listed in Claude's connector directory. In Claude: Settings → Connectors → Add → Browse connectors, search CreatorDB, open CreatorDB MCP, and click Connect to Claude.

Add it manually. You can also add it directly: Settings → Connectors → Add → Add custom connector, and enter the URL:

https://mcp.creatordb.app/mcp

Leave the Advanced OAuth Client ID / Secret fields empty — the server registers the client automatically.

Either way, you'll be prompted to enter your CreatorDB API key when you connect, and the same 43 tools appear.

Notes:

  • You'll be prompted to enter your key when you connect; the connector seals it into an encrypted session token and keeps no separate copy. CreatorDB stores the key only as the credential it issued you.
  • Programmatic clients calling the endpoint directly can instead send Authorization: Bearer <your CreatorDB V3 API key>.
  • Health check: https://mcp.creatordb.app/health (no auth, 0 credits) — returns {"status":"ok",...} when the service is up.
  • Hosted as a Firebase Cloud Function (gen 2) in asia-northeast1; source is in functions/.
  • Don't have a key? Get one at https://app.creatordb.app or email [email protected].

Changing your API key

You don't update a key inside the MCP server — it doesn't store keys. You change it in your client's MCP configuration and restart.

Local install (Claude Code, Claude Desktop, Cursor)

Edit the same config file you used during setup:

  • Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
  • Cursor: ~/.cursor/mcp.json (or the in-app MCP settings UI)
  • Claude Code: ~/.mcp.json or your project's .mcp.json

Change the CREATORDB_API_KEY value, then fully restart the client (⌘Q + reopen for Claude Desktop, restart the Cursor app, etc.). MCP clients only read the key at process startup.

If you set the key from your shell environment (Method C above, with ${CREATORDB_API_KEY} syntax), update ~/.zshrc / ~/.bash_profile and restart your terminal before restarting the client.

Remote connector (Claude web, desktop, mobile)

In Settings → Connectors → CreatorDB, disconnect and reconnect, then enter the new key when prompted. (A programmatic client sending a Bearer token just starts sending the new key.)

One thing to know about rotating a leaked key

Changing the key on the client side only swaps which key your tools authenticate with. It does NOT invalidate the previous key. If you're rotating because the old key was exposed:

  1. Go to your CreatorDB account and revoke the old key there — that's what actually kills it at the V3 API layer.
  2. Then update the MCP client to use the new key as above.

The MCP server never persists your key past a single request, so there's no server-side "stored key" to purge.

Verify it works

After install, restart Claude Code (or your MCP client) and:

  1. Run /mcp — you should see creatordb listed with status connected
  2. Ask Claude something that uses the tools, e.g. "use creatordb to look up the YouTube profile for MrBeast (channelId UCX6OQ3DkcsbYNE6H8uQQuVA)"
  3. The response should include creator data and a Credits used: 2 | Remaining: … footer

Troubleshooting

Symptom Cause Fix
/mcp shows creatordb as failed or connecting forever API key missing or wrong Re-add with claude mcp remove creatordb && claude mcp add … using the correct key
Tools work but every response ends Credits used: undefined Stale tool schema from an older build of this server Restart the MCP client — clients cache the schema at session start
Error: VALIDATION_ERROR on Instagram tools Passing userId instead of uniqueId IG endpoints take the handle as uniqueId. Older clients with stale schemas hit this most
npx install fails with EACCES: permission denied npx cache permission issue rm -rf ~/.npm/_npx and re-run
Error: ENOENT or cannot find dist/index.js Method B didn't run npm run build cd into the repo and run npm install && npm run build
Tool descriptions seem outdated vs this README Schema cached from an old version claude mcp remove creatordb && claude mcp add … to force a re-fetch

Why restarts matter — MCP clients fetch the tool list once at session start. Server updates (new tools, renamed params, fixed costs) only show up after the client reconnects. This is the single most common confusion.

Upgrading to a newer published version? npx caches packages by exact version, so a configured client keeps running whatever version it first downloaded. To force-pull the latest, either pin to @latest in your config (npx -y @creatordbai/mcp-server@latest re-resolves each launch) or clear the npx cache once (rm -rf ~/.npm/_npx). Then restart the MCP client.

Releasing (maintainers)

The .github/workflows/release.yml workflow publishes to npm whenever a v*.*.* tag is pushed.

# bump version, commit, tag, push
npm version patch              # or minor / major
git push && git push --tags

The workflow validates that the tag matches package.json version, runs npm ci, builds, and publishes via npm Trusted Publishing with sigstore provenance attestation. No long-lived NPM_TOKEN is stored — the workflow exchanges a GitHub OIDC token for a short-lived npm publish token at runtime.

Roadmap

  • Goal: list in the MCP registry and Claude's MCP marketplace so the server shows up when users browse MCP servers from inside their client.
  • Contributions, issues, and feedback welcome — see Getting help below.

Tools

43 tools across six categories. Every tool returns a structured JSON payload plus a Credits used: N | Remaining: M footer line.

Account (1)
Tool Cost Notes
get_api_usage 0 Daily request counts and credit consumption by endpoint. Defaults to last 7 days; takes optional start/end Unix-ms timestamps.
Search (4)
Tool Cost Notes
search_creators_nls dynamic (token-based) Natural-language search across all three platforms. The AI picks the platform and converts the query into filters.
search_youtube 1 per 10 filters Structured filter search. Use totalSubscribers for count thresholds.
search_instagram 1 per 10 filters Structured filter search. Use totalFollowers for count thresholds.
search_tiktok 1 per 10 filters Structured filter search. Use totalFollowers for count thresholds.

Filter type gotcha: numeric ops (>, <, = on subscriber/follower/rate fields) require a number value, not a numeric string. "1000000" → VALIDATION_ERROR; 1000000 → ok.

Filter value notes: hashtag values match with or without a leading # and are case-insensitive. Ratio and percentile fields (audienceMaleRatio, audienceFemaleRatio, and YouTube's *Percentile fields) take a decimal from 0 to 1, not 0-100: 0.6 = 60%, 0.9 = top 10%.

Sponsors / brand data (8)

Brand-side intelligence: which brands sponsor creators, how much they spend, which creators they work with. Sponsor data covers YouTube and Instagram only — TikTok is not indexed for brands.

Brand-key: brandId, typically the brand's primary domain (e.g. "acer.com", "nike.com").

Tool Cost Returns
search_sponsors 2 per page Brand search by structured filters. Lean records (brandId, name, logo, industries, country).
list_sponsors 1 per page Paginated directory of all 10K+ indexed brands.
get_sponsor_information 2 Full brand profile: aliases, keyPeople, industries, location, website, socialMedia, competitors.
get_sponsor_creators 25 per page Inverse of get_*_sponsorship — which creators has this brand sponsored. Returns followers, lastSponsoredDate, sponsoredCount, topics, niches per creator.
get_sponsor_performance 25 per page Per-content sponsorship perf. Three stats scopes per creator (creatorTotal, allSponsored lifetime, this-brand-only). YT-only: estimatedCost, CPM.
get_sponsor_audience 25 Aggregated audience demographics across the brand's sponsored creator pool. IG block reserved but null today (backend YT-only).
get_sponsor_summary 25 Cross-platform rollup: totalSponsoredCreators/Content, per-platform creators + performance + growth30d.
submit_sponsor 1 (0 if duplicate) Submit a brand for indexing. Rate-limited 100/day per key. Returns submissionId + status.

Cost warning — get_sponsor_creators, get_sponsor_performance, get_sponsor_audience, get_sponsor_summary each cost 25 credits per call. Use search_sponsors / list_sponsors / get_sponsor_information for cheap exploration first.

YouTube creator data (7 + 4 platform-specific)

Creator-key: channelId (the UC… form — @handle / /c/ / /user/ URLs are not accepted; resolve first).

Tool Cost Returns
get_youtube_profile 2 Identity, subscribers, country, language, linked socials, channel categories, plus the creator's topics and niches.
get_youtube_contact 15 Email addresses.
get_youtube_performance 3 R20 (last 20 videos) + all-time (up to 800) engagement metrics; consistency scores; 30d/90d view windows.
get_youtube_performance_history 3 Daily snapshots over the past N days. Takes pastDayRange (string integer, 1–365).
get_youtube_audience 10 Age buckets, gender split, top countries.
get_youtube_content_detail 3 Recent videos + shorts with per-item engagement.
get_youtube_sponsorship 5 Sponsored content grouped by indexed brand (recent posts only — empty list ≠ "no sponsors").
list_youtube_topics 1 The YT TOPIC taxonomy (~470 entries with channelCount), paged. YouTube-only — IG and TT do not have a topic taxonomy. search, category, minChannelCount, pageSize, offset.
list_youtube_niches 1 The YT NICHE taxonomy (~16K entries with channelCount), paged. search, category, minChannelCount, pageSize, offset.
get_youtube_subtitles_meta 1 Per-video subtitle track listing. Takes videoId (not channelId).
get_youtube_subtitles_download 3 Subtitle text for one video. Takes videoId, optional language (ISO 639-3).
Instagram creator data (7 + 1)

Creator-key: uniqueId (the handle, no @).

Tool Cost Returns
get_instagram_profile 2 Identity, followers, country, language, isBusinessAccount, linked socials, hashtags, account categories, plus the creator's niches.
get_instagram_contact 15 Email addresses.
get_instagram_performance 2 First-page image + reels engagement; consistency scores.
get_instagram_performance_history 3 Daily snapshots over the past N days. Takes pastDayRange.
get_instagram_audience 10 Age buckets, gender split, top countries.
get_instagram_content_detail 2 Recent images + reels with per-item engagement.
get_instagram_sponsorship 5 Sponsored content grouped by indexed brand (recent posts only).
list_instagram_niches 1 The IG NICHE taxonomy (~40K entries), paged. Instagram does NOT have a "topics" taxonomy. search, minChannelCount, pageSize, offset.
TikTok creator data (7 + 1)

Creator-key: uniqueId (the handle, no @).

Tool Cost Returns
get_tiktok_profile 2 Identity, followers, country, language, hashtags, plus the creator's niches.
get_tiktok_contact 15 Email addresses.
get_tiktok_performance 2 Recent videos engagement (views, likes, comments, shares); consistency scores.
get_tiktok_performance_history 3 Daily snapshots over the past N days. Takes pastDayRange.
get_tiktok_audience 10 Age buckets, gender split, top countries.
get_tiktok_content_detail 2 Recent videos with audio metadata, duet/stitch/commerce flags, per-item engagement.
search_tiktok_content 2 per page Search individual VIDEOS by content-level filters (different from search_tiktok, which searches creators). NO isSponsored/partneredBrands (TT brand-attribution not implemented). Filter terminology uses diggs but response normalizes to likes.
list_tiktok_niches 1 The TT NICHE taxonomy (~40K entries), paged. TikTok does NOT have a topics taxonomy, and does NOT expose a per-brand sponsorship endpoint. search, minChannelCount, pageSize, offset.

Cross-platform differences cheat-sheet

Dimension YouTube Instagram TikTok
Creator parameter channelId (UC…) uniqueId (handle) uniqueId (handle)
Follower field totalSubscribers totalFollowers totalFollowers
Has a topic taxonomy ✅ list_youtube_topics ❌ ❌
Has a niche taxonomy ✅ list_youtube_niches ✅ list_instagram_niches ✅ list_tiktok_niches
Per-creator niches in /profile ✅ ✅ ✅
Per-creator topics in /profile ✅ ❌ ❌
Sponsorship per-brand endpoint ✅ ✅ ❌
Content types in /content-detail videos + shorts images + reels videos
/content-detail cost 3 2 2
Performance windows R20 + all-time (up to 800) First-page Recent
Engagement formula (L+C+V) / subscribers (L+C) / followers (L+C+Shares) / followers
Subtitles endpoints ✅ ❌ ❌
Content-search endpoint ✅ ✅ ✅
Brand-side sponsor data ✅ ✅ ❌

Niche IDs are not interchangeable across platforms — id_vlog_PeopleBlogs (YT) and id_love_All (IG) live in different namespaces. Niche/topic IDs follow the pattern id_{slug}_{Category}, so you can group by category by splitting on the last _.

Response shape highlights

These are the fields that aren't obvious from the endpoint name but you'll reach for constantly. All confirmed against live responses.

/profile

Shared across YT/IG/TT:

  • subscriberGrowth: { g7, g30, g90 } — % change in subscribers/followers over the last 7/30/90 days. Free trend signal — no need to call performance-history if you only want the headline number.
  • hashtags: [{ name, contentCount }] — hashtags the creator uses (note: name carries the # on IG/TT).
  • niches: ["id_vlog_PeopleBlogs", …] — per-creator niche IDs. To resolve the human-readable name + category + channelCount, cross-reference list_{platform}_niches.
  • relatedCreators — accounts the platform itself recommends or lists as related to the creator. YT: UC channelIds of channels YouTube recommends alongside this channel's videos, most frequent first. IG/TT: handles, passed through as the platform provides them. On TikTok the list often includes the creator's own handle. Cheap way to expand a seed list.
  • hasEmail — whether get_{platform}_contact would return an email. Request it via fields (0.1 credit) before paying 15 for contact.
  • isAgencyRepresented — true when CreatorDB has a record of agency representation; false also covers creators with no record.
  • lastPublishTime / lastDbUpdateTime — Unix-ms; pair them to know how stale the snapshot is vs how recently the creator posted.
  • country — ISO 3166-1 alpha-3 (e.g. "USA", "JPN"). On IG this value is derived from a content classifier rather than a self-declared field, and can occasionally be wrong for creators with multi-country presence — cross-check against audienceLocations and the creator's bio if accuracy matters.

YT-only:

  • topics: ["id_challenges_Comedy", …] — coarse topic IDs (~470 universe). Resolve via list_youtube_topics.
  • totalViews — lifetime channel views, as shown on the channel's About panel.
  • joinedDate — when the channel was created (Unix ms, day precision).
  • Sponsored video / shorts CPM and rate bands (videoPrice, shortsPrice) are no longer on profile; they're on get_youtube_performance.
  • categoryBreakdown: [{ category, share }] — share of recent content by YouTube native category.
  • hasMemberOnlyContents — boolean.

IG-only:

  • isBusinessAccount, isPrivateAccount — flags worth checking before promising audience data; private accounts can't be scraped.
  • otherLinks — bio links array.
  • imageLastPublishTime / reelsLastPublishTime — latest image post and latest reel (Unix ms); lastPublishTime is the later of the two.

TT-only:

  • otherLinks — bio link (TikTok allows one).
  • joinedDate — when the account was created (Unix ms).
/audience

Identical shape across platforms:

  • audienceLocations: [{ country, share }] — top 6 countries with shares summing to roughly 1.0.
  • audienceGender: { maleRatio, femaleRatio } — sums to ~1.0; binary split only.
  • audienceAvgAge — integer.
  • audienceAgeBreakdown: [{ ageRange, share }] — fixed buckets 13-17 | 18-24 | 25-34 | 35-44 | 45-54 | 55-64 | 65+. Always 7 entries; placeholder rows are all-zero (see footgun list below).
/performance

The R20-vs-all distinction is YT-only:

  • YT returns four sibling objects: videosPerformanceRecent, videosPerformanceAll, shortsPerformanceRecent, shortsPerformanceAll. "Recent" = R20 (last 20). "All" = up to 800. Each has likes/comments/views (with avg/median/min/max/percentile25/percentile75/iqr) and an engagement block.
  • IG returns imagesPerformanceRecent + reelsPerformanceRecent. No all-time window.
  • TT returns videosPerformanceRecent. No all-time window.
  • Every engagement block ends with engagementConsistency: { cv, medianVsMean, topBottomRatio, consistencyScore, consistencyLevel }. consistencyScore is 0–100; consistencyLevel is "high" (81–100), "moderate" (51–80), or "low" (0–50). Requires ≥6 content pieces, otherwise the consistency block is absent.
  • ranking block carries global, country, language percentile ranks for totalSubscribers/totalFollowers and avgEngagementRate — useful for "is this creator above average for their country" without separate benchmarking.
  • recentVideosGrowth.g7/g30/g90 — engagement-rate delta over 7/30/90 days. Negative numbers mean engagement is declining.
  • contentCountByDays: { 7d, 30d, 90d } — how many posts in each window (use to detect dormant creators).
/content-detail

Per-item objects across platforms:

  • publishTime (Unix-ms), contentId, likes, comments, views (YT/TT only — IG images have no view count), engagementRate (rounded to 4 decimals).
  • hashtags: ["#example", …] — already includes # prefix.

Platform-specific extras:

  • YT: length (seconds), isMemberOnly, content mix includes both videos and shorts.
  • IG: mentionedCreators — @-mentions in caption.
  • TT: audioId, audioTitle, audioAuthor, audioAlbum, isDuetEnabled, isAd, length (seconds), shares. The audio block is the cheapest way to find trending sounds.

Freshness rule — content published within the last 4 days is excluded from all metric calculations (all platforms). Pinned-post rule — on IG/TT, a pinned post older than 90 days is excluded if it would be the oldest item in the sample.

/sponsorship

YT and IG only — TikTok does not have a per-brand sponsorship endpoint.

  • sponsorList: [{ brandName, brandId, brandIgIds, sponsoredVideos, sponsoredVideosPerformance }].
  • brandIgIds — the brand's IG handles. Use this to follow a brand from a sponsored creator back to the brand's own profile.
  • sponsoredVideos includes each sponsored content's full per-item engagement (same shape as /content-detail).
  • Important caveat — only scans the most recent ~20–30 posts and only detects brands already indexed in CreatorDB. An empty sponsorList is not proof the creator has no sponsors; it's "we didn't find indexed sponsors in their recent posts."
Search (search_{platform} and search_creators_nls)

Structured search response:

  • creatorList: [{ displayName, uniqueId, channelId (YT only), avatarUrl, totalSubscribers | totalFollowers }] — minimal projection; hydrate with get_*_profile for full data.
  • totalResults — total matching the filter set, not just the page.
  • hasNextPage + nextOffset — pagination idiom. Pass nextOffset as the next request's offset to advance.

NLS response:

  • Same creatorList shape as structured search, plus a platform: "youtube" | "instagram" | "tiktok" field telling you which platform the AI routed to.
  • Streamed over SSE under the hood; the MCP layer collects the final data: event and returns it as one payload.
  • Dynamic pricing — typically 1–10 credits depending on input + output token count.
/usage
  • records: [{ date (YYYYMMDD), requestCount, totalQuotaUsed, endpoints: { …per-endpoint counts }, platforms: { …per-platform counts }, quotaByPlatform }].
  • totalQuotaUsed can be fractional (e.g. 4.49 for an NLS call).
  • endpoints keys are camelCase: getYoutubeProfile, getInstagramAudience, searchYoutube, getNLS, etc. Useful for building a spend dashboard.

Common footguns

  • Placeholder demographics: when CreatorDB doesn't have real audience data, /audience returns the all-zero shape (audienceGender: { maleRatio: 0, femaleRatio: 0 }, age buckets all 0.0). Treat any row where male+female=0 as missing, not as "no gender data."
  • Empty sponsorList ≠ no sponsors (see above).
  • relatedCreators is unranked — order is not significance. Don't slice the first N and call them "top related"; sample or rerank by your own metric.
  • Freshness lag — lastDbUpdateTime is when CreatorDB last refreshed. If it's older than ~14 days, the profile may not reflect recent breakout content.
  • Niche channelCount drifts — list_*_niches is updated daily; don't cache it longer than that or your "creators in X niche" count will lag reality.
  • Search the taxonomy, don't page it — list_*_niches returns one page at a time (100 by default, largest first) because the full taxonomies run to ~40,000 entries on Instagram and TikTok. Both are a single flat "All" category with no structure to browse, and the top 100 entries account for only ~18% of creator assignments, so paging rarely gets you anywhere. Pass search to resolve a phrase to niche names instead. Matching is whole-word, so skin will not find Skincare; CamelCase names are split (StreetFood matches street food) and common variants are folded (vloggers→vlog, japanese→japan). On TikTok ~44% of niches have under 100 creators — minChannelCount trims that tail.
  • IG country is modelled, not self-declared — YouTube and TikTok return the country a creator set on their own profile; for Instagram, CreatorDB's location model supplies it, so IG has country coverage where the profile states nothing.

Filter reference (search tools)

Common fields across all three platforms:

  • displayName — string, supports fuzzy
  • uniqueId — string, exact
  • country — string, ISO 3166-1 alpha-3 (e.g. "USA", "JPN", "GBR")
  • mainLanguage — string, ISO 639-3 (e.g. "eng", "jpn", "zhs")
  • hashtags — string (with # prefix on IG/TT)
  • niches — string (use IDs from the platform's list_*_niches)
  • mainAudienceLocation / mainAudienceAge / mainAudienceGender — string
  • hasSponsors — boolean

Platform-specific:

  • YouTube: totalSubscribers (number), topics (string from list_youtube_topics)
  • Instagram / TikTok: totalFollowers (number)

Operators: >, <, = for numbers; =, in for strings; = for booleans. in takes an array of up to 100 values. pageSize max 100; filters max 10 per request.

Response envelope

Every tool returns the underlying CreatorDB V3 envelope:

{
  "data": { },
  "creditsUsed": 2,
  "creditsAvailable": 953270.5,
  "traceId": "abc-123",
  "timestamp": 1779722787120,
  "errorCode": "",
  "errorDescription": "",
  "success": true
}

On error, the envelope carries errorCode, error, message, and details. The MCP layer flattens that into a clean error message with a TraceId: line for support.

Development

npm run dev   # tsc --watch
npm run build # tsc once
npm start     # node dist/index.js

Source layout:

src/
  index.ts                 # registers all tools, stdio transport
  tools/
    account.ts             # 1 tool
    search.ts              # 4 tools (NLS + 3 platform creator searches)
    youtube.ts             # 12 tools
    instagram.ts           # 9 tools
    tiktok.ts              # 9 tools (incl. search_tiktok_content)
    sponsors.ts            # 8 tools (brand-side sponsor intelligence)
  util/
    api-client.ts          # fetch wrapper for REST + SSE
    response.ts            # MCP result formatter (credits, errors)

Getting help

License

MIT

1# creatordb-mcp-server
2 
3A [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the [CreatorDB V3 API](https://apiv3.creatordb.app) to any MCP-compatible client (Claude Code, Claude Desktop, Cursor, etc.).
4 
5**43 tools across six surfaces:**
6 
7- **Creator-side data** — profile, performance, audience demographics, contact, content-detail, performance history for YouTube, Instagram, and TikTok
8- **Creator search** — natural-language search across all three platforms, plus structured filter search per platform (country, language, follower thresholds, niches, hashtags, audience demographics, etc.)
9- **Brand-side / sponsor intelligence** *(YouTube + Instagram only — TikTok brand data is not indexed)* — search CreatorDB's 10K+ indexed brands, pull a brand's full profile, list every creator a brand has sponsored, get aggregated audience demographics across a brand's sponsored creator pool, and cross-platform spend / CPM / CPE rollups. The heavier sponsor reads (`get_sponsor_creators`, `get_sponsor_performance`, `get_sponsor_audience`, `get_sponsor_summary`) cost 15 credits each — use deliberately. `get_sponsor_information` is 2, `search_sponsors` 2, `list_sponsors` 1.
10- **Content search** — find individual TikTok videos by content-level filters (publish time window, view/like thresholds, hashtags, language, etc.). Different from creator search — this returns posts, not channels. *(YouTube and Instagram content search are temporarily unavailable while their search is optimized for lower credit consumption; TikTok remains.)*
11- **Topic + niche taxonomies** — paged, searchable catalogs (~470 YT topics, ~16K YT niches, ~40K each on IG/TT) for resolving the per-creator topic/niche IDs returned in profile responses. Pass `search` to resolve a phrase to entry names rather than paging.
12- **Account** — credit usage broken down by endpoint and platform.
13 
14Every tool returns the underlying V3 JSON plus a `Credits used: N | Remaining: M` footer line, so the AI knows exactly what it's spending.
15 
16> **Working with Claude Code?** Open this README in Claude Code (or paste the URL into a Claude session) and say *"set up this MCP for me."* The steps below are written so an AI assistant can follow them top to bottom.
17 
18## Quick start
19 
20There are two ways to connect, depending on your client:
21 
22- **Local clients** (Claude Code, Claude Desktop, Cursor) run the server as a subprocess via `npx` — see [Install (local / stdio)](#install-local--stdio).
23- **Web / desktop / mobile clients** connect to the hosted endpoint, or add CreatorDB straight from Claude's connector directory — see [Remote connector](#remote-connector-claude-web-desktop-mobile).
24 
25Both expose the same 43 tools. Both need a CreatorDB V3 API key.
26 
271. **Prerequisites**
28 - For the local route: Node.js 22 or newer (`node -v` to check)
29 - A CreatorDB V3 API key — get one from <https://creatordb.app> account settings, or ask your team admin
302. **Pick a connection method** below
313. **Restart your MCP client** so it picks up the new tools
324. **Verify** by running `/mcp` in Claude Code — `creatordb` should appear with status `connected`
33 
34## Install (local / stdio)
35 
36For Claude Code, Claude Desktop, and Cursor. The server reads one environment variable: `CREATORDB_API_KEY` (your V3 key).
37 
38### Method A — `npx` from npm (recommended)
39 
40The package is published to npm as **`@creatordbai/mcp-server`**. No local clone, no SSH key, no GitHub access required:
41 
42**Claude Code:**
43```bash
44claude mcp add creatordb -s user \
45 -e CREATORDB_API_KEY=YOUR_CREATORDB_API_KEY \
46 -- npx -y @creatordbai/mcp-server
47```
48 
49**Claude Desktop** — edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
50```json
51{
52 "mcpServers": {
53 "creatordb": {
54 "command": "npx",
55 "args": ["-y", "@creatordbai/mcp-server"],
56 "env": { "CREATORDB_API_KEY": "YOUR_CREATORDB_API_KEY" }
57 }
58 }
59}
60```
61 
62If you have GitHub org access and want to track `main` instead of the npm release, swap the npm name for `git+ssh://[email protected]/CreatorDB/creatordb-mcp-server.git` — the repo's `prepare` script will build on install.
63 
64### Method B — clone and build locally
65 
66Good if you want to read/modify the source, or if `npx` from git doesn't work in your environment.
67 
68```bash
69git clone https://github.com/CreatorDB/creatordb-mcp-server.git
70cd creatordb-mcp-server
71npm install
72npm run build
73 
74# Then register with Claude Code:
75claude mcp add creatordb -s user \
76 -e CREATORDB_API_KEY=YOUR_CREATORDB_API_KEY \
77 -- node "$(pwd)/dist/index.js"
78```
79 
80For Claude Desktop, use the same JSON as Method A but swap `command` + `args`:
81```json
82"command": "node",
83"args": ["/absolute/path/to/creatordb-mcp-server/dist/index.js"],
84```
85 
86### Method C — project-scoped via `.mcp.json` (best for teams)
87 
88Drop a `.mcp.json` into a CreatorDB project repo. Anyone who opens that repo in Claude Code gets prompted to enable the MCP — no per-person setup commands.
89 
90```json
91{
92 "mcpServers": {
93 "creatordb": {
94 "command": "npx",
95 "args": ["-y", "git+ssh://[email protected]/CreatorDB/creatordb-mcp-server.git"],
96 "env": { "CREATORDB_API_KEY": "${CREATORDB_API_KEY}" }
97 }
98 }
99}
100```
101 
102`${CREATORDB_API_KEY}` reads from the user's shell environment, so the key stays out of git. Each teammate sets it once in their `.zshrc`/`.bash_profile`:
103```bash
104export CREATORDB_API_KEY=YOUR_CREATORDB_API_KEY
105```
106 
107## Remote connector (Claude web, desktop, mobile)
108 
109Claude clients that can't spawn a local subprocess connect to the hosted endpoint instead of running `npx`. There are two ways in.
110 
111**From the connector directory (easiest).** CreatorDB is listed in Claude's connector directory. In Claude: **Settings → Connectors → Add → Browse connectors**, search **CreatorDB**, open **CreatorDB MCP**, and click **Connect to Claude**.
112 
113**Add it manually.** You can also add it directly: **Settings → Connectors → Add → Add custom connector**, and enter the URL:
114 
115```
116https://mcp.creatordb.app/mcp
117```
118 
119Leave the Advanced OAuth Client ID / Secret fields empty — the server registers the client automatically.
120 
121Either way, you'll be prompted to enter your CreatorDB API key when you connect, and the same 43 tools appear.
122 
123Notes:
124- You'll be prompted to enter your key when you connect; the connector seals it into an encrypted session token and keeps no separate copy. CreatorDB stores the key only as the credential it issued you.
125- Programmatic clients calling the endpoint directly can instead send `Authorization: Bearer <your CreatorDB V3 API key>`.
126- Health check: <https://mcp.creatordb.app/health> (no auth, 0 credits) — returns `{"status":"ok",...}` when the service is up.
127- Hosted as a Firebase Cloud Function (gen 2) in `asia-northeast1`; source is in [`functions/`](./functions).
128- Don't have a key? Get one at <https://app.creatordb.app> or email [email protected].
129 
130## Changing your API key
131 
132You don't update a key inside the MCP server — it doesn't store keys. You change it in your client's MCP configuration and restart.
133 
134### Local install (Claude Code, Claude Desktop, Cursor)
135 
136Edit the same config file you used during setup:
137 
138- **Claude Desktop:** `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows)
139- **Cursor:** `~/.cursor/mcp.json` (or the in-app MCP settings UI)
140- **Claude Code:** `~/.mcp.json` or your project's `.mcp.json`
141 
142Change the `CREATORDB_API_KEY` value, then **fully restart the client** (⌘Q + reopen for Claude Desktop, restart the Cursor app, etc.). MCP clients only read the key at process startup.
143 
144If you set the key from your shell environment (Method C above, with `${CREATORDB_API_KEY}` syntax), update `~/.zshrc` / `~/.bash_profile` and restart your terminal before restarting the client.
145 
146### Remote connector (Claude web, desktop, mobile)
147 
148In **Settings → Connectors → CreatorDB**, disconnect and reconnect, then enter the new key when prompted. (A programmatic client sending a Bearer token just starts sending the new key.)
149 
150### One thing to know about rotating a leaked key
151 
152Changing the key on the client side only swaps which key your tools authenticate with. **It does NOT invalidate the previous key.** If you're rotating because the old key was exposed:
153 
1541. Go to your CreatorDB account and **revoke the old key** there — that's what actually kills it at the V3 API layer.
1552. Then update the MCP client to use the new key as above.
156 
157The MCP server never persists your key past a single request, so there's no server-side "stored key" to purge.
158 
159## Verify it works
160 
161After install, restart Claude Code (or your MCP client) and:
162 
1631. Run `/mcp` — you should see `creatordb` listed with status **connected**
1642. Ask Claude something that uses the tools, e.g. *"use creatordb to look up the YouTube profile for MrBeast (channelId UCX6OQ3DkcsbYNE6H8uQQuVA)"*
1653. The response should include creator data and a `Credits used: 2 | Remaining: …` footer
166 
167## Troubleshooting
168 
169| Symptom | Cause | Fix |
170| --- | --- | --- |
171| `/mcp` shows `creatordb` as `failed` or `connecting` forever | API key missing or wrong | Re-add with `claude mcp remove creatordb && claude mcp add …` using the correct key |
172| Tools work but every response ends `Credits used: undefined` | Stale tool schema from an older build of this server | Restart the MCP client — clients cache the schema at session start |
173| `Error: VALIDATION_ERROR` on Instagram tools | Passing `userId` instead of `uniqueId` | IG endpoints take the handle as `uniqueId`. Older clients with stale schemas hit this most |
174| `npx` install fails with `EACCES: permission denied` | npx cache permission issue | `rm -rf ~/.npm/_npx` and re-run |
175| `Error: ENOENT` or `cannot find dist/index.js` | Method B didn't run `npm run build` | `cd` into the repo and run `npm install && npm run build` |
176| Tool descriptions seem outdated vs this README | Schema cached from an old version | `claude mcp remove creatordb && claude mcp add …` to force a re-fetch |
177 
178> **Why restarts matter** — MCP clients fetch the tool list once at session start. Server updates (new tools, renamed params, fixed costs) only show up after the client reconnects. This is the single most common confusion.
179 
180> **Upgrading to a newer published version?** `npx` caches packages by exact version, so a configured client keeps running whatever version it first downloaded. To force-pull the latest, either pin to `@latest` in your config (`npx -y @creatordbai/mcp-server@latest` re-resolves each launch) or clear the npx cache once (`rm -rf ~/.npm/_npx`). Then restart the MCP client.
181 
182## Releasing (maintainers)
183 
184The `.github/workflows/release.yml` workflow publishes to npm whenever a `v*.*.*` tag is pushed.
185 
186```bash
187# bump version, commit, tag, push
188npm version patch # or minor / major
189git push && git push --tags
190```
191 
192The workflow validates that the tag matches `package.json` `version`, runs `npm ci`, builds, and publishes via [npm Trusted Publishing](https://docs.npmjs.com/trusted-publishers) with sigstore provenance attestation. No long-lived `NPM_TOKEN` is stored — the workflow exchanges a GitHub OIDC token for a short-lived npm publish token at runtime.
193 
194## Roadmap
195 
196- **Goal**: list in the [MCP registry](https://modelcontextprotocol.io) and Claude's MCP marketplace so the server shows up when users browse MCP servers from inside their client.
197- Contributions, issues, and feedback welcome — see [Getting help](#getting-help) below.
198 
199## Tools
200 
20143 tools across six categories. Every tool returns a structured JSON payload plus a `Credits used: N | Remaining: M` footer line.
202 
203### Account (1)
204 
205| Tool | Cost | Notes |
206| --- | --- | --- |
207| `get_api_usage` | 0 | Daily request counts and credit consumption by endpoint. Defaults to last 7 days; takes optional `start`/`end` Unix-ms timestamps. |
208 
209### Search (4)
210 
211| Tool | Cost | Notes |
212| --- | --- | --- |
213| `search_creators_nls` | dynamic (token-based) | Natural-language search across all three platforms. The AI picks the platform and converts the query into filters. |
214| `search_youtube` | 1 per 10 filters | Structured filter search. Use `totalSubscribers` for count thresholds. |
215| `search_instagram` | 1 per 10 filters | Structured filter search. Use `totalFollowers` for count thresholds. |
216| `search_tiktok` | 1 per 10 filters | Structured filter search. Use `totalFollowers` for count thresholds. |
217 
218**Filter type gotcha:** numeric ops (`>`, `<`, `=` on subscriber/follower/rate fields) require a **number** value, not a numeric string. `"1000000"` → `VALIDATION_ERROR`; `1000000` → ok.
219 
220**Filter value notes:** hashtag values match with or without a leading `#` and are case-insensitive. Ratio and percentile fields (`audienceMaleRatio`, `audienceFemaleRatio`, and YouTube's `*Percentile` fields) take a decimal from 0 to 1, not 0-100: `0.6` = 60%, `0.9` = top 10%.
221 
222### Sponsors / brand data (8)
223 
224Brand-side intelligence: which brands sponsor creators, how much they spend, which creators they work with. Sponsor data covers **YouTube and Instagram only** — TikTok is not indexed for brands.
225 
226Brand-key: `brandId`, typically the brand's primary domain (e.g. `"acer.com"`, `"nike.com"`).
227 
228| Tool | Cost | Returns |
229| --- | --- | --- |
230| `search_sponsors` | 2 per page | Brand search by structured filters. Lean records (brandId, name, logo, industries, country). |
231| `list_sponsors` | 1 per page | Paginated directory of all 10K+ indexed brands. |
232| `get_sponsor_information` | 2 | Full brand profile: aliases, keyPeople, industries, location, website, socialMedia, competitors. |
233| `get_sponsor_creators` | **25 per page** | Inverse of `get_*_sponsorship` — which creators has this brand sponsored. Returns followers, lastSponsoredDate, sponsoredCount, topics, niches per creator. |
234| `get_sponsor_performance` | **25 per page** | Per-content sponsorship perf. Three stats scopes per creator (creatorTotal, allSponsored lifetime, this-brand-only). YT-only: estimatedCost, CPM. |
235| `get_sponsor_audience` | **25** | Aggregated audience demographics across the brand's sponsored creator pool. IG block reserved but null today (backend YT-only). |
236| `get_sponsor_summary` | **25** | Cross-platform rollup: totalSponsoredCreators/Content, per-platform creators + performance + growth30d. |
237| `submit_sponsor` | 1 (0 if duplicate) | Submit a brand for indexing. Rate-limited 100/day per key. Returns submissionId + status. |
238 
239**Cost warning** — `get_sponsor_creators`, `get_sponsor_performance`, `get_sponsor_audience`, `get_sponsor_summary` each cost **25 credits** per call. Use `search_sponsors` / `list_sponsors` / `get_sponsor_information` for cheap exploration first.
240 
241### YouTube creator data (7 + 4 platform-specific)
242 
243Creator-key: `channelId` (the UC… form — `@handle` / `/c/` / `/user/` URLs are not accepted; resolve first).
244 
245| Tool | Cost | Returns |
246| --- | --- | --- |
247| `get_youtube_profile` | 2 | Identity, subscribers, country, language, linked socials, channel categories, plus the creator's `topics` and `niches`. |
248| `get_youtube_contact` | 15 | Email addresses. |
249| `get_youtube_performance` | 3 | R20 (last 20 videos) + all-time (up to 800) engagement metrics; consistency scores; 30d/90d view windows. |
250| `get_youtube_performance_history` | 3 | Daily snapshots over the past N days. Takes `pastDayRange` (string integer, 1–365). |
251| `get_youtube_audience` | 10 | Age buckets, gender split, top countries. |
252| `get_youtube_content_detail` | 3 | Recent videos + shorts with per-item engagement. |
253| `get_youtube_sponsorship` | 5 | Sponsored content grouped by indexed brand (recent posts only — empty list ≠ "no sponsors"). |
254| `list_youtube_topics` | 1 | The YT TOPIC taxonomy (~470 entries with channelCount), paged. **YouTube-only — IG and TT do not have a topic taxonomy.** `search`, `category`, `minChannelCount`, `pageSize`, `offset`. |
255| `list_youtube_niches` | 1 | The YT NICHE taxonomy (~16K entries with channelCount), paged. `search`, `category`, `minChannelCount`, `pageSize`, `offset`. |
256| `get_youtube_subtitles_meta` | 1 | Per-video subtitle track listing. Takes `videoId` (not channelId). |
257| `get_youtube_subtitles_download` | 3 | Subtitle text for one video. Takes `videoId`, optional `language` (ISO 639-3). |
258 
259### Instagram creator data (7 + 1)
260 
261Creator-key: `uniqueId` (the handle, no `@`).
262 
263| Tool | Cost | Returns |
264| --- | --- | --- |
265| `get_instagram_profile` | 2 | Identity, followers, country, language, isBusinessAccount, linked socials, hashtags, account categories, plus the creator's `niches`. |
266| `get_instagram_contact` | 15 | Email addresses. |
267| `get_instagram_performance` | 2 | First-page image + reels engagement; consistency scores. |
268| `get_instagram_performance_history` | 3 | Daily snapshots over the past N days. Takes `pastDayRange`. |
269| `get_instagram_audience` | 10 | Age buckets, gender split, top countries. |
270| `get_instagram_content_detail` | 2 | Recent images + reels with per-item engagement. |
271| `get_instagram_sponsorship` | 5 | Sponsored content grouped by indexed brand (recent posts only). |
272| `list_instagram_niches` | 1 | The IG NICHE taxonomy (~40K entries), paged. **Instagram does NOT have a "topics" taxonomy.** `search`, `minChannelCount`, `pageSize`, `offset`. |
273 
274### TikTok creator data (7 + 1)
275 
276Creator-key: `uniqueId` (the handle, no `@`).
277 
278| Tool | Cost | Returns |
279| --- | --- | --- |
280| `get_tiktok_profile` | 2 | Identity, followers, country, language, hashtags, plus the creator's `niches`. |
281| `get_tiktok_contact` | 15 | Email addresses. |
282| `get_tiktok_performance` | 2 | Recent videos engagement (views, likes, comments, shares); consistency scores. |
283| `get_tiktok_performance_history` | 3 | Daily snapshots over the past N days. Takes `pastDayRange`. |
284| `get_tiktok_audience` | 10 | Age buckets, gender split, top countries. |
285| `get_tiktok_content_detail` | 2 | Recent videos with audio metadata, duet/stitch/commerce flags, per-item engagement. |
286| `search_tiktok_content` | 2 per page | Search individual VIDEOS by content-level filters (different from `search_tiktok`, which searches creators). NO isSponsored/partneredBrands (TT brand-attribution not implemented). Filter terminology uses `diggs` but response normalizes to `likes`. |
287| `list_tiktok_niches` | 1 | The TT NICHE taxonomy (~40K entries), paged. **TikTok does NOT have a topics taxonomy, and does NOT expose a per-brand sponsorship endpoint.** `search`, `minChannelCount`, `pageSize`, `offset`. |
288 
289## Cross-platform differences cheat-sheet
290 
291| Dimension | YouTube | Instagram | TikTok |
292| --- | --- | --- | --- |
293| Creator parameter | `channelId` (UC…) | `uniqueId` (handle) | `uniqueId` (handle) |
294| Follower field | `totalSubscribers` | `totalFollowers` | `totalFollowers` |
295| Has a topic taxonomy | ✅ `list_youtube_topics` | ❌ | ❌ |
296| Has a niche taxonomy | ✅ `list_youtube_niches` | ✅ `list_instagram_niches` | ✅ `list_tiktok_niches` |
297| Per-creator niches in `/profile` | ✅ | ✅ | ✅ |
298| Per-creator topics in `/profile` | ✅ | ❌ | ❌ |
299| Sponsorship per-brand endpoint | ✅ | ✅ | ❌ |
300| Content types in `/content-detail` | videos + shorts | images + reels | videos |
301| `/content-detail` cost | 3 | 2 | 2 |
302| Performance windows | R20 + all-time (up to 800) | First-page | Recent |
303| Engagement formula | (L+C+V) / subscribers | (L+C) / followers | (L+C+Shares) / followers |
304| Subtitles endpoints | ✅ | ❌ | ❌ |
305| Content-search endpoint | ✅ | ✅ | ✅ |
306| Brand-side sponsor data | ✅ | ✅ | ❌ |
307 
308Niche IDs are **not interchangeable across platforms** — `id_vlog_PeopleBlogs` (YT) and `id_love_All` (IG) live in different namespaces. Niche/topic IDs follow the pattern `id_{slug}_{Category}`, so you can group by category by splitting on the last `_`.
309 
310## Response shape highlights
311 
312These are the fields that aren't obvious from the endpoint name but you'll reach for constantly. All confirmed against live responses.
313 
314### `/profile`
315 
316Shared across YT/IG/TT:
317- `subscriberGrowth: { g7, g30, g90 }` — % change in subscribers/followers over the last 7/30/90 days. Free trend signal — no need to call `performance-history` if you only want the headline number.
318- `hashtags: [{ name, contentCount }]` — hashtags the creator uses (note: `name` carries the `#` on IG/TT).
319- `niches: ["id_vlog_PeopleBlogs", …]` — per-creator niche IDs. To resolve the human-readable name + category + channelCount, cross-reference `list_{platform}_niches`.
320- `relatedCreators` — accounts the platform itself recommends or lists as related to the creator. YT: UC channelIds of channels YouTube recommends alongside this channel's videos, most frequent first. IG/TT: handles, passed through as the platform provides them. On TikTok the list often includes the creator's own handle. Cheap way to expand a seed list.
321- `hasEmail` — whether `get_{platform}_contact` would return an email. Request it via `fields` (0.1 credit) before paying 15 for contact.
322- `isAgencyRepresented` — `true` when CreatorDB has a record of agency representation; `false` also covers creators with no record.
323- `lastPublishTime` / `lastDbUpdateTime` — Unix-ms; pair them to know how stale the snapshot is vs how recently the creator posted.
324- `country` — ISO 3166-1 alpha-3 (e.g. `"USA"`, `"JPN"`). On IG this value is derived from a content classifier rather than a self-declared field, and can occasionally be wrong for creators with multi-country presence — cross-check against `audienceLocations` and the creator's bio if accuracy matters.
325 
326YT-only:
327- `topics: ["id_challenges_Comedy", …]` — coarse topic IDs (~470 universe). Resolve via `list_youtube_topics`.
328- `totalViews` — lifetime channel views, as shown on the channel's About panel.
329- `joinedDate` — when the channel was created (Unix ms, day precision).
330- Sponsored video / shorts CPM and rate bands (`videoPrice`, `shortsPrice`) are no longer on profile; they're on `get_youtube_performance`.
331- `categoryBreakdown: [{ category, share }]` — share of recent content by YouTube native category.
332- `hasMemberOnlyContents` — boolean.
333 
334IG-only:
335- `isBusinessAccount`, `isPrivateAccount` — flags worth checking before promising audience data; private accounts can't be scraped.
336- `otherLinks` — bio links array.
337- `imageLastPublishTime` / `reelsLastPublishTime` — latest image post and latest reel (Unix ms); `lastPublishTime` is the later of the two.
338 
339TT-only:
340- `otherLinks` — bio link (TikTok allows one).
341- `joinedDate` — when the account was created (Unix ms).
342 
343### `/audience`
344 
345Identical shape across platforms:
346- `audienceLocations: [{ country, share }]` — top 6 countries with shares summing to roughly 1.0.
347- `audienceGender: { maleRatio, femaleRatio }` — sums to ~1.0; binary split only.
348- `audienceAvgAge` — integer.
349- `audienceAgeBreakdown: [{ ageRange, share }]` — fixed buckets `13-17 | 18-24 | 25-34 | 35-44 | 45-54 | 55-64 | 65+`. Always 7 entries; placeholder rows are all-zero (see footgun list below).
350 
351### `/performance`
352 
353The R20-vs-all distinction is YT-only:
354- YT returns four sibling objects: `videosPerformanceRecent`, `videosPerformanceAll`, `shortsPerformanceRecent`, `shortsPerformanceAll`. "Recent" = R20 (last 20). "All" = up to 800. Each has `likes/comments/views` (with `avg/median/min/max/percentile25/percentile75/iqr`) and an `engagement` block.
355- IG returns `imagesPerformanceRecent` + `reelsPerformanceRecent`. No all-time window.
356- TT returns `videosPerformanceRecent`. No all-time window.
357- Every `engagement` block ends with `engagementConsistency: { cv, medianVsMean, topBottomRatio, consistencyScore, consistencyLevel }`. `consistencyScore` is 0–100; `consistencyLevel` is `"high"` (81–100), `"moderate"` (51–80), or `"low"` (0–50). Requires ≥6 content pieces, otherwise the consistency block is absent.
358- `ranking` block carries `global`, `country`, `language` percentile ranks for `totalSubscribers`/`totalFollowers` and `avgEngagementRate` — useful for "is this creator above average for their country" without separate benchmarking.
359- `recentVideosGrowth.g7/g30/g90` — engagement-rate delta over 7/30/90 days. Negative numbers mean engagement is declining.
360- `contentCountByDays: { 7d, 30d, 90d }` — how many posts in each window (use to detect dormant creators).
361 
362### `/content-detail`
363 
364Per-item objects across platforms:
365- `publishTime` (Unix-ms), `contentId`, `likes`, `comments`, `views` (YT/TT only — IG images have no view count), `engagementRate` (rounded to 4 decimals).
366- `hashtags: ["#example", …]` — already includes `#` prefix.
367 
368Platform-specific extras:
369- YT: `length` (seconds), `isMemberOnly`, content mix includes both videos and shorts.
370- IG: `mentionedCreators` — `@`-mentions in caption.
371- TT: `audioId`, `audioTitle`, `audioAuthor`, `audioAlbum`, `isDuetEnabled`, `isAd`, `length` (seconds), `shares`. The audio block is the cheapest way to find trending sounds.
372 
373**Freshness rule** — content published within the last 4 days is excluded from all metric calculations (all platforms). **Pinned-post rule** — on IG/TT, a pinned post older than 90 days is excluded if it would be the oldest item in the sample.
374 
375### `/sponsorship`
376 
377YT and IG only — TikTok does not have a per-brand sponsorship endpoint.
378- `sponsorList: [{ brandName, brandId, brandIgIds, sponsoredVideos, sponsoredVideosPerformance }]`.
379- `brandIgIds` — the brand's IG handles. Use this to follow a brand from a sponsored creator back to the brand's own profile.
380- `sponsoredVideos` includes each sponsored content's full per-item engagement (same shape as `/content-detail`).
381- **Important caveat** — only scans the most recent ~20–30 posts and only detects brands already indexed in CreatorDB. An empty `sponsorList` is **not** proof the creator has no sponsors; it's "we didn't find indexed sponsors in their recent posts."
382 
383### Search (`search_{platform}` and `search_creators_nls`)
384 
385Structured search response:
386- `creatorList: [{ displayName, uniqueId, channelId (YT only), avatarUrl, totalSubscribers | totalFollowers }]` — minimal projection; hydrate with `get_*_profile` for full data.
387- `totalResults` — total matching the filter set, not just the page.
388- `hasNextPage` + `nextOffset` — pagination idiom. Pass `nextOffset` as the next request's `offset` to advance.
389 
390NLS response:
391- Same `creatorList` shape as structured search, plus a `platform: "youtube" | "instagram" | "tiktok"` field telling you which platform the AI routed to.
392- Streamed over SSE under the hood; the MCP layer collects the final `data:` event and returns it as one payload.
393- Dynamic pricing — typically 1–10 credits depending on input + output token count.
394 
395### `/usage`
396 
397- `records: [{ date (YYYYMMDD), requestCount, totalQuotaUsed, endpoints: { …per-endpoint counts }, platforms: { …per-platform counts }, quotaByPlatform }]`.
398- `totalQuotaUsed` can be fractional (e.g. 4.49 for an NLS call).
399- `endpoints` keys are camelCase: `getYoutubeProfile`, `getInstagramAudience`, `searchYoutube`, `getNLS`, etc. Useful for building a spend dashboard.
400 
401## Common footguns
402 
403- **Placeholder demographics**: when CreatorDB doesn't have real audience data, `/audience` returns the all-zero shape (`audienceGender: { maleRatio: 0, femaleRatio: 0 }`, age buckets all 0.0). Treat any row where male+female=0 as missing, not as "no gender data."
404- **Empty `sponsorList` ≠ no sponsors** (see above).
405- **`relatedCreators` is unranked** — order is not significance. Don't slice the first N and call them "top related"; sample or rerank by your own metric.
406- **Freshness lag** — `lastDbUpdateTime` is when CreatorDB last refreshed. If it's older than ~14 days, the profile may not reflect recent breakout content.
407- **Niche channelCount drifts** — `list_*_niches` is updated daily; don't cache it longer than that or your "creators in X niche" count will lag reality.
408- **Search the taxonomy, don't page it** — `list_*_niches` returns one page at a time (100 by default, largest first) because the full taxonomies run to ~40,000 entries on Instagram and TikTok. Both are a single flat "All" category with no structure to browse, and the top 100 entries account for only ~18% of creator assignments, so paging rarely gets you anywhere. Pass `search` to resolve a phrase to niche names instead. Matching is whole-word, so `skin` will not find `Skincare`; CamelCase names are split (`StreetFood` matches `street food`) and common variants are folded (`vloggers`→`vlog`, `japanese`→`japan`). On TikTok ~44% of niches have under 100 creators — `minChannelCount` trims that tail.
409- **IG `country` is modelled, not self-declared** — YouTube and TikTok return the country a creator set on their own profile; for Instagram, CreatorDB's location model supplies it, so IG has country coverage where the profile states nothing.
410 
411## Filter reference (search tools)
412 
413Common fields across all three platforms:
414- `displayName` — string, supports fuzzy
415- `uniqueId` — string, exact
416- `country` — string, ISO 3166-1 alpha-3 (e.g. `"USA"`, `"JPN"`, `"GBR"`)
417- `mainLanguage` — string, ISO 639-3 (e.g. `"eng"`, `"jpn"`, `"zhs"`)
418- `hashtags` — string (with `#` prefix on IG/TT)
419- `niches` — string (use IDs from the platform's `list_*_niches`)
420- `mainAudienceLocation` / `mainAudienceAge` / `mainAudienceGender` — string
421- `hasSponsors` — boolean
422 
423Platform-specific:
424- YouTube: `totalSubscribers` (number), `topics` (string from `list_youtube_topics`)
425- Instagram / TikTok: `totalFollowers` (number)
426 
427Operators: `>`, `<`, `=` for numbers; `=`, `in` for strings; `=` for booleans. `in` takes an array of up to 100 values. `pageSize` max 100; `filters` max 10 per request.
428 
429## Response envelope
430 
431Every tool returns the underlying CreatorDB V3 envelope:
432 
433```json
434{
435 "data": { },
436 "creditsUsed": 2,
437 "creditsAvailable": 953270.5,
438 "traceId": "abc-123",
439 "timestamp": 1779722787120,
440 "errorCode": "",
441 "errorDescription": "",
442 "success": true
443}
444```
445 
446On error, the envelope carries `errorCode`, `error`, `message`, and `details`. The MCP layer flattens that into a clean error message with a `TraceId:` line for support.
447 
448## Development
449 
450```bash
451npm run dev # tsc --watch
452npm run build # tsc once
453npm start # node dist/index.js
454```
455 
456Source layout:
457 
458```
459src/
460 index.ts # registers all tools, stdio transport
461 tools/
462 account.ts # 1 tool
463 search.ts # 4 tools (NLS + 3 platform creator searches)
464 youtube.ts # 12 tools
465 instagram.ts # 9 tools
466 tiktok.ts # 9 tools (incl. search_tiktok_content)
467 sponsors.ts # 8 tools (brand-side sponsor intelligence)
468 util/
469 api-client.ts # fetch wrapper for REST + SSE
470 response.ts # MCP result formatter (credits, errors)
471```
472 
473## Getting help
474 
475- **Bugs / feature requests / new endpoint coverage**: open an issue at <https://github.com/CreatorDB/creatordb-mcp-server/issues>
476- **API key / data questions**: <[email protected]>
477- **Just trying to install it on your machine?** See [SETUP.md](./SETUP.md) — a 5-minute guide aimed at end users rather than contributors.
478 
479## License
480 
481MIT
482 

Discussion

Alternatives