Social Fetch provides a hosted MCP server with OAuth, plus /llms.txt and /llms.json for agent orientation. Add the server URL to Cursor or Claude, complete OAuth, and tell the agent to read llms.txt before writing integration code. Use nl_ask_post to explore; pin typed tools once you know the route. Endpoint tools bill like REST; docs tools are free. Optional: install the Agent Skills pack so the harness loads Social Fetch onboarding without pasting a prompt every time.
You'll need a Social Fetch account, credits for metered routes (Pricing), and an MCP client that supports remote Streamable HTTP with OAuth — Cursor, VS Code, Claude Code, or Claude Desktop. Product overview: MCP. Reference docs: MCP integration.
Who this is for
- Developers using Cursor or Claude to scaffold social-data features while coding.
- Teams building agent workflows that need live TikTok, YouTube, Reddit, or Instagram JSON — not HTML to parse.
- Anyone who wants the agent to pick the right endpoint instead of guessing field names from training data.
If you are wiring a custom orchestrator (LangChain, Vercel AI SDK, your own runtime), the function-calling and error-handling sections apply even without MCP — register REST routes as tools and use the same response envelope.
MCP vs REST vs llms.txt
| Surface | Purpose | Auth | Credits |
|---|---|---|---|
| REST / SDK | Production integrations | x-api-key | Per endpoint |
| MCP tools | Agent-driven lookups while building | OAuth | Same as REST for endpoint tools |
| llms.txt | Orientation — what to read, in what order | None (public) | Free |
| llms.json | Full structured operation inventory | None (public) | Free |
The MCP server exposes 154 endpoint tools (one per public API route) plus docs_search and docs_read. Tool names mirror OpenAPI operation IDs with dots replaced by underscores — tiktok.profile.get becomes tiktok_profile_get, reddit.search.get becomes reddit_search_get.
| MCP tool | REST equivalent | Notes |
|---|---|---|
tiktok_profile_get | GET /v1/tiktok/profiles/{handle} | 1 credit on completed lookup |
nl_ask_post | POST /v1/ask | 0 credits to route; nested lookup bills normally |
billing_balance_get | GET /v1/balance | Free — check before large batches |
docs_search | — | Free — search live docs |
auth_whoami | GET /v1/whoami | Free — confirm OAuth session |
MCP is for building. Production traffic should use @socialfetch/sdk or fetch with an API key — same JSON shapes, different auth surface.
Phase 1: Connect MCP in Cursor
Step 1 — Add the server config
Create or edit ~/.cursor/mcp.json for global access, or .cursor/mcp.json in a project repo so teammates share the same config:
No API key goes in this file. The URL is the entire config for remote HTTP MCP.
Step 2 — Restart and open MCP settings
Restart Cursor (or reload the window). Open Settings → MCP and confirm socialfetch appears. Status should show "needs authentication" until you complete OAuth.
One-click install links for Cursor, VS Code, and others: MCP docs.
Step 3 — Complete OAuth
Click Connect or trigger a tool call. Cursor opens your browser to the Social Fetch sign-in page:
- Sign in or create an account.
- Approve MCP access for your client.
- Return to Cursor — the server status should flip to connected.
Credits charge to the account you signed in with, same as REST.
Step 4 — Verify tools load
In Agent chat, ask:
You should see endpoint tools (tiktok_profile_get, reddit_search_get, …) plus docs_search, docs_read, nl_ask_post, and billing_balance_get. If the list is empty, see Troubleshooting.
Step 5 — Optional project rules
Add a Cursor rule (.cursor/rules/social-fetch.mdc or project instructions) so every session starts oriented:
Phase 2: Connect MCP in Claude
Claude Code (terminal agent)
Then inside a Claude Code session:
Select Social Fetch and complete the browser OAuth flow. Test with:
Claude Desktop
- Open Settings → Connectors (or Developer → Edit Config depending on version).
- Add a custom remote MCP connector.
- Set URL to
https://api.socialfetch.dev/mcp. - Save, restart Claude Desktop if prompted.
- Authorize when Claude first calls a Social Fetch tool.
In a new conversation, enable the Social Fetch connector in the tools panel before sending prompts that need live data.
stdio-only clients
Some older MCP clients only speak stdio. Bridge to the hosted server:
Point your client at the stdio process mcp-remote spawns. OAuth still runs through the browser when the bridge connects.
VS Code
Add to settings.json:
Restart VS Code and complete OAuth when Copilot or your MCP extension prompts you.
OAuth — what actually happens
Social Fetch MCP uses OAuth 2.1. Your client never stores an API key in config.
| Step | What happens |
|---|---|
| 1 | Client discovers the MCP server at https://api.socialfetch.dev/mcp |
| 2 | Client redirects you to Social Fetch sign-in in the browser |
| 3 | You approve access; client receives a short-lived access token |
| 4 | Every tool call sends Authorization: Bearer <token> |
| 5 | Metered lookups debit credits on your signed-in account |
Token expiry: if every call returns 401, reconnect — open MCP settings and re-authenticate. Do not paste a dashboard API key into mcp.json; that is for REST/SDK only.
Team note: OAuth ties to a personal account. For CI or server-side agents, use x-api-key with REST function calling instead of MCP.
Point agents at llms.txt
llms.txt is a ~100-line orientation file: platform coverage, recommended reading order, workflow hints, and links to Quickstart, Credits, and Errors. llms.json lists every operation with method, path, and operation ID — useful when you are registering dozens of function schemas.
To load the same guidance as an installable skill (instead of pasting a prompt each session):
See Agent Skills.
Paste this into your first message or system prompt:
The MCP server also returns workflow instructions in its initialize handshake (docs first, check lookupStatus, call billing_balance_get before batches). Your agent sees this automatically when connected — but llms.txt in Cursor rules catches sessions before the first MCP call.
Example agent prompts
These prompts work in Cursor Agent or Claude with the connector enabled. They assume Social Fetch MCP is connected.
Scaffold a feature with live JSON
Multi-platform creator check
Reddit research while coding
See the Reddit product research guide for a full research sprint.
Docs-driven SDK integration
Pre-flight credit check
Explore with nl_ask_post
When you do not know which typed tool to call, use nl_ask_post — the MCP mirror of POST /v1/ask. Routing costs 0 credits; only the nested lookup bills.
MCP call:
REST equivalent:
TypeScript SDK:
Example response shape:
Pin the typed tool after exploration. Once routedOperation tells you tiktok.profile.get, switch to tiktok_profile_get for repeat calls. Typed tools are faster, more deterministic, and easier to budget.
Use nl_ask_post | Use typed tools |
|---|---|
| First time exploring a question | Production agent loops |
| User speaks in plain English | You know platform + resource |
| Prototyping in chat | Cron jobs, CI, server runtimes |
Discovering routedOperation | Paginated search with cursors |
nl_ask_post is one-shot routing, not a chat endpoint. For Q&A about a single public URL's content, use web_ask_get (GET /v1/web/ask) instead.
Try routing in the Playground or the free Ask tool before wiring it into an agent.
Function calling patterns
Whether you use MCP or register REST routes in a custom runtime, these patterns keep agent loops predictable.
One tool per route
Register tiktok_profile_get, reddit_search_get, and youtube_videos_transcript_get as separate functions. Do not build one mega-tool with a free-text platform field — models pick wrong values and you lose schema validation.
Map OpenAPI operation IDs to tool names the same way MCP does: dots to underscores.
Schema from OpenAPI, not prose
Generate JSON Schema from the OpenAPI spec or copy parameter definitions from llms.json. Required fields (handle, url, query) should be in the schema's required array so the runtime rejects bad calls before they hit the API (pre-send validation is free).
Explore, then pin
Free guardrail tools
| Tool | When to call |
|---|---|
docs_search | Before choosing an endpoint |
docs_read | For full parameter docs on one page |
billing_balance_get | Before parallel batches |
auth_whoami | Confirm OAuth session in a new chat |
Parallel fan-out
Agents often fire ten profile lookups at once. That is fine if you have ten credits — there are no request quotas on paid metered routes; credits are the only limit. Under extreme concurrency you may get 503 with Retry-After (not charged). Stay under ~500 concurrent requests for reliability. Sequential pagination with modest concurrency is cheaper and easier to debug.
Pagination in tool loops
Search and list tools return data.page.nextCursor and data.page.hasMore. Teach the agent:
curl -sS \
-H "x-api-key: $SOCIALFETCH_API_KEY" \
"https://api.socialfetch.dev/v1/tiktok/profiles/charlidamelio"Error handling in agent loops
Most agent failures around social data are integration mistakes, not model mistakes. Encode these rules in your system prompt or orchestrator.
HTTP 200 is not always "found"
Profile and post routes return data.lookupStatus on HTTP 200:
lookupStatus | Meaning | Retry? | Charged? |
|---|---|---|---|
found | Data returned | — | Yes |
not_found | Target does not exist | No | Yes |
private | Account exists but is private | No | Yes |
restricted | Post not publicly scrapable (Instagram) | No | Yes |
hidden | List hidden (e.g. TikTok followers) | No | Yes |
Transport and billing errors
| HTTP | error.code | Agent action | Charged? |
|---|---|---|---|
| 400 | bad_request | Fix parameters; do not retry same payload | No |
| 401 | unauthorized | Reconnect OAuth or check API key | No |
| 402 | insufficient_credits | Stop loop; surface to user | No |
| 502 | lookup_failed | Retry with backoff (up to 3×) | No |
| 503 | temporarily_unavailable | Retry with backoff | No |
Always log meta.requestId (or error.requestId) — support can trace the exact lookup.
MCP-specific: read meta at the top level
MCP tool results put meta beside data, not nested under structuredContent. After each call, parse meta.creditsCharged and meta.requestId from the tool JSON your client returns.
Stop conditions for loops
Add explicit guardrails:
- 402 — halt immediately; do not retry.
not_found— record and continue to next item; do not retry the same handle.- Same
requestIdtwice — orchestrator bug; halt. - Credit budget — call
billing_balance_getfirst; stop whencreditsChargedcumulative exceeds your limit.
End-to-end workflow
A typical session building a creator dashboard:
- Orient — agent reads
llms.txtand runsdocs_searchfor "tiktok profile" + "youtube channel". - Explore —
nl_ask_postwith "YouTube subscribers for @mrbeast" → learnsyoutube.channel.get. - Prototype — parallel MCP calls:
tiktok_profile_get,youtube_channel_get,instagram_profile_getwith handlemrbeast. Agent inspects real JSON. - Implement — you merge SDK code the agent scaffolds:
- Validate — run the same handles in the Playground and compare
requestIdif numbers disagree. - Ship — production uses API key; MCP stays in dev.
import { SocialFetchClient } from "@socialfetch/sdk";
const client = new SocialFetchClient({
apiKey: process.env.SOCIALFETCH_API_KEY!,
});
const handle = "mrbeast";
const [tiktok, youtube, instagram] = await Promise.all([
client.tiktok.getProfile({ handle }),
client.youtube.getChannel({ handle }),
client.instagram.getProfile({ handle }),
]);
for (const result of [tiktok, youtube, instagram]) {
if (!result.ok) {
console.error(result.error.code, result.error.requestId);
continue;
}
console.log(result.value.data.lookupStatus, result.value.meta.creditsCharged);
}Move from MCP to production SDK
| Concern | MCP (dev) | SDK (prod) |
|---|---|---|
| Auth | OAuth browser flow | x-api-key env var |
| Where it runs | Cursor, Claude Desktop | Your server, CI, cron |
| Tool discovery | Automatic | You import typed methods |
| Billing account | Developer who OAuth'd | API key owner |
Copy field paths verbatim from MCP responses into your types. data.profile.metrics.followers in MCP is the same path in SDK result.value.data.
Do not deploy MCP inside a server runtime — use REST. For no-code workflows with API keys, see n8n integration.
Billing and credits
- Endpoint tools (MCP or REST): billed per completed lookup — see Credits.
nl_ask_postrouting: 0 credits;meta.creditsChargedreflects the nested lookup only.not_found/privateon HTTP 200: still charged — the lookup completed.- Pre-send validation errors,
lookup_failed,503: not charged. docs_search,docs_read,auth_whoami,billing_balance_get: no lookup credits.- 100 free credits on signup — Pricing.
Agent loop math: 5 creators × 3 platforms = 15 credits if every lookup completes. Add pagination credits per page. Call billing_balance_get before fan-out.
Troubleshooting
401 on every MCP call
Token expired or OAuth incomplete. Open MCP settings → reconnect → finish browser sign-in.
OAuth redirect loop
Complete sign-in at app.socialfetch.dev, then click Approve to return to your client. Disable aggressive popup blockers for the OAuth window.
402 insufficient_credits
Top up in Credits & billing. Teach the agent to stop on 402 instead of retrying.
Empty tool list after connect
Restart the client. Check mcp.json URL is exactly https://api.socialfetch.dev/mcp (no trailing path).
Agent keeps retrying not_found
Add a rule: "lookupStatus: not_found is a valid outcome — never retry." See Errors.
Wrong platform routed from nl_ask_post
Be specific: "TikTok followers for @handle" not "followers for handle". Pin the typed tool once you know the route.
MCP works but SDK returns different numbers
Point-in-time snapshots differ. Compare requestId in Playground vs your logs.
stdio client cannot connect
Use npx mcp-remote https://api.socialfetch.dev/mcp as a bridge.
FAQ
See the questions in frontmatter above. Quick pointers: OAuth for MCP (not API keys in config); llms.txt first; nl_ask_post until you know the route; treat not_found as final (no retries); ship production with the SDK or REST, not MCP.
Next steps: MCP · MCP integration · AI agents use case · llms.txt · Playground · Pricing