Answers

How do I run a Xiaohongshu MCP on a cloud server without a browser?

Short answer

Point the agent at a hosted MCP server instead of running Chrome in your container: okdata at https://api.okdata.online/mcp takes an API key in a header and returns Xiaohongshu results as JSON, so the server needs no browser, no display and no login. A search page costs $0.02 and a full note $0.02; failed calls are free.

Take the browser out of the picture. Self-hosted Xiaohongshu MCP servers run a full Chrome inside the container, logged into your account, and that is where cloud deployments go wrong: searches that hang until a 60-second deadline, containers that shut down when idle, a login that has to be redone by QR code, and a datacenter IP that Xiaohongshu treats with more suspicion than a home connection. The project's issue tracker has reports of exactly these. With a hosted server, your machine makes one HTTPS request and gets JSON back. That runs fine on a 1 GB VPS, a cron job in GitHub Actions or a serverless function.

Two ways to wire it

  • Your agent speaks MCP. Add https://api.okdata.online/mcp as a remote server with an Authorization: Bearer header. The agent gets find, describe and call, and can reach every platform, not only Xiaohongshu. Client configs are on the MCP page.
  • A scheduled job, no agent. Call the HTTP endpoints directly: Xiaohongshu note search and note detail. The script below is what you would put in cron.
import os, time, uuid, requests

API = "https://api.okdata.online"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}

def search(query, sort="latest", tries=3):
    key = str(uuid.uuid4())  # same key on every retry: never billed twice
    for _ in range(tries):
        r = requests.get(API + "/v1/xiaohongshu/notes/search",
                         headers={**H, "Idempotency-Key": key},
                         params={"query": query, "sort": sort,
                                 "fields": "id,url,title,metrics.likes,published_at"},
                         timeout=90)
        body = r.json()
        if body["code"] == "ok":
            return body["data"]["items"]
        if body["retry"] in ("yes", "same_key"):
            time.sleep(body.get("retry_after_seconds") or 5)
            continue
        raise RuntimeError(f"{body['code']}: {body['message']}")
    raise RuntimeError("gave up")

for note in search("露营装备"):
    print(note["metrics"]["likes"], note["title"], note["url"])

What it costs to run on a schedule

Job Calls Cost
20 keywords, first page, once a day 20 a day $0.40 a day
Same job for 30 days 600 $12.00
Plus full text of 10 new notes a day for 30 days 300 $6.00

There is nothing to pay for the server beyond what you already run, since it only waits on HTTP.

Gotchas

  • Set your HTTP timeout to 60 seconds or more. Most calls are quicker, but a slow platform response should not be cut off on your side.
  • A timeout from us comes back as timeout with charged: null. Resend with the same Idempotency-Key and you will get the stored result or a fresh run, never a second charge. The errors page lists every code.
  • Watch X-RateLimit-Remaining if you run many keywords in parallel; a rate_limited reply says how many seconds to wait.
  • Xiaohongshu hides view counts, so metrics.views is always null.

When to keep the self-hosted MCP

If your agent has to publish notes or reply to comments as your account, the browser-based server is still the tool, and a machine on a home connection tends to behave better than a datacenter VM. Keep it for writing and move reading to an API key. For one-off research by hand, the Xiaohongshu app is still the cheapest way to look.

Updated