Skip to main content
Glama

Update HelpCenter Article

helpcenter_update_article
Destructive

Update an existing article by id in the connected HelpCenter.io help center.

Partial update: only the fields you pass are changed. Requires a write-scoped API key. Per-language fields (title, content, slug) are objects keyed by language code and merge per language.

Args:

  • article_id (number, required): id of the article to update.

  • title, content, slug (objects, optional): per-language fields to set.

  • category_id (number, optional): primary category id.

  • categories (number[], optional): replace the set of additional categories.

  • type ('article' | 'faq', optional).

  • visibility ('public' | 'private' | 'link_only', optional).

  • published (boolean, optional): true publishes, false reverts to draft.

  • external_id (string, optional): adopt this article under a stable key you own, so later upserts by that key hit this article.

  • content_format ('html' | 'markdown', optional): defaults to 'html'. Set 'markdown' when sending markdown, or the raw markup is stored as the body.

  • rehost_images (boolean, optional): ON by default through this connector. Copies externally hosted images in the content you send into this help center's storage (see helpcenter_create_article). Send false to keep the original image URLs.

  • change_note (string, optional, up to 2,000 characters): why you are making this change, in a sentence or two of plain text. TEAM-ONLY: the team reads it beside the edit in the dashboard's Overview; it is never in a response, a webhook, search, or anything a reader sees. Give one whenever you change content.

  • change_refs (array, optional, at most 5): links to what asked for the change — a ticket, a pull request, a release note — each { label (up to 80 characters), url (https on a public host name; not an IP address or localhost, no user:password@) }. Team-only, like change_note.

  • notes (array, optional, at most 20): private team notes on passages of the text THIS call writes, each { quote, note, lang }. quote: the passage as PLAIN TEXT exactly as it will read in the new content you send (not Markdown or HTML), occurring there exactly once. note: 1-5000 characters, what you changed and why. lang: the language of that content — required when this call writes more than one language's content, optional when it writes one.

  • annotate_changes ({ note }, optional): ONE private note per language whose content this call changes, highlighting what changed against the live text it replaces — every added block whole, and in each edited block the span from its first to its last changed word — with note (1-5000 characters) as your reason. A language whose content does not change gets no note.

IMPORTANT — this writes LIVE. On a published article the change is visible to readers immediately. To prepare an edit privately and release it deliberately, use helpcenter_stage_article_changes and helpcenter_publish_staged_changes instead.

NOTES ON WHAT YOU CHANGE: notes and annotate_changes put your reason on the passage itself, so a reviewer sees the change and why in place. The notes are PRIVATE — the team sees them highlighted in the editor; readers never do — so never repeat one into reader-facing text.

  • They need the notes.write scope ON TOP of what the write needs (it is separate from content access, and an API key holds it only if it was issued with it), and the account's dashboard access to team notes. Without them the call is refused with 403 insufficient_scope, role_forbidden or notes_forbidden, and NOTHING is written.

  • ALL OR NOTHING: if any quote is refused, nothing is written — no content, no staged version, no revision, no note, no re-hosted image. Fix the note and send the WHOLE call again.

  • NOT IDEMPOTENT with notes: repeating a call that succeeded leaves its notes a second time. Read them back with helpcenter_list_article_notes before retrying.

  • 422 refusals name the field at fault (e.g. notes.0.quote): note_quote_not_found — the quote is not in the new text (a passage that is only in the text being replaced cannot be noted); note_quote_ambiguous — it occurs more than once (occurrences says how often): quote more of the sentence; note_lang_required — the call writes several languages and a note has no lang; note_locale_not_written — a note names a language this call writes no content for. For a passage already in the article, use helpcenter_create_article_note.

  • ONE NOTE PER PASSAGE: a passage carries one note's highlight. Two notes of one call may not quote overlapping text (422 note_quotes_overlap). With both fields, each note keeps its quote and annotate_changes highlights the rest of the change; if your notes quote EVERY change in a language, annotate_changes would have nothing left and the call is refused (422 annotate_changes_covered): leave it out, or quote less.

Returns: { status: "success", article: {...}, images? } with the updated article; images reports re-hosted and failed images as for helpcenter_create_article. With notes or annotate_changes, the response also carries notes: [every note this call created, each { id, lang, note, anchor: { mark_id, quote, highlighted }, author, via }] and, with annotate_changes, annotate_changes: [{ lang, status: "annotated" | "skipped", note_id, highlighted, passages, unplaced_passages, reason }]. reason is "unchanged" on a skipped language, or why an annotated note has no highlight: "nothing_to_highlight" (only removals, or changes with no text such as an image), "not_located" (a changed passage could not be pinned to one place), "too_long" (too large to compare word by word). A response WITHOUT notes means the HelpCenter.io API is older than this connector: it ignored both fields and wrote the content without any note. The result then says so, and carries notes_warning.

Errors: 403 if the key is read-scoped; 404 if the article id is not in this help center; 400 for a language code the site does not have; 422 (validation_error) for an invalid category id or a malformed field. A change_note or change_refs the API refuses (too long, too many links, a url that is not https on a public host) refuses the whole call, and nothing is written. With notes or annotate_changes, also the 403 and 422 refusals above.

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": {
      "article_id": "<article_id>"
    },
    "name": "helpcenter_update_article"
  }
}

Input Schema

NameRequiredDescriptionDefault
slugNoPer-language URL slug. Auto-generated from the title if omitted.
typeNoContent type (default 'article').
notesNoPrivate team notes on passages of the text THIS call writes, at most 20: say on the passage itself what you changed and why. Each quote must occur exactly once in the new text. Needs the notes.write scope, and if any quote is refused nothing at all is written.
titleNoPer-language title to set.
contentNoPer-language article body (HTML/markdown as your site uses).
site_idNoWhich help center to act on: an id from helpcenter_list_sites. Needed when this connection reaches more than one help center; omit it when it reaches one. Applies to this call only — pass it on every call of a task, and ask the user which help center they mean if their request does not say.
publishedNotrue publishes the article, false keeps it as a draft.
article_idYesId of the article to update.
categoriesNoAdditional category ids to attach (multi-category). All must belong to this site.
visibilityNoVisibility: 'public', 'private' (team only), or 'link_only' (shareable token URL).
category_idNoPrimary category id, or 0 for uncategorized. Must belong to this site.
change_noteNoWhy you are making this change, in a sentence or two of plain text, up to 2,000 characters, e.g. "Pro plan renamed Growth in the 4.2 pricing." TEAM-ONLY: kept beside the edit in the dashboard's Overview, never in an API response, a webhook, search or anything a reader sees. Give one whenever you change content.
change_refsNoUp to 5 links to what asked for this change — a ticket, a pull request, a release note — each { label, url }. Team-only, like change_note.
external_idNoA stable key you own (a source filename, CMS id, repo slug). Makes writes idempotent: sending the same key again updates the article it created instead of creating a second one, so an interrupted run can simply be replayed. Strongly recommended whenever you may retry.
rehost_imagesNoCopy images the content references from other hosts (and inline data: images) into this help center's own storage, and point the article at the copies. ON by default through this connector; send false to keep the original image URLs. The response's `images` reports what was re-hosted and what failed.
content_formatNoFormat of the `content` you are sending. Defaults to 'html'. Set 'markdown' when content is markdown and the API will convert it — sending markdown without this stores the raw markup as the article body.
annotate_changesNoLeave ONE private note per language whose content this call changes, highlighting what changed against the live text it replaces: every added block whole, and in each edited block the span from its first to its last changed word. Content that does not change gets no note. Needs the notes.write scope.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Far exceeds the annotations: it discloses that writes are LIVE and immediately reader-visible, the extra notes.write scope and the exact 403 codes when it is missing, all-or-nothing atomicity on note refusals, non-idempotency with notes, the version-skew case where old APIs silently drop notes, and the full 400/404/422 error surface.

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?

Front-loaded and logically ordered, but very long for a description of this size, with the notes block restating schema-level constraints (character limits, max items) already in the JSON Schema. The density is defensible for the gotchas, but several lines could be trimmed without loss.

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 17-parameter nested mutation with no output schema, it covers the return shape ({ status, article, images?, notes?, annotate_changes?, notes_warning }), the reason codes on skipped annotations, and every refusal path an agent must handle to call it correctly.

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

Parameters5/5

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

Schema coverage is already 100%, yet the description adds real meaning beyond it: content_format stores raw markup if unset, rehost_images is ON by default through this connector, external_id 'adopts' the article under a key you own, and the notes/annotate_changes interplay (one note per passage, note_quotes_overlap, annotate_changes_covered) is explained in ways the schema does not.

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 specific verb+resource+identifier ('Update an existing article by id in the connected HelpCenter.io help center') and immediately states partial-update semantics. It is clearly separable from helpcenter_create_article, helpcenter_stage_article_changes and helpcenter_delete_article named elsewhere in the text.

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 an explicit alternative path: to prepare privately, use helpcenter_stage_article_changes and helpcenter_publish_staged_changes instead. It also routes the agent elsewhere for adjacent cases (helpcenter_create_article_note for passages already in the article, helpcenter_list_article_notes before retrying after a notes failure).

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