Skip to main content
Glama

Approve Posts

approve_posts
Destructive

Approves the exact revisions given ([{postId, rev}], where rev comes from get_post/search_posts). There is no separate publish step. For website channels the result names the next CMS step (queued at a time, or a CMS draft that does not go live). An approved social post reads approved for a few seconds while Mark hands it to the publisher, then scheduled, and publishes at its scheduled time; confirm with get_post. An approved email stays approved: Mark doesn't send email yet. An approved LinkedIn Article stays approved with handoff publish_by_hand (publish_now once its slot time passes) until someone records its live URL with record_post_published. Each approved outcome carries handoff: handing_off, or stuck with the reason and fix when the post can't go (no scheduled time, no connected account for the channel, or Mark couldn't start the handoff), so you don't have to wait to learn it. A post whose handoff couldn't start can still read handing_off on get_post for up to 5 minutes after approval; trust this result. A stale rev is refused. On a channel set to admins only, only workspace admins can approve; anyone else gets those posts back skipped. Only use it when the user has explicitly asked to approve. Related: get_post, search_posts, review_post.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
postsYesPairs of postId and rev to approve.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
outcomesYes
submittedYes
lifecycleWarningsYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedOutput schema / properties / outcomes / items / properties / handoff / anyOf
      Previous value: -[
      -  {
      -    "oneOf": [
      -      {
      -        "additionalProperties": false,
      -        "properties": {
      -          "state": {
      -            "const": "handing_off",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "state"
      -        ],
      -        "type": "object"
      -      },
      -      {
      -        "additionalProperties": false,
      -        "properties": {
      -          "reason": {
      -            "type": "string"
      -          },
      -          "state": {
      -            "const": "stuck",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "reason",
      -          "state"
      -        ],
      -        "type": "object"
      -      }
      -    ]
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "oneOf": [
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "state": {
      +            "const": "handing_off",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "state"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "reason": {
      +            "type": "string"
      +          },
      +          "state": {
      +            "const": "stuck",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "reason",
      +          "state"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "reason": {
      +            "type": "string"
      +          },
      +          "state": {
      +            "const": "publish_by_hand",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "reason",
      +          "state"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "reason": {
      +            "type": "string"
      +          },
      +          "state": {
      +            "const": "publish_now",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "reason",
      +          "state"
      +        ],
      +        "type": "object"
      +      }
      +    ]
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / properties / outcomes / items / properties / handoff / description
      Previous value: -"An approved social post's handoff to the publisher: handing_off (it moves to scheduled within seconds), stuck with the reason and fix (no scheduled time, no connected account for the channel, or no progress 5 minutes after approval), or null for every other status and every website post."New value: +"An approved social post's handoff to the publisher: handing_off (it moves to scheduled within seconds), stuck with the reason and fix (no scheduled time, no connected account for the channel, or no progress 5 minutes after approval), or null for every other status and every website post. An approved LinkedIn Article has no publisher: publish_by_hand before its scheduled time and publish_now from it on, until someone records its URL with record_post_published."
  2. Changed1 schema field changed
    • addedOutput schema / properties / outcomes / items / properties / handoff
      Added value: +{
      +  "anyOf": [
      +    {
      +      "oneOf": [
      +        {
      +          "additionalProperties": false,
      +          "properties": {
      +            "state": {
      +              "const": "handing_off",
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "state"
      +          ],
      +          "type": "object"
      +        },
      +        {
      +          "additionalProperties": false,
      +          "properties": {
      +            "reason": {
      +              "type": "string"
      +            },
      +            "state": {
      +              "const": "stuck",
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "reason",
      +            "state"
      +          ],
      +          "type": "object"
      +        }
      +      ]
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "An approved social post's handoff to the publisher: handing_off (it moves to scheduled within seconds), stuck with the reason and fix (no scheduled time, no connected account for the channel, or no progress 5 minutes after approval), or null for every other status and every website post."
      +}
  3. First observed

TDQS

A4.4/5.0
Behavior5/5

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

With annotations already declaring destructiveHint=true and idempotentHint=false, the description still adds substantial behavioral context beyond them: there is no separate publish step, outcomes vary by channel (social goes scheduled, email stays approved, LinkedIn Article waits on publish_by_hand), stale revs are refused, admins-only channels return skipped posts, and the handoff/stuck result is authoritative even if get_post lags 5 minutes. This is unusually rich disclosure.

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?

The description is long, but it is front-loaded with the action and scope, then proceeds through channel-specific outcomes and failure modes in roughly descending importance. Some of the per-channel outcome enumeration overlaps with what the existing output schema would convey, which keeps it short of a 5.

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 single-parameter mutation tool with annotations and an output schema already present, the description covers everything an agent needs: input provenance, the no-publish-step model, per-channel end states, permission constraints, staleness handling, and where to verify results. Nothing material is missing.

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

Parameters3/5

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

Schema description coverage is 100% and the schema already documents postId, rev, and their provenance. The description's only parameter-level addition is that a stale rev is refused; otherwise the single param is fully covered by the schema, so the baseline 3 applies.

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?

The description opens with a specific verb and resource ('Approves the exact revisions given') and immediately scopes the input to [{postId, rev}]. It is readily distinguishable from siblings like review_post, submit_post, and get_post, which are called out by name as the source of rev and as related tools.

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

Usage Guidelines4/5

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

It gives a clear precondition/exclusion: 'Only use it when the user has explicitly asked to approve,' and states that rev must come from get_post or search_posts. It falls just short of 5 because it doesn't explicitly route the agent to an alternative action (e.g., submit_post) when approval isn't requested.

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