Horizontal

WorksMaps, weather and travelCode and development

dotsy

Build and publish static sites on dotsy with draft-first MCP tools, OAuth Connect, and API keys.

Addresshttps://mcp.dotsy.ai/mcp
Claude Codeclaude mcp add --transport http mcp https://mcp.dotsy.ai/mcp
For Cursor and other clients
{
  "mcpServers": {
    "mcp": {
      "type": "http",
      "url": "https://mcp.dotsy.ai/mcp"
    }
  }
}

Watch out

Has tools that change things: 40 of them

The server itself marks these tools as deleting or overwriting data (destructiveHint): have the agent ask you before it calls them.

Test
Works: Handshake succeeded
Tools
117 tools
Handshake
768 ms
Transport
streamable-http · 2025-06-18
Tested
6 November 2026
Registry name
ai.dotsy/mcp v0.8.10
Listed
6 November 2026
Updated
6 November 2026
Website
dotsy.ai
The last 1 tests
WhenResultTime
2026-11-06 12:09 UTCHandshake succeeded768 ms

The 117 tools it listed

"Read only" and "Changes data" are the server's own marks. Underlined parameters are required.

  1. adapt_site_analyzeRead only

    Propose nav wiring + blog collectionization for an imported mirror (draft, opt-in). Read-only; returns per-adapter reports + proposalEtag. Nav decline may include nextStep (e.g. mega-menu → edit fragments/header.html). Wait for mirror-vs-editable answer if requiredDecision pending.

    site full adapters options refreshProposal context

  2. adapt_site_applyChanges data

    Apply the adapt proposal (draft): wire nav into the menu store and/or rewrite the blog index to a live <dotsy-collection>. One undo covers the whole apply; a second apply is refused until adapt_site_revert (or force). Queued applies are polled to completion.

    site ifMatch adapters dryRun force context

  3. adapt_site_revertChanges data

    Atomically restore everything the last adapt_site_apply wrote (fragments, the menu doc when the op touched it, index, member configs, routes).

    site context

  4. add_custom_domain

    Connect apex and/or www on a paid plan; starts a DNS connect session.

    site hosts domain context

  5. add_idea

    Add an idea from outside the site (draft board item or inbox suggestion). Idempotent on externalRef.

    site title description board status area source externalRef requester asSuggestion context

  6. apply_changesetChanges data

    Stage writes[] + deletes[] in one call; attach routes via writes[].route. writes[].ifMatch (hash from get_site_manifest; "" = must not exist) guards each key (a delete takes { key, ifMatch } too); atomic:true makes one stale key write nothing (409 changeset_conflict). At most 10 writes; each body ≤60KB and the call ≤80KB. Larger new pages: stage_content_chunk then writes[].bodyStaging, or dotsy push / PUT content-raw.

    site writes deletes message atomic context guestToken

  7. batch_patch_contentChanges data

    patch_content on multiple keys; all-or-nothing validation. Preferred edit path for pages over 60KB. replace-string value/replace ≤60KB; whole call ≤80KB.

    site items context guestToken

  8. bulk_put_assetsChanges data

    Upload 1–200 CMS assets; key = path after /assets/, or sitePath for an exact URL path (e.g. /.well-known/security.txt, /ads.txt). Each item: exactly one of bodyBase64, bodyText (plain text for .css/.js/.mjs/.json/.svg/.txt/.xml only — not .html pages), or importFromUrl. Optional bodySha256 verifies submitted bytes before write; response sha256 is stored bytes (JS/CSS match; WebP rasters may differ). JPEG/PNG/static GIF are re-encoded to WebP (response key photo.webp; /assets/photo.jpg keeps serving it) — use the response key in CSS/JS; optimize:false stores the bytes as sent at your key; animated GIFs are always kept. Uploaded files are live in the editor and draft preview at once; the published site picks them up at the next publish.

    site items context

  9. bulk_put_contentChanges data

    Stage many content keys (pages, layouts, fragments). Content only — not routes or assets. Each body ≤60KB and the whole call ≤80KB; larger pages use stage_content_chunk, dotsy push, or PUT content-raw. May queue above the inline threshold.

    site title content context

  10. claim_site

    Move the guest draft onto your signed-in dotsy account. Requires OAuth Connect; pass the guestToken from start_site.

    context guestToken

  11. create_site

    Create empty site; seeds brief. Globally taken slugs auto-suffix to `{slug}-{adjective}-{noun}` (default); pass onSlugTaken:"fail" to get a 409 instead of a renamed site.

    slug title keyConvention purpose onSlugTaken editingMode workspace context

  12. delete_assetChanges data

    Delete a static asset by key. The editor and draft preview drop it at once; the published site drops it at the next publish.

    site key context

  13. delete_contentChanges data

    Delete content key (tombstone if published). A fragments/* section that pages still place is refused with section_in_use (lists the pages) — detach it or remove it first.

    site key context

  14. delete_draft_testChanges data

    Remove a draft A/B test (releases variant bodies; does not publish).

    site experimentId context

  15. delete_menu_itemChanges data

    Remove one item from a menu (page stays live).

    site menu id context

  16. delete_routeChanges data

    Remove a route by path.

    site path context

  17. delete_siteChanges data

    Permanently delete site; confirmSlug must equal slug.

    site confirmSlug context

  18. detach_sectionChanges data

    Give one page its own copy of a shared section; every other page keeps the shared one. A draft — publish_site to go live. A section the layout places is hidden on that page instead (share_section name + hide).

    site name pageKey ifMatch dryRun context guestToken

  19. discard_draftsChanges data

    Discard unpublished drafts: all (omit key/keys/routes/menus), one content key (key), menu draft only (menus:true), or a selection (keys, routes). Destructive — check get_draft_status first.

    site key keys routes menus context

  20. edit_pageRead only

    Open the interactive page canvas to change content: the user clicks an element, then you call patch_content. Use when the intent is editing — not for verify-only checks (use preview_page).

    site path stage

  21. estimate_testRead only

    Estimate days to reach promote readiness for a page (traffic baseline). Read-only.

    site path context

  22. find_replaceChanges data

    Case-insensitive find→replace across pages in one staged commit. Batch all replacements into ONE call — never parallelize find_replace on the same key (concurrent edits surface as per-key conflict). find/replace ≤60KB.

    site find replace keys expectPerKey context

  23. form_recipients

    Who a site's forms may email. A form's `to` address gets submissions only when it is a verified site member or it confirmed by a one-click link we email it (no account, no sign-in, no site access). action: `list` (confirmed + waiting addresses), `status` (one address: member | confirmed | pending | expired | unconfirmed), `request` (email the confirm link; 7 days, single use; max 3 per address, 20 per site and 50 per account a day), `revoke` (stop form emails to a confirmed address). A publish already sends the link once by itself when a form emails an unconfirmed address. Never ask the user for the link — it goes to that inbox only.

    site action email context

  24. get_account_contextRead only

    Account, user, memberships[]. Pass workspace on writes when memberships.length > 1.

    workspace context

  25. get_activityRead only

    List site activity or fetch one change diff (pass id). Filters: who, state, actor (me), since, limit≤20. Notes from context are visible to everyone on the site — no secrets.

    slug who state actor since limit id key context guestToken

  26. get_adapt_statusRead only

    Read adapt state: proposal summary + proposalEtag (+ applied/consumed flag), undo-record presence, active or queued job progress. Use to resume in a fresh session.

    site context

  27. get_analyticsRead only

    Read-only traffic overview (default) or full breakdowns via include[]; optional bot id for crawler page drill-down.

    site range include bot context

  28. get_assetRead only

    Read one asset (metadata + base64 + stored sha256). sha256 is the stored blob; may differ from upload bodySha256 when IMAGES re-encodes rasters. Uploaded files are live in the editor and draft preview at once; the published site picks them up at the next publish.

    site key context

  29. get_boardRead only

    List board items with status, stamp fields, and baked vote counts (draft overlay included). Live vote totals: site host GET /__dotsy/votes.

    site collection context

  30. get_collection_schemaRead only

    Read the site's collection field definitions (`_data/collections.json`, draft view): { schema: { v: 1, collections: { "<key>": { fields[], settings? } } }, hash }. hash is null when no schema exists yet — pass it as put_collection_schema ifMatch. 409 collection_schema_invalid { hash, issues } means the stored file is broken: fix it with put_collection_schema using that hash.

    site context

  31. get_contentRead only

    Read one content key; optional selector (region) or published=true (live body). Bodies over 40KB without a selector return a truncated summary — use selector, batch_patch_content, or dotsy pull.

    site key selector published context guestToken

  32. get_custom_codeRead only

    Read the site-wide custom code: `draft` (what the next publish puts live) and `published` (what visitors get now) for both boxes — head (before </head>) and body (before </body>) — plus `pending`, `runOn` and `maxChars`.

    site context

  33. get_custom_domain_connectRead only

    Current connect session and nextAction (browser URL or manual DNS guide).

    site sessionId context

  34. get_draft_statusRead only

    Pending draft changes: content keys and routes with status. May include requiredDecision (publish_confirm) before publish_site.

    site context

  35. get_form_submissionRead only

    Read one form submission with the full field payload (explicit PII access — use only when needed).

    site id context

  36. get_menuRead only

    Read a menu's draft items and etag; menu rules → get_skill('nav').

    site menu context

  37. get_menu_docRead only

    Read the whole menu doc (all menus + shell/template), etag for put_menu_doc, and issues (by item id) — page_not_routable, page_missing, page_dead_link, page_is_redirect — computed from the draft routes, so a link that won't show or leads nowhere shows up before publish.

    site source context

  38. get_planRead only

    Read-only workspace plan and pooled usage; pass slug for this site's add-ons. Call before a large build.

    slug context

  39. get_reportRead only

    Your dotsy bug reports. Omit id for the list; pass id for one ticket and its public replies.

    id cursor context

  40. get_routeRead only

    Get one route by path (home is '/').

    site path context guestToken

  41. get_siteRead only

    Site detail, stats, publicUrl, brief head (default-on), and readiness flags. pages[] is a ~25-entry head by default (stats.pages has the true count) — pass pages: true for the full array (capped at 1000), or enumerate everything with list_content/get_site_manifest. Large sites (200+ pages): list_pages is paginated — use cursor or get_site_manifest for the full route set.

    site brief pages context guestToken

  42. get_site_build_progressRead only

    Read-only build progress view (structure/adapt jobs or after import). structuredContent.forHumans holds the headline and progress. import_site_from_url blocks until done, so this is not needed during an import; get_site has the full state.

    site

  43. get_site_manifestRead only

    Content keys + hashes only (optional routes=true) — static files live in list_assets, not manifest. Diff keys+hashes before apply_changeset; stage only changed bodies.

    site mode routes limit cursor context

  44. get_site_outlineRead only

    Site shape: every layout and shared section (`sections`: fragments/* by name, with page count, whether the file exists and staged-change flag), whether a layout is missing, redirects count, menus grouped by where they show, and collections with their page placements. Use for 'is my layout missing', 'which shared sections exist and where', 'where does this menu show' — without listing every page. Read-only; indexing mirrors list_pages (a freshly imported/graduated site may still be indexing).

    site context

  45. get_skillRead only

    Skill body + optional questions[]. Accepts an id OR a synonym (e.g. 'list', 'menu') — resolves aliases and suggests near-misses. Start with intake when ambiguous.

    id

  46. get_structure_resultRead only

    Last structure apply job result (structuredKeys, conflicts, partial).

    site full context

  47. get_structure_statusRead only

    Flat vs structured page counts; chromeCoverage = real per-fragment page counts + missedPages (check before promising sitewide edits). Informs user — do not auto-run analyze/apply while requiredDecision pending.

    site context

  48. graduate_siteChanges data

    Enable site search & collections (kv → do-sqlite), one-way. Unlocks search_content, collection indexes, visitor /__paige/search, and moves any R2 form-submission ledger into SiteDb. 409 blocked covers three unrelated gates: an unsupported source backend (no override, ever); strictDrafts — default true, this client sends true unless you pass strictDrafts:false — blocking on unpublished drafts or unrecovered KV content rows; or a KV snapshot that looks incomplete (e.g. a page deleted in the last couple of minutes). force:true overrides ONLY that last, incomplete-snapshot gate — never the backend or strictDrafts gates. The blocked response's `reason` names which gate fired, and `audit` (+ `audit.warnings`) is aggregate COUNTS only (published/route/pending-draft counts) — never row keys — so judge the size of the gap, not a row list, before forcing. The flip is one-way: anything outside the frozen snapshot is unreachable once it lands.

    site strictDrafts force context

  49. import_site_from_url

    Import URL to draft. On complete, response may include requiredDecision — preview then ask mirror vs editable before structure_*.

    site sourceUrl mode pages segments keyConvention onSlugTaken workspace context

  50. infer_collection_schemaRead only

    Suggest fields for one collection from a sample of its items' meta.custom values (published data, else drafts) — writes nothing. Returns { sampled, suggestions: [{ field: { key, type, options? }, count, samples, defined }], skipped }. Review, then add the ones you want via put_collection_schema.

    site collection context

  51. inspect_collectionRead only

    Collection state — count, server.mode, sample entries, tag (membershipKind, match=) when discovered; plus name, noun, URL pattern, layout, where it's listed, and post fields used. Pass status/q/cursor/limit (any one, even empty) for a full items[] page instead: status draft = never published; a published post with unpublished edits is status published with hasChanges:true (never draft) and shows its staged title/date/tags/author; scheduled = future visibleAt. Never-published drafts come from staged content (no extra reads, no publish needed to see them); published/scheduled come from the index. limit defaults to 50, clamped 1-200. Omit all four for just the base inspect (no items[]).

    site prefix status q cursor limit context

  52. install_product_kit

    Add a roadmap, changelog and/or help centre to a site as drafts (never overwrites; rerun finishes a partial install).

    site parts context

  53. list_assetsRead only

    CMS uploads under assets/ only — not mirrored clone CDN (get_site mirroredAssets or import warmJob). Not content — use list_content. Uploaded files are live in the editor and draft preview at once; the published site picks them up at the next publish.

    site limit cursor context

  54. list_collectionsRead only

    Collections on the site — name, noun, item count (or 'not published yet'), URL pattern, and whether any member is staged. Includes a collection only a draft page lists. Returns a bare array (not wrapped in an object) — pass each row's key verbatim to inspect_collection/update_collection.

    site context

  55. list_contentRead only

    List content keys (HTML/md); not assets — use list_assets. Defaults to 50 keys per page — raise limit (max 1000) or pass cursor (from nextCursor) to page through the rest. Per-row `size`/`missing` are measured automatically only on pages of ≤100 rows; past that they're ABSENT (not measured, never `null`) unless you pass withSize:true, which forces measurement at a cost of one storage read per returned row. Only `size: null` + `missing: true` means the page's stored bytes are gone.

    site limit cursor withSize context guestToken

  56. list_custom_domainsRead only

    List all custom hostnames and connection status for the site.

    site context

  57. list_form_submissionsRead only

    List form submissions (metadata + bounded field preview — not full PII). Works on kv and do-sqlite backends.

    site form limit cursor fromMs toMs q context

  58. list_goalsRead only

    List site conversion goals (pageview paths and form submits). Required before start_test.

    site context

  59. list_ideasRead only

    Search draft/published board items and open suggestions by title token overlap.

    site q board context

  60. list_my_sitesRead only

    List your dotsy sites. Renders a site-picker for humans; agent reads structuredContent. Use to choose a site — not for editing content (use edit_page) or verify-only checks (use preview_page). Defaults to your active workspace; pass workspace (org id or slug from get_account_context memberships) to list another workspace's sites without switching the dashboard session.

    workspace

  61. list_notificationsRead only

    Account notification inbox (Needs you · Updates). Summary-first: tab counts plus compact rows with nextAction (MCP tool or dashboard URL). OAuth person only — not API keys.

    tab scope slug unreadOnly context

  62. list_pagesRead only

    List pages on a site — route settings (path/title/navLabel/purpose) by default, one row per route. Renders a page-picker for humans (redirect and worker routes left out there — nothing to open in edit_page); agent reads structuredContent. Use after picking a site — not for editing (use edit_page) or verify-only checks (use preview_page). Pass view:'pages' to group by layout instead — adds layout/noLayout/q filters, what each page places, and indexing progress; use that for 'what pages use this layout' or 'is this page indexed yet', not for route settings. Paginated — pass cursor (from nextCursor) for more; partial:true means this page is a window, not the full route set.

    site limit cursor view layout noLayout q

  63. list_skillsRead only

    Paige build skills (id + whenToUse). Pull get_skill on demand — do not duplicate in tool text.

  64. list_suggestionsRead only

    List form suggestions awaiting moderation (duplicate hints against the board).

    site status context

  65. list_versionsRead only

    List the site's published versions, newest first (who, when, pages, live, restorable). Use before restore_version.

    site cursor limit context

  66. list_votesRead only

    List voters on one board item (voter id + source only — no email).

    site collection item context

  67. mark_notifications_read

    Mark Update notifications read (ids or all). Needs-you Actions refuse with 422 action_not_markable — fix the cause (it clears itself); only the person can dismiss them in the dashboard.

    ids all context

  68. moderate_suggestion

    Decide one form suggestion from list_suggestions: approve (new draft board item; stages content, does not publish), merge (into an existing board item, subscribes the voter/email) or decline (no board item).

    site id decision itemKey title slug body status reason context

  69. new_post_templateRead only

    Read-only scaffold for a new post — suggested key/path, membership meta, blank or duplicate body. Then put_post (+ optional put_route).

    site collection templateKey mode context

  70. optimize_assetsChanges data

    Shrink heavy images in place (0.98): JPEG/PNG/still GIF → WebP at the same address, so no HTML changes. keys = site paths from verify_page health.assets[].ref — /assets/… uploads or clone paths like /wp-content/… (1–50 per call; batch keys from several entries). Skips animated images, already-small files and non-images (`skipped`); idempotent. The replaced file is kept under .originals (never served). Spends the daily image budget like an upload — dryRun:true reports the saving without spending it. The draft serves the smaller file at once. Your live site shows the smaller file after you publish (some imported files sooner).

    site keys dryRun context

  71. patch_contentChanges data

    Edit one content key via ops[] (selector ops or replace-string; wrap/unwrap/move restructure siblings). Stages draft; op shapes in schema.

    site key ops context guestToken

  72. patch_routeChanges data

    Partial route update (only sent fields change; an OMITTED field is left alone). On a field that accepts null (contentKey, redirectTo, redirectStatus, preserveQuery), sending null CLEARS it back to its default — different from omitting it. To set redirectTo/redirectStatus, include purpose: "redirect" in the SAME call — the check looks only at what's sent, not the route's stored purpose, so a PATCH that sets redirectTo without repeating purpose: "redirect" (even on a route that's already a redirect) 400s invalid_body.

    site path contentKey layout title vars purpose redirectTo redirectStatus preserveQuery experiment noindex context guestToken

  73. preflight_siteRead only

    Plan check before publish or large build (counts, route soft limit, seo suggestions; imports: form_unwired advisory, webflow_store blocking). When ok is false, blocking lists the failed suggestion codes. Read-only.

    site requiredRoutes requiredAssets context

  74. preview_pageRead only

    Verify-only composed HTML check; home preview may include requiredDecision — ask mirror vs editable before structure_*.

    site path selector contains notContains variant context guestToken

  75. promote_experimentChanges data

    Promote a winning A/B variant to live — explicit user instruction only; see get_skill('verify') § A/B.

    site experimentId variantId loserDisposition context

  76. publish_siteChanges data

    Publish draft to live. handoff required; feedback optional. May return advisory form_unwired / store warnings (never blocks) — tell the user.

    site feedback handoff confirmedDraftFingerprint acknowledgeSeoWarnings pages onlyReady context

  77. put_collection_schemaChanges data

    Replace the whole field schema (draft; publish makes it live). Read it with get_collection_schema first and send it back edited. Collection keys exactly as list_collections returns them ("blog/" or an id). Field: { key, type, label?, help?, required?, unique?, inCard?, default? } — type text (multiline, minLength, maxLength) | number (min, max, integer) | boolean | option (options[] required) | multiOption (options[] required, max) | link | email | phone | color. Keys: letter then letters/digits/_ (≤40), not a built-in post field (title, date, excerpt, tags, image, url, slug, …; author only as text), not secret-looking. ≤60 fields per collection. settings.defaultSort: date:desc|date:asc|title:asc|slug:asc. Removing a collection's entry drops its definitions (values stay on the posts). Values live in put_post meta.custom; writes then return fieldWarnings (soft, never blocking). 400 invalid_collection_schema lists issues; 409 conflict = stale ifMatch.

    site schema ifMatch context

  78. put_contentChanges data

    Stage one content key. Body ≤60KB. Larger pages: stage_content_chunk + apply_changeset bodyStaging, dotsy push, or PUT content-raw. Edits to an existing large page: batch_patch_content.

    site key body contentType context guestToken

  79. put_goalsChanges data

    Create or replace all site conversion goals (≤50). Required before start_test when no goal exists.

    site goals context

  80. put_menu_docChanges data

    Replace the whole menu doc (ifMatch from get_menu_doc required). Each item may omit menu — the enclosing menu key in doc is used.

    site doc ifMatch context

  81. put_menu_itemChanges data

    Partial upsert one menu item: provided fields overwrite; omitted html/childTemplate/childShell/attrs/data are preserved. To remove those keys, use put_menu_doc. A brand-new id dedupes by (menu, ref) — reuses an existing item linking the same target instead of creating a duplicate. An id that already names an item always updates that exact item, even if another item links the same page.

    site menu id sort parent label kind ref newTab attrs data html childShell childTemplate context

  82. put_postChanges data

    Stage a blog post via structured meta+body (?format=post). Key e.g. blog/my-post.html. Declared membership: meta.collections; schedule: meta.visibleAt; SEO title override: meta.seoTitle (card always shows meta.title); custom fields: meta.custom (typed per collection by get_collection_schema; the response's fieldWarnings flag values that don't fit — soft, never blocking).

    site key meta body head context

  83. put_routeChanges data

    Create/replace route; contentKey derived from path if omitted. On a field that accepts null (contentKey, redirectTo, redirectStatus, preserveQuery), sending null clears it back to its default.

    site path contentKey layout title vars purpose redirectTo redirectStatus preserveQuery experiment noindex context guestToken

  84. reapply_custom_domain_oauth

    Re-apply DNS with stored Cloudflare OAuth grant (no browser).

    site context

  85. refresh_custom_domain

    Poll one hostname until DNS/cert propagates.

    site host context

  86. reindex_collection

    Build/finish collection indexes after publish returns collectionDataPending or collectionSqlPending.

    site context

  87. remove_custom_domainChanges data

    Remove one custom hostname from the site.

    site host context

  88. remove_votesChanges data

    Remove one voter's vote and drop their release subscription for that item.

    site collection item voterId context

  89. rename_contentChanges data

    Re-key a page by slug (draft or published static). Server-side hash copy — no body round-trip. Default deletes static routes (obscure-URL); movePath:true repoints the route, rewrites menu refs and other redirects aimed at the old path, rewrites root-relative and https://{slug}.dotsy.site/ hrefs in draft HTML (always linksRewritten; not custom-domain absolutes or script/code samples; linksRewriteTruncated when scan caps at 100 HTML keys (500 on sites with full content search); publish to ship), and — only for an already-PUBLISHED page — leaves a 301 there too (leaveRedirect, default true; no effect on a never-published page, or when movePath is false). Retry-safe: a part-way failure (409 rename_failed) rolls everything back, so resend the same call. On fragments/<name>.html it also rewrites every <dotsy-fragment name> reference and hide marker in the same all-or-nothing commit. Then publish_site.

    site key newSlug movePath leaveRedirect context

  90. rename_pageChanges data

    Change a page's URL: moves its route from `from` to `to`. Menu links and other redirects that pointed at the old path retarget automatically; a 301 is left at the old path by default (leaveRedirect). Root-relative and https://{slug}.dotsy.site/ hrefs in draft page, layout and fragment HTML are rewritten (always linksRewritten; not custom-domain absolutes or script/code samples; linksRewriteTruncated when scan caps at 100 HTML keys (500 on sites with full content search); publish to ship). Retry-safe (resend the same call after any error). Errors: 404 route_not_found (from isn't a route); 400 reserved_route (to is under /__dotsy/) or invalid_body (missing/malformed from or to); 422 rename_same_path (from equals to already), rename_pattern_route (from or to contains a :param segment — pattern routes can't be renamed this way), rename_redirect_route (from is itself a different redirect — edit its redirectTo instead); 409 rename_experiment_running (an A/B test is running on from — end it f

    site from to leaveRedirect context

  91. rename_siteChanges data

    Rename the site slug (public hostname {slug}.dotsy.site). Owner-only. After success: use the returned slug in every later tool. Published site: the old slug redirects on the API (301 for reads, 308 for writes) while it stays reserved; the old host 301s and stays reserved until delete or rename-back. Never published: the old slug 404s on the API and the old hostname is released (no 301; create_site can reuse it). Analytics history stays on the old slug. HTML absolute URLs are not rewritten — publish_site refreshes sitemap; find_replace if stored HTML must change.

    site newSlug context

  92. reorder_menu

    Set final menu order. Pass ifMatch from get_menu; stale → 409 with current items.

    site menu orderedIds ifMatch context

  93. reply_to_report

    Add information or answer dotsy's question on your own report.

    id text requestIds attachments context

  94. report_bug

    Report a dotsy bug, or ask a support question (kind question — AI answer from the help centre). Bugs attach recent errors and return a ticket id.

    site kind reportedBy title actual expected steps severity tool operationId requestIds page model attachments context

  95. restore_versionChanges data

    Bring an earlier published version back as unpublished changes (page content only — routes, menus, images and settings stay). version: a number from list_versions, or "previous". dryRun: show what would change. Then review and publish_site, or discard_drafts to undo; publish:true makes it live at once.

    site version dryRun keys removeAdded replaceDrafts publish context

  96. revert_change

    Undo one activity event by staging the prior version as draft only — call publish_site to go live. Respects AI access.

    slug id keys reason context guestToken

  97. review_changes

    Review queue: what changed and isn't live yet. list (counts first) → get one item (hidden changes, optional diff, bodyChanged: false means only title/meta/route fields changed — review hidden, not the visible page) → mark_ready / unmark (≤50 ids). Then publish_site onlyReady:true. Drafts-only sites: a person marks.

    site action state detail cursor id diff ids all dryRun context

  98. search_contentRead only

    Find pages containing a phrase (grep without reading bodies). Requires do-sqlite — graduate_site first if search_unavailable.

    site q limit context

  99. set_analytics_providerChanges data

    Connect a third-party analytics provider (GA4, Plausible, Fathom, Umami) or remove it (provider 'none'). dotsy adds the provider's script to the <head> of every live page — live immediately, no publish needed. Replaces any earlier provider (one per site). Use this instead of pasting a GA4 gtag snippet into a layout. Other tags (Google Tag Manager, ads pixels, Clarity, search-console verification <meta>) go in set_custom_code.

    site provider measurementId domain siteId websiteId host context

  100. set_custom_codeChanges data

    Set site-wide custom code: `head` goes before </head> and `body` before </body> on every page, on every layout. It is saved as a draft and goes live with the next publish_site (on a live-mode site the dashboard publishes only the code). It never runs in the editor. Up to 20,000 characters per box, stored as sent; `warnings` flags likely mistakes (unclosed <script>, <html>/<head>/<body> tags, a canonical or robots tag, GA4 already connected) without rejecting. Send only the boxes you change; "" clears a box. `runOn` ('live' = live site only, default; 'live-and-preview' = also in the editor's preview) applies at once — agents limited to drafts can't set it. Use for tag managers (GTM), Clarity, ads pixels, chat widgets and verification tags. For plain GA4, Plausible, Fathom or Umami prefer set_analytics_provider.

    site head body runOn context

  101. set_experiment_note

    Record what was learned from an ended A/B test (≤500 chars; null clears).

    site experimentId note context

  102. set_item_status

    Change a roadmap/board item status (stamps dates; on release drafts the changelog post and links both ways). Never hand-edit *At, daysToRelease, or votes.

    site collection key status at reply draftChangelog publish context

  103. set_primary_custom_domain

    Set the canonical host (301 target) when multiple hostnames are connected.

    site host context

  104. share_sectionChanges data

    Make a block that repeats on several pages one shared section, or change where one shows. No arguments: lists blocks repeated on 3+ pages. sourceKey + selector (or selectors: a sibling run, one wrapper): a dry run finds every page with it; dryRun:false shares it. name + scope/hide/show: move an existing section to/from every page, or hide/show it per page. Over the per-call cap (too_many_pages, nothing written): share with keys, then again under the same name from a page that still has a copy; for every page then move with name + scope every_page + keys (max-1 pages a call; put all hide on the first) until all are moved. Always a draft (publish_site to go live; undo: revert_change).

    site sourceKey selector ifMatch name scope keys similar hide show dryRun selectors wrapTag keepLayout context guestToken

  105. stage_content_chunk

    Append one ≤60KB chunk of a large new page. Omit stagingId on seq 0; pass the returned stagingId on later seq. Set finalize:true on the last chunk, then apply_changeset with writes[].bodyStaging.

    site stagingId seq body contentType finalize context

  106. start_edit_session

    Open a draft session. Returns preview/edit URLs for the person (see linkGuidance). draftEditorUrl only when the site gives AI agents Full access. path defaults to '/'.

    site path context

  107. start_site

    Start one draft site with no dotsy account. Returns slug + guestToken — pass guestToken on every later tool call until claim_site.

    title purpose

  108. start_test

    Start a same-URL A/B test (draft or live source). Rules → get_skill('verify') § A/B.

    site path goalId source weights name hypothesis changeNote handsOff context

  109. structure_site_analyze

    Propose shared layout + fragments; persist:false first. Wait for mirror-vs-editable answer if requiredDecision pending.

    site sampleLimit profileId scope persist refreshManifest full context

  110. structure_site_applyChanges data

    Rewrite flat pages to layout + fragments (draft). Do not call while requiredDecision pending — user must pick editable first. It extracts header/footer only; report chromeCoverage counts, not 'sitewide'. Afterwards share_section with no arguments lists the other repeated blocks (banner, CTA).

    site ifMatch mode scope keys restructure overrides context

  111. submit_feedback

    Optional mid-session feedback (required feedback rides with publish_site).

    site category impactPercent title description suggestedImprovement findings context

  112. undo_publishChanges data

    Take back the last publish at once: restores the version before it for the pages that publish changed and publishes them, and the undone changes stay as unpublished changes (`restaged`). On a live-mode site nothing is kept (its next save would publish it again): the answer has `redo.version` — restore_version with that version and publish: true brings it back. publishVersion = the version publish_site returned. Fails with not_latest if another publish landed since. If its publish fails, the undo stays as unpublished changes — publish_site finishes it.

    site publishVersion context

  113. update_briefChanges data

    Update `_intent/site.md` (site brief) or a page brief when `page` is set. See field descriptions for rules, notes, and head enums.

    site page head body goal notes rules removeRules appendHandoff context guestToken

  114. update_collection

    Rename a collection's display name and/or noun (e.g. the generic 'posts' key shown as 'Recipes' / 'recipe') — cosmetic only, stored separately from the tag that defines membership; doesn't need publish. Provide at least one of name/noun. null (or "") resets that field back to its derived default — different from omitting it, which leaves the current value alone.

    site key name noun context

  115. update_site

    Update site settings: title, keyConvention, or editingMode ('live' = each editor save publishes immediately; 'staged' = saves stay drafts until publish_site). Slug is the hostname — change it with rename_site, not this tool. Set 'staged' before handing the editor to a person via start_edit_session's draftEditorUrl. signature toggles the "Made with dotsy" badge ({enabled, mark: logo|dot, reveal: pill|seal, side: right|left}); it is live immediately. trailingSlash (ignore|never|always) sets the page URL form: the other form 301s to it and canonicals/sitemap use it; live immediately. ownSeoFiles: true lets the next publish use the site's own robots.txt that blocks the whole site (Disallow: /) and its own static sitemap.xml (replaces the generated one, collection pages included); a robots.txt without Disallow: / is used anyway. aiTrain (true or false) says whether AI training crawlers may use the live site; false asks them not to, true allows them (the default). Live immediately.

    site title keyConvention editingMode signature trailingSlash ownSeoFiles aiTrain context

  116. verify_pageRead only

    Pre-publish lint (tags, assets, layout, SEO, speed and accessibility). Summary first: health issues grouped by code, each with fix:{tool,args,fill?} — supply the fill args, then call. health.summary counts are whole-site (groups/codes filter only issues and assets). Pair with preview_page — see get_skill('verify').

    site paths groups codes detail context

  117. wait_for_custom_domain

    Poll one hostname until it is connected or the timeout is reached.

    site host timeoutSec intervalSec context

Is this yours?

Claim it to hear the moment it breaks, correct this page and add your own ways to use it.

A test is the handshake and the tool list: no tool was called. Names and descriptions are as listed by whoever registered the server; we haven't checked them.

Back to Tested MCP Servers