Skip to main content
Glama
facebook-mcp

facebook-mcp

by IvanBBaev

Private reply to comment

facebook_private_reply
Destructive

Sends one private message to a Facebook comment or visitor post author within 7 days, requiring apply:true and a plan_id from a dry run; no second attempt.

Instructions

Send a private message to the author of a comment, or of a visitor post on the Page (post_id). TWO hard limits, both checked before anything is sent: exactly ONE private reply is possible per comment or post (there is no second attempt, ever — the local journal is checked too) and only within 7 DAYS of it. The message carries text or ONE attachment (a public https URL or a reusable attachment id). It appears in the Page inbox and cannot be unsent, so it always requires apply:true plus the plan_id from a dry run. Do not retry a failed call blindly — a lost response may already have delivered the message. Sending needs a PAGE token with pages_messaging and the MESSAGING task; the comment or post is read first to check the window, which also needs pages_read_engagement (plus pages_read_user_content for a visitor's comment).

Input Schema

NameRequiredDescriptionDefault
applyNoSet true to actually perform the write. Omitted or false ⇒ the server decides from its configured write mode: usually a dry run that returns a plan preview and changes nothing, but a server (or package) configured apply-first performs the write. To be certain nothing happens, read the result: a dry run always reports the plan and says the write was NOT performed.
messageNoThe text to send. Written by you — Facebook rejects an empty message.
plan_idNoThe `planId` returned by a preceding dry-run preview of this same tool. Required for irreversible and spend-tier writes; plans expire a few minutes after they are created.
post_idNoVisitor post id (pageid_postid) to answer privately. Use instead of comment_id.
profileNoPage profile key (e.g. "brand-a") or a raw Page ID. Omitted ⇒ the default Page (FB_PAGE_ID).
attachmentNoONE attachment instead of text: exactly one of url / attachment_id. A message carries text or one attachment, never both.
comment_idNoComment ID, e.g. "123456_789012" as returned by facebook_list_comments. Not a post ID.
allow_repeatNoSend even though the local journal records an earlier ATTEMPTED (unconfirmed) private reply to the same comment or post — only after the inbox shows it never arrived. Never overrides one recorded as delivered.
confirm_tokenNoOut-of-band operator token (FB_CONFIRM_TOKEN) authorizing this one irreversible or spend-tier apply. Needed only when the MCP client cannot show a confirmation prompt. Ask the human operator for it; it is not stored between calls and is never echoed back.
saved_reply_idNoId of a saved reply (facebook_list_saved_replies) to send instead of `message`. Its text is resolved now and bound to the plan, so editing the template after the preview makes the apply diverge.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv0.8.0
    • addedInput schema / properties / allow_repeat
      Added value: +{
      +  "description": "Send even though the local journal records an earlier ATTEMPTED (unconfirmed) private reply to the same comment or post — only after the inbox shows it never arrived. Never overrides one recorded as delivered.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / attachment
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "ONE attachment instead of text: exactly one of url / attachment_id. A message carries text or one attachment, never both.",
      +  "properties": {
      +    "attachment_id": {
      +      "description": "A reusable attachment id from facebook_upload_message_attachment (valid for about 90 days, this Page only).",
      +      "pattern": "^\\d{1,32}$",
      +      "type": "string"
      +    },
      +    "type": {
      +      "description": "Attachment kind: image, audio, video or file (for example a PDF).",
      +      "enum": [
      +        "image",
      +        "audio",
      +        "video",
      +        "file"
      +      ],
      +      "type": "string"
      +    },
      +    "url": {
      +      "description": "A public https:// URL Meta fetches itself (no credentials in it). Meta gives up after about 10 s (75 s for video); images up to 8 MB, other files up to 25 MB.",
      +      "format": "uri",
      +      "maxLength": 2048,
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "type"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / comment_id / pattern
      Added value: +"^(?=.*\\w)[\\w.-]+$"
    • addedInput schema / properties / post_id
      Added value: +{
      +  "description": "Visitor post id (pageid_postid) to answer privately. Use instead of comment_id.",
      +  "minLength": 1,
      +  "pattern": "^(?=.*\\w)[\\w.-]+$",
      +  "type": "string"
      +}
    • addedInput schema / properties / saved_reply_id
      Added value: +{
      +  "description": "Id of a saved reply (facebook_list_saved_replies) to send instead of `message`. Its text is resolved now and bound to the plan, so editing the template after the preview makes the apply diverge.",
      +  "pattern": "^[a-z0-9][a-z0-9-]{0,47}$",
      +  "type": "string"
      +}
    • removedInput schema / required
      Removed value: -[
      -  "comment_id",
      -  "message"
      -]
  2. First observedv0.7.0

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the destructive/non-idempotent annotations: it discloses that the message lands in the Page inbox, cannot be unsent, that the one-attempt limit is enforced against a local journal too, the 7-day window, and the exact token scopes (pages_messaging, MESSAGING task, pages_read_engagement, pages_read_user_content). The retry hazard for a lost response is a genuinely non-obvious behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the two hard limits immediately after the purpose statement, then covers content rules, irreversibility, and permissions in descending order of decision value. Dense but every clause carries information an agent needs before calling.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter, nested-object, irreversible write with no output schema, the description covers constraints, auth prerequisites, dry-run protocol, and failure-recovery semantics. Nothing material is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema coverage the baseline is 3, and the description earns a bump by explaining the message/attachment exclusivity, the apply+plan_id pairing, and that a comment or post is read first to check the window. It doesn't explain profile, confirm_token, or saved_reply_id beyond what the schema already says, so it is not a full 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — 'Send a private message to the author of a comment, or of a visitor post on the Page (post_id)' — with the target entity named. The 'private' framing plus the comment_id/post_id alternatives distinguish it from the public-reply and inbox-message siblings without needing to name them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit about the conditions that select this tool versus a plain reply: one private reply per comment/post, within 7 days, requiring apply:true plus plan_id from a dry run. It also gives negative guidance — 'Do not retry a failed call blindly' — and explains when allow_repeat is legitimate, which is exactly the when/when-not/alternative coverage a 5 requires.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.