Skip to main content
Glama

Manage scheduled messages

manage_scheduled_messages
Destructive

Schedule WhatsApp messages to be sent automatically at a specific time, in one of two modes: bot (default) - sent from Kaption's WhatsApp number, not the user's own. Stored in Kaption's cloud and sent even when this computer is off. One-to-one chats only (no groups); one line, max 800 characters. local ("From this computer") - sent from the user's own WhatsApp number, as them, while this computer and WhatsApp are open. Stays on this device. Kaption keeps it within safe limits automatically (a few messages an hour and a day, minutes apart, only to chats where the other person has written, at most 3 a day to groups) and refuses what does not fit. The only mode that can send to groups (ones the user can post in and posted in within 30 days). Supports one image, document, audio or video attachment (8 MiB max), when attachments from an assistant are turned on for the account and Kaption is up to date; audio captions are refused. A message whose time passes while this computer is off is missed, never sent late on its own. The local mode must first be turned on by the user in Kaption (its "From this computer" option, after reading the risks); an assistant cannot turn it on. A refused local request says why and ends with a reason code, e.g. "(reason: per-day)".

Actions: list - List scheduled messages of both modes (each has "mode"); pass mode to list only one get - Get a specific scheduled message by ID create - Schedule a new message (requires message + datetime + conversation_id) update - Change the message and/or datetime (requires id) delete - Cancel/delete a scheduled message (requires id); in local mode it cancels a waiting message and removes a finished one cancel - Local mode only: cancel a waiting, missed or failed message remove - Local mode only: remove a finished message from the list send_now - Local mode only: send a missed or failed message now (still within the limits) Pass mode "local" for every action on a local message.

Examples: List all: { action: "list" } Schedule (Kaption bot): { action: "create", message: "Hey, just following up!", datetime: "2026-03-07T09:00:00Z", conversation_id: "5491157390064@c.us" } Schedule from the user's own number: { action: "create", mode: "local", message: "Running 10 min late", datetime: "2026-03-07T09:00:00-03:00", conversation_id: "5491157390064@c.us" } Schedule to a group: { action: "create", mode: "local", message: "Standup moved to 10", datetime: "2026-03-07T09:00:00Z", conversation_id: "120363000000000000@g.us" } Cancel: { action: "delete", id: "msg_abc123" }

Input Schema

NameRequiredDescriptionDefault
idNoScheduled message ID (required for get/update/delete/cancel/remove/send_now)
modeNo"bot" (default): sent from Kaption's WhatsApp number. "local": sent from the user's own WhatsApp number while this computer and WhatsApp are open, within safe limits kept automatically; needed for groups. For list, omit to get both modes
actionYesScheduled message action to perform (cancel, remove and send_now need mode "local")
filterNoFilter for list action. Default: "pending" (not sent yet; in local mode also missed or failed ones waiting for the user)
messageNoMessage text to send (required for create, optional for update). Bot: one line, max 800 characters. Local: text or caption up to 2000 characters; omit with an attachment
datetimeNoISO 8601 datetime when the message should be sent (required for create, optional for update)
attachmentNoLocal create/update only. One attachment; null removes it on update. Omit message for attachment-only sends
target_sessionNoSession ID for multi-account routing
conversation_idNoChat to send the message to (required for create): a person, or a group with mode "local"
notification_typeNoBot mode only. Notification type. Default: "automatic"

Output Schema

