ai.dotsy/mcp

Dotsy

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

Endpointhttps://mcp.dotsy.ai/mcp (streamable-http)
Registry version0.6.2
Now104 tools · grade D (57) · pin ts_ac1894babcb6d4f948694a4f82afefba · protocol 2025-06-18
First / last listed2026-10-28 00:55 UTC / 2026-10-28 00:55 UTC
Grade over time2026-10-28: D (57), 104 tools

Is this your server? Own a server? ToolFit hosted watch re-checks it every 24 h ($0.25 per 30 days) or 6 h ($0.60) and sends you an HMAC-signed webhook when its tools or grade change: POST https://api.youraitools.co/toolfit/v1/watch. To opt out, see About & opt-out.

Timeline

First listing · 2026-10-28 00:55 UTC
104 tools, grade D (57)

Tools: create_site get_site update_brief get_plan get_analytics set_analytics_provider get_custom_code set_custom_code update_site rename_site publish_site get_draft_status discard_drafts delete_site bulk_put_content get_site_manifest find_replace search_content graduate_site apply_changeset import_site_from_url get_structure_status structure_site_analyze decompose_analyze structure_site_apply get_structure_result adapt_site_analyze adapt_site_apply adapt_site_revert get_adapt_status list_content get_content put_content stage_content_chunk patch_content batch_patch_content delete_content rename_content put_post inspect_collection list_collections update_collection new_post_template get_collection_schema put_collection_schema infer_collection_schema reindex_collection preview_page verify_page preflight_site start_edit_session get_site_outline share_section detach_section get_route put_route patch_route rename_page delete_route list_goals put_goals estimate_test start_test promote_experiment delete_draft_test set_experiment_note get_menu put_menu_item delete_menu_item reorder_menu get_menu_doc put_menu_doc list_assets get_asset bulk_put_assets delete_asset optimize_assets start_site claim_site list_skills get_skill submit_feedback get_activity list_versions restore_version undo_publish revert_change get_account_context add_custom_domain get_custom_domain_connect reapply_custom_domain_oauth refresh_custom_domain wait_for_custom_domain set_primary_custom_domain list_custom_domains remove_custom_domain list_form_submissions get_form_submission list_notifications mark_notifications_read list_my_sites list_pages edit_page get_site_build_progress

