Answers
How do I give a LangChain or LangGraph agent social media data tools?
Short answer
Either wrap the endpoints you need as LangChain tools that call okdata over HTTP, or load the okdata MCP server with langchain-mcp-adapters and get find, describe and call tools for all 51 endpoints at once. Only data calls are billed, for example $0.02 per Xiaohongshu search page and $0.006 per X search page.
Pick the shape by how open the task is. A fixed pipeline, say "every morning, search Xiaohongshu for our three product names and summarize the new notes", is best served by one or two hand-written tools: small prompts, predictable calls, nothing for the model to explore. An open research agent that might need Douyin today and X tomorrow is better off with the MCP server, which lets it discover endpoints and prices by itself.
Option 1: a hand-written tool
import os, requests
from langchain_core.tools import tool
API = "https://api.okdata.online"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
@tool
def search_xiaohongshu(query: str, sort: str = "general") -> list[dict]:
"""Search public Xiaohongshu notes. sort is general, latest or popular.
One call returns about 20 notes and is billed once."""
body = requests.get(API + "/v1/xiaohongshu/notes/search", headers=H, timeout=60,
params={"query": query, "sort": sort,
"fields": "id,url,title,text,metrics.likes,author.name"}).json()
if body["code"] != "ok":
# give the model the error so it can fix a parameter or stop
return [{"error": body["code"], "message": body["message"], "retry": body["retry"]}]
return body["data"]["items"]
Return errors as data rather than raising. The retry field tells the model whether trying again makes sense, and failed calls are not charged. The endpoint behind it is Xiaohongshu note search; Douyin video search and X post search work the same way with their own paths.
Option 2: the MCP server through langchain-mcp-adapters
import os
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient({
"okdata": {
"transport": "streamable_http",
"url": "https://api.okdata.online/mcp",
"headers": {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"},
}
})
tools = await client.get_tools() # find, describe, call, account
Pass tools to create_agent or a LangGraph ToolNode like any other tools. find and describe are free, so the agent can read the price of an endpoint before it calls it.
What a research run costs
| Run | Calls | Cost |
|---|---|---|
| 3 Xiaohongshu searches | 3 | $0.06 |
| 3 Douyin searches | 3 | $0.06 |
| 5 pages of X search | 5 | $0.03 |
| One mixed run with all of the above | 11 | {{cost:xiaohongshu.notes.search3+douyin.videos.search3+x.posts.search*5}} |
Things to set before it runs unattended
- A step limit. LangGraph's
recursion_limit(ormax_iterationson older agents) is your cheapest guard against a loop that keeps paging. - Small results. Ask for
fieldsso each tool result stays a few kilobytes; see view and fields. - Untrusted text. Captions, notes and comments come from strangers. Tell the model they are data, and keep tools that send messages or spend money behind a human check.
- Safe retries. Over HTTP, send an
Idempotency-Key; over MCP, passidempotency_keytocall. A repeat within 24 hours returns the stored result for free.
Alternatives
LangChain's community loaders, such as the YouTube loader, are free and fine on a laptop, but many depend on scraping libraries that break or get blocked on cloud IPs. Official platform APIs are the right choice where they exist and cover your use, as with the YouTube Data API for search metadata. For Douyin and Xiaohongshu, there is no official public data API to fall back on. Client setups for other frameworks are on the MCP page.
Updated