NameRequiredDescriptionDefault
resultNoThe JSON-compatible result returned by the Kaption extension

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / attachment / anyOf
      Previous value: -[
      -  {
      -    "anyOf": [
      -      {
      -        "additionalProperties": false,
      -        "properties": {
      -          "dataB64": {
      -            "description": "Standard padded base64 bytes, without a data URL prefix",
      -            "maxLength": 11184812,
      -            "minLength": 4,
      -            "pattern": "^[A-Za-z0-9+/]*={0,2}$",
      -            "type": "string"
      -          },
      -          "mime": {
      -            "description": "MIME type, e.g. image/png, application/pdf, audio/ogg, video/mp4",
      -            "maxLength": 200,
      -            "minLength": 3,
      -            "type": "string"
      -          },
      -          "name": {
      -            "description": "Filename without a path",
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "pattern": "^[^\\\\/\\x00-\\x1f\\x7f]+$",
      -            "type": "string"
      -          },
      -          "size": {
      -            "description": "Decoded byte count (maximum 8 MiB)",
      -            "maximum": 8388608,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "required": [
      -          "name",
      -          "mime",
      -          "size",
      -          "dataB64"
      -        ],
      -        "type": "object"
      -      },
      -      {
      -        "additionalProperties": false,
      -        "properties": {
      -          "ref": {
      -            "description": "One-time attachmentRef returned by create_attachment_upload after PUT of the bytes",
      -            "pattern": "^[a-f0-9]{64}$",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "ref"
      -        ],
      -        "type": "object"
      -      }
      -    ],
      -    "description": "Exactly one attachment source: dataB64 or uploaded ref (paths are never accepted); max 8 MiB. Requires MCP_LOCAL_SEND and local delivery"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "anyOf": [
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "dataB64": {
      +            "description": "Standard padded base64 bytes, without a data URL prefix",
      +            "maxLength": 11184812,
      +            "minLength": 4,
      +            "pattern": "^[A-Za-z0-9+/]*={0,2}$",
      +            "type": "string"
      +          },
      +          "mime": {
      +            "description": "MIME type, e.g. image/png, application/pdf, audio/ogg, video/mp4",
      +            "maxLength": 200,
      +            "minLength": 3,
      +            "type": "string"
      +          },
      +          "name": {
      +            "description": "Filename without a path",
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "pattern": "^[^\\\\/\\x00-\\x1f\\x7f]+$",
      +            "type": "string"
      +          },
      +          "size": {
      +            "description": "Decoded byte count (maximum 8 MiB)",
      +            "maximum": 8388608,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "required": [
      +          "name",
      +          "mime",
      +          "size",
      +          "dataB64"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "ref": {
      +            "description": "One-time attachmentRef returned by create_attachment_upload after PUT of the bytes",
      +            "pattern": "^[a-f0-9]{64}$",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "ref"
      +        ],
      +        "type": "object"
      +      }
      +    ],
      +    "description": "Exactly one attachment source: dataB64 or uploaded ref (paths are never accepted); max 8 MiB. Only when sending from this computer is turned on for the account"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  2. Changed1 schema field changed
    • changedInput schema / properties / attachment / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "description": "One inline attachment; requires the owner-only MCP_LOCAL_SEND flag and local delivery",
      -    "properties": {
      -      "dataB64": {
      -        "description": "Standard padded base64 bytes, without a data URL prefix",
      -        "maxLength": 11184812,
      -        "minLength": 4,
      -        "pattern": "^[A-Za-z0-9+/]*={0,2}$",
      -        "type": "string"
      -      },
      -      "mime": {
      -        "description": "MIME type, e.g. image/png, application/pdf, audio/ogg, video/mp4",
      -        "maxLength": 200,
      -        "minLength": 3,
      -        "type": "string"
      -      },
      -      "name": {
      -        "description": "Filename without a path",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "pattern": "^[^\\\\/\\x00-\\x1f\\x7f]+$",
      -        "type": "string"
      -      },
      -      "size": {
      -        "description": "Decoded byte count (maximum 8 MiB)",
      -        "maximum": 8388608,
      -        "minimum": 1,
      -        "type": "integer"
      -      }
      -    },
      -    "required": [
      -      "name",
      -      "mime",
      -      "size",
      -      "dataB64"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "anyOf": [
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "dataB64": {
      +            "description": "Standard padded base64 bytes, without a data URL prefix",
      +            "maxLength": 11184812,
      +            "minLength": 4,
      +            "pattern": "^[A-Za-z0-9+/]*={0,2}$",
      +            "type": "string"
      +          },
      +          "mime": {
      +            "description": "MIME type, e.g. image/png, application/pdf, audio/ogg, video/mp4",
      +            "maxLength": 200,
      +            "minLength": 3,
      +            "type": "string"
      +          },
      +          "name": {
      +            "description": "Filename without a path",
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "pattern": "^[^\\\\/\\x00-\\x1f\\x7f]+$",
      +            "type": "string"
      +          },
      +          "size": {
      +            "description": "Decoded byte count (maximum 8 MiB)",
      +            "maximum": 8388608,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "required": [
      +          "name",
      +          "mime",
      +          "size",
      +          "dataB64"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "ref": {
      +            "description": "One-time attachmentRef returned by create_attachment_upload after PUT of the bytes",
      +            "pattern": "^[a-f0-9]{64}$",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "ref"
      +        ],
      +        "type": "object"
      +      }
      +    ],
      +    "description": "Exactly one attachment source: dataB64 or uploaded ref (paths are never accepted); max 8 MiB. Requires MCP_LOCAL_SEND and local delivery"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  3. Changed2 schema fields changed
    • addedInput schema / properties / attachment
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": false,
      +      "description": "One inline attachment; requires the owner-only MCP_LOCAL_SEND flag and local delivery",
      +      "properties": {
      +        "dataB64": {
      +          "description": "Standard padded base64 bytes, without a data URL prefix",
      +          "maxLength": 11184812,
      +          "minLength": 4,
      +          "pattern": "^[A-Za-z0-9+/]*={0,2}$",
      +          "type": "string"
      +        },
      +        "mime": {
      +          "description": "MIME type, e.g. image/png, application/pdf, audio/ogg, video/mp4",
      +          "maxLength": 200,
      +          "minLength": 3,
      +          "type": "string"
      +        },
      +        "name": {
      +          "description": "Filename without a path",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "pattern": "^[^\\\\/\\x00-\\x1f\\x7f]+$",
      +          "type": "string"
      +        },
      +        "size": {
      +          "description": "Decoded byte count (maximum 8 MiB)",
      +          "maximum": 8388608,
      +          "minimum": 1,
      +          "type": "integer"
      +        }
      +      },
      +      "required": [
      +        "name",
      +        "mime",
      +        "size",
      +        "dataB64"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Local create/update only. One attachment; null removes it on update. Omit message for attachment-only sends"
      +}
    • changedInput schema / properties / message / description
      Previous value: -"Message text to send (required for create, optional for update). Bot: one line, max 800 characters. Local: text only, up to 2000 characters"New value: +"Message text to send (required for create, optional for update). Bot: one line, max 800 characters. Local: text or caption up to 2000 characters; omit with an attachment"
  4. First observed

TDQS

A4.4/5.0
Behavior3/5

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

Annotations already declare destructiveHint=true, readOnlyHint=false and openWorldHint=true, so the safety profile is carried structurally. The description nevertheless adds substantive context: automatic rate limiting, per-day caps, 30-day group posting window, 800-character and 8 MiB ceilings, and that a message whose time passes while the machine is off is missed rather than sent late. It does not discuss irreversibility of delete or auth/scope requirements beyond the local-mode toggle, so it sits above baseline but not at the top.

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

Conciseness4/5

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

Front-loads the mode distinction, which is the decision an agent must make first, then actions, then examples. It is long, and several limits (800 characters, 8 MiB, safe-limit caps) are repeated in both the prose and the schema descriptions, but nearly every sentence carries operational meaning rather than filler.

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?

Ten parameters, four enums, destructive semantics and a dual-mode model make this a complex tool, and the definition covers modes, per-action requirements, examples, limits and failure modes. An output schema exists, so return values need not be explained, and nothing an agent needs to call it correctly appears to be 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 100%, so the baseline is 3; however the description adds real value by pairing parameters with concrete invocation shapes, showing the ISO datetime with offsets, the @c.us vs @g.us conversation_id formats, and that mode must be "local" for every action on a local message. It also notes which fields are required per action (message+datetime+conversation_id for create, id for the rest), which the schema only partially encodes.

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+resource (schedule WhatsApp messages) and immediately splits into two named modes with explicit semantics for each (bot = Kaption's number, cloud-stored, one-to-one; local = user's own number, device-bound, groups allowed). The action list further pins down each operation, so an agent can distinguish this from send_message or manage_reminders 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?

Gives explicit when-to-use guidance per case: bot for offline delivery and 1:1 only, local when groups or the user's own identity are needed, plus the prerequisite that local mode must be enabled by the user and cannot be turned on by an assistant. It also states exclusions and failure behavior (refusals end with a reason code), which is stronger than most definitions.

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