Current tools (104)

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.
params: slug*, title, keyConvention, purpose, onSlugTaken, editingMode, workspace, context*, guestToken
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): list_pages is paginated — use cursor or get_site_manifest for the full route set.
params: site*, brief, pages, context*, guestToken
update_briefUpdate `_intent/site.md` (site brief) or a page brief when `page` is set. See field descriptions for rules, notes, and head enums.
params: site*, page, head, body, goal, notes, rules, removeRules, appendHandoff, context*, guestToken
get_planRead-only workspace plan and pooled usage; pass slug for this site's add-ons. Call before a large build.
params: slug, context*, guestToken
get_analyticsRead-only traffic overview (default) or full breakdowns via include[]; optional bot id for crawler page drill-down.
params: site*, range, include, bot, context*, guestToken
set_analytics_providerConnect 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 <
params: site*, provider*, measurementId, domain, siteId, websiteId, host, context*, guestToken
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`.
params: site*, context*, guestToken
set_custom_codeSet 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 can
params: site*, head, body, runOn, context*, guestToken
update_siteUpdate 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: pi
params: site*, title, keyConvention, editingMode, signature, trailingSlash, ownSeoFiles, context*, guestToken
rename_siteRename 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
params: site*, newSlug*, context*, guestToken
publish_sitePublish draft to live. feedback and handoff required (use dummy feedback + one-line handoff if clean).
params: site*, feedback*, handoff*, confirmedDraftFingerprint, acknowledgeSeoWarnings, pages, context*, guestToken
get_draft_statusPending draft changes: content keys and routes with status. May include requiredDecision (publish_confirm) before publish_site.
params: site*, context*, guestToken
discard_draftsDiscard unpublished drafts: all (omit key/keys/routes), one content key (key), or a selection (keys, routes). Destructive — check get_draft_status first.
params: site*, key, keys, routes, context*, guestToken
delete_sitePermanently delete site; confirmSlug must equal slug.
params: site*, confirmSlug*, context*, guestToken
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.
params: site*, title, content*, context*, guestToken
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.
params: site*, mode, routes, limit, cursor, context*, guestToken
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.
params: site*, find*, replace*, keys, expectPerKey, context*, guestToken
search_contentFind pages containing a phrase (grep without reading bodies). Requires do-sqlite — graduate_site first if search_unavailable.
params: site*, q*, limit, context*, guestToken
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 true, this client sends true unless you pass strictDrafts:false — blocking on unpublished drafts or un
params: site*, strictDrafts, force, context*, guestToken
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 ≤60KB and the call ≤80KB. Larger new pages: stage_content_chunk then writes[].bodyStaging, or dotsy pu
params: site*, writes, deletes, message, atomic, context*, guestToken
import_site_from_urlImport URL to draft. On complete, response may include requiredDecision — preview then ask mirror vs editable before structure_*.
params: site*, sourceUrl*, mode, pages, segments, keyConvention, onSlugTaken, workspace, context*, guestToken
get_structure_statusFlat vs structured page counts; informs user — do not auto-run analyze/apply while requiredDecision pending.
params: site*, context*, guestToken
structure_site_analyzePropose shared layout + fragments; persist:false first. Wait for mirror-vs-editable answer if requiredDecision pending.
params: site*, sampleLimit, profileId, scope, persist, refreshManifest, full, context*, guestToken
decompose_analyzeDeprecated — use structure_site_analyze.
params: site*, sampleLimit, profileId, scope, persist, refreshManifest, full, context*, guestToken
structure_site_applyRewrite flat pages to layout + fragments (draft). Do not call while requiredDecision pending — user must pick editable first. It extracts header/footer only: afterwards share_section with no arguments lists the other repeated blocks (banner, CTA).
params: site*, ifMatch*, mode, scope, keys, restructure, overrides, context*, guestToken
get_structure_resultLast structure apply job result (structuredKeys, conflicts, partial).
params: site*, full, context*, guestToken
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.
params: site*, full, adapters, options, refreshProposal, context*, guestToken
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.
params: site*, ifMatch*, adapters*, dryRun, force, context*, guestToken
adapt_site_revertAtomically restore everything the last adapt_site_apply wrote (fragments, the menu doc when the op touched it, index, member configs, routes).
params: site*, context*, guestToken
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.
params: site*, context*, guestToken
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 `null`) unless you pass withSize:true, which forces measurement at a cost of one storage read per retu
params: site*, limit, cursor, withSize, context*, guestToken
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.
params: site*, key*, selector, published, context*, guestToken
put_contentStage 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.
params: site*, key*, body*, contentType, context*, guestToken
stage_content_chunkAppend 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.
params: site*, stagingId, seq*, body*, contentType, finalize, context*, guestToken
patch_contentEdit one content key via ops[] (selector ops or replace-string; wrap/unwrap/move restructure siblings). Stages draft; op shapes in schema.
params: site*, key*, ops*, context*, guestToken
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.
params: site*, items*, context*, guestToken
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.
params: site*, key*, context*, guestToken
rename_contentRe-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, 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). Ret
params: site*, key*, newSlug*, movePath, leaveRedirect, context*, guestToken
put_postStage 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).
params: site*, key*, meta*, body*, head, context*, guestToken
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 published post with unpublished edits is status published with hasChanges:true (never draft) and shows i
params: site*, prefix*, status, q, cursor, limit, context*, guestToken
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.
params: site*, context*, guestToken
update_collectionRename 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.
params: site*, key*, name, noun, context*, guestToken
new_post_templateRead-only scaffold for a new post — suggested key/path, membership meta, blank or duplicate body. Then put_post (+ optional put_route).
params: site*, collection*, templateKey, mode, context*, guestToken
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 } means the stored file is broken: fix it with put_collection_schema using that hash.
params: site*, context*, guestToken
put_collection_schemaReplace 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) | mu
params: site*, schema*, ifMatch, context*, guestToken
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.
params: site*, collection*, context*, guestToken
reindex_collectionBuild/finish collection indexes after publish returns collectionDataPending or collectionSqlPending.
params: site*, context*, guestToken
preview_pageVerify-only composed HTML check; home preview may include requiredDecision — ask mirror vs editable before structure_*.
params: site*, path, selector, contains, notContains, variant, context*, guestToken
verify_pagePre-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').
params: site*, paths, groups, codes, detail, context*, guestToken
preflight_sitePlan check before publish or large build (counts, route soft limit, seo suggestions). When ok is false, blocking lists the failed suggestion codes. Read-only.
params: site*, requiredRoutes, requiredAssets, context*, guestToken
start_edit_sessionOpen 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 '/'.
params: site*, path, context*, guestToken
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 missing', 'which shared sections exist and where', 'where does this menu show' — without listing every page. R
params: site*, context*, guestToken
share_sectionMake 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, no
params: site*, sourceKey, selector, ifMatch, name, scope, keys, similar, hide, show, dryRun, selectors, wrapTag, keepLayout, context*, guestToken
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).
params: site*, name*, pageKey*, ifMatch, dryRun, context*, guestToken
get_routeGet one route by path (home is '/').
params: site*, path*, context*, guestToken
put_routeCreate/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.
params: site*, path*, contentKey, layout, title, vars, purpose, redirectTo, redirectStatus, preserveQuery, navLabel, nav, experiment, noindex, context*, guestToken
patch_routePartial 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
params: site*, path*, contentKey, layout, title, vars, purpose, redirectTo, redirectStatus, preserveQuery, navLabel, nav, experiment, noindex, context*, guestToken
rename_pageChange 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). 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 rena
params: site*, from*, to*, leaveRedirect, context*, guestToken
delete_routeRemove a route by path.
params: site*, path*, context*, guestToken
list_goalsList site conversion goals (pageview paths and form submits). Required before start_test.
params: site*, context*, guestToken
put_goalsCreate or replace all site conversion goals (≤50). Required before start_test when no goal exists.
params: site*, goals*, context*, guestToken
estimate_testEstimate days to reach promote readiness for a page (traffic baseline). Read-only.
params: site*, path*, context*, guestToken
start_testStart a same-URL A/B test (draft or live source). Rules → get_skill('verify') § A/B.
params: site*, path*, goalId*, source*, weights, name, hypothesis, changeNote, handsOff, context*, guestToken
promote_experimentPromote a winning A/B variant to live — explicit user instruction only; see get_skill('verify') § A/B.
params: site*, experimentId*, variantId*, loserDisposition, context*, guestToken
delete_draft_testRemove a draft A/B test (releases variant bodies; does not publish).
params: site*, experimentId*, context*, guestToken
set_experiment_noteRecord what was learned from an ended A/B test (≤500 chars; null clears).
params: site*, experimentId*, note*, context*, guestToken
get_menuRead a menu's draft items and etag; menu rules → get_skill('nav').
params: site*, menu*, context*, guestToken
put_menu_itemPartial 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.
params: site*, menu*, id*, sort*, parent*, label*, kind*, ref*, newTab, attrs, data, html, childShell, childTemplate, context*, guestToken
delete_menu_itemRemove one item from a menu (page stays live).
params: site*, menu*, id*, context*, guestToken
reorder_menuSet final menu order. Pass ifMatch from get_menu; stale → 409 with current items.
params: site*, menu*, orderedIds*, ifMatch, context*, guestToken
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.
params: site*, source, context*, guestToken
put_menu_docReplace the whole menu doc (ifMatch from get_menu_doc required). Each item may omit menu — the enclosing menu key in doc is used.
params: site*, doc*, ifMatch*, context*, guestToken
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.
params: site*, limit, cursor, context*, guestToken
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.
params: site*, key*, context*, guestToken
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 verifies submitted bytes before write; response sha256 is stored bytes (JS/CSS match; WebP rasters may differ
params: site*, items*, context*, guestToken
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.
params: site*, key*, context*, guestToken
optimize_assetsShrink 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 serv
params: site*, keys*, dryRun, context*, guestToken
start_siteStart one draft site with no Dotsy account. Returns slug + guestToken — pass guestToken on every later tool call until claim_site.
params: title, purpose, context*
claim_siteMove the guest draft onto your signed-in Dotsy account. Requires OAuth Connect; pass the guestToken from start_site.
params: context*, guestToken*
list_skillsPaige build skills (id + whenToUse). Pull get_skill on demand — do not duplicate in tool text.
params: context*
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.
params: id*, context*
submit_feedbackOptional mid-session feedback (required feedback rides with publish_site).
params: site*, category*, impactPercent*, title*, description, suggestedImprovement, findings, context*, guestToken
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.
params: slug*, who, state, actor, since, limit, id, key, context*, guestToken
list_versionsList the site's published versions, newest first (who, when, pages, live, restorable). Use before restore_version.
params: site*, cursor, limit, context*, guestToken
restore_versionBring 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.
params: site*, version*, dryRun, keys, removeAdded, replaceDrafts, publish, context*, guestToken
undo_publishTake 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_
params: site*, publishVersion*, context*, guestToken
revert_changeUndo one activity event by staging the prior version as draft only — call publish_site to go live. Respects AI access.
params: slug*, id*, keys, reason, context*, guestToken
get_account_contextAccount, user, memberships[]. Pass workspace on writes when memberships.length > 1.
params: workspace, context*, guestToken
add_custom_domainConnect apex and/or www on a paid plan; starts a DNS connect session.
params: site*, hosts, domain, context*, guestToken
get_custom_domain_connectCurrent connect session and nextAction (browser URL or manual DNS guide).
params: site*, sessionId, context*, guestToken
reapply_custom_domain_oauthRe-apply DNS with stored Cloudflare OAuth grant (no browser).
params: site*, context*, guestToken
refresh_custom_domainPoll one hostname until DNS/cert propagates.
params: site*, host*, context*, guestToken
wait_for_custom_domainPoll one hostname until it is connected or the timeout is reached.
params: site*, host*, timeoutSec, intervalSec, context*, guestToken
set_primary_custom_domainSet the canonical host (301 target) when multiple hostnames are connected.
params: site*, host*, context*, guestToken
list_custom_domainsList all custom hostnames and connection status for the site.
params: site*, context*, guestToken
remove_custom_domainRemove one custom hostname from the site.
params: site*, host*, context*, guestToken
list_form_submissionsList form submissions (metadata + bounded field preview — not full PII). Works on kv and do-sqlite backends.
params: site*, form*, limit, cursor, fromMs, toMs, q, context*, guestToken
get_form_submissionRead one form submission with the full field payload (explicit PII access — use only when needed).
params: site*, id*, context*, guestToken
list_notificationsAccount 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.
params: tab, scope, slug, unreadOnly, context*
mark_notifications_readMark Update notifications read (ids or all). Needs-you Actions refuse with 422 action_not_markable — fix the cause; it clears itself.
params: ids, all, context*
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) to list another workspace's sites without switching the dashboard session.
params: workspace
list_pagesList 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/n
params: site*, limit, cursor, view, layout, noLayout, q
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).
params: site*, path, stage
get_site_build_progressRead-only build progress for humans (build-theater view) during structure/adapt or after import. Agent reads structuredContent.forHumans — optional; do not call in a loop during import_site_from_url (that tool blocks until done). Prefer get_site for agent logic.
params: site*

Entries describe changes in tool definitions. They are not statements about a server, its quality or its author. The grade measures how the tool definitions fit model providers (token cost, schema compatibility, confusable names) as scored by the ToolFit engine at the time of the listing. JSON: append .json. Opt-out: how or hello@youraitools.co.