Bots St

bots.st/dotsy

dotsy

Apply draft-first site changes

3187 ms

answered our call

State
Answered
Protocol
MCP 2025-06-18
Tools listed
117
Answered
3 of the last 3 calls

How to reach it

  • MCP, HTTPhttps://mcp.dotsy.ai/mcp

What it can do

ToolWhat it says it does
adapt_site_analyzePropose 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.
adapt_site_applyApply 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.
adapt_site_revertAtomically restore everything the last adapt_site_apply wrote (fragments, the menu doc when the op touched it, index, member configs, routes).
add_custom_domainConnect apex and/or www on a paid plan; starts a DNS connect session.
add_ideaAdd an idea from outside the site (draft board item or inbox suggestion). Idempotent on externalRef.
apply_changesetStage 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…
batch_patch_contentpatch_content on multiple keys; all-or-nothing validation. Preferred edit path for pages over 60KB. replace-string value/replace ≤60KB; whole call ≤80KB.
bulk_put_assetsUpload 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…
bulk_put_contentStage 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.
claim_siteMove the guest draft onto your signed-in dotsy account. Requires OAuth Connect; pass the guestToken from start_site.
create_siteCreate 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.
delete_assetDelete a static asset by key. The editor and draft preview drop it at once; the published site drops it at the next publish.
delete_contentDelete 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.
delete_draft_testRemove a draft A/B test (releases variant bodies; does not publish).
delete_menu_itemRemove one item from a menu (page stays live).
delete_routeRemove a route by path.
delete_sitePermanently delete site; confirmSlug must equal slug.
detach_sectionGive 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).
discard_draftsDiscard 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.
edit_pageOpen 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).
estimate_testEstimate days to reach promote readiness for a page (traffic baseline). Read-only.
find_replaceCase-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.
form_recipientsWho 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…
get_account_contextAccount, user, memberships[]. Pass workspace on writes when memberships.length > 1.
get_activityList 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.
get_adapt_statusRead adapt state: proposal summary + proposalEtag (+ applied/consumed flag), undo-record presence, active or queued job progress. Use to resume in a fresh session.
get_analyticsRead-only traffic overview (default) or full breakdowns via include[]; optional bot id for crawler page drill-down.
get_assetRead 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.
get_boardList board items with status, stamp fields, and baked vote counts (draft overlay included). Live vote totals: site host GET /__dotsy/votes.
get_collection_schemaRead 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 }…
get_contentRead 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.
get_custom_codeRead 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`.
get_custom_domain_connectCurrent connect session and nextAction (browser URL or manual DNS guide).
get_draft_statusPending draft changes: content keys and routes with status. May include requiredDecision (publish_confirm) before publish_site.
get_form_submissionRead one form submission with the full field payload (explicit PII access — use only when needed).
get_menuRead a menu's draft items and etag; menu rules → get_skill('nav').
get_menu_docRead 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.
get_planRead-only workspace plan and pooled usage; pass slug for this site's add-ons. Call before a large build.
get_reportYour dotsy bug reports. Omit id for the list; pass id for one ticket and its public replies.
get_routeGet one route by path (home is '/').
get_siteSite 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)…
get_site_build_progressRead-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.
get_site_manifestContent keys + hashes only (optional routes=true) — static files live in list_assets, not manifest. Diff keys+hashes before apply_changeset; stage only changed bodies.
get_site_outlineSite 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…
get_skillSkill body + optional questions[]. Accepts an id OR a synonym (e.g. 'list', 'menu') — resolves aliases and suggests near-misses. Start with intake when ambiguous.
get_structure_resultLast structure apply job result (structuredKeys, conflicts, partial).
get_structure_statusFlat 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.
graduate_siteEnable 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…
import_site_from_urlImport URL to draft. On complete, response may include requiredDecision — preview then ask mirror vs editable before structure_*.
infer_collection_schemaSuggest 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.
inspect_collectionCollection 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…
install_product_kitAdd a roadmap, changelog and/or help centre to a site as drafts (never overwrites; rerun finishes a partial install).
list_assetsCMS 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.
list_collectionsCollections 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.
list_contentList 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…
list_custom_domainsList all custom hostnames and connection status for the site.
list_form_submissionsList form submissions (metadata + bounded field preview — not full PII). Works on kv and do-sqlite backends.
list_goalsList site conversion goals (pageview paths and form submits). Required before start_test.
list_ideasSearch draft/published board items and open suggestions by title token overlap.
list_my_sitesList 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)…

And 57 more tools.

In its maker's words

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

Website
dotsy.ai
Publisher
dotsy.ai
Listed from
the official MCP Registry as ai.dotsy/mcp
Version
0.8.15, updated 7 Nov 2026
Kinds of work
Domains and websites, Documents and files, Writing and translation

The domain it lives on

dotsy.ai
registered 8 Jun 2026 (5 months ago), at Porkbun LLC, its home page is a working site

From our own crawl of domain names: registry records and the home page as our crawler last saw it.

Every call we made

WhenWhat happenedTime
Answered3187 ms
Answered2688 ms
Answered1337 ms

Next door

Is this your bot? Claim its address to add a verified badge and keep the listing current.