Threads MCP Server

Threads MCP Server

Enables AI assistants to manage a Threads posting schedule through natural language, allowing them to view, add, update, reschedule, and skip posts in a local CSV schedule.

Category
Visit Server

README

Safe Threads Auto-Poster & Planner

A local, safety-first scheduler for Threads posts using Meta's official Threads API.

  • Autoposter (threads_autoposter.py) — publishes due posts from a CSV schedule. Locked in dry-run mode until you explicitly approve live posting.
  • Planner dashboard (threads_dashboard.py) — a local web UI with calendar and list views for adding, editing, skipping, and tracking single posts and multi-part thread chains. No Terminal or CSV editing needed day to day.
  • MCP server (threads_mcp_server.py) — lets AI assistants such as Claude (Claude Desktop / Claude Code) or Codex manage your schedule with natural language.

Everything runs from one folder and one CSV file (threads_schedule.csv), so the dashboard, the autoposter, and the AI assistant always see the same schedule.

Requirements

  • Python 3.10 or newer (the autoposter and dashboard use only the standard library)
  • mcp package, only if you want the Claude/Codex integration: pip install -r requirements.txt
  • A Meta Developer account and a Meta app with the Threads use case (see step 2)

Step-by-step setup

1. Get the code

git clone https://github.com/<your-username>/<your-repo>.git
cd <your-repo>
cp .env.example .env

.env holds your private settings and tokens. It is listed in .gitignore and must never be committed. Never paste tokens or app secrets into an AI chat either — put them only in your local .env.

2. Create a Meta app and get Threads API credentials

Meta's current flow (verified July 2026):

  1. In the Meta Developer dashboard, create an app with the Threads use case. Meta issues separate Threads app credentials; use the Threads app ID and its matching secret.
  2. Add your Threads account as a Threads Tester in the app dashboard, then accept the invitation in your Threads account settings (Website permissions → Invitations). Accounts without an app/tester role need approved permissions through App Review and a published app.
  3. Authorize the account with the official OAuth flow using these permissions:
    • threads_basic (required for everything)
    • threads_content_publish (publishing)
    • threads_manage_replies (needed for multi-part thread chains)
  4. Exchange the short-lived token (1 hour) for a long-lived token (60 days). Refresh it before expiry by running python3 refresh_threads_token.py (it calls Meta's official refresh endpoint and updates .env in place). Public profiles can extend grants by refreshing; private profiles must re-authorize after expiry.
  5. Note your Threads user ID — you'll need it together with the token.

Official references: Threads API · Get Started · Create Posts · Create Replies · Rate Limits

3. Fill in .env

Open .env and set at minimum:

THREADS_ACCESS_TOKEN=your-long-lived-token
THREADS_USER_ID=your-threads-user-id

Leave the safety locks as they are (DRY_RUN=true, APPROVED_TO_POST=false). See .env.example for every field and what it does.

4. Set your schedule start date and dry-run

python3 threads_autoposter.py --set-start-date YYYY-MM-DD
python3 threads_autoposter.py

The first command fills in dates for every calendar item. The second is a dry run — it selects the next due post and logs exactly what it would publish, without any API call.

Inspect what would happen at a specific moment:

python3 threads_autoposter.py --now 2026-08-01T09:01:00+08:00

Run the test suite any time:

python3 -m unittest -v test_threads_autoposter.py

5. Open the planner dashboard

python3 threads_dashboard.py

(On macOS you can instead double-click Open Threads Planner.command.) The dashboard opens at http://127.0.0.1:8765 (change with --host/--port). Keep the Terminal window open while using it; press Control+C to stop.

The planner supports calendar and upcoming-list views, single posts and multi-part chains, topics and filtering, scheduled/skipped/error/published statuses, UTF-8 byte checks for every post part, and safe deletion of unpublished entries. Published rows are read-only, and the dashboard never edits .env or enables live posting.

6. Approve live posting (deliberately)

Live posting requires all three settings in .env:

DRY_RUN=false
APPROVED_TO_POST=true
LIVE_POSTING_CONFIRMATION=I approve live Threads posting.

Test one specific row first:

TEST_MODE=true
TEST_POST_ID=D01-AM

Test mode selects only that row but does not bypass any safety lock. After a successful test, set TEST_MODE=false.

Pause posting at any time by setting DRY_RUN=true or APPROVED_TO_POST=false.

7. Run it on a schedule

Run the autoposter every 15 minutes from the project folder:

cd /absolute/path/to/this/folder && python3 threads_autoposter.py

Each run processes at most one due item, uses a local lock so overlapping runs exit safely, and respects all safety settings.

You can host the scheduler on your own computer (macOS launchd or Linux cron) or on an always-on VPS with systemd — full walkthroughs for both, including the systemd unit files, private dashboard access over SSH, and monthly token refresh, are in DEPLOYMENT.md.

Keep the automation disabled or dry-run-only until the schedule has a start date and you have reviewed the dry-run output. Run the scheduler in exactly one place — post statuses live in the local CSV and do not sync between machines.

Using it with Claude or Codex (MCP)

threads_mcp_server.py exposes the planner over the Model Context Protocol via stdio. It edits the same CSV as the dashboard and never exposes .env secrets. Tools available to the assistant:

safety_status, list_posts, get_post, add_post, update_post, reschedule_post, skip_post, mark_published, run_scheduler_once (obeys all DRY_RUN/approval locks).

Install the dependency first: pip install "mcp[cli]>=1.27,<2".

Claude Desktop

Add to claude_desktop_config.json (Settings → Developer → Edit Config):

{
  "mcpServers": {
    "threads-planner": {
      "command": "python3",
      "args": ["/absolute/path/to/this/folder/threads_mcp_server.py"]
    }
  }
}

If the planner lives on a remote server, run it over SSH instead — see claude_desktop_mcp_config.example.json for both variants.

Claude Code

claude mcp add threads-planner -- python3 /absolute/path/to/this/folder/threads_mcp_server.py

Codex CLI

Add to ~/.codex/config.toml:

[mcp_servers.threads-planner]
command = "python3"
args = ["/absolute/path/to/this/folder/threads_mcp_server.py"]

Then ask things like: "List next week's scheduled threads", "Add a 3-part chain about client onboarding on Friday at 9am", or "Skip post D14-PM".

The schedule CSV

threads_schedule.csv is the single source of truth. You can also edit it in a spreadsheet (UTF-8, keep the exact column names, close the editor before the scheduler runs). Valid statuses:

  • scheduled — eligible when due
  • published — always skipped
  • skipped — always skipped
  • publishing — safety marker while a chain is being sent
  • error — skipped until you inspect the error and deliberately reset it

post_text holds a JSON list of strings — one entry per post in the chain. Logs are written to logs/threads_autoposter.log; every selection, dry run, container, publish, retry, and error is recorded. Tokens are never logged.

Threads API limits (as of July 2026)

  • Text: 500 UTF-8 bytes per post segment (emoji count by bytes)
  • API-published posts: 250 per profile per rolling 24 hours; replies: 1,000
  • General call quota: 4,800 × impressions per rolling 24 hours (minimum 10 impressions in the formula)
  • Check your usage with GET /{threads-user-id}/threads_publishing_limit

There is no native future-time scheduling in the Threads publishing flow — this local scheduler decides when to call the API. A typical two-chains-per-day calendar (2 roots + 8 replies) sits comfortably below the limits.

Troubleshooting

  • Blank dates — run --set-start-date YYYY-MM-DD.
  • 401 / invalid token — renew the OAuth token (or refresh the long-lived token) and update only your local .env.
  • Permission error — confirm the tester invitation was accepted (or App Review passed) and all three permissions were granted.
  • Container timeout — the row is marked error and partial published IDs are retained to prevent duplicates; inspect the logged Meta error.
  • 429 / rate limit — leave the row in error, wait for the rolling window, check quota usage, then reset deliberately.
  • Partial chain — don't reset blindly. Check threads_post_id (a JSON list of already-published IDs) and finish manually or edit the remaining content before rescheduling.
  • CSV locked or damaged — restore the exact header listed above using a UTF-8 CSV editor.

Security notes

  • .env is git-ignored; keep it that way. Set file permissions to 600 on shared machines.
  • Before exposing the dashboard beyond localhost, set DASHBOARD_USERNAME and DASHBOARD_PASSWORD in .env (never reuse your Meta password).
  • Meta describes publishing as acting on a person's behalf. External users (no app role) require App Review and a published app — check Meta's current Platform Terms before running this for accounts other than your own.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured