Skip to main content

Threads MCP

CI

An MCP server that gives Claude (or any MCP client) access to Threads through your own logged-in browser. Search posts by keyword and get the top results with their likes, replies and reposts, read your feed, profiles and replies, work with your DMs, and draft posts, all from your AI assistant.

Everything runs on your machine. There is no Meta developer app, no API key, and no third-party server: the tool drives a dedicated Chrome profile that only you log in to.

Independent open-source project, not affiliated with Meta or Threads. Threads is a trademark of Meta Platforms, used here only to identify the service this software works with. Automated use of Threads may conflict with its terms; use it at a low, personal volume and at your own risk.

What you can do

Tool What it does
search_posts Keyword search returning the top posts, ranked by engagement. Top or recent, minimum likes, last N days, and export to JSON, CSV or Markdown.
keyword_insights Analyze a keyword: engagement totals and medians, top authors, best posting hours, media mix, top posts.
search_profiles Find accounts by keyword (name or bio), by relevance or follower count.
get_trending Trending topics on Threads with their AI summary and post counts.
get_feed Posts from your home feed.
get_profile A user's profile: name, bio, followers, links, verified badge.
get_user_posts A user's most recent posts.
get_post One post with its replies.
list_conversations Your DM inbox: who, last message, time, unread.
get_conversation The recent messages in a DM thread, including shared posts.
send_message Send a DM, after you confirm the preview.
create_post Publish a thread (up to 500 characters), after you confirm the preview.
reply_to_post Reply to a post, after you confirm the preview.
session_status Which account the browser is logged in as.
close_session Close the browser without logging out.

Post-returning tools (search_posts, get_feed, get_user_posts, get_post replies) default to format="compact": text trimmed to 280 characters and ids and media links left out, about a third smaller than format="full", which returns every field. Exports always contain full data.

With format="full", every post comes back with the same fields: url, author (username, name, verified), text, created_at (UTC), likes, replies, reposts, quotes, score, media_type, media_urls, is_reply. The score is likes + 2 x replies + 3 x reposts + 2 x quotes.

Requirements

  • macOS, Linux or Windows
  • uv
  • Google Chrome (recommended). Without it, run uvx --from git+https://github.com/sunnycho100/threads-mcp patchright install chromium once and the server uses Chromium instead.
  • A Threads account

Setup

1. Log in once

uvx threads-mcp@latest --login

@latest installs from PyPI and picks up fixes automatically, which matters because Threads changes its pages from time to time. To run the newest unreleased code instead, use uvx --from git+https://github.com/sunnycho100/threads-mcp threads-mcp wherever this README says uvx threads-mcp@latest.

A Chrome window opens on threads.com. Log in (Instagram login works) and the window closes by itself. The session is saved in ~/.threads-mcp/profile, separate from your everyday Chrome.

Check it:

uvx threads-mcp@latest --status
logged in as @your_username
profile: /Users/you/.threads-mcp/profile

2. Add it to your MCP client

Claude Code

claude mcp add threads -- uvx threads-mcp@latest

Or, inside a clone of this repo, the included .mcp.json registers the server automatically.

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows)

{
  "mcpServers": {
    "threads": {
      "command": "uvx",
      "args": ["threads-mcp@latest"],
      "env": { "UV_HTTP_TIMEOUT": "300" }
    }
  }
}

Cursor, Windsurf and other clients use the same command and args in their MCP settings.

Claude Desktop, one-click bundle

git clone https://github.com/sunnycho100/threads-mcp && cd threads-mcp
npx @anthropic-ai/mcpb pack . threads-mcp.mcpb

Open threads-mcp.mcpb with Claude Desktop (double-click, or Settings > Extensions > Install Extension). The install dialog offers a read-only toggle. Run --login once in a terminal first, as above.

Docker

Log in from inside the container with the built-in viewer:

docker build -t threads-mcp https://github.com/sunnycho100/threads-mcp.git
docker run --rm -it -p 127.0.0.1:6080:6080 -v ~/.threads-mcp-docker:/data threads-mcp --login-viewer

Open the printed http://localhost:6080/vnc.html, enter the one-time password it prints, and log in to Threads in the window that appears. The container exits once the session is saved. The viewer listens on localhost only.

Or log in on your computer and move the session in:

uvx --from git+https://github.com/sunnycho100/threads-mcp threads-mcp --export-session ~/threads-session.json
docker run --rm -v ~/.threads-mcp-docker:/data -v ~/threads-session.json:/session.json:ro threads-mcp --import-session /session.json
rm ~/threads-session.json

The exported file holds your login cookies and is created readable only by you; delete it after importing. Then point your client at the container:

{
  "mcpServers": {
    "threads": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-v", "/Users/you/.threads-mcp-docker:/data", "threads-mcp"]
    }
  }
}

Restart the client, then ask something like "search Threads for posts about rust async and show me the top 10".

Examples

Ask in plain language; the assistant picks the tool. The calls below show what it sends.

Top posts for a keyword

search_posts(query="rust async", limit=10)
{
  "query": "rust async", "sort": "top", "count": 10,
  "results": [
    {"url": "https://www.threads.com/@someone/post/DZ6Wq...", "author": {"username": "someone", "full_name": "Some One", "verified": false},
     "text": "...", "created_at": "2026-06-23T02:33:30Z", "likes": 2692, "replies": 334, "reposts": 377, "quotes": 12, "score": 4848,
     "media_type": "image", "media_urls": ["..."], "is_reply": false}
  ]
}

Only popular posts from the last week, saved to a spreadsheet

search_posts(query="indie hacker", min_likes=100, since_days=7, limit=30, export="csv")

The response includes export_path, for example ~/.threads-mcp/exports/search-indie-hacker-20261011-091500.csv. CSV and Markdown files are UTF-8, so Korean, Japanese and emoji come through intact.

Newest posts first

search_posts(query="rust async", sort="recent", limit=20)

What works for a topic

keyword_insights(query="vibe coding", limit=50)

Returns engagement medians, the authors with the most total engagement, the hours (your local time) when the best-performing posts went up, and the media mix.

Who to follow on a topic

search_profiles(query="ios developer", sort="followers", limit=10)

A post and its replies

get_post(url="https://www.threads.com/@someone/post/DZ6WqOxlC-t", reply_limit=20)

DMs

list_conversations()
get_conversation(username="friend_name", limit=20)

Writing, with a confirmation step

create_post(text="Shipping a new side project today")
{"confirm_required": true, "preview": {"action": "create_post", "text": "Shipping a new side project today", "length": 33},
 "note": "Show this preview to the user and call again with confirm=true to proceed."}

Nothing is posted until the assistant shows you the preview and calls again with confirm=true. The same applies to send_message and reply_to_post.

Usernames are accepted as name, @name or a profile URL. Post links work with threads.com or threads.net.

How it works

Threads' web app ships its data as JSON: posts and profiles are embedded in each page, and more arrive through the page's own GraphQL requests as you scroll. The server opens the page in your logged-in profile, collects that JSON, and picks out anything shaped like a post or a user, wherever it sits. It does not replay Meta's internal API calls; it reads what the page itself loads, the way you would by scrolling.

DMs are loaded over a live connection rather than page JSON, so the DM tools read the rendered conversation instead. Posting and replying use the normal composer.

MCP client --stdio--> server.py      tools, confirmations, error messages
                        service.py   search, feed, profiles, posts
                        session.py   one Chrome profile, one page, one task at a time
                        extract.py   finds posts and users in the page JSON
                        ranking.py   score, sort, filter, insights, export
                        dm.py        inbox and conversations
                        compose.py   new posts and replies

Safety

  • Writes need confirmation. send_message, create_post and reply_to_post return a preview and do nothing until called again with confirm=true.
  • Human pace. Scrolls and typing use randomized delays, and only one browser task runs at a time, even when the client calls tools in parallel.
  • Low volume. Every list is capped at 100 items, and a call is a few page loads, not a crawl.
  • Account checks. If Threads shows a checkpoint or account warning, the server stops all browser activity and tells you to resolve it in the app.
  • No social actions. There are no tools for likes, follows, reposts or deletes.
  • Local data. The browser profile and exports live in ~/.threads-mcp. Nothing is sent anywhere except threads.com.

Command line

threads-mcp               run the MCP server over stdio (what clients launch)
threads-mcp --login       open a browser window and sign in
threads-mcp --status      show the logged-in account (exit code 1 if not logged in)
threads-mcp --logout      delete the saved browser profile
threads-mcp --export-session FILE   save the login cookies (owner-only file) for Docker or another machine
threads-mcp --import-session FILE   load cookies saved by --export-session
threads-mcp --no-headless run the server with the browser window visible
threads-mcp --version

Options for the server and login:

Flag Default Meaning
--transport {stdio,streamable-http} stdio Serve over HTTP instead of stdio.
--host, --port 127.0.0.1, 8000 HTTP address; the endpoint is /mcp.
--user-data-dir PATH ~/.threads-mcp/profile Browser profile to use.
--login-timeout SECONDS 900 How long --login waits for you to sign in.
--browser-idle-timeout SECONDS 600 Close an idle browser after this long.
--viewport WxH 1280x900 Browser window size.
--proxy-server URL none Route the browser through a proxy (http://, socks5://).
--slow-mo MS 0 Delay between browser actions, for debugging.
--chrome-path PATH Google Chrome Use a specific Chrome or Chromium executable.

Environment variables:

Variable Default Meaning
THREADS_MCP_HOME ~/.threads-mcp Where the profile and exports live.
THREADS_MCP_HEADLESS 1 Set to 0 to show the browser window.
THREADS_MCP_READONLY 0 Set to 1 to refuse confirmed writes; previews still work. Handy for demos and testing.

The browser closes itself after 10 idle minutes and reopens on the next call.

Troubleshooting

"Not logged in to Threads. Run threads-mcp --login"

The saved session expired or was never created. Run threads-mcp --login (with the same uvx --from ... prefix you use in your client config), log in, then retry.

"The browser profile is in use by another threads-mcp process"

Only one process can use the profile at a time. Another MCP client, a second Claude window, or a --login window has it open. Close that, or call close_session from the client that holds it. Idle servers release it after 10 minutes.

Replies fail with "private profiles can only reply to their followers"

That is a Threads rule. If your profile is private, you can only reply to people who follow you. Reply to a follower's post, or switch your profile to public in the Threads app.

"Threads page error" or empty results

Threads may have changed its page layout. Run threads-mcp --no-headless, call the tool again and watch the window, then open an issue with the tool name and what you saw. Updating (uvx --refresh ...) picks up fixes.

Fewer results than the limit

Threads loads about 7 more posts per scroll after the first 20, and some keywords or profiles simply have fewer posts. Filters like min_likes and since_days are applied after loading, so they can return fewer items than limit.

The first call is slow

The first call starts Chrome (a few seconds). A 30-post search usually takes 10 to 20 seconds. If your client times out, raise its MCP tool timeout.

Chrome is not installed

Run uvx --from git+https://github.com/sunnycho100/threads-mcp patchright install chromium once. The server falls back to that Chromium automatically.

Development

git clone https://github.com/sunnycho100/threads-mcp
cd threads-mcp
uv sync
uv run pytest -q              # unit tests, no browser needed
uv run threads-mcp --login    # once
uv run python scripts/e2e.py  # every tool against your live account
  • Unit tests run against scrubbed fixtures captured from real pages (tests/fixtures/). scripts/scrub_fixture.py turns a raw capture into a fixture, replacing usernames, names, bios, captions and media links.
  • scripts/e2e.py starts the server over stdio with the MCP client and calls every tool. Writes run in dry-run mode: the composer is opened, filled, checked and cancelled. Put your own test keywords in .local/keywords.txt (gitignored, one per line); they are never written to the report. The latest results are in docs/E2E_REPORT.md.
  • Releasing: bump version in pyproject.toml, then uv build and uv publish (needs a PyPI token in UV_PUBLISH_TOKEN). uvx twine check dist/* validates the files first.
  • Design notes: docs/superpowers/specs/2026-10-11-threads-mcp-design.md.
  • How this compares with linkedin-mcp-server, including what is not built yet: docs/LINKEDIN_PARITY.md.

Acknowledgements

The browser-session approach follows stickerdaniel/linkedin-mcp-server, and reading the page's own JSON follows xpzouying/xiaohongshu-mcp.

Metadata

Release files for threads-mcp 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for threads-mcp 0.1.2
File Size Uploaded
threads_mcp-0.1.2.tar.gz 24.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for threads-mcp 0.1.2
File Interpreter ABI Platform
threads_mcp-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 53.4 kB

Release files / threads_mcp-0.1.2.tar.gz

Download URL threads_mcp-0.1.2.tar.gz
Size 24.9 kB
Tags Source
SHA-256 checksum
How to use checksums
992baf728b19fee334f96c864dcf986c48159b3a0bf686baa1a158ae9fec0fe2
BLAKE2b-256 checksum
How to use checksums
5177e3d3c8b278b95e7af05dd9aa3b9a0b1d977e6cab099846f8df67d18f7f56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / threads_mcp-0.1.2-py3-none-any.whl

Download URL threads_mcp-0.1.2-py3-none-any.whl
Size 28.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
baec906254f8ff76da85a3bf2a36f2d04f83ee1d8c65632fd32db230fe5d6f88
BLAKE2b-256 checksum
How to use checksums
eba8588f535feab7b34361f275e7e52ebc877f45170d6202c9b6197d2ed68307
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.1.3

2 release files

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page