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.
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)
mcppackage, 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):
- 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.
- 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.
- 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)
- 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.envin place). Public profiles can extend grants by refreshing; private profiles must re-authorize after expiry. - 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 duepublished— always skippedskipped— always skippedpublishing— safety marker while a chain is being senterror— 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 × impressionsper 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
errorand 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
.envis git-ignored; keep it that way. Set file permissions to600on shared machines.- Before exposing the dashboard beyond localhost, set
DASHBOARD_USERNAMEandDASHBOARD_PASSWORDin.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.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。