Connect your AI agent to Helpdesky
Helpdesky ships a remote MCP (Model Context Protocol) server. Connect Claude Desktop, Claude.ai, ChatGPT, Cursor, Claude Code, Replit Agent or a custom agent once, and it can read and write your knowledge base on your behalf, within your operator permissions.
Endpoint
Authentication: OAuth 2.1 (authorization code + PKCE, dynamic client registration — what Claude and ChatGPT use when you paste the URL) or a personal MCP token sent as Authorization: Bearer hdmcp_pt_…. Tokens and connected agents are managed in Dashboard → MCP.
Connect from your client
Claude Desktop / Claude.ai
- Settings → Connectors → Add custom connector.
- Paste
https://helpdesky.io/mcp. - Sign in to Helpdesky and approve the consent screen.
ChatGPT
- Settings → Connectors → Create (developer mode).
- URL
https://helpdesky.io/mcp, authentication OAuth. - Sign in and approve.
searchandfetchmake your help center usable as a knowledge source.
Cursor
Create a personal token, then add to .cursor/mcp.json:
{ "mcpServers": { "helpdesky": {
"url": "https://helpdesky.io/mcp/x/lite",
"headers": { "Authorization": "Bearer hdmcp_pt_…" } } } }/x/lite stays under Cursor's 40-tool cap; /x/all serves everything.
Claude Code
claude mcp add --transport http helpdesky \
https://helpdesky.io/mcp \
--header "Authorization: Bearer hdmcp_pt_…"Without --header, Claude Code uses OAuth instead.
Replit Agent, scripts, custom agents
Any MCP client that speaks Streamable HTTP works: use the URL with either a personal token header or the OAuth flow via the discovery documents above.
Directories and plugins
The server's name in the official MCP Registry is io.helpdesky/helpdesky (a streamable-http remote at https://helpdesky.io/mcp); once the entry is published, clients that read the registry can connect by name. It is also packaged as a ChatGPT plugin whose manifest references this MCP connection and bundles a Helpdesky skill; the directory listing is pending review, so for now connect in developer mode as described above. The facts a directory or reviewer asks for are collected on /mcp-server.
OAuth vs personal tokens
OAuth is right for hosted clients (Claude, ChatGPT): the client registers itself, sends you to Helpdesky to sign in and approve, and receives short-lived access tokens with rotating refresh tokens. Each approval appears under Connected agents on the MCP page, where you can disconnect it at any time — disconnecting stops the agent immediately.
Personal tokens are for tools where you paste a header (Cursor, Claude Code, scripts). A token is shown once when created and stored hashed; name tokens after the tool using them and revoke any you no longer need.
How the agent picks a helpdesk
Start with list_helpdesks. Every other tool takes an optional helpdeskId. It is filled in automatically only when your account belongs to exactly one helpdesk; with several, the agent must pass it explicitly, and a helpdesk you cannot access returns a clear error — the server never silently falls back to another one.
Let an agent install Helpdesky
With an operator's token, an agent can set a help center up end to end — including installing it into the customer's own site — without opening the dashboard. A typical run:
- Create or pick the helpdesk.
list_helpdesks, orcreate_helpdeskfor a new one;check_slug_availabilityfirst. - Brand it.
detect_brandingreads the company website;update_brandingsaves the logo URL and colours;update_helpdesk_settingsandupdate_seo_metadatacover names, labels and meta tags. - Write content.
create_categoryandcreate_article(Markdown), thenpublish_article. At least one published article is required before any hosting check can pass. - Install the embeds.
get_embed_snippetsreturns the widget, ticket center and contact form snippets with the helpdesk id filled in, plus the server-side HMAC signing recipes. The HMAC secret itself is never available through MCP: the user copies it from the Ticket Center page.update_widget_settings,update_ticket_center_settingsandupdate_contact_form_settingstune each surface;get_contact_form_settingsandget_ticket_center_settingsalso return a styling reference — every configurable key, the custom CSS key, the embed's CSS selectors and starter snippets — so an agent can restyle both embeds without the dashboard. - Choose the address.
get_hosting_statusshows the live mode. Custom domain:set_custom_domain, thenget_custom_domain_statusfor the CNAME/TXT records the user's DNS must have — the domain goes live only once DNS and the certificate are ready. Subfolder or headless:get_hosting_instructionsreturns the proxy snippets, or the Content API base URL, stylesheet, spec link and an implementation prompt for the coding agent building the site; thensave_*_hosting→check_*_setup(read-only) →activate_*_hosting, which re-checks and only switches the live address when the check passes. - Keep it healthy.
add_data_sourcesfeeds the Help Center AI;preview_seo_run/run_seo_optimizationandstart_link_scanrun the maintenance tools (a run that is still going after ~20 s returns running plus a job id to poll withget_job_status;preview_seo_runpages through articles in small batches);get_overviewreports the numbers.
For the code side of that run — placing the embed tags, signing ticket center users server-side, writing the subfolder proxy or the headless templates — a coding agent should also follow the AI Agent Skill (plain Markdown).
Security guidance
- Connect agents you trust: tools can publish, edit and delete articles, reply to customers, manage contacts and administer your team within the connected operator's permissions. Deletes, mass-close, blocking a contact, removing a team member, and anything a person receives and cannot be unsent (customer replies, team invitations) are flagged as destructive and agents are instructed to confirm first.
- Give staff only the operator permissions they need — MCP inherits them exactly.
- Review Connected agents and tokens periodically; the list shows when each was last used.
- Billing, passwords, API keys and the connections themselves can never be changed through MCP.
Tool sets
Every tool belongs to one set. What a connection sees depends on the sets stored on its credential (chosen on the consent screen or in Dashboard → MCP) or pinned by its URL. New connections get Support desk; core is always included.
| Preset | Sets | Tools | When |
|---|---|---|---|
| Support desk (default) | core, knowledge-base, inbox, inbox-admin, team | 59 | Day-to-day support: ChatGPT, Claude and other hosted agents. |
| Setup | + settings, hosting, embeds, ai, data-sources | +41 | Onboarding: settings, branding, domain & address, embeds, AI, data sources. |
| Growth | + seo, links | +18 | SEO advisor and link scanner. |
| Lite | core, knowledge-base, inbox | 33 | Clients with a tool cap (Cursor lists 40 across all servers). |
| Everything | all 12 sets | 118 | Scripts and agents that need the full surface. |
Enabling more on request. The agent can call list_tool_sets and enable_tool_sets (e.g. ["setup"]) when you ask it to configure something; the sets are saved on that connection and tools/list grows. A tool from a disabled set answers with an "enable the … set first" message. Turning the permission off, or removing sets, is done in the dashboard — agents can only add.
URL variants pin the sets regardless of the credential: https://helpdesky.io/mcp/x/lite, https://helpdesky.io/mcp/x/support,setup, https://helpdesky.io/mcp/x/all, and …/readonly on any of them keeps only read-only tools (e.g. https://helpdesky.io/mcp/x/all/readonly). OAuth works on variants too (the resource URL is the variant).
Available tools
Generated from the live registry. Each tool returns structured output (structuredContent) plus a short text summary. Article content is Markdown.
Account
get_profilereadReturns the connected Helpdesky user: a stable opaque id, display name and email. Use it to tell accounts apart.
list_helpdesksreadLists the helpdesks the connected user belongs to, with their role and operator permissions. Call this first; other tools need a helpdeskId when the user has more than one helpdesk.
get_helpdeskreadReturns a helpdesk's name, slug, public URL, enabled features and plan limits. Settings fields are limited to what the user's role may see.
Articles
list_articlesreadLists knowledge-base articles (drafts and published) with optional status, category and title filters, paginated. Returns summaries; call get_article for the Markdown body.
get_articlereadReturns one article in full (Markdown content, publish state, category, authors, public URL) by id or by slug.
create_articlewriteCreates a knowledge-base article. Content is Markdown. The slug is derived from the title unless given (must be unique per helpdesk). Articles are drafts unless published=true; publishing generates search embeddings, same as the dashboard. Fails with a clear message when the plan's article limit is reached.
update_articlewriteUpdates an article's title, Markdown content, excerpt, category, slug or display options. Only the fields you pass change. Use publish_article / unpublish_article to change the publish state.
publish_articlewritePublishes a draft so it appears on the public help center, in search and in AI answers (embeddings are generated). Counts toward the plan's article limit.
unpublish_articlewriteUnpublishes an article: it disappears from the public help center, search and AI answers but keeps its content and slug as a draft.
delete_articledestructivePermanently deletes an article and its redirects. This cannot be undone — confirm with the user first. Consider unpublish_article instead when the content might be needed later.
Categories
list_categoriesreadLists the help center's categories in display order.
create_categorywriteCreates a category. The slug is derived from the name. Optional icon is a Lucide icon name.
update_categorywriteRenames a category (its slug follows the name) or changes its description/icon. Only passed fields change.
reorder_categorieswriteSets the display order of categories. Pass every category id in the desired order; ids that do not belong to the helpdesk are ignored.
delete_categorydestructivePermanently deletes a category. Its articles are kept but become uncategorised. Confirm with the user first.
Redirects
list_redirectsreadLists slug redirects (old article URL → current article), created automatically when a published article's slug changes or added manually.
update_redirectwriteChanges the old slug of a redirect (the source URL). The slug must not be in use by an article or another redirect.
delete_redirectdestructivePermanently deletes a redirect; the old URL will return 404 afterwards. Confirm with the user first.
Search & answers
search_help_centerreadSearches the helpdesk's published articles the way the public help center does (semantic search when embeddings exist). Returns summaries with public URLs.
ask_help_centerreadAsks the helpdesk's AI assistant a question and returns its answer with source articles, using the same retrieval-augmented pipeline (published articles + data sources) that answers visitors. Goes through the dashboard's authenticated Ask AI, so it works even when the widget is restricted to specific domains; requires an AI key (Settings > AI) and the messages permission.
searchreadSearches the published help-center articles of every helpdesk the user belongs to. Returns result ids, titles and absolute public URLs; pass an id to fetch for the full text.
fetchreadFetches the full Markdown text of an article by the id returned from search.
Contacts
list_contactsreadLists the customers (contacts) of a helpdesk with their conversation count and last contact date, optionally filtered to blocked or active contacts or searched by name/email. Paginated (limit ≤ 200).
list_contact_conversationsreadReturns the contact and every conversation they have had with the helpdesk, newest first. Useful to see history before replying.
block_contactdestructiveBlocks a contact: their new widget messages, emails and contact-form submissions are dropped and they can no longer open conversations. Existing conversations stay. Reversible with unblock_contact, but it silences a customer — confirm with the user first.
unblock_contactwriteLifts a block so the contact can message the helpdesk again.
update_contact_emailwriteChanges a contact's email address; future replies on their conversations go to the new address. Fails when another contact of the helpdesk already uses it (merge by moving conversations with set_conversation_contact instead).
Conversations
list_conversationsreadLists customer conversations (tickets) of a helpdesk, newest first by default, paginated. Status values: pending = new, awaiting the first operator reply; unresolved = in progress (an operator has replied); resolved = closed; stale = auto-flagged after a period without activity; promotional = bulk/marketing email kept out of the default list. Omitting status returns every status except promotional. assignee "me" means assigned to the connected operator. sort "unread" puts unread conversations first. search matches the contact name/email and the last message preview. Call get_conversation for the thread.
get_conversation_countsreadReturns the number of conversations that still need attention (every status except resolved and promotional) and the number of unread promotional conversations. The non-resolved count is owner-only; for staff it is returned as null.
get_conversationreadReads one conversation: its details, the contact, and the latest messages (up to 20, oldest first). Use list_conversation_messages with offset to page through longer threads. Attachments are listed as filename/type/size plus the URL the dashboard uses; access to that URL is bound to the uploader and conversation, so the agent cannot necessarily download them. Replies through MCP are text-only: never pass attachment URLs or file contents when replying.
list_conversation_messagesreadPages through a conversation's messages, oldest first (limit ≤ 100). Reading also marks the thread as seen by an operator, like opening it in the inbox. Attachments are listed as filename/type/size plus the URL the dashboard uses; access to that URL is bound to the uploader and conversation, so the agent cannot necessarily download them. Replies through MCP are text-only: never pass attachment URLs or file contents when replying.
reply_to_conversationdestructiveSends an operator reply exactly as the dashboard does: the message is delivered to the customer by email (queued for a minute unless sendInstantly) and pushed live to the widget; the conversation is marked read, assigned to you if unassigned, and moved from pending/stale to unresolved. A sent reply cannot be unsent — confirm with the user (quote the draft) before calling this unless they already approved the exact text. Set isPrivateNote for an internal note that the customer never sees. Text-only: never include attachment URLs.
edit_messagewriteRewrites the body of an operator message you sent (owners can edit any operator message). Customer messages cannot be edited. Already-sent emails are not recalled; the widget and ticket center show the edited text.
delete_messagedestructivePermanently deletes an operator message you sent (owners can delete any operator message); customer messages cannot be deleted. This cannot be undone — confirm with the user first.
translate_messagewriteTranslates one message into a target language with the helpdesk's AI translation (en, el, fr, de, es, it, pt, nl, ru, tr, ar, zh, ja, ko). Translations are cached per message and language; the original is never changed.
set_conversation_statuswriteChanges a conversation's status. resolved closes it and records you as the resolver; pending or unresolved reopens it. Status values: pending = new, awaiting the first operator reply; unresolved = in progress (an operator has replied); resolved = closed; stale = auto-flagged after a period without activity; promotional = bulk/marketing email kept out of the default list. Stale and promotional cannot be set by hand.
assign_conversationwriteAssigns a conversation to an operator of the same helpdesk (ids from list_assignable_operators; your own id is currentOperatorId in get_conversation), or unassigns it when operatorId is null. Assignment only affects inbox filters and avatars; it does not notify the operator.
mark_conversation_readwriteClears (or, with unread: true, restores) the unread flag on a conversation, exactly like the inbox's read/unread toggle.
set_conversation_contactwriteRe-links a conversation to a different contact of the same helpdesk (for example after a customer wrote from a second address). Future reply emails go to the new contact.
set_conversation_notification_emailswriteReplaces the list of extra email addresses (max 5) that receive operator replies for this conversation instead of the contact's own address. Pass an empty list to go back to emailing the contact.
mass_close_conversationsdestructiveMarks EVERY conversation of the helpdesk that is not yet resolved (pending, unresolved, stale, open) as resolved in one go. Owner only. There is no undo and no per-conversation selection — confirm with the user first, naming the exact helpdesk; use set_conversation_status to close individual conversations.
delete_conversationdestructivePermanently deletes a conversation with all of its messages and attachments. This cannot be undone — confirm with the user first. Prefer set_conversation_status resolved when the history should be kept.
Team
list_operatorsreadLists the helpdesk's team: owners and staff, pending invitations included, with each member's permissions. Requires the staff permission (owners always have it).
list_assignable_operatorsreadLists the active operators a conversation can be assigned to (id + display label). Needs only the messages permission, so any inbox user can assign.
invite_operatordestructiveInvites a person to the helpdesk team by email with a role and permissions; Helpdesky sends the invitation email (the same one the dashboard sends) and it cannot be recalled, so confirm with the user first. An existing user is added straight away and gains access immediately. Requires the staff permission (owners always have it).
invite_operator_batchdestructiveInvites the same person to several helpdesks at once with one role and permission set; one invitation email covers all of them and cannot be recalled, so confirm with the user first. Each helpdesk is checked separately and reported in results. Requires the staff permission (owners always have it).
update_operator_permissionswriteReplaces a staff member's permission set (pass the full list you want them to end up with). Owner only; owners' own permissions cannot be restricted.
update_operator_rolewritePromotes a staff member to owner or demotes an owner to staff. Owner only. Demoting keeps the member's existing permission list, so review it with update_operator_permissions afterwards.
update_operator_notificationswriteTurns new-message email notifications on or off for one team member. Members can change their own setting; owners can change anyone's.
remove_operatordestructiveRemoves a team member (or cancels a pending invitation) from the helpdesk; their conversations become unassigned. They lose access immediately and must be re-invited to return — confirm with the user first. Requires the staff permission (owners always have it).
Settings & branding
get_helpdesk_settingsreadReturns the helpdesk's general settings, branding (colours, logo URL, theme, labels) and SEO metadata as the dashboard pages show them. Fields are limited to what the user's permissions allow (settings, branding, seo, widget, ticket_center, contact_form or email_forwarding); keys and secrets are never included.
update_helpdesk_settingswriteUpdates general settings (name, website URL, powered-by badge, author display, Help Center AI, allowed widget domains, homepage mode, navigation labels, messaging/widget toggles). Only the fields you pass change. Use change_helpdesk_address for the slug, update_branding for colours/logo, update_seo_metadata for meta tags.
update_brandingwriteUpdates the help center's look: logo/favicon/share-image URLs (URLs only — no uploads), colours, button radius, theme, hero text, template layout and navigation labels. Only the fields you pass change. Use detect_branding to pull colours and logo from the company website first.
update_seo_metadatawriteSets the help center's meta title and meta description (the homepage <title> and description tag). Pass only what should change.
detect_brandingreadScans a public website's homepage and returns the logo, favicon and colours it finds, as the Branding page's auto-detect does. Nothing is saved: pass the values you want to update_branding. Pass the customer's website URL; without one the helpdesk must already have a custom domain connected (the Branding page flow), and its website/apex is scanned instead.
check_slug_availabilityreadChecks whether helpdesky.io/help/<slug> is available. Returns the normalised slug; the helpdesk's own current slug counts as available.
change_helpdesk_addresswriteChanges the slug behind helpdesky.io/help/<slug>. Check availability first with check_slug_availability; existing links to the old address stop working, so confirm with the user.
create_helpdeskwriteCreates another help center owned by the user (name + slug, optional meta title/description and logo URL). May be refused when the user's plan has no free slot; the response then explains what the user must do in the dashboard. Billing cannot be changed through MCP.
Hosting: Domain & Address
get_hosting_statusreadShows how the help center is served: the live mode (helpdesky address, custom domain, subfolder or headless), the live URL, the saved-but-inactive addresses, verification state and the previous address still kept for redirects. For custom-domain DNS/certificate details call get_custom_domain_status.
get_custom_domain_statusreadReports the custom domain's state at Cloudflare and in public DNS, with the CNAME (and any TXT) records the user must create at their DNS provider. Readiness depends on DNS changes only the user (or their DNS provider's agent) can make; poll this after they change records — certificates can take minutes.
set_custom_domainwriteRegisters a custom hostname (e.g. help.example.com) for the help center and returns the DNS records to create. The domain only goes live once the CNAME points at the expected target and the certificate is issued — use get_custom_domain_status to poll. Replaces any previously saved custom domain.
remove_custom_domaindestructiveDisconnects the custom domain; the help center falls back to its Helpdesky address (or another active mode). Confirm with the user first — visitors on the old domain will no longer reach the help center.
save_subfolder_hostingwriteSaves the public address for subfolder hosting, where the customer's site reverse-proxies the help center under a path on their own domain (snippets from get_hosting_instructions). Saving changes nothing visible yet: run check_subfolder_setup, then activate_subfolder_hosting. Checks are read-only and need at least one published article; activation re-runs the check and only switches the live address when it passes.
check_subfolder_setupreadRuns the read-only setup check against the saved subfolder address and reports each step (pass/fail with a message). It changes nothing. Requires at least one published article. When ok is true, call activate_subfolder_hosting to go live.
activate_subfolder_hostingwriteRe-runs the setup check for the saved address and, only if it passes, makes it the live help center address (the old address keeps redirecting). Pass the exact address the check reported. Fails harmlessly when the check does not pass.
remove_subfolder_hostingdestructiveRemoves the saved subfolder address. If it was live, the help center falls back to the next address and the removed one is kept as the previous address for redirects. Confirm with the user first.
forget_previous_subfolder_addressdestructiveForgets the previous subfolder address so it no longer redirects to the live help center. Only do this when old links no longer matter; confirm with the user first.
save_headless_hostingwriteSaves the public address for headless hosting, where the customer's own site renders the help center from the public Content API (spec and prompt from get_hosting_instructions). Saving changes nothing visible yet: run check_headless_setup, then activate_headless_hosting. Checks are read-only and need at least one published article; activation re-runs the check and only switches the live address when it passes.
check_headless_setupreadRuns the read-only setup check against the saved headless address and reports each step (pass/fail with a message). It changes nothing. Requires at least one published article. When ok is true, call activate_headless_hosting to go live.
activate_headless_hostingwriteRe-runs the setup check for the saved address and, only if it passes, makes it the live help center address (the old address keeps redirecting). Pass the exact address the check reported. Fails harmlessly when the check does not pass.
remove_headless_hostingdestructiveRemoves the saved headless address. If it was live, the help center falls back to the next address and the removed one is kept as the previous address for redirects. Confirm with the user first.
forget_previous_headless_addressdestructiveForgets the previous headless address so it no longer redirects to the live help center. Only do this when old links no longer matter; confirm with the user first.
get_hosting_instructionsreadReturns what the Domain & Address panels offer as copyables, filled in with this helpdesk's values: reverse-proxy snippets for subfolder hosting (Cloudflare, Vercel, Next.js, Netlify, nginx) and, for headless hosting, the public Content API base URL, the article stylesheet URL, the implementation spec link and a ready-to-use implementation prompt for a coding agent. Pass the intended public address to tailor them before saving it; saved addresses are used otherwise.
Embeds: widget, ticket center, contact form
get_widget_settingsreadReturns the embeddable widget's state: enabled flag, widgetConfig (appearance, labels, suggested articles), messaging-in-widget flag and the widget-related messaging texts.
update_widget_settingswriteEnables/disables the widget and updates widgetConfig (merged key by key with the saved config) and the widget messaging texts (welcome note, disclaimer, live-chat notes). Pass only what should change.
get_ticket_center_settingsreadReturns the ticket center configuration (messagingConfig keys ticketCenter*, tc*, customFields), whether messaging is enabled, and a styling reference: every configurable key with its type, allowed values, default and purpose (including ticketCenterCss for custom CSS), the CSS selectors the embed renders and the dashboard's starter CSS snippets. The Turnstile secret and the HMAC secret are never returned.
update_ticket_center_settingswriteUpdates ticket center configuration keys (ticketCenter*, tc*, customFields); they are merged into the saved config, so pass only what should change. Custom CSS goes in ticketCenterCss (plain CSS using the embed's .hdh-tc-* selectors; it lands in the embed's shadow DOM unchanged). Known keys: ticketCenterCss, ticketCenterStyle, ticketCenterAlign, tcAccentSource, tcHideBorder, tcShowEmailField, tcColorPrimary, tcColorPrimaryHover, tcColorPrimaryText, tcColorBg, tcColorSurface, tcColorText, tcColorTextSubdued, tcColorBorder, tcColorAccent, tcColorBubble, tcRadiusButton, tcRadiusCard, tcLabelTitle, tcLabelNewMessage, tcLabelEmptyHeading, tcLabelEmptyBody, tcLabelPlaceholder, tcLabelSend, tcLabelSending, tcLabelClosed, tcLabelSubject, customFields. Read the current values, allowed values, defaults, selectors and starter snippets with get_ticket_center_settings.
get_contact_form_settingsreadReturns the contact form configuration (messagingConfig keys contactForm*, cf*, turnstile*, customFields), whether messaging is enabled, and a styling reference: every configurable key with its type, allowed values, default and purpose (including contactFormCss for custom CSS), the CSS selectors the embed renders and the dashboard's starter CSS snippets. The Turnstile secret and the HMAC secret are never returned.
update_contact_form_settingswriteUpdates contact form configuration keys (contactForm*, cf*, turnstile*, customFields); they are merged into the saved config, so pass only what should change. Custom CSS goes in contactFormCss (plain CSS using the embed's .hdh-cf-* selectors; it lands in the embed's shadow DOM unchanged). Known keys: contactFormCss, contactFormAlign, contactFormMaxWidth, cfAccentSource, contactFormButtonColor, cfButtonTextColor, cfLabelColor, cfUseBranding, cfBgColor, cfHideBorder, contactFormButtonText, contactFormSuccessHeading, contactFormSuccessBody, cfNameLabel, cfNamePlaceholder, cfEmailLabel, cfEmailPlaceholder, cfMessageLabel, cfMessagePlaceholder, customFields, turnstileSiteKey, turnstileSecretKey. Read the current values, allowed values, defaults, selectors and starter snippets with get_contact_form_settings.
get_embed_snippetsreadReturns the widget, ticket center and contact form embed snippets with this helpdesk's id filled in, plus the server-side HMAC signing recipes the ticket center needs (Node.js, Python, PHP, Ruby, Shopify Liquid). The HMAC secret itself is never returned: recipes use the placeholder YOUR_HMAC_SECRET; tell the user to copy the secret from the Ticket Center page.
AI settings & question log
get_ai_settingsreadReturns the preferred AI provider and model and, per provider, whether an API key is saved. Keys are write-only and never returned. Owner only.
update_ai_settingswriteSets the preferred provider/model and saves provider API keys. Keys are stored encrypted and never returned; pass an empty string to delete a key. Verify with check_ai_configuration afterwards. Owner only.
check_ai_configurationreadSends a tiny request to the provider with the saved key (or a key passed just for this test) and reports whether it works. Nothing is saved. Owner only.
list_ai_modelsreadReturns the chat models available for a provider: the provider's live list when a key is saved, otherwise the built-in defaults. Owner only.
list_ai_questionsreadLists questions visitors asked the Help Center AI (most recent first) with the answer given, plus the most popular questions. Filter by text and date.
Data sources
list_data_sourcesreadLists the web pages the Help Center AI learns from, with scrape status (pending/processing/ready/error). Poll this after add_data_sources or rescrape_data_source.
add_data_sourceswriteAdds web pages as AI data sources. Scraping starts in the background; returns immediately with status pending/processing — poll list_data_sources. Use discover_data_source_urls to find pages on a site first.
update_data_sourcewriteTurns a data source on or off for AI answers without deleting it.
delete_data_sourcedestructivePermanently removes a data source and its indexed content. Confirm with the user first.
rescrape_data_sourcewriteFetches and re-indexes a data source in the background. Returns immediately with status processing — poll list_data_sources until it is ready or error.
discover_data_source_urlsreadReads a site's sitemap and returns page URLs, optionally filtered by a path pattern (e.g. /docs/*). Nothing is added — pass the URLs you want to add_data_sources.
SEO advisor
get_seo_suggestionsreadRuns the AI SEO advisor on one article and returns a 1-10 score with concrete suggestions (category, issue, fix). Nothing changes; feed a suggestion to preview_seo_fix or apply_seo_fix.
preview_seo_fixreadShows what applying one suggestion would change (field, current value, proposed value) without saving anything.
apply_seo_fixwriteApplies one suggestion to the article (title, meta description, slug or content) and records an undoable SEO change. Preview first with preview_seo_fix.
preview_internal_linksreadAsks the AI where an article could link to other published articles; returns the proposed links and the rewritten content without saving. Target and method restrictions apply to this preview only (as on the SEO page): add_internal_links re-runs the AI across all published articles.
add_internal_linkswriteLets the AI insert links to other published articles into this article and saves the result as an undoable SEO change (undo_seo_change). The AI considers every published article; it cannot be restricted to specific targets. Use preview_internal_links first.
preview_seo_runreadAnalyses published articles with the AI and returns a plan (per article: score + suggestions) without changing anything; pass it, possibly trimmed, to run_seo_optimization. Each article is one AI analysis, so the work is paged: a call analyses `limit` articles (default 3, max 10, in the order the dashboard uses) starting at `offset`, or exactly the `articleIds` you name. Keep batches small enough to finish within a minute; `nextOffset` is null once every published article has been covered. Needs seo and articles permissions.
run_seo_optimizationwriteApplies the suggestions in a plan from preview_seo_run (pass it back, possibly trimmed). Every change is recorded and undoable. Long-running: when the run is not finished after ~20 s the tool returns status running plus a jobId — poll get_job_status until it is completed or failed before starting another run (a retry would apply the plan again). Needs seo and articles permissions.
list_seo_changesreadLists changes made by the SEO advisor (manual and automated), newest first, with previous/new values and whether each was undone. Needs seo and articles permissions.
undo_seo_changewriteRestores the previous value of one SEO change (from list_seo_changes). Needs seo and articles permissions.
get_seo_automationreadReturns whether the SEO advisor runs on a schedule, the schedule and the last run time.
update_seo_automationwriteTurns scheduled SEO optimisation on or off and sets how often it runs.
get_job_statusreadReports a job started by run_seo_optimization or start_link_scan: running, completed (with the handler's result) or failed (with the error), so you know when to stop polling and whether a retry is safe. Jobs are kept in memory on the server that started them for a few hours; status unknown means the id is not held here (server restart or another instance) — then check the persisted outcome with list_seo_changes or get_link_scan_results.
Link scanner
start_link_scanwriteChecks every link in published articles and stores the results. Long-running: when the scan is not finished after ~20 s the tool returns status running plus a jobId — poll get_job_status, then read get_link_scan_results.
get_link_scan_resultsreadReturns the stored results of the last link scan (URL, HTTP status, article, follow/nofollow). Use brokenOnly to list just the failures.
fix_linkwriteReplaces a scanned link's URL inside the article that contains it (from get_link_scan_results).
update_link_followwriteMarks the given scan results as follow or nofollow, updating the links in their articles.
get_link_scanner_settingsreadReturns whether links are scanned automatically, how often, and when the last automatic scan ran.
update_link_scanner_settingswriteTurns automatic link scanning on or off and sets how often it runs.
Overview
get_overviewreadThe same numbers the dashboard Overview shows: published and draft article counts, total article views, category count and the five most recently updated articles.
Messaging settings
get_notification_settingsreadReads who gets emailed about new customer messages: the owner toggle, promotional toggle, extra notification addresses and each operator's own preference.
update_notification_settingswriteChanges the helpdesk-wide new-message notification settings. Owner only; only the fields you pass change. Use update_operator_notifications for a single member's preference.
get_messaging_settingsreadReads whether messaging is enabled and the messaging configuration (widget/ticket-center/contact-form options and custom fields). Works while messaging is switched off. Credentials (ticket-center signing secret, Turnstile secret key) are never returned; manage them in the dashboard.
update_messaging_settingswriteTurns messaging on/off (also the way to re-enable it) and/or merges top-level keys into the messaging configuration (keys you pass overwrite the stored value of that key; other keys are kept). Ticket-center keys need the ticket_center permission and contact-form/turnstile keys the contact_form permission; anything else needs settings. Credential keys such as turnstileSecretKey are refused — set them in the dashboard. Read get_messaging_settings first and send complete values for the keys you change.
get_automation_settingsreadReads the inbox automations: auto-resolve (close conversations with no activity after N days) and stale marking (flag quiet conversations after N days).
update_automation_settingswriteChanges auto-resolve and stale-marking automations (1–365 days). Only the fields you pass change; enabling auto-resolve starts the clock from now, so older quiet conversations are not closed retroactively.
Other tools
list_tool_setsreadLists the tool sets of this server with their tools and whether each is enabled for this connection, plus the presets (named bundles of sets). Tools from disabled sets are not listed by tools/list; use enable_tool_sets to turn a set on, then list tools again.
enable_tool_setswriteEnables one or more tool sets (or presets such as setup / growth / all) for this connection, saved on the credential so later requests keep them. Returns the tools that became available; call tools/list again afterwards. Sets can only be added here — the user removes sets from the Helpdesky dashboard. Permissions still apply: a set never grants more than the user's operator role allows.
Prefer plain HTTP? The REST API covers categories and articles with an API key. Overview, example prompts and the facts directories ask for: /mcp-server.