General

How to Use Social Fetch with Cursor & Claude (MCP + llms.txt) (2026)

Connect Cursor, VS Code, or Claude to Social Fetch via MCP — OAuth tools for every endpoint, llms.txt for agent orientation, and the same credit billing as the REST API.

Social FetchUpdated

How to Use Social Fetch with Cursor & Claude (MCP + llms.txt) (2026)

Connect Cursor, VS Code, or Claude to Social Fetch via MCP — OAuth tools for every endpoint, llms.txt for agent orientation, and the same credit billing as the REST API.

Coding agents ship faster when they can call live APIs as tools and read your docs without you pasting OpenAPI fragments into chat. Social Fetch provides a hosted MCP server with OAuth, plus /llms.txt and /llms.json written for agent orientation.

This guide walks through setup in Cursor and Claude, example prompts that work, how to prototype with nl_ask_post (the MCP wrapper for POST /v1/ask), and how to teach your agent loop to handle Social Fetch errors without burning credits on retries.

The short version

Add https://api.socialfetch.dev/mcp to Cursor or Claude, complete OAuth in the browser, 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.

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. 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

SurfacePurposeAuthCredits
REST / SDKProduction integrationsx-api-keyPer endpoint
MCP toolsAgent-driven lookups while buildingOAuthSame as REST for endpoint tools
llms.txtOrientation — what to read, in what orderNone (public)Free
llms.jsonFull structured operation inventoryNone (public)Free

The MCP server exposes 87+ 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 toolREST equivalentNotes
tiktok_profile_getGET /v1/tiktok/profiles/{handle}1 credit on completed lookup
nl_ask_postPOST /v1/ask0 credits to route; nested lookup bills normally
billing_balance_getGET /v1/balanceFree — check before large batches
docs_searchFree — search live docs
auth_whoamiGET /v1/whoamiFree — 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:

{
  "mcpServers": {
    "socialfetch": {
      "url": "https://api.socialfetch.dev/mcp"
    }
  }
}

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:

  1. Sign in or create an account.
  2. Approve MCP access for your client.
  3. 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:

List the Social Fetch MCP tools you have access to. Then call auth_whoami and show the result.

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:

Before implementing Social Fetch API calls:
1. Read https://www.socialfetch.dev/llms.txt
2. Use docs_search / docs_read MCP tools for parameter details
3. Prefer typed MCP tools over nl_ask_post once the route is known
4. Log meta.requestId on every response
5. Check data.lookupStatus before assuming a profile was found

Phase 2: Connect MCP in Claude

Claude Code (terminal agent)

claude mcp add --transport http socialfetch https://api.socialfetch.dev/mcp

Then inside a Claude Code session:

/mcp

Select Social Fetch and complete the browser OAuth flow. Test with:

Use the socialfetch MCP server. Call billing_balance_get and report my credit balance.

Claude Desktop

  1. Open Settings → Connectors (or Developer → Edit Config depending on version).
  2. Add a custom remote MCP connector.
  3. Set URL to https://api.socialfetch.dev/mcp.
  4. Save, restart Claude Desktop if prompted.
  5. 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:

npx mcp-remote https://api.socialfetch.dev/mcp

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:

{
  "mcp": {
    "servers": {
      "socialfetch": {
        "url": "https://api.socialfetch.dev/mcp"
      }
    }
  }
}

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.

StepWhat happens
1Client discovers the MCP server at https://api.socialfetch.dev/mcp
2Client redirects you to Social Fetch sign-in in the browser
3You approve access; client receives a short-lived access token
4Every tool call sends Authorization: Bearer <token>
5Metered 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.

Paste this into your first message or system prompt:

Read https://www.socialfetch.dev/llms.txt before implementing Social Fetch API calls.
Use https://www.socialfetch.dev/llms.json when you need the full operation inventory.
For parameter details, use the docs_search and docs_read MCP tools — not training data.

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

I need TikTok profile lookup in this Express app.

1. Read llms.txt and docs_search for "tiktok profile"
2. Call tiktok_profile_get with handle "nike" and show me the response shape
3. Add a GET /creators/:handle route using @socialfetch/sdk with the same fields
4. Handle lookupStatus found, private, and not_found explicitly

Multi-platform creator check

Compare @mrbeast across TikTok, YouTube, and Instagram.

Call the profile tools for each platform in parallel. Build a markdown table:
platform, handle, followers/subscribers, lookupStatus, creditsCharged per call.
If any call returns not_found, say so — do not retry.

Reddit research while coding

I'm building a competitor research script. Use reddit_search_get with
query "switching from notion", sortBy top, timeframe year. Paginate one page.
Show the top 5 posts by score with title, subreddit, url.
Then scaffold a TypeScript function that does the same via the SDK.

See the Reddit product research guide for a full research sprint.

Docs-driven SDK integration

Use docs_search to find how Instagram post lookup handles restricted content.
Read the full page with docs_read. Then add client.instagram.getPost to this
service with proper lookupStatus handling for found, not_found, and restricted.

Pre-flight credit check

I need follower counts for these 20 TikTok handles: [list].

First call billing_balance_get. If balance < 20, stop and tell me.
Otherwise fetch profiles sequentially and log requestId + creditsCharged per handle.

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:

{ "query": "How many TikTok followers does MrBeast have?" }

REST equivalent:

curl -sS \
  -H "x-api-key: $SOCIALFETCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "How many TikTok followers does MrBeast have?"}' \
  "https://api.socialfetch.dev/v1/ask"

TypeScript SDK:

const result = await client.ask({
  query: "How many TikTok followers does MrBeast have?",
});

if (!result.ok) {
  console.error(result.error.code, result.error.requestId);
} else {
  const { routedOperation, lookup } = result.value.data;
  console.log(routedOperation.path, routedOperation.params);
  console.log(lookup.data.lookupStatus, result.value.meta.creditsCharged);
}

Example response shape:

{
  "data": {
    "query": "How many TikTok followers does MrBeast have?",
    "routedOperation": {
      "operationId": "tiktok.profile.get",
      "method": "GET",
      "path": "/v1/tiktok/profiles/{handle}",
      "params": { "handle": "MrBeast" }
    },
    "lookup": {
      "data": { "lookupStatus": "found", "profile": { "...": "..." } },
      "meta": { "requestId": "req_01example", "creditsCharged": 1 }
    }
  },
  "meta": { "requestId": "req_01example", "creditsCharged": 1 }
}

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_postUse typed tools
First time exploring a questionProduction agent loops
User speaks in plain EnglishYou know platform + resource
Prototyping in chatCron jobs, CI, server runtimes
Discovering routedOperationPaginated 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

User question → nl_ask_post → read routedOperation → add typed tool to manifest → drop nl_ask for that workflow

Free guardrail tools

ToolWhen to call
docs_searchBefore choosing an endpoint
docs_readFor full parameter docs on one page
billing_balance_getBefore parallel batches
auth_whoamiConfirm 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 is no published per-route rate cap; your prepaid balance is the ceiling. 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:

Paginate until hasMore is false or I say stop. Pass cursor verbatim — do not construct cursors manually.
Request
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:

lookupStatusMeaningRetry?Charged?
foundData returnedYes
not_foundTarget does not existNoYes
privateAccount exists but is privateNoYes
restrictedPost not publicly scrapable (Instagram)NoYes
hiddenList hidden (e.g. TikTok followers)NoYes
if (result.ok && result.value.data.lookupStatus === "not_found") {
  // Valid outcome — do not retry
  return { status: "missing", requestId: result.value.meta.requestId };
}

Transport and billing errors

HTTPerror.codeAgent actionCharged?
400bad_requestFix parameters; do not retry same payloadNo
401unauthorizedReconnect OAuth or check API keyNo
402insufficient_creditsStop loop; surface to userNo
502lookup_failedRetry with backoff (up to 3×)No
503temporarily_unavailableRetry with backoffNo
async function callWithRetry<T>(fn: () => Promise<Result<T>>, requestId?: string) {
  for (let attempt = 0; attempt < 3; attempt++) {
    const result = await fn();
    if (result.ok) return result;

    const retryable =
      result.error.code === "lookup_failed" ||
      result.error.code === "temporarily_unavailable";

    if (!retryable) return result;

    await sleep(500 * 2 ** attempt);
  }
  return fn();
}

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:

  1. 402 — halt immediately; do not retry.
  2. not_found — record and continue to next item; do not retry the same handle.
  3. Same requestId twice — orchestrator bug; halt.
  4. Credit budget — call billing_balance_get first; stop when creditsCharged cumulative exceeds your limit.

End-to-end workflow

A typical session building a creator dashboard:

  1. Orient — agent reads llms.txt and runs docs_search for "tiktok profile" + "youtube channel".
  2. Explorenl_ask_post with "YouTube subscribers for @mrbeast" → learns youtube.channel.get.
  3. Prototype — parallel MCP calls: tiktok_profile_get, youtube_channel_get, instagram_profile_get with handle mrbeast. Agent inspects real JSON.
  4. Implement — you merge SDK code the agent scaffolds:
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);
}
  1. Validate — run the same handles in the Playground and compare requestId if numbers disagree.
  2. Ship — production uses API key; MCP stays in dev.
Example
typescript
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

ConcernMCP (dev)SDK (prod)
AuthOAuth browser flowx-api-key env var
Where it runsCursor, Claude DesktopYour server, CI, cron
Tool discoveryAutomaticYou import typed methods
Billing accountDeveloper who OAuth'dAPI 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_post routing: 0 credits; meta.creditsCharged reflects the nested lookup only.
  • not_found / private on 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

Do MCP tool calls cost credits?

Yes for endpoint tools, same as REST. docs_search, docs_read, auth_whoami, and billing_balance_get are free.

Do I paste an API key into MCP config?

No — OAuth for MCP; API keys for REST/SDK from API keys.

What should my agent read first?

llms.txt, then Quickstart and endpoint reference pages. Use MCP docs tools for parameters.

When should I use nl_ask_post instead of a typed tool?

When you do not know the route yet. After you have routedOperation, switch to the explicit tool.

Why did my agent retry not_found five times?

not_found is HTTP 200 with a completed lookup. Add explicit stop conditions in your prompt or orchestrator.

Can I use MCP in production?

No — MCP targets dev agents. Ship with the SDK or REST and an API key.


Next steps: MCP integration · AI agents use case · llms.txt · Playground · Pricing