mcp-meta-inbox
mcp-meta-inbox enables LLM agents to manage a Facebook Page’s inbox and moderate comments on Facebook and Instagram via natural language.
Diagnostics: Check token health and which capabilities are working (Messenger inbox, Instagram Direct, comments).
Inbox & Direct Messages: List conversations, read threads and messages (including attachments), send text or image DMs (subject to Meta’s 24-hour window, extendable with
HUMAN_AGENTtag), mark conversations as seen, and show typing indicators.Post & Comment Management: List posts/media, list and read comments, create top-level comments on Facebook, reply publicly on both platforms, edit own Page comments (Facebook only), hide/unhide and permanently delete comments, and send a private DM to a comment author (once per comment within 7 days).
Instagram Direct: Tools for Instagram Direct are shipped but require Advanced Access (App Review) to work; public comment tools are unaffected.
Allows managing Facebook Page inbox, posts, and comments, including sending messages, moderating comments, and replying.
Allows reading and replying to Instagram comments on business accounts, and with advanced access, Instagram Direct messages.
Allows reading and sending messages in Messenger conversations as a Facebook Page.
Provides tools for integrating with Meta's Messenger Platform and Instagram Messaging APIs to manage inbox, comments, and moderation.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-meta-inboxSummarize the last 10 conversations and flag unanswered ones."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-meta-inbox
MCP server that wraps the Meta Messenger Platform, Instagram Messaging and comment moderation APIs (Graph API v25.0) as semantic tools for LLM agents.
Read your Page inbox, reply to students, and moderate comments on Facebook posts and Instagram media — from natural language.
Works with Claude Code, Codex, Claude Desktop, Cursor, VS Code, Windsurf, and any MCP-compatible client.
Companion to mcp-meta-marketing, which covers ads. They do not share a token — see Why not the Marketing API token.
Quick Start
claude mcp add meta-inbox -s user \
-e META_PAGE_ACCESS_TOKEN=your-page-token \
-e META_PAGE_ID=your-page-id \
-- npx -y github:pauloFroes/mcp-meta-inboxThen just ask in natural language:
Don't have a Page token yet? See How to get your Page Access Token below.
Related MCP server: facebook-pages-mcp
What you can do
Work the inbox:
"Who messaged the Page today and what did they ask?"
"Summarize the last 20 conversations and flag the ones still unanswered"
"Read thread t_1997631717587281 and draft a reply about the course schedule"
"Mark Sandro's conversation as seen"Moderate comments:
"List the comments on my latest Instagram post"
"Which comments are questions nobody answered?"
"Reply to that comment asking about the price"
"Hide the spam comment on last week's Facebook post"
"Answer that public question privately instead"Availability at a glance
Surface | Read | Write | Requirement |
Messenger inbox | ✅ | ✅ | Page token |
Facebook comments | ✅ | ✅ | Page token |
Instagram comments | ✅ | ✅ | Page token |
Instagram Direct | ⛔ | ⛔ | Advanced Access to |
Instagram Direct is gated by Meta, not by this server. Without Advanced Access the API answers a /conversations?platform=instagram call with a ~27s timeout (error_subcode: 2534084) explaining that too many threads belong to people with no role on the app. Instagram comments are unaffected and work today. The tools are shipped anyway so they start working the moment App Review clears — and check_access tells you where you stand.
Available Tools
Diagnostics
Tool | Description |
| Report token type, expiry, messaging scopes, and which capabilities actually answer right now |
Inbox
Tool | Description |
| List inbox threads with participants, unread count and last-message snippet |
| Read one thread in full — participants plus recent messages |
| List messages inside a thread |
| Read a single message, including attachments |
| Send a DM as the Page (text or image) |
| Mark seen, or toggle the typing indicator |
Posts and comments
Tool | Description |
| List Facebook Page posts or Instagram media |
| List comments on a post/media, or replies to a comment |
| Read one comment with its moderation flags |
| Post a top-level comment (Facebook only) |
| Reply publicly as the Page (routes Facebook vs Instagram automatically) |
| Edit a comment the Page authored (Facebook only) |
| Hide/unhide a comment — reversible moderation |
| Delete a comment permanently (irreversible) |
| Answer a public comment with a private DM to its author |
Platform asymmetries worth knowing
These are Meta's limits, surfaced as clear tool errors rather than opaque failures:
Operation | ||
Reply to a comment |
|
|
Edit your own comment | ✅ | ⛔ not supported by the API — delete and re-post |
New top-level comment | ✅ | ⛔ replies only |
Hide a comment |
|
|
Messaging windows
The two ways to DM someone have different clocks, and confusing them is how a stale inbox comes to look like a work queue right up until every send fails.
Clock starts at | Window | |
| the person's last message | 24 hours |
| the person's last message | 7 days |
| the comment | 7 days, once per comment |
The 24-hour limit is Meta's standard messaging window — "Businesses have up to 24 hours to respond to a user" (Messenger Platform policy). It is not a WhatsApp-only rule.
Pass tag only when it honestly describes the message: HUMAN_AGENT (a human answering the person's own question), ACCOUNT_UPDATE, CONFIRMED_EVENT_UPDATE, POST_PURCHASE_UPDATE. Sending off-purpose is a policy violation, and HUMAN_AGENT also needs the Human Agent feature approved for the app — without it Meta rejects the call.
Because private_reply is measured from the comment rather than from a message, it is usually the only live channel: a comment posted this morning is reachable for a week, while an inbox thread that went quiet yesterday is already closed.
Installation
You need two environment variables (a third is optional):
Variable | Required | Description |
| yes | Page token issued to a person who administers the Page (how to get one) |
| yes | Numeric Page ID — Meta Business Suite → Page → About |
| no | Instagram Business account ID. Auto-discovered from the Page when omitted |
Claude Code
Three installation scopes are available:
Scope | Flag | Config file | Use case |
local |
|
| This project only (default) |
project |
|
| Shared with team via git |
user |
|
| All your projects |
Quick setup (inline env vars):
claude mcp add meta-inbox -s user \
-e META_PAGE_ACCESS_TOKEN=your-page-token \
-e META_PAGE_ID=your-page-id \
-- npx -y github:pauloFroes/mcp-meta-inboxPersistent setup (.env file):
Add to your .mcp.json:
{
"meta-inbox": {
"command": "npx",
"args": ["-y", "github:pauloFroes/mcp-meta-inbox"],
"env": {
"META_PAGE_ACCESS_TOKEN": "${META_PAGE_ACCESS_TOKEN}",
"META_PAGE_ID": "${META_PAGE_ID}",
"META_IG_USER_ID": "${META_IG_USER_ID}"
}
}
}Then define the values in your .env file. See .env.example.
Codex
[mcp_servers.meta-inbox]
command = "npx"
args = ["-y", "github:pauloFroes/mcp-meta-inbox"]
env_vars = ["META_PAGE_ACCESS_TOKEN", "META_PAGE_ID", "META_IG_USER_ID"]Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"meta-inbox": {
"command": "npx",
"args": ["-y", "github:pauloFroes/mcp-meta-inbox"],
"env": {
"META_PAGE_ACCESS_TOKEN": "your-page-token",
"META_PAGE_ID": "your-page-id"
}
}
}
}Cursor
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"meta-inbox": {
"command": "npx",
"args": ["-y", "github:pauloFroes/mcp-meta-inbox"],
"env": {
"META_PAGE_ACCESS_TOKEN": "your-page-token",
"META_PAGE_ID": "your-page-id"
}
}
}
}VS Code
Add to .vscode/mcp.json in your project:
{
"servers": {
"meta-inbox": {
"command": "npx",
"args": ["-y", "github:pauloFroes/mcp-meta-inbox"],
"env": {
"META_PAGE_ACCESS_TOKEN": "your-page-token",
"META_PAGE_ID": "your-page-id"
}
}
}
}Windsurf
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"meta-inbox": {
"command": "npx",
"args": ["-y", "github:pauloFroes/mcp-meta-inbox"],
"env": {
"META_PAGE_ACCESS_TOKEN": "your-page-token",
"META_PAGE_ID": "your-page-id"
}
}
}
}Why not the Marketing API token
If you already run mcp-meta-marketing, the obvious move is to reuse its META_ACCESS_TOKEN. It does not work here.
That token is normally a System User token. The Conversations API rejects System User tokens — but it does not say so. It answers:
{"error":{"message":"An unexpected error has occurred. Please retry your request later.",
"type":"OAuthException","code":2,"is_transient":true}}…which reads like a transient server fault and is identical across API versions. Retrying never helps. The inbox needs a Page token that was requested by a person with the MODERATE task on the Page.
This server refuses to start if it finds META_ACCESS_TOKEN but no META_PAGE_ACCESS_TOKEN, and prints how to fix it. Run check_access any time you're unsure which kind of token you're holding.
Instagram comments happen to work with either token. Everything else needs the Page token, so this server standardizes on it.
How to get your Page Access Token
Requires an existing Meta App with the Messenger and Instagram use cases added, and a Business Portfolio that owns the Page.
Go to developers.facebook.com → your app → Use cases
Open "Interact with customers on Messenger from Meta" → Customize
In the left menu, pick Messenger API settings
Under 2. Generate access tokens, connect your Page if it isn't listed
Click Generate on the Page row → tick the acknowledgement → Copy
The token is shown only once. It never expires (expires_at: 0 in the Access Token Debugger) unless you revoke it or lose the admin role.
Do not generate this from business.facebook.com → System Users — that produces a System User token, which the inbox rejects. See the section above.
Verify what you got:
curl -s "https://graph.facebook.com/v25.0/debug_token?input_token=$TOKEN&access_token=$TOKEN"You want "type": "PAGE", "expires_at": 0, and a user_id that is your personal profile — not a System User.
Instagram Direct: requesting Advanced Access
Reading Instagram DMs from people who have no role on your app requires Advanced Access to instagram_manage_messages, which only App Review grants. In your app → Use cases → the Instagram or Messenger use case → Permissions and features → the permission row → Actions → Add to app review. Expect to supply a working prototype and a screencast.
Nothing else in this server depends on it.
Safety notes
Six tools write to the outside world. send_message and private_reply message a real person; create_comment, reply_to_comment and update_comment publish publicly under the Page's name; delete_comment is irreversible. They are annotated (readOnlyHint / destructiveHint) so MCP clients can gate them, but you should still confirm the recipient and the exact text with a human before firing them.
hide_comment is the reversible alternative to delete_comment for moderation.
License
MIT
Available Tools
16 toolscheck_accessCheck AccessARead-only
Diagnose the configured token: its type, whether it never expires, which messaging scopes it carries, and which of the four capabilities (Messenger inbox, Instagram Direct, Facebook comments, Instagram comments) actually answer right now. Run this first when any other tool fails — it separates a wrong token type from a missing Advanced Access grant.
Inputs: no named parameters.
create_commentCreate CommentA
Post a new top-level comment on your own Facebook post. This publishes publicly under the Page's name — confirm the text with a human first. Instagram does not allow creating top-level comments via the API; use reply_to_comment there.
Inputs: message (required), object_id (required).
delete_commentDelete CommentADestructiveIdempotent
Permanently delete a comment. IRREVERSIBLE — the comment cannot be restored. Confirm with a human before calling. Prefer hide_comment when the intent is moderation rather than removal.
Inputs: comment_id (required).
get_commentGet CommentARead-only
Read a single comment by ID, with its author, timestamp and moderation flags (can_hide / can_remove on Facebook, hidden on Instagram). Call this before hiding or deleting so the decision is made on the real text.
Inputs: comment_id (required), fields, platform.
get_conversationGet ConversationARead-only
Read one thread in full: participants plus the most recent messages with sender, body text, attachments and timestamps. This is the tool to call before replying to someone, so the reply has context.
Inputs: conversation_id (required), message_limit.
get_messageGet MessageARead-only
Read a single message by ID, including attachments and shared media. Useful when a thread listing shows an attachment you need the URL for.
Inputs: message_id (required), fields.
hide_commentHide CommentAIdempotent
Hide or unhide someone else's comment. A hidden comment stays visible to its author and their friends but disappears for everyone else — the reversible alternative to delete_comment for spam or abuse.
Inputs: comment_id (required), hide, platform.
list_commentsList CommentsARead-only
List comments on a post (Facebook) or media (Instagram), including each author's ID — which doubles as the DM recipient ID for send_message or private_reply. Instagram results nest their replies; Facebook top-level comments carry a comment_count you can drill into by passing the comment ID back in as object_id. Passing a comment ID works on Instagram too — the tool falls back to the /replies edge and reports which edge answered. Works on both platforms with a plain Page token.
Inputs: object_id (required), limit, order, fields, +2 more.
list_conversationsList ConversationsARead-only
List inbox threads for the Page, newest activity first. Returns thread ID, participants, message count, unread count and a snippet of the last message. Use the returned thread ID with get_conversation or list_messages. Instagram Direct additionally requires Advanced Access to instagram_manage_messages (App Review). Without it Meta answers with a ~27s timeout, subcode 2534084. Instagram comments are NOT affected.
Inputs: limit, fields, platform, max_pages.
list_messagesList MessagesARead-only
List messages inside a thread without the surrounding conversation metadata. Use get_conversation instead when you also want the participant list.
Inputs: conversation_id (required), limit, fields, max_pages.
list_postsList PostsARead-only
List published posts on the Facebook Page, or media on the linked Instagram account. Returns each post's ID, caption/message, timestamp and engagement counts. Use the returned ID with list_comments to moderate its comment thread.
Inputs: limit, fields, platform, max_pages.
private_replyPrivate Reply to CommentA
Answer a public comment with a private direct message to its author. Meta allows exactly one private reply per comment, and only within 7 days of the comment. This is the supported way to move a public question into the inbox. It messages a real person — confirm with a human first. Instagram private replies need the same Advanced Access as Instagram Direct.
Inputs: message (required), comment_id (required).
reply_to_commentReply to CommentA
Reply publicly to a comment, as the Page. Facebook and Instagram use different endpoints for this and the tool routes automatically. This publishes publicly — confirm the text with a human first. To answer someone privately instead, use private_reply.
Inputs: message (required), comment_id (required), platform.
send_messageSend MessageA
Send a direct message from the Page to a person, on Messenger or Instagram Direct. This publishes to a real person's inbox — confirm the recipient and the text with a human before calling it. Meta only allows a free-form reply within 24 hours of that person's last message; outside that window the call fails and a message tag or paid channel is required. Instagram Direct additionally requires Advanced Access to instagram_manage_messages (App Review). Without it Meta answers with a ~27s timeout, subcode 2534084. Instagram comments are NOT affected.
Inputs: text (required), recipient_id (required), image_url.
send_sender_actionSend Sender ActionAIdempotent
Mark a conversation as seen, or show/hide the typing indicator. Cosmetic and safe: it posts no content. Useful before a slow reply so the person sees the Page is responding.
Inputs: action (required), recipient_id (required).
update_commentUpdate CommentAIdempotent
Edit the text of a comment the Page authored. FACEBOOK ONLY — the Instagram Graph API has no edit operation for comments, so an Instagram reply can only be deleted and re-posted. This tool rejects Instagram IDs rather than failing opaquely.
Inputs: message (required), comment_id (required), platform.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
TDQS
Scored across 16 tools
Each tool targets a distinct resource/action: conversations, messages, comments, posts, or access diagnostics. Potential confusion between private_reply and reply_to_comment is resolved by clear descriptions stating public vs private.
All tool names follow a consistent verb_noun pattern using snake_case (e.g., get_conversation, send_message, list_comments). No naming convention violations.
16 tools cover the full scope of social media inbox management without being excessive. Each tool serves a specific need, and the count is well-scoped for the domain.
Covers CRUD for comments and messages, plus conversation listing and access diagnostics. Minor gaps exist (e.g., no tool for deleting conversations or creating Instagram posts), but core workflows are fully supported.
Maintenance
Related MCP Connectors
Instagram MCP for DM and comment automation, AI Agent and content publishing via Meta's official API
Unified messaging MCP server: WhatsApp, Instagram, Telegram, SMS, Messenger & email support inbox
Agent-first social media publishing, scheduling, analytics, and unified inbox API + 16-tool MCP server across 18 social platforms (X, LinkedIn, Instagram, YouTube, TikTok, Threads, Bluesky, Reddit, Telegram, Discord, Mastodon, Facebook, Pinterest).
MCP server for QPost — lets AI agents publish video and image posts to YouTube, TikTok, Instagram.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server that wraps the Meta Marketing API (Graph API v25.0) as semantic tools for LLM agents.181MIT
- AlicenseAqualityDmaintenanceMCP server for Facebook Pages organic analytics and management using Meta Graph API v25.0. Enables AI assistants to read page insights, posts, comments, and publish content via natural language.961 npmMIT
- FlicenseAqualityDmaintenanceLocal MCP server for operating Instagram, Meta Ads, and Facebook Page from Claude Code via Meta's Graph API. Provides 20 tools for publishing, campaign management, and insights.20-
- AlicenseAqualityBmaintenanceA Facebook/Messenger MCP server that lets AI agents read and engage with profiles, pages, posts, comments, groups, Messenger conversations, notifications, and events using the user's existing browser session cookies — no Graph API app, tokens, or browser automation required. It supports multi-account and Page switching, write operations (posting, commenting, messaging) with per-identity limits and cooldowns, and honest error reporting where Meta has decommissioned cookie-era endpoints.411MIT