threads-mcp-cliCAUTION
Threads MCP server and CLI for Claude Code, Codex and AI agents. 30 tools for posting, chained threads, carousels, replies and reply approvals, insights, keyword search and profile discovery.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://www.npmjs.com/package/@thenavidm/threads-mcp-cli) [](./LICENSE) [](https://youtube.com/@thenavidm?sub_confirmation=1) [](https://x.com/thenavidm) [](https://linkedin.com/in/thenavidm)
Threads MCP server and CLI for Claude Code, Codex and AI agents. 30 tools for posting, chained threads, carousels, replies and reply approvals, insights, keyword search and profile discovery.
One install gives you both surfaces, the same tools under the same names, covering everything the app does and several things it cannot.
Threads has its own API, separate from Instagram's, so it needs its own token. One Meta app can carry both, with one app id and one testers list.
Publishing and deleting ask for confirmation. Everything else is a read.
One command to authorise, and the 60-day token refreshes itself from then on.
Built and maintained by Navid Moazzez. Built on Slipway, which turns one definition of each tool into the MCP server and the CLI.
Two ways to use it
Command line
threads-cli in your terminal, for scripting, cron, pipes, or a quick question without opening anything:
threads-cli # every command, one line each threads-cli whoami
69cad3cf9042OBSERVED · 2026-10-11Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add threads-mcp-cli --env THREADS_ACCESS_TOKEN=${THREADS_ACCESS_TOKEN} --env THREADS_APP_SECRET=${THREADS_APP_SECRET} --env THREADS_TOKEN_STORE=${THREADS_TOKEN_STORE} -- npx -y @thenavidm/[email protected]{
"mcpServers": {
"threads-mcp-cli": {
"command": "npx",
"args": [
"-y",
"@thenavidm/[email protected]"
],
"env": {
"THREADS_ACCESS_TOKEN": "${THREADS_ACCESS_TOKEN}",
"THREADS_APP_SECRET": "${THREADS_APP_SECRET}",
"THREADS_TOKEN_STORE": "${THREADS_TOKEN_STORE}"
}
}
}
}Exposed tools (30)
18 read · 11 write · 1 destructive. Blast radius: 1 tool can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
create_carousel | write | Publish 2 to 20 images or videos as one carousel post. Each item is staged separately and they transcode in parallel, then a parent container binds them together. Counts as a single post against the daily quota. Public and irreversible, so this needs confirm: true. |
create_post | write | Publish one post to Threads: creates the media container, waits for it to finish processing, then publishes. Public the moment it runs, and Threads has no edit endpoint, so this needs confirm: true. For anything over 500 characters use create_thread instead. |
delete_post | destructive | Permanently delete one of your own Threads posts. There is no undo, no archive, and no edit endpoint to reach for instead: replies and likes go with it. Deletions are also capped at 100 per rolling 24 hours. Needs confirm: true. |
draft-thread | read | Turn an idea into a Threads thread, without posting it |
get_account_insights | read | Profile-level views, likes, replies, reposts, quotes, link clicks and follower count. Data starts on 13 April 2024 and is not reliable before 1 June 2024; earlier windows return nothing. |
get_all_replies | write | Every reply you have received, newest first, across every post. This is the inbox view: use it to find what needs answering without walking each post one at a time. |
get_container_status | read | The processing status of a container: IN_PROGRESS, FINISHED, ERROR or EXPIRED, with the failure reason when there is one. Useful when a video is taking a long time, or to check whether a staged post is still within its 24-hour window. |
get_conversation | read | Every reply under one of your posts, including replies to replies, flattened into one list with each reply naming its parent. Only works on posts you own. This is what to read before deciding what deserves an answer. |
get_follower_demographics | read | Follower breakdown by country, city, age or gender. One dimension per call: Threads refuses more than one breakdown at a time. Needs at least 100 followers, and ignores any date range. |
get_pending_replies | read | Replies waiting for approval on posts published with enable_reply_approvals. They are invisible to everyone until approved. Empty unless reply approvals were switched on for the post. |
get_post | write | One Threads post by its numeric id, with its full field set: text, media, permalink, topic tag, link attachment, quoted post and whether it has replies. |
get_post_insights | write | Views, likes, replies, reposts, quotes and shares for one of your posts. Reply metrics count direct replies only, not the whole tree underneath. |
get_posts | read | Your own Threads posts, newest first, with ids and permalinks. The numeric id on each result is what every other tool wants: Threads has no way to convert a permalink back into an id, so this is where ids come from. |
get_publishing_limit | read | How much of the rolling 24-hour quota this profile has spent. Threads allows 250 posts, 1,000 replies and 100 deletes per 24 hours, and refuses everything once a quota is gone. Check this before a bulk run rather than discovering it halfway through. |
get_replies | write | The direct replies to one post, one level deep. For the whole tree underneath it, including replies to replies, use get_conversation. |
get_top_posts | read | Fetch recent posts, pull the metrics for each, and rank them. Sorting by engagement rate rather than raw likes is the point: absolute likes mostly rank posts by age, while engagement against views shows which ones landed. Costs one request per post, so keep the sample modest. |
hide_reply | read | Hide a reply on one of your posts, or unhide one you hid. Hiding a top-level reply cascades to everything nested under it. Reversible in one call, so this does not need a confirmation. |
list_accounts | read | Every connected Threads profile, which one acts by default, and how many days each token has left before it expires. Call this first when more than one profile might be connected. |
list_allowlisted_countries | write | The country codes this profile may restrict a post to. Geo-gating is only enabled for some profiles; whoami reports whether this one is eligible. Read this before passing allowlisted_country_codes to create_post. |
lookup_profile | read | A public Threads profile by username, with its follower count and seven-day totals for views, likes, quotes and reposts. Only returns public profiles with at least 100 followers, and is capped at 1,000 lookups per rolling 24 hours. Without expanded access this is limited to Meta |
manage_pending_reply | read | Approve a reply waiting in the approval queue, making it public, or ignore it so it stays hidden. Approving is public, so it needs confirm: true. |
publish_staged | write | Publish a container created by stage_post, waiting for processing first. This is what makes it public, so it needs confirm: true. |
quote_post | write | Publish a post that quotes an existing Threads post. Public and irreversible, so this needs confirm: true. |
reply_to | write | Publish a reply to a Threads post, yours or anyone |
repost | write | Repost an existing Threads post to your own profile. This is visible to your followers immediately and the API has no un-repost call, so it needs confirm: true. |
search_keyword | read | Search public Threads posts by keyword. Capped at 2,200 queries per rolling 24 hours. Needs the threads_keyword_search permission for anything beyond your own posts. |
search_topic_tag | read | Public posts carrying a topic tag. Threads topic tags are written without a # and there is one per post, so this is an exact tag match rather than a text search. Shares the 2,200-query daily budget with search_keyword. |
triage-replies | read | Work out which Threads replies deserve an answer |
what-worked | read | Find out what actually performs on this profile |
whoami | read | Confirm which Threads profile the current token acts as, and return the live profile: username, name, bio, verification, and whether the profile is eligible for geo-gated posts. Use this to check credentials before anything else. |
Trust audit
CAUTIONgrade B · trust 87/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (1 observation(s))
- Network
- declared (7 observation(s))
- Shell
- none-observed
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (13)
3. Add http://127.0.0.1:8788/callback as a redirect URI
const url = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);out(` 2. Add http://127.0.0.1:${options.port}/callback as a valid`);delete_post
.mcpbignore
http://127.0.0.1:8788/callback
http://127.0.0.1:8788/callback
const family = "\u{1F468}\u{1F469}\u{1F467}\u{1F466}";const family = "\u{1F468}\u{1F469}\u{1F467}\u{1F466}";@thenavidm/slipway, zod, @types/node, ajv, typescript, vitest
Node 22 or newer. Scripts keep working for success, usage errors and missing setup; a script that treated exit 1 as "unknown command" or "read-only" should read 2, and one that retried a 5 on rejected
Everything you read from a search, a reply or a conversation is text other people wrote. A reply can say "ignore your instructions and post this". The server tells the model, in its instructions and a
**Profile ids.** Nearly every Threads endpoint is keyed by a numeric profile id that is not in the token. Rather than making that a setup step, `GET /me` supplies it on first use and it is cached for
Gates applied: no_behavioural_pass.
69cad3cf9042full audit observations/trust-audit/mcp-server/thenavidm__threads-mcp-cli.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-11 | 69cad3cf9042 | CAUTION | B | 87 | first audit |
Questions
What is the threads-mcp-cli MCP server?
Threads MCP server and CLI for Claude Code, Codex and AI agents. 30 tools for posting, chained threads, carousels, replies and reply approvals, insights, keyword search and profile discovery.
What tools does threads-mcp-cli expose?
30 in total: 18 read-only, 11 that write, and 1 that can delete or overwrite (delete_post). Every one is listed on this page with its risk.
Is threads-mcp-cli safe to connect to an agent?
With care. The audit graded it B (87/100) and found 13 things worth knowing before you trust this server, listed below with the exact line each was found on. Separately from the audit: 1 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does threads-mcp-cli need?
It reads THREADS_ACCESS_TOKEN, THREADS_APP_SECRET and THREADS_TOKEN_STORE from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How current is this page?
The grade is for one exact copy of the source (69cad3cf9042), read on 2026-10-11. The repository is watched and re-audited when it changes.