Skip to main content
Glama

Schedule article

schedule_article

Schedule an article to Substack, Medium, LinkedIn Articles, X, WordPress, or Ghost. WordPress and Ghost support publishMode draft, which saves a remote draft without publishing or emailing. Always pass draftId for an article that is already saved (from create_draft, get_draft or list_drafts). title and contentHtml create a new draft and are only for an article that has not been saved yet. A new draft whose title matches an article still queued on the same platform is refused; to change a queued article, use amend_scheduled_item. Supports cover and inline images, Substack-only inline video, and destination-specific SEO metadata. Substack supports native paywall and subscribe controls at explicit positions in contentHtml; ordinary links remain links. Audience and email delivery are controlled by the supplied fields. LinkedIn Articles requires a separate browser-session connection from regular posts; pending session sync saves new input as a draft without scheduling. Settle content, title, paywall, audience and email delivery with the writer before calling. To change only the time of an article that is already scheduled, use amend_scheduled_item or reschedule_scheduled_item rather than cancel_scheduled_item followed by schedule_article. To publish right away, pass publishNow: true instead of inventing a time a few minutes ahead. Each returned post has writerState: tell the writer the article is published only when writerState is published, and share its liveUrl; scheduled or publishing means it is not live yet. Returns scheduling outcomes and advisories; an advisory with action RESYNC_LINKEDIN_ARTICLES means the LinkedIn article is scheduled but may not publish until the writer signs in to LinkedIn or resyncs LinkedIn Articles in Narrareach, so tell the writer its message. When reviewing a Substack article with the writer, briefly mention once per article that they can ask for a Subscribe button after a named paragraph, a caption beneath it, a paywall before a named section (a paywall makes the article paid-only), or a Freewall before a named section (everyone reads the opening; free and paid subscribers keep reading, and readers without an email are invited to subscribe free). Use the requested position; ask where only if it is ambiguous.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "platforms": "<platforms>"
    },
    "name": "schedule_article"
  }
}

Input Schema

NameRequiredDescriptionDefault
tagsNoOptional tag list for newly created drafts. Substack receives all supplied tags. Medium receives its supported first 5 topics and returns a warning when extras are omitted. The saved draft remains unchanged.
mediaNoOptional inline images or Substack article videos for a newly created draft. Replaces {{media:N}} placeholders in array order; leftovers are appended. kind defaults to image; video requires Substack as the sole platform. Supports public URLs, data URIs, and base64 bytes. In ChatGPT, for a file the user attached in the chat, first call upload_media with it in file, then pass the returned publicUrl here as url.
titleNoRequired when creating a new draft.
draftIdNoThe saved article draft id to schedule. Pass it whenever the article was saved with create_draft or exists already. Its body is used as saved; isPaidContent and sendToNewsletter, when supplied, set its Substack audience and email delivery and must match its wall (a Freewall is never paid-only; a paywall is always paid).
freewallNoMake the article's single wall divider (or paywallMarker) a Substack Freewall: everyone sees the content above it; free and paid subscribers keep reading below it. Requires SUBSTACK and a publication with Substack Freewalls. For a new draft (title and contentHtml) it sets the Freewall. A saved draft (draftId) keeps the wall already in its body: a Freewall there is scheduled as a Freewall with or without this field, and true only confirms it. Never combine with isPaidContent. Default false.
subtitleNoOptional article subtitle for newly created drafts. Substack omits subtitles over 250 characters and returns a warning without changing the saved draft.
timezoneNoIANA timezone the scheduledFor time(s) above are expressed in (e.g. "Europe/London"). Defaults to the writer's saved timezone, else UTC.
coverFileNoThe approved cover image the user attached in ChatGPT, passed by the client, for a newly created draft. Use this OR coverImage, never both. For a saved draft (draftId), attach the cover first with update_draft coverFile. Never substitute another image.
platformsYes
coverImageNoOptional cover image for a newly created draft, placed at the top of the published body. Supports public HTTPS URLs, data URIs, or base64 image bytes. URL ingestion depends on source-host access. For an image attached in ChatGPT, use coverFile instead. For a saved draft (draftId), attach the cover first with update_draft.
publishNowNoPublish as soon as possible instead of at a set time. Use this, not a near-future scheduledFor, when the writer asks to publish now. Do not combine it with scheduledFor or platformSchedules. LinkedIn articles still need their minimum notice and go out at the earliest safe time.
contentHtmlNoRequired when creating a new draft. Supports public <img> or <video> elements and {{media:N}} placeholders resolved from media entries. Video articles require Substack as the sole platform. Native Substack paywall markup is <hr data-type="paywall"> at the selected paragraph boundary, or a single {{NARRAREACH_PAYWALL}} token; paywallMarker supports custom tokens. A Substack Freewall (free and paid subscribers keep reading) is <hr data-type="paywall" data-access="subscribers">, or set freewall to true. Native subscribe block markup is <div data-type="button" data-kind="subscribeCaption" data-text="Subscribe" data-caption="Your caption"></div> with HTML-escaped attribute values. data-kind="subscribe" represents a button without caption. Ordinary links remain links. Audience sections use a div with data-dynamic-content="true" and data-dynamic-audiences="paid_sub", containing data-dynamic-content-match="true" and data-dynamic-content-else="true" divs. Supported audience conditions: non_sub, free_sub, paid_sub, founding_sub (comma-separated). Keep both branches. Subscriber-tag targeting must be published in Substack.
publicationNoSubstack destination as a publication name, handle, or URL, for example "AI Newsroom", "@theainewsroom", or "https://theainewsroom.substack.com". Optional when exactly one active Substack publication is connected; Narrareach selects it automatically. Required when more than one active Substack publication is connected, except that when it is missing Narrareach uses the publication the writer scheduled or published to most recently and says so in substackPublicationSelection.message, with publicationChoices listing the others; tell the writer which one was used. If there is no previous choice, the value is ambiguous, or Narrareach cannot confirm the session publishes there, nothing is scheduled and the result has requiresPublicationChoice: true with publicationChoices (name, handle, url, substackConnectionId). Ask which one they want, then call again with publication set to the chosen handle (and draftId when a draft was already saved).
publishModeNoOnly valid when all selected destinations are WordPress or Ghost. Defaults to publish; draft saves a remote draft at the scheduled time without publication.
scheduledForNoRequired unless publishNow or platformSchedules is given, and must be in the future. Shared local wall-clock publishing date/time interpreted in timezone, including DST. A Z or explicit UTC offset represents an absolute instant. LinkedIn articles require at least 20 minutes of lead time.
isPaidContentNoWhether the Substack article is paid-only. Default false. Do not combine with freewall.
paywallMarkerNoOptional custom marker in contentHtml where the selected free preview ends; must appear exactly once. The standard {{NARRAREACH_PAYWALL}} marker is recognized without this field. Creates a native divider without changing sendToNewsletter. With freewall true it allows free and paid subscribers; otherwise it enables paid access.
sendToNewsletterNoSubstack email delivery setting. Default true.
addSearchMetadataNoGenerate SEO titles, descriptions, and a Substack slug for supported article destinations. SEO metadata is generated automatically on Revenue Writer, Full Agentic Mode, and Teams & Agencies, and for trials or other accounts with article SEO access. Set this option to false to turn it off. X does not support separate article SEO settings.
linkedinAuthorUrnNoLinkedIn personal profile or Company Page author URN belonging to the connected LinkedIn Articles account.
platformSchedulesNoOptional per-platform overrides taking precedence over scheduledFor. Same wall-clock + timezone rule applies to each scheduledFor here; LinkedIn entries require at least 20 minutes of lead time.
allowDuplicateTitleNoOnly after the writer confirms they want a second copy of an article with this title that is already queued on the same platform. Defaults to false.
mediumPublicationIdNoOptional authorized Medium publication id when platforms includes MEDIUM. Absent means the personal profile. Writer-only access submits for editorial review and leaves the story unscheduled until acceptance. Explicit publication rejection allows personal-profile delivery with a warning; ambiguous submissions remain unpublished for review. Draft-only delivery does not submit to a publication.
substackConnectionIdNoExact Substack connection identifier, retained for backward compatibility, for example publicationChoices[].substackConnectionId from a requiresPublicationChoice result. publication is the preferred public destination selector; when both are given they must name the same publication.
linkedinNewsletterUrnNoLinkedIn newsletter URN belonging to the connected LinkedIn Articles account. Required when linkedinPublicationType is newsletter.
mediumNotifyFollowersNoWhether to email Medium subscribers about this story. true is only valid when platforms includes MEDIUM; false is ignored. Defaults to false (no email). Best-effort: a failure to apply this setting never blocks the publish/schedule and is reported as a warning.
linkedinPublicationTypeNoLinkedIn destination type. Defaults to an individual article; newsletter represents a user-selected newsletter destination.
linkedinShareCommentaryNoOptional LinkedIn share text used when publishing a LinkedIn article.

Output Schema

NameRequiredDescriptionDefault
codeNo
countYes
postsYes
messageNo
nextStepNo
warningsYes
amendHintNo
advisoriesNo
choiceScopeNo
aiVisibilityNo
createdDraftYes
connectedAccountNo
publicationChoicesNo
substackPublicationYes
archivedEarlierCopiesNo
publicationChoiceReasonNo
archivedEarlierCopiesNoteNo
requiresPublicationChoiceNo
substackPublicationSelectionNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / mediumNotifyFollowers / description
      Previous value: -"Whether to email Medium subscribers about this story. Only valid when platforms includes MEDIUM. Defaults to false (no email). Best-effort: a failure to apply this setting never blocks the publish/schedule and is reported as a warning."New value: +"Whether to email Medium subscribers about this story. true is only valid when platforms includes MEDIUM; false is ignored. Defaults to false (no email). Best-effort: a failure to apply this setting never blocks the publish/schedule and is reported as a warning."
  2. Changed9 schema fields changed
    • addedInput schema / properties / allowDuplicateTitle
      Added value: +{
      +  "description": "Only after the writer confirms they want a second copy of an article with this title that is already queued on the same platform. Defaults to false.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / draftId / description
      Previous value: -"Optional existing article draft id to schedule. Its body is used as saved; isPaidContent and sendToNewsletter, when supplied, set its Substack audience and email delivery and must match its wall (a Freewall is never paid-only; a paywall is always paid)."New value: +"The saved article draft id to schedule. Pass it whenever the article was saved with create_draft or exists already. Its body is used as saved; isPaidContent and sendToNewsletter, when supplied, set its Substack audience and email delivery and must match its wall (a Freewall is never paid-only; a paywall is always paid)."
    • addedInput schema / properties / publishNow
      Added value: +{
      +  "description": "Publish as soon as possible instead of at a set time. Use this, not a near-future scheduledFor, when the writer asks to publish now. Do not combine it with scheduledFor or platformSchedules. LinkedIn articles still need their minimum notice and go out at the earliest safe time.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / scheduledFor / description
      Previous value: -"Required unless platformSchedules is given, and must be in the future. Shared local wall-clock publishing date/time interpreted in timezone, including DST. A Z or explicit UTC offset represents an absolute instant. LinkedIn articles require at least 20 minutes of lead time."New value: +"Required unless publishNow or platformSchedules is given, and must be in the future. Shared local wall-clock publishing date/time interpreted in timezone, including DST. A Z or explicit UTC offset represents an absolute instant. LinkedIn articles require at least 20 minutes of lead time."
    • addedOutput schema / properties / archivedEarlierCopies
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / archivedEarlierCopiesNote
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / posts / items / properties / liveUrl
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "The public post, once the platform confirmed it. Share this link, not itemUrl, when the writer asks where it is."
      +}
    • addedOutput schema / properties / posts / items / properties / writerNextAction
      Added value: +{
      +  "description": "What the writer needs to do next, if anything.",
      +  "enum": [
      +    "none",
      +    "enter_code",
      +    "resync",
      +    "open_narrareach"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / posts / items / properties / writerState
      Added value: +{
      +  "description": "Where the article is, in the writer's words. Tell the writer it is published only when this is published.",
      +  "enum": [
      +    "scheduled",
      +    "publishing",
      +    "waiting_for_you",
      +    "in_review",
      +    "published",
      +    "saved_as_draft",
      +    "needs_attention",
      +    "cancelled"
      +  ],
      +  "type": "string"
      +}
  3. Changed5 schema fields changed
    • changedInput schema / properties / freewall / description
      Previous value: -"Make the article's single wall divider (or paywallMarker) a Substack Freewall: everyone sees the content above it; free and paid subscribers keep reading below it. Requires SUBSTACK and a new draft (title and contentHtml). The publication must have Substack Freewalls available. Default false."New value: +"Make the article's single wall divider (or paywallMarker) a Substack Freewall: everyone sees the content above it; free and paid subscribers keep reading below it. Requires SUBSTACK and a publication with Substack Freewalls. For a new draft (title and contentHtml) it sets the Freewall. A saved draft (draftId) keeps the wall already in its body: a Freewall there is scheduled as a Freewall with or without this field, and true only confirms it. Never combine with isPaidContent. Default false."
    • changedInput schema / properties / timezone / description
      Previous value: -"IANA timezone the scheduledFor time(s) above are expressed in (e.g. \"Europe/London\"). Default UTC."New value: +"IANA timezone the scheduledFor time(s) above are expressed in (e.g. \"Europe/London\"). Defaults to the writer's saved timezone, else UTC."
    • addedOutput schema / properties / posts / items / properties / scheduleAdvisory
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / posts / items / properties / scheduledForLocal
      Added value: +{
      +  "type": "string"
      +}
    • changedOutput schema / properties / posts / items / required
      Previous value: -[
      -  "substackDelivery",
      -  "heldForEditorialReview",
      -  "deliveryNote",
      -  "id",
      -  "itemUrl",
      -  "type",
      -  "status",
      -  "scheduledFor",
      -  "timezone",
      -  "publishedAt",
      -  "error",
      -  "platforms",
      -  "recurringScheduleId",
      -  "draft"
      -]New value: +[
      +  "substackDelivery",
      +  "heldForEditorialReview",
      +  "deliveryNote",
      +  "id",
      +  "itemUrl",
      +  "type",
      +  "status",
      +  "scheduledFor",
      +  "timezone",
      +  "scheduledForLocal",
      +  "scheduleAdvisory",
      +  "publishedAt",
      +  "error",
      +  "platforms",
      +  "recurringScheduleId",
      +  "draft"
      +]
  4. Changed1 schema field changed
    • changedInput schema / properties / scheduledFor / description
      Previous value: -"Shared local wall-clock publishing date/time interpreted in timezone, including DST. A Z or explicit UTC offset represents an absolute instant. LinkedIn articles require at least 20 minutes of lead time."New value: +"Required unless platformSchedules is given, and must be in the future. Shared local wall-clock publishing date/time interpreted in timezone, including DST. A Z or explicit UTC offset represents an absolute instant. LinkedIn articles require at least 20 minutes of lead time."
  5. Changed2 schema fields changed
    • addedInput schema / properties / coverFile
      Added value: +{
      +  "description": "The approved cover image the user attached in ChatGPT, passed by the client, for a newly created draft. Use this OR coverImage, never both. For a saved draft (draftId), attach the cover first with update_draft coverFile. Never substitute another image.",
      +  "properties": {
      +    "download_url": {
      +      "type": "string"
      +    },
      +    "file_id": {
      +      "type": "string"
      +    },
      +    "file_name": {
      +      "type": "string"
      +    },
      +    "mime_type": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "download_url",
      +    "file_id"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / properties / coverImage / description
      Previous value: -"Optional cover image for a newly created draft, placed at the top of the published body. Supports public HTTPS URLs, data URIs, or base64 image bytes. URL ingestion depends on source-host access. In ChatGPT, for a file the user attached in the chat, first call upload_media with it in file, then pass the returned publicUrl here as url."New value: +"Optional cover image for a newly created draft, placed at the top of the published body. Supports public HTTPS URLs, data URIs, or base64 image bytes. URL ingestion depends on source-host access. For an image attached in ChatGPT, use coverFile instead. For a saved draft (draftId), attach the cover first with update_draft."
  6. Changed1 schema field changed
    • changedOutput schema / properties / posts / items / properties / substackDelivery / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "note": {
      -        "type": "string"
      -      },
      -      "requiresVerification": {
      -        "type": "boolean"
      -      },
      -      "state": {
      -        "enum": [
      -          "waiting",
      -          "publishing",
      -          "verifying"
      -        ],
      -        "type": "string"
      -      },
      -      "verification": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "action": {
      -            "type": "string"
      -          },
      -          "connectionId": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "endpoint": {
      -            "type": "string"
      -          },
      -          "instruction": {
      -            "type": "string"
      -          },
      -          "scheduledPostId": {
      -            "type": "string"
      -          },
      -          "tool": {
      -            "type": "string"
      -          },
      -          "tools": {
      -            "additionalProperties": false,
      -            "properties": {
      -              "cancel": {
      -                "type": "string"
      -              },
      -              "complete": {
      -                "type": "string"
      -              },
      -              "start": {
      -                "type": "string"
      -              },
      -              "status": {
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "status",
      -              "start",
      -              "complete",
      -              "cancel"
      -            ],
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "connectionId",
      -          "tool",
      -          "endpoint",
      -          "action",
      -          "instruction"
      -        ],
      -        "type": "object"
      -      },
      -      "verificationUrl": {
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "note",
      -      "requiresVerification"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "note": {
      +        "type": "string"
      +      },
      +      "reason": {
      +        "type": "string"
      +      },
      +      "recoveryRequired": {
      +        "type": "boolean"
      +      },
      +      "requiresVerification": {
      +        "type": "boolean"
      +      },
      +      "state": {
      +        "enum": [
      +          "waiting",
      +          "publishing",
      +          "verifying"
      +        ],
      +        "type": "string"
      +      },
      +      "verification": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "action": {
      +            "type": "string"
      +          },
      +          "connectionId": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "endpoint": {
      +            "type": "string"
      +          },
      +          "instruction": {
      +            "type": "string"
      +          },
      +          "scheduledPostId": {
      +            "type": "string"
      +          },
      +          "tool": {
      +            "type": "string"
      +          },
      +          "tools": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "cancel": {
      +                "type": "string"
      +              },
      +              "complete": {
      +                "type": "string"
      +              },
      +              "start": {
      +                "type": "string"
      +              },
      +              "status": {
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "status",
      +              "start",
      +              "complete",
      +              "cancel"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "connectionId",
      +          "tool",
      +          "endpoint",
      +          "action",
      +          "instruction"
      +        ],
      +        "type": "object"
      +      },
      +      "verificationUrl": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "note",
      +      "requiresVerification"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  7. Changed1 schema field changed
    • addedOutput schema / properties / amendHint
      Added value: +{
      +  "type": "string"
      +}
  8. Changed3 schema fields changed
    • changedInput schema / properties / contentHtml / description
      Previous value: -"Required when creating a new draft. Supports public <img> or <video> elements and {{media:N}} placeholders resolved from media entries. Video articles require Substack as the sole platform. Native Substack paywall markup is <hr data-type=\"paywall\"> at the selected paragraph boundary, or a single {{NARRAREACH_PAYWALL}} token; paywallMarker supports custom tokens. A Substack Freewall (free and paid subscribers keep reading) is <hr data-type=\"paywall\" data-access=\"subscribers\">, or set freewall to true. Native subscribe block markup is <div data-type=\"button\" data-kind=\"subscribeCaption\" data-text=\"Subscribe\" data-caption=\"Your caption\"></div> with HTML-escaped attribute values. data-kind=\"subscribe\" represents a button without caption. Ordinary links remain links."New value: +"Required when creating a new draft. Supports public <img> or <video> elements and {{media:N}} placeholders resolved from media entries. Video articles require Substack as the sole platform. Native Substack paywall markup is <hr data-type=\"paywall\"> at the selected paragraph boundary, or a single {{NARRAREACH_PAYWALL}} token; paywallMarker supports custom tokens. A Substack Freewall (free and paid subscribers keep reading) is <hr data-type=\"paywall\" data-access=\"subscribers\">, or set freewall to true. Native subscribe block markup is <div data-type=\"button\" data-kind=\"subscribeCaption\" data-text=\"Subscribe\" data-caption=\"Your caption\"></div> with HTML-escaped attribute values. data-kind=\"subscribe\" represents a button without caption. Ordinary links remain links. Audience sections use a div with data-dynamic-content=\"true\" and data-dynamic-audiences=\"paid_sub\", containing data-dynamic-content-match=\"true\" and data-dynamic-content-else=\"true\" divs. Supported audience conditions: non_sub, free_sub, paid_sub, founding_sub (comma-separated). Keep both branches. Subscriber-tag targeting must be published in Substack."
    • changedInput schema / properties / draftId / description
      Previous value: -"Optional existing article draft id to schedule as-is."New value: +"Optional existing article draft id to schedule. Its body is used as saved; isPaidContent and sendToNewsletter, when supplied, set its Substack audience and email delivery and must match its wall (a Freewall is never paid-only; a paywall is always paid)."
    • changedInput schema / properties / paywallMarker / description
      Previous value: -"Optional custom marker in contentHtml where the selected free preview ends; must appear exactly once. The standard {{NARRAREACH_PAYWALL}} marker is recognized without this field. Creates a native paywall and enables paid access without changing sendToNewsletter."New value: +"Optional custom marker in contentHtml where the selected free preview ends; must appear exactly once. The standard {{NARRAREACH_PAYWALL}} marker is recognized without this field. Creates a native divider without changing sendToNewsletter. With freewall true it allows free and paid subscribers; otherwise it enables paid access."
  9. Changed3 schema fields changed
    • changedInput schema / properties / contentHtml / description
      Previous value: -"Required when creating a new draft. Supports public <img> or <video> elements and {{media:N}} placeholders resolved from media entries. Video articles require Substack as the sole platform. Native Substack paywall markup is <hr data-type=\"paywall\"> at the selected paragraph boundary, or a single {{NARRAREACH_PAYWALL}} token; paywallMarker supports custom tokens. Native subscribe block markup is <div data-type=\"button\" data-kind=\"subscribeCaption\" data-text=\"Subscribe\" data-caption=\"Your caption\"></div> with HTML-escaped attribute values. data-kind=\"subscribe\" represents a button without caption. Ordinary links remain links."New value: +"Required when creating a new draft. Supports public <img> or <video> elements and {{media:N}} placeholders resolved from media entries. Video articles require Substack as the sole platform. Native Substack paywall markup is <hr data-type=\"paywall\"> at the selected paragraph boundary, or a single {{NARRAREACH_PAYWALL}} token; paywallMarker supports custom tokens. A Substack Freewall (free and paid subscribers keep reading) is <hr data-type=\"paywall\" data-access=\"subscribers\">, or set freewall to true. Native subscribe block markup is <div data-type=\"button\" data-kind=\"subscribeCaption\" data-text=\"Subscribe\" data-caption=\"Your caption\"></div> with HTML-escaped attribute values. data-kind=\"subscribe\" represents a button without caption. Ordinary links remain links."
    • addedInput schema / properties / freewall
      Added value: +{
      +  "description": "Make the article's single wall divider (or paywallMarker) a Substack Freewall: everyone sees the content above it; free and paid subscribers keep reading below it. Requires SUBSTACK and a new draft (title and contentHtml). The publication must have Substack Freewalls available. Default false.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / isPaidContent / description
      Previous value: -"Whether the Substack article is paid-only. Default false."New value: +"Whether the Substack article is paid-only. Default false. Do not combine with freewall."
  10. Changed1 schema field changed
    • addedOutput schema / properties / aiVisibility
      Added value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "checks": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "detail": {
      +            "type": "string"
      +          },
      +          "id": {
      +            "type": "string"
      +          },
      +          "status": {
      +            "enum": [
      +              "pass",
      +              "weak",
      +              "missing"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "id",
      +          "status",
      +          "detail"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "guidance": {
      +      "type": "string"
      +    },
      +    "needsJudgment": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "topFixes": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "wordCount": {
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "wordCount",
      +    "checks",
      +    "topFixes",
      +    "needsJudgment",
      +    "guidance"
      +  ],
      +  "type": "object"
      +}
  11. Changed1 schema field changed
    • changedOutput schema / properties / posts / items / properties / substackDelivery / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "note": {
      -        "type": "string"
      -      },
      -      "requiresVerification": {
      -        "type": "boolean"
      -      },
      -      "state": {
      -        "enum": [
      -          "waiting",
      -          "publishing",
      -          "verifying"
      -        ],
      -        "type": "string"
      -      },
      -      "verification": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "action": {
      -            "type": "string"
      -          },
      -          "connectionId": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "endpoint": {
      -            "type": "string"
      -          },
      -          "instruction": {
      -            "type": "string"
      -          },
      -          "tool": {
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "connectionId",
      -          "tool",
      -          "endpoint",
      -          "action",
      -          "instruction"
      -        ],
      -        "type": "object"
      -      },
      -      "verificationUrl": {
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "note",
      -      "requiresVerification"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "note": {
      +        "type": "string"
      +      },
      +      "requiresVerification": {
      +        "type": "boolean"
      +      },
      +      "state": {
      +        "enum": [
      +          "waiting",
      +          "publishing",
      +          "verifying"
      +        ],
      +        "type": "string"
      +      },
      +      "verification": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "action": {
      +            "type": "string"
      +          },
      +          "connectionId": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "endpoint": {
      +            "type": "string"
      +          },
      +          "instruction": {
      +            "type": "string"
      +          },
      +          "scheduledPostId": {
      +            "type": "string"
      +          },
      +          "tool": {
      +            "type": "string"
      +          },
      +          "tools": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "cancel": {
      +                "type": "string"
      +              },
      +              "complete": {
      +                "type": "string"
      +              },
      +              "start": {
      +                "type": "string"
      +              },
      +              "status": {
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "status",
      +              "start",
      +              "complete",
      +              "cancel"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "connectionId",
      +          "tool",
      +          "endpoint",
      +          "action",
      +          "instruction"
      +        ],
      +        "type": "object"
      +      },
      +      "verificationUrl": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "note",
      +      "requiresVerification"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  12. Changed1 schema field changed
    • changedInput schema / properties / addSearchMetadata / description
      Previous value: -"Generate SEO titles, descriptions, and a Substack slug for supported article destinations. In MCP it defaults to true when the account has article SEO access; pass false to skip. Readers do not see these fields; they help search engines and AI tools understand the article. X does not expose separate article SEO settings."New value: +"Generate SEO titles, descriptions, and a Substack slug for supported article destinations. SEO metadata is generated automatically on Revenue Writer, Full Agentic Mode, and Teams & Agencies, and for trials or other accounts with article SEO access. Set this option to false to turn it off. X does not support separate article SEO settings."
  13. Changed1 schema field changed
    • changedInput schema / properties / addSearchMetadata / description
      Previous value: -"Generate SEO titles, descriptions, and a Substack slug for supported article destinations. Requires article SEO access. X does not expose separate article SEO settings."New value: +"Generate SEO titles, descriptions, and a Substack slug for supported article destinations. In MCP it defaults to true when the account has article SEO access; pass false to skip. Readers do not see these fields; they help search engines and AI tools understand the article. X does not expose separate article SEO settings."
  14. Changed5 schema fields changed
    • changedInput schema / properties / platformSchedules / items / properties / platform / enum
      Previous value: -[
      -  "SUBSTACK",
      -  "MEDIUM",
      -  "LINKEDIN",
      -  "X"
      -]New value: +[
      +  "SUBSTACK",
      +  "MEDIUM",
      +  "LINKEDIN",
      +  "X",
      +  "WORDPRESS",
      +  "GHOST"
      +]
    • changedInput schema / properties / platforms / items / enum
      Previous value: -[
      -  "SUBSTACK",
      -  "MEDIUM",
      -  "LINKEDIN",
      -  "X"
      -]New value: +[
      +  "SUBSTACK",
      +  "MEDIUM",
      +  "LINKEDIN",
      +  "X",
      +  "WORDPRESS",
      +  "GHOST"
      +]
    • addedInput schema / properties / publishMode
      Added value: +{
      +  "description": "Only valid when all selected destinations are WordPress or Ghost. Defaults to publish; draft saves a remote draft at the scheduled time without publication.",
      +  "enum": [
      +    "publish",
      +    "draft"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / posts / items / properties / outcome
      Added value: +{
      +  "enum": [
      +    "saved_draft"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / posts / items / properties / remoteEditUrl
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
  15. Changed1 schema field changed
    • changedOutput schema / properties / posts / items / properties / substackDelivery / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "note": {
      -        "type": "string"
      -      },
      -      "requiresVerification": {
      -        "type": "boolean"
      -      },
      -      "state": {
      -        "enum": [
      -          "waiting",
      -          "publishing"
      -        ],
      -        "type": "string"
      -      },
      -      "verification": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "action": {
      -            "type": "string"
      -          },
      -          "connectionId": {
      -            "anyOf": [
      -              {
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "endpoint": {
      -            "type": "string"
      -          },
      -          "instruction": {
      -            "type": "string"
      -          },
      -          "tool": {
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "connectionId",
      -          "tool",
      -          "endpoint",
      -          "action",
      -          "instruction"
      -        ],
      -        "type": "object"
      -      },
      -      "verificationUrl": {
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "note",
      -      "requiresVerification"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "note": {
      +        "type": "string"
      +      },
      +      "requiresVerification": {
      +        "type": "boolean"
      +      },
      +      "state": {
      +        "enum": [
      +          "waiting",
      +          "publishing",
      +          "verifying"
      +        ],
      +        "type": "string"
      +      },
      +      "verification": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "action": {
      +            "type": "string"
      +          },
      +          "connectionId": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "endpoint": {
      +            "type": "string"
      +          },
      +          "instruction": {
      +            "type": "string"
      +          },
      +          "tool": {
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "connectionId",
      +          "tool",
      +          "endpoint",
      +          "action",
      +          "instruction"
      +        ],
      +        "type": "object"
      +      },
      +      "verificationUrl": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "note",
      +      "requiresVerification"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  16. Changed1 schema field changed
    • changedOutput schema / properties / posts / items / properties / substackDelivery / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "note": {
      -        "type": "string"
      -      },
      -      "requiresVerification": {
      -        "type": "boolean"
      -      },
      -      "state": {
      -        "enum": [
      -          "waiting",
      -          "publishing"
      -        ],
      -        "type": "string"
      -      },
      -      "verificationUrl": {
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "note",
      -      "requiresVerification"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "note": {
      +        "type": "string"
      +      },
      +      "requiresVerification": {
      +        "type": "boolean"
      +      },
      +      "state": {
      +        "enum": [
      +          "waiting",
      +          "publishing"
      +        ],
      +        "type": "string"
      +      },
      +      "verification": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "action": {
      +            "type": "string"
      +          },
      +          "connectionId": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "endpoint": {
      +            "type": "string"
      +          },
      +          "instruction": {
      +            "type": "string"
      +          },
      +          "tool": {
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "connectionId",
      +          "tool",
      +          "endpoint",
      +          "action",
      +          "instruction"
      +        ],
      +        "type": "object"
      +      },
      +      "verificationUrl": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "note",
      +      "requiresVerification"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  17. Changed2 schema fields changed
    • addedOutput schema / properties / posts / items / properties / substackDelivery
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "note": {
      +          "type": "string"
      +        },
      +        "requiresVerification": {
      +          "type": "boolean"
      +        },
      +        "state": {
      +          "enum": [
      +            "waiting",
      +            "publishing"
      +          ],
      +          "type": "string"
      +        },
      +        "verificationUrl": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "state",
      +        "note",
      +        "requiresVerification"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • changedOutput schema / properties / posts / items / required
      Previous value: -[
      -  "heldForEditorialReview",
      -  "deliveryNote",
      -  "id",
      -  "itemUrl",
      -  "type",
      -  "status",
      -  "scheduledFor",
      -  "timezone",
      -  "publishedAt",
      -  "error",
      -  "platforms",
      -  "recurringScheduleId",
      -  "draft"
      -]New value: +[
      +  "substackDelivery",
      +  "heldForEditorialReview",
      +  "deliveryNote",
      +  "id",
      +  "itemUrl",
      +  "type",
      +  "status",
      +  "scheduledFor",
      +  "timezone",
      +  "publishedAt",
      +  "error",
      +  "platforms",
      +  "recurringScheduleId",
      +  "draft"
      +]
  18. Changed2 schema fields changed
    • addedOutput schema / properties / posts / items / properties / deliveryNote
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • changedOutput schema / properties / posts / items / required
      Previous value: -[
      -  "heldForEditorialReview",
      -  "id",
      -  "itemUrl",
      -  "type",
      -  "status",
      -  "scheduledFor",
      -  "timezone",
      -  "publishedAt",
      -  "error",
      -  "platforms",
      -  "recurringScheduleId",
      -  "draft"
      -]New value: +[
      +  "heldForEditorialReview",
      +  "deliveryNote",
      +  "id",
      +  "itemUrl",
      +  "type",
      +  "status",
      +  "scheduledFor",
      +  "timezone",
      +  "publishedAt",
      +  "error",
      +  "platforms",
      +  "recurringScheduleId",
      +  "draft"
      +]
  19. Changed3 schema fields changed
    • changedOutput schema / properties / publicationChoiceReason / enum
      Previous value: -[
      -  "not_specified",
      -  "ambiguous",
      -  "identity_unconfirmed"
      -]New value: +[
      +  "not_specified",
      +  "ambiguous",
      +  "identity_unconfirmed",
      +  "confirmation_required"
      +]
    • removedOutput schema / properties / substackPublicationSelection / properties / source / const
      Removed value: -"remembered_choice"
    • addedOutput schema / properties / substackPublicationSelection / properties / source / enum
      Added value: +[
      +  "remembered_choice",
      +  "sole_connection"
      +]
  20. Changed10 schema fields changed
    • changedInput schema / properties / publication / description
      Previous value: -"Substack destination as a publication name, handle, or URL, for example \"AI Newsroom\", \"@theainewsroom\", or \"https://theainewsroom.substack.com\". Optional when exactly one active Substack publication is connected; Narrareach selects it automatically. Required when more than one active Substack publication is connected."New value: +"Substack destination as a publication name, handle, or URL, for example \"AI Newsroom\", \"@theainewsroom\", or \"https://theainewsroom.substack.com\". Optional when exactly one active Substack publication is connected; Narrareach selects it automatically. Required when more than one active Substack publication is connected, except that when it is missing Narrareach uses the publication the writer scheduled or published to most recently and says so in substackPublicationSelection.message, with publicationChoices listing the others; tell the writer which one was used. If there is no previous choice, the value is ambiguous, or Narrareach cannot confirm the session publishes there, nothing is scheduled and the result has requiresPublicationChoice: true with publicationChoices (name, handle, url, substackConnectionId). Ask which one they want, then call again with publication set to the chosen handle (and draftId when a draft was already saved)."
    • changedInput schema / properties / substackConnectionId / description
      Previous value: -"Legacy internal Substack connection identifier retained for backward compatibility; publication is the public destination selector."New value: +"Exact Substack connection identifier, retained for backward compatibility, for example publicationChoices[].substackConnectionId from a requiresPublicationChoice result. publication is the preferred public destination selector; when both are given they must name the same publication."
    • addedOutput schema / properties / choiceScope
      Added value: +{
      +  "enum": [
      +    "publication",
      +    "profile"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / code
      Added value: +{
      +  "const": "SUBSTACK_PUBLICATION_CHOICE_REQUIRED",
      +  "type": "string"
      +}
    • addedOutput schema / properties / message
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / nextStep
      Added value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "instruction": {
      +      "type": "string"
      +    },
      +    "tool": {
      +      "enum": [
      +        "schedule_article",
      +        "schedule_note"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "tool",
      +    "instruction"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / publicationChoiceReason
      Added value: +{
      +  "enum": [
      +    "not_specified",
      +    "ambiguous",
      +    "identity_unconfirmed"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / publicationChoices
      Added value: +{
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "handle": {
      +        "type": "string"
      +      },
      +      "isDefault": {
      +        "type": "boolean"
      +      },
      +      "name": {
      +        "type": "string"
      +      },
      +      "substackConnectionId": {
      +        "type": "string"
      +      },
      +      "url": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "handle",
      +      "url",
      +      "isDefault",
      +      "substackConnectionId"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / requiresPublicationChoice
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / substackPublicationSelection
      Added value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "instruction": {
      +      "type": "string"
      +    },
      +    "message": {
      +      "type": "string"
      +    },
      +    "publication": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "handle": {
      +          "type": "string"
      +        },
      +        "isDefault": {
      +          "type": "boolean"
      +        },
      +        "name": {
      +          "type": "string"
      +        },
      +        "substackConnectionId": {
      +          "type": "string"
      +        },
      +        "url": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "name",
      +        "handle",
      +        "url",
      +        "isDefault",
      +        "substackConnectionId"
      +      ],
      +      "type": "object"
      +    },
      +    "source": {
      +      "const": "remembered_choice",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "source",
      +    "message",
      +    "publication",
      +    "instruction"
      +  ],
      +  "type": "object"
      +}
  21. Changed2 schema fields changed
    • changedInput schema / properties / coverImage / description
      Previous value: -"Optional cover image for a newly created draft, placed at the top of the published body. Supports public HTTPS URLs, data URIs, or base64 image bytes. URL ingestion depends on source-host access."New value: +"Optional cover image for a newly created draft, placed at the top of the published body. Supports public HTTPS URLs, data URIs, or base64 image bytes. URL ingestion depends on source-host access. In ChatGPT, for a file the user attached in the chat, first call upload_media with it in file, then pass the returned publicUrl here as url."
    • changedInput schema / properties / media / description
      Previous value: -"Optional inline images or Substack article videos for a newly created draft. Replaces {{media:N}} placeholders in array order; leftovers are appended. kind defaults to image; video requires Substack as the sole platform. Supports public URLs, data URIs, and base64 bytes."New value: +"Optional inline images or Substack article videos for a newly created draft. Replaces {{media:N}} placeholders in array order; leftovers are appended. kind defaults to image; video requires Substack as the sole platform. Supports public URLs, data URIs, and base64 bytes. In ChatGPT, for a file the user attached in the chat, first call upload_media with it in file, then pass the returned publicUrl here as url."
  22. First observed

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations' general mutation and open-world signals, it discloses concrete behaviors such as duplicate-title refusal, remote drafts that do not publish or email, and LinkedIn session sync falling back to saving a draft without scheduling. The writerState and RESYNC_LINKEDIN_ARTICLES guidance also explains how to interpret partial, pending, and completed outcomes without overstating that an article is live.

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 purpose and most important invocation rules are front-loaded, and most sentences contain actionable information. However, the very long single paragraph is difficult to scan, repeats substantial schema detail, and gives disproportionate space to the extended Substack feature-review script.

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 28-parameter, multi-platform scheduling tool, the definition covers the major invocation paths, prerequisites, sibling alternatives, platform-specific fallbacks, duplicate handling, and post-call status interpretation. The richly described input schema supplies the remaining field formats and constraints, while the output schema means additional return-value documentation is not required.

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?

Although schema description coverage is 96%, the description adds useful cross-parameter invocation semantics by contrasting the draftId and title/contentHtml paths and connecting publishNow, publishMode, contentHtml controls, and audience fields to operational decisions. Much of the remaining platform and markup detail repeats the schema, so the added value is strong but not uniformly new.

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 opening sentence gives a specific verb, resource, and destination scope: scheduling articles to six named platforms. It further distinguishes remote-draft saving, new-draft scheduling, queued-item amendment, and rescheduling, making the tool's role clear relative to its siblings.

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?

It gives explicit routing rules: use draftId for saved articles, title and contentHtml only for unsaved ones, amend_scheduled_item for queued changes, and amend_scheduled_item or reschedule_scheduled_item for time-only changes. It also says to use publishNow for immediate publishing, avoid the cancel-and-reschedule workaround, and confirm consequential content and delivery choices with the writer first.

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