by OneInterface
Open-source cookbook for the Stormy Social Data API and MCP server (Model Context Protocol) — one REST API for the TikTok API, YouTube API, Instagram API, LinkedIn API, X (Twitter) API and Reddit API. Search creators, resolve profiles, read posts and find verified emails from Claude, Cursor, Codex, ChatGPT or curl. One key, no scrapers.
# Add to your Claude Code skills
git clone https://github.com/OneInterface/stormy-cookbookGuides for using ai agents skills like stormy-cookbook.
Last scanned: 7/28/2026
{
"issues": [
{
"file": "README.md",
"line": 105,
"type": "secret-exfiltration",
"message": "Instruction appears to send credentials/secrets to an external endpoint",
"severity": "medium"
},
{
"file": "README.md",
"line": 126,
"type": "secret-exfiltration",
"message": "Instruction appears to send credentials/secrets to an external endpoint",
"severity": "medium"
},
{
"file": "README.md",
"line": 152,
"type": "secret-exfiltration",
"message": "Instruction appears to send credentials/secrets to an external endpoint",
"severity": "medium"
}
],
"status": "PASSED",
"scannedAt": "2026-07-28T06:26:06.773Z",
"npmAuditRan": true,
"pipAuditRan": true,
"promptInjectionRan": true
}stormy-cookbook is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by OneInterface. Open-source cookbook for the Stormy Social Data API and MCP server (Model Context Protocol) — one REST API for the TikTok API, YouTube API, Instagram API, LinkedIn API, X (Twitter) API and Reddit API. Search creators, resolve profiles, read posts and find verified emails from Claude, Cursor, Codex, ChatGPT or curl. One key, no scrapers. It has 59 GitHub stars.
Yes. stormy-cookbook passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/OneInterface/stormy-cookbook" and add it to your Claude Code skills directory (see the Installation section above).
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh stormy-cookbook against similar tools.
No comments yet. Be the first to share your thoughts!
Open-source, copy-pasteable recipes for the Stormy Social Data API and the Stormy MCP server (Model Context Protocol, Streamable HTTP).
One HTTP contract — search, profile, emails, jobs — across six social networks. No proxy pool, no six vendor SDKs, no scraper to babysit. Point your agent at https://stormy.ai/mcp, or curl the REST base at https://stormy.ai/api/v1.
Jump to: Recipes · MCP quickstart · REST quickstart · Endpoints · Pricing · Errors · FAQ
Every "get social data" project starts the same way: six different APIs, six auth schemes, six rate limits, six response shapes, and a scraper that breaks on a Tuesday. Then you bolt an LLM on top and discover none of it is shaped for an agent — no cost signal, no idempotency, no durable jobs, no machine-readable capability list.
Stormy is that layer, already built. This cookbook is how you use it.
The Stormy MCP server speaks Streamable HTTP at https://stormy.ai/mcp and authenticates with an HTTP bearer token. Get a key at stormy.ai/account and export it:
export STORMY_API_KEY="stm_live_..." # never commit this
claude mcp add --transport http stormy https://stormy.ai/mcp \
--header "Authorization: Bearer $STORMY_API_KEY"
~/.codex/config.toml)[mcp_servers.stormy]
url = "https://stormy.ai/mcp"
bearer_token_env_var = "STORMY_API_KEY"
mcp.json client{
"mcpServers": {
"stormy": {
"url": "https://stormy.ai/mcp",
"headers": {
"Authorization": "Bearer ${STORMY_API_KEY}"
}
}
}
}
Name: Stormy Social Data
MCP URL: https://stormy.ai/mcp
Authentication: OAuth
| Tool | What it does |
|---|---|
search_people(platform, query, limit=10, fresh=false) |
Search one network from a natural-language query |
lookup_profile(target, platform=null, fresh=false, include_posts=false) |
Resolve a URL / @handle / channel ID to a normalized profile |
find_emails(platform, targets) |
Verified contact emails for 1–25 Instagram, TikTok or YouTube profiles |
estimate_price(quantity=100, include_email=false) |
Rate card + a maximum estimate, spends nothing |
account_status() |
Plan, remaining prepaid usage, top-up URL |
describe_social_data() |
The machine-readable platform / field / pricing / workflow contract |
start_social_job(operation, arguments, idempotency_key, ...) |
Queue fresh, bulk or email work durably |
get_social_job(job_id) |
Status, progress, poll_after_seconds, result, full timeline |
list_social_jobs(status=null, limit=20) |
Recover prior work instead of resubmitting |
cancel_social_job(job_id) |
Cancel queued / scheduled / throttled / retrying work |
Then just ask:
Find 25 TikTok creators posting about home espresso, pull their follower counts, and tell me what it cost.
Base URL: https://stormy.ai/api/v1 (also reachable at https://api.stormy.ai/api/v1).
Auth: Authorization: Bearer <key> or X-API-Key: <key>. Never put a key in a URL, a JSON body, a prompt, or an MCP tool argument.
curl -X POST 'https://stormy.ai/api/v1/search' \
-H "Authorization: Bearer $STORMY_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: espresso-tiktok-2026-07' \
-d '{
"platform": "tiktok",
"query": "home espresso and coffee gear creators",
"limit": 25,
"fresh": true
}'
import os
import requests
response = requests.post(
"https://stormy.ai/api/v1/search",
headers={
"Authorization": f"Bearer {os.environ['STORMY_API_KEY']}",
"Idempotency-Key": "espresso-tiktok-2026-07",
},
json={
"platform": "tiktok",
"query": "home espresso and coffee gear creators",
"limit": 25,
"fresh": True,
},
timeout=90,
)
response.raise_for_status()
payload = response.json()
for creator in payload["results"]:
print(creator["handle"], creator["follower_count"])
print("cost:", payload["usage"]["cost_usd"], "USD")
const response = await fetch("https://stormy.ai/api/v1/search", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.STORMY_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "espresso-tiktok-2026-07",
},
body: JSON.stringify({
platform: "tiktok",
query: "home espresso and coffee gear creators",
limit: 25,
fresh: true,
}),
});
if (!response.ok) throw new Error(await response.text());
const { results, usage } = await response.json();
console.log(results.length, "creators for", usage.cost_usd, "USD");
{
"ok": true,
"platform": "tiktok",
"query": "home espresso and coffee gear creators",
"fresh": true,
"results": [
{
"id": "6812...",
"handle": "@homebarista",
"nickname": "Home Barista",
"url": "https://tiktok.com/@homebarista",
"signature": "Espresso at home, no snobbery.",
"verified": false,
"follower_count": 184000,
"following_count": 312,
"likes_count": 4210000,
"video_count": 612
}
],
"usage": {
"operation": "fresh_discovery",
"metered_results": 25,
"billed_results": 25,
"cost_usd": "2.00",
"credits": 200,
"plan": "paid",
"remaining_usage_usd": "23.00"
}
}
Every successful response carries a usage receipt. You are billed for outcomes, not requests.
| Network | POST /search |
POST /profile |
include_posts |
POST /emails |
Public fields |
|---|---|---|---|---|---|
| TikTok API | Creators by niche | @handle or URL |
Videos, views, shares, saves, music, hashtags | ✅ verified email | 27 |
| YouTube API | Channels by topic | Handle or channel ID | Videos, transcripts, captions | ✅ verified email | 25 |
| Instagram API | Creators by niche | Username or URL | Posts, captions, engagement, location | ✅ verified email | 23 |
| X (Twitter) API | Accounts and posts | @handle or URL |
Posts, views, bookmarks, conversation ID | — | 26 |
| LinkedIn API | People and companies | Profile URL | Posts, reaction breakdowns, cadence | — | 31 |
| Reddit API | Threads by topic | Author karma and age | Score, upvote ratio, comment count | — | 17 |
Field lists are authoritative in GET /api/v1/capabilities → fields_by_platform. Treat every platform-specific field as nullable — you get it when it is public and the source supplied it.
TikTok — profile: id, sec_uid, handle, nickname, url, signature, avatar_url, verified, follower_count, following_count, likes_count, video_count · posts: video_id, url, description, create_time, duration, views, likes, comments, shares, saves, image_url, is_pinned, music, hashtags, caption_url
YouTube — profile: channel_id, handle, name, url, subscribers, description, videos_count, total_views, profile_image_url, banner_image_url, country, keywords, links · posts: video_id, url, title, description, published_at, duration, views, likes, comments, thumbnail_url, transcript, caption_url
Instagram — profile: username, full_name, biography, profile_pic_url, follower_count, following_count, posts_count, avg_engagement_rate, biolinks, country, is_verified, is_business_account, business_category_name · posts: media_id, post_url, caption, taken_at, like_count, comment_count, image_url, location, location_data, comments
X (Twitter) — profile: id, handle, name, url, description, profile_image_url, verified, location, website, followers, following, posts_count, joined_at · posts: id, url, text, created_at, language, likes, replies, reposts, quotes, views, bookmarks, conversation_id, author
LinkedIn — profile: id, name, linkedin_url, headline, country, country_iso_2, followers, total_posts, posts_last_6_months, posting_frequency, avg_likes, `a