Skip to main content
Glama

Create a comment-to-DM automation (draft)

create_comment_to_dm

The most common automation: when someone comments on a post, DM them. Creates a draft; nothing goes out until enable_automation. How Meta works: a DM cannot be started by the account. The only automatic door is a private reply to a comment, one per comment, within 7 days of the comment, and once the person answers the 24-hour window opens for the rest. Instagram can check whether the person follows the account (requireFollow); Facebook cannot, so requireFollow is rejected there. Threads has no DMs at all; use create_automation with comment_public_reply. A file to deliver: if it already has a public https link that returns the file itself (jpeg, png, gif, webp, mp4, mov or PDF), pass it as deliver.fileUrl and it goes to the person as-is; the link is opened once on save and a web page (a Google Drive or Dropbox share page), a private address or a dead link is rejected. If the file has no public link, upload it to Uplika first (media_upload_link without a shell, media_presign then media_complete with one) and pass deliver.mediaId (photos, videos, PDF or HWP/HWPX documents; on Instagram a document other than PDF goes as a download link, because Instagram DMs attach PDF only). Not both. post can be our post id, the post's own id on the platform, a link to the post, "any" for every post, or "next" for the next post you publish (or pass automation on publish to do both in one call). Only one enabled automation per account can wait for "next" (409 next_post_taken). Order when everything is on: opening DM (message + button) -> askEmail -> requireFollow -> deliver (text, up to three link buttons, file; clicks are tracked) -> followUp if no link was clicked. openingDm:false sends deliver as the private reply itself; then requireFollow, askEmail, followUp and files are rejected because the window never opens. The optional public reply under the comment is fixed sentences (publicReply) or written by the AI for each comment (publicReplyMode: "ai" with publicReplyInstruction); either way it is posted only after the private reply went out, and the AI is told a DM was sent.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameNo
postYesOur post id, the platform post id, a link to the post, "any", or "next".
matchNo
deliverYesWhat to send after the tap: text, up to three link buttons, and/or one file (fileUrl or mediaId).
enabledNoDefault false. Prefer leaving it off and calling enable_automation after the person confirms.
messageNoThe opening DM (private reply). One message. Required unless openingDm is false.
askEmailNoAsk for their email after the tap and store it in contact field `email`. Three tries, then continue without.
followUpNoSent followUpAfterMinutes later if none of deliver.links was clicked. Needs openingDm and at least one link.
keywordsNoTrigger words in the comment. Empty means every comment.
accountIdYesConnected Instagram or Facebook account id from list_accounts.
openingDmNoDefault true. false: deliver goes out as the private reply itself (no button, no window afterwards).
emailRetryNo
buttonTitleNoButton under the opening DM, at most 20 characters.
likeCommentNoLike the comment first. Instagram accounts connected through Facebook only.
publicReplyNoOptional public replies under the comment, one picked at random. Posted after the private reply goes out, and skipped when it could not be sent, so a reply saying a DM was sent stays true.
workspaceIdNoWhich workspace this is for. Only needed when the account has more than one — the error tells you the ids when it matters. Leave it out if it is already decided; do not ask the person again.
emailMessageNo
recheckTitleNo
requireFollowNoInstagram only. Deliver only to followers; others are asked to follow and check again.
publicReplyModeNofixed (default) uses publicReply. ai: the AI writes the public reply for each comment in the channel's persona; needs publicReplyInstruction. Counts toward the daily AI limit.
notFollowingMessageNo
followUpAfterMinutesNo1 to 1380 (23 hours). Default 60.
publicReplyInstructionNoWith publicReplyMode ai: what the public reply should say. DM contents (links, codes, prices) are never repeated in public.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • addedInput schema / properties / likeComment
      Added value: +{
      +  "description": "Like the comment first. Instagram accounts connected through Facebook only.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / publicReplyInstruction
      Added value: +{
      +  "description": "With publicReplyMode ai: what the public reply should say. DM contents (links, codes, prices) are never repeated in public.",
      +  "type": "string"
      +}
    • addedInput schema / properties / publicReplyMode
      Added value: +{
      +  "description": "fixed (default) uses publicReply. ai: the AI writes the public reply for each comment in the channel's persona; needs publicReplyInstruction. Counts toward the daily AI limit.",
      +  "enum": [
      +    "fixed",
      +    "ai"
      +  ],
      +  "type": "string"
      +}
  2. Changed1 schema field changed
    • changedInput schema / properties / publicReply / description
      Previous value: -"Optional public replies under the comment; one is picked at random."New value: +"Optional public replies under the comment, one picked at random. Posted after the private reply goes out, and skipped when it could not be sent, so a reply saying a DM was sent stays true."
  3. Changed4 schema fields changed
    • changedInput schema / properties / deliver / description
      Previous value: -"What to send after the tap: text, up to three link buttons, and/or a media id."New value: +"What to send after the tap: text, up to three link buttons, and/or one file (fileUrl or mediaId)."
    • addedInput schema / properties / deliver / properties / fileUrl
      Added value: +{
      +  "description": "Public https link to the file itself, sent as-is. Checked once on save.",
      +  "type": "string"
      +}
    • addedInput schema / properties / deliver / properties / mediaId / description
      Added value: +"A file uploaded to Uplika media, for a file with no public link."
    • addedInput schema / properties / deliver / properties / mediaKind / description
      Added value: +"Filled in from the file when you pass fileUrl."
  4. Changed1 schema field changed
    • addedInput schema / properties / post / type
      Added value: +"string"
  5. Changed12 schema fields changed
    • addedInput schema / properties / askEmail
      Added value: +{
      +  "description": "Ask for their email after the tap and store it in contact field `email`. Three tries, then continue without.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / buttonTitle / description
      Previous value: -"Button under the private reply, at most 20 characters."New value: +"Button under the opening DM, at most 20 characters."
    • changedInput schema / properties / deliver / description
      Previous value: -"What to send after the tap: text, link, and/or a media id."New value: +"What to send after the tap: text, up to three link buttons, and/or a media id."
    • addedInput schema / properties / deliver / properties / link / description
      Added value: +"Legacy: one url appended to the text. Prefer links."
    • addedInput schema / properties / deliver / properties / links
      Added value: +{
      +  "items": {
      +    "properties": {
      +      "title": {
      +        "description": "At most 20 characters.",
      +        "type": "string"
      +      },
      +      "url": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "title",
      +      "url"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 3,
      +  "type": "array"
      +}
    • addedInput schema / properties / emailMessage
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / emailRetry
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / followUp
      Added value: +{
      +  "description": "Sent followUpAfterMinutes later if none of deliver.links was clicked. Needs openingDm and at least one link.",
      +  "type": "string"
      +}
    • addedInput schema / properties / followUpAfterMinutes
      Added value: +{
      +  "description": "1 to 1380 (23 hours). Default 60.",
      +  "type": "number"
      +}
    • changedInput schema / properties / message / description
      Previous value: -"The private reply. One message."New value: +"The opening DM (private reply). One message. Required unless openingDm is false."
    • addedInput schema / properties / openingDm
      Added value: +{
      +  "description": "Default true. false: deliver goes out as the private reply itself (no button, no window afterwards).",
      +  "type": "boolean"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "accountId",
      -  "post",
      -  "message",
      -  "deliver"
      -]New value: +[
      +  "accountId",
      +  "post",
      +  "deliver"
      +]
  6. Added
  7. Removed
  8. Added

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only declare it is a non-read-only, non-destructive, closed-world write. The description goes far beyond that: draft-only until enable_automation, the Meta private-reply mechanics (one per comment, 7-day limit, 24-hour window), one-time fileUrl validation on save, delivery ordering, and platform-specific rejection rules. This is exactly the behavioral context annotations cannot carry.

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

Conciseness3/5

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

The critical constraint ('Creates a draft; nothing goes out until enable_automation') is bolded and front-loaded, which is good. But the body is a single dense run-on paragraph mixing file handling, platform rules, ordering, and error codes; it is informative yet hard to scan and could be structured into sections.

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 23-parameter, nested-object tool with no output schema, the description covers the essential behaviors an agent needs: lifecycle (draft + enable), platform constraints, delivery ordering, file-delivery paths, and public-reply rules including the AI mode's dependency on publicReplyInstruction. Little an agent needs to invoke it correctly is missing.

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?

Schema coverage is 74% and the description adds real meaning on top: post accepts 'any'/'next'/id/link, fileUrl vs mediaId 'not both', openingDm:false semantics, and followUp's dependency on openingDm plus a link. However several params (match, emailRetry, recheckTitle, emailMessage, notFollowingMessage) remain undocumented in both schema and description, so it doesn't fully compensate.

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?

Opens with a concrete verb+resource framing ('when someone comments on a post, DM them') and immediately clarifies the draft semantics. It names the sibling that must run afterward (enable_automation) and the alternative for Threads (create_automation with comment_public_reply), so an agent can distinguish it from siblings without opening a schema.

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 when/when-not coverage: use create_automation for Threads, requireFollow is rejected on Facebook, openingDm:false rejects requireFollow/askEmail/followUp/files, and fileUrl vs mediaId are mutually exclusive. The 409 next_post_taken and 7-day window constraints tell the agent exactly when this call succeeds or fails.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources