dotsy
REMOTE · MCP.DOTSY.AI
Build and publish static sites on dotsy with draft-first MCP tools, OAuth Connect, and API keys.
Available components
Last scanned (11 hours ago)
Scores higher than 98% of remote servers
Reachable. Last reached 5 Nov 2026.
Category Developer Tools
How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →
Endpoint Security89
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token. View diagnostics → Pass
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- HSTS check failed: the Strict-Transport-Security header is absent. See how to fix → View diagnostics → Fail
- DNSSEC check failed: this domain isn't protected by DNSSEC. See how to fix → View diagnostics → Fail
- The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents. View diagnostics → Partial
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
Schema Quality & AI Usability76
- 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
- AI-judged instruction clarity (good).Pass
- Context-footprint check failed: tool/resource definitions use about 18437 tokens (~147/item across 125 items; 117 tools + 8 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management94
- Stability check failed: schema churn in the 29 days we've observed: 1 tool removals, 3 breaking changes, 0 auth/transport breaks, 29 additions. See how to fix → Fail
Tool Coverage92
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 76% of tool parameters carry a description.Partial
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- All 10 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
- An AI judge read all 119 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
- Supports UI / widget rendering.Pass
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 5 Nov 26 +1
- Resource “get_site_build_progress” now points somewhere else: ui://views/apps-sdk/build-theater.html?v=0b9659cd → ui://views/ext-apps/build-theater.html?v=0b9659cd security
- Resource “edit_page” now points somewhere else: ui://views/apps-sdk/page-canvas.html?v=88974c83 → ui://views/ext-apps/page-canvas.html?v=88974c83 security
- Resource “get_site_build_progress” now points somewhere else: ui://views/apps-sdk/build-theater.html?v=34c6d210 → ui://views/ext-apps/build-theater.html?v=0b9659cd security
- Resource “get_site_build_progress” now points somewhere else: ui://views/ext-apps/build-theater.html?v=34c6d210 → ui://views/ext-apps/build-theater.html?v=0b9659cd security
- Resource “list_my_sites” now points somewhere else: ui://views/apps-sdk/site-picker.html?v=20fa5fa4 → ui://views/ext-apps/site-picker.html?v=20fa5fa4 security
- Resource “list_pages” now points somewhere else: ui://views/apps-sdk/page-picker.html?v=3fce7297 → ui://views/ext-apps/page-picker.html?v=3fce7297 security
- Tool “update_site” rewrote its description, which is the text the model reads security
- Server version: 0.8.6 → 0.8.8 functional
- New tool “form_recipients” functional
- New tool “install_product_kit” functional
- 4 Nov 26 0
- Resource “edit_page” now points somewhere else: ui://views/apps-sdk/page-canvas.html?v=88974c83 → ui://views/ext-apps/page-canvas.html?v=88974c83 security
- Resource “get_site_build_progress” now points somewhere else: ui://views/apps-sdk/build-theater.html?v=34c6d210 → ui://views/ext-apps/build-theater.html?v=34c6d210 security
- Resource “list_my_sites” now points somewhere else: ui://views/apps-sdk/site-picker.html?v=20fa5fa4 → ui://views/ext-apps/site-picker.html?v=20fa5fa4 security
- Resource “list_pages” now points somewhere else: ui://views/apps-sdk/page-picker.html?v=3fce7297 → ui://views/ext-apps/page-picker.html?v=3fce7297 security
- 3 Nov 26 +1
- Resource “edit_page” now points somewhere else: ui://views/apps-sdk/page-canvas.html?v=bfd4da19 → ui://views/ext-apps/page-canvas.html?v=88974c83 security
- Resource “edit_page” now points somewhere else: ui://views/ext-apps/page-canvas.html?v=bfd4da19 → ui://views/ext-apps/page-canvas.html?v=88974c83 security
- Resource “get_site_build_progress” now points somewhere else: ui://views/apps-sdk/build-theater.html?v=317f2c43 → ui://views/ext-apps/build-theater.html?v=34c6d210 security
- Resource “get_site_build_progress” now points somewhere else: ui://views/ext-apps/build-theater.html?v=317f2c43 → ui://views/ext-apps/build-theater.html?v=34c6d210 security
- Resource “list_my_sites” now points somewhere else: ui://views/apps-sdk/site-picker.html?v=f9802318 → ui://views/ext-apps/site-picker.html?v=20fa5fa4 security
- Resource “list_my_sites” now points somewhere else: ui://views/ext-apps/site-picker.html?v=f9802318 → ui://views/ext-apps/site-picker.html?v=20fa5fa4 security
- Resource “list_pages” now points somewhere else: ui://views/apps-sdk/page-picker.html?v=f80b1d11 → ui://views/ext-apps/page-picker.html?v=3fce7297 security
- Resource “list_pages” now points somewhere else: ui://views/ext-apps/page-picker.html?v=f80b1d11 → ui://views/ext-apps/page-picker.html?v=3fce7297 security
- Resource “edit_page” now points somewhere else: ui://views/apps-sdk/page-canvas.html?v=bfd4da19 → ui://views/ext-apps/page-canvas.html?v=bfd4da19 security
- Resource “get_site_build_progress” now points somewhere else: ui://views/apps-sdk/build-theater.html?v=317f2c43 → ui://views/ext-apps/build-theater.html?v=317f2c43 security
- Resource “list_my_sites” now points somewhere else: ui://views/apps-sdk/site-picker.html?v=f9802318 → ui://views/ext-apps/site-picker.html?v=f9802318 security
- Resource “list_pages” now points somewhere else: ui://views/apps-sdk/page-picker.html?v=f80b1d11 → ui://views/ext-apps/page-picker.html?v=f80b1d11 security
- Tool “report_bug” rewrote its description, which is the text the model reads security
- Server version: 0.8.5 → 0.8.6 functional
- Server version: 0.8.4 → 0.8.5 functional
- “get_analytics” reworded the description of “include” cosmetic
- “report_bug” reworded the description of “kind” cosmetic
- 2 Nov 26 0
We did not load change detail this far back for this component, so this day may have recorded more than is shown.
- Stability: 0.83 → fail ▼ security
- Tool “approve_suggestion” was removed ▼ security
- Tool “decline_suggestion” was removed ▼ security
- Tool “merge_suggestion” was removed ▼ security
- Tool “support_inbox” was removed ▼ security
- Tool “decompose_analyze” was removed ▼ security
- The server rewrote its instructions, which are the text every model session reads security
- The server changed its declared name: paige → dotsy security
- Tool “claim_site” rewrote its description, which is the text the model reads security
- Tool “get_report” rewrote its description, which is the text the model reads security
- Tool “list_my_sites” rewrote its description, which is the text the model reads security
- Tool “reply_to_report” rewrote its description, which is the text the model reads security
- Tool “report_bug” rewrote its description, which is the text the model reads security
- Tool “set_analytics_provider” rewrote its description, which is the text the model reads security
- Tool “start_site” rewrote its description, which is the text the model reads security
- Tool “update_site” rewrote its description, which is the text the model reads security
- Tool “publish_site” rewrote its description, which is the text the model reads security
- Tool “get_site_build_progress” rewrote its description, which is the text the model reads security
- Tool “support_inbox” is now declared destructive security
- Tool “restore_version” is now declared destructive security
- Tool “graduate_site” is now declared destructive security
- “get_skill” dropped the required parameter “context” ▼ functional
- “start_site” dropped the required parameter “context” ▼ functional
- “list_skills” dropped the required parameter “context” ▼ functional
- Schema quality: 208 → 147 ▲ functional
- Schema quality: 208 → 161 ▲ functional
- Too many changes on this day to record them all, so 157 were dropped functional
- Server version: 0.8.1 → 0.8.4 functional
- Server version: 0.3.0 → 0.8.1 functional
- New tool “moderate_suggestion” functional
- “add_custom_domain” reworded the description of “context” cosmetic
- “batch_patch_content” reworded the description of “context” cosmetic
- “bulk_put_assets” reworded the description of “context” cosmetic
- “create_site” reworded the description of “context” cosmetic
- “delete_content” reworded the description of “context” cosmetic
- “delete_draft_test” reworded the description of “context” cosmetic
- “delete_route” reworded the description of “context” cosmetic
- “delete_site” reworded the description of “context” cosmetic
- “discard_drafts” reworded the description of “context” cosmetic
- “estimate_test” reworded the description of “context” cosmetic
- “find_replace” reworded the description of “context” cosmetic
- “get_analytics” reworded the description of “context” cosmetic
- “get_asset” reworded the description of “context” cosmetic
- “get_board” reworded the description of “context” cosmetic
- “get_collection_schema” reworded the description of “context” cosmetic
- “get_custom_domain_connect” reworded the description of “context” cosmetic
- “get_menu_doc” reworded the description of “context” cosmetic
- “get_site” reworded the description of “context” cosmetic
- “get_site_manifest” reworded the description of “context” cosmetic
- “get_structure_status” reworded the description of “context” cosmetic
- “graduate_site” reworded the description of “context” cosmetic
- “list_assets” reworded the description of “context” cosmetic
- “list_collections” reworded the description of “context” cosmetic
- “list_content” reworded the description of “context” cosmetic
- “list_ideas” reworded the description of “context” cosmetic
- “list_notifications” reworded the description of “context” cosmetic
- “patch_route” reworded the description of “context” cosmetic
- “preflight_site” reworded the description of “context” cosmetic
- “promote_experiment” reworded the description of “context” cosmetic
- “publish_site” reworded the description of “context” cosmetic
- “put_collection_schema” reworded the description of “context” cosmetic
- “put_goals” reworded the description of “context” cosmetic
- “put_menu_item” reworded the description of “context” cosmetic
- “put_post” reworded the description of “context” cosmetic
- “refresh_custom_domain” reworded the description of “context” cosmetic
- “remove_votes” reworded the description of “context” cosmetic
- “rename_content” reworded the description of “context” cosmetic
- “rename_site” reworded the description of “context” cosmetic
- “reorder_menu” reworded the description of “context” cosmetic
- “report_bug” reworded the description of “context” cosmetic
- “report_bug” reworded the description of “site” cosmetic
- “review_changes” reworded the description of “context” cosmetic
- “search_content” reworded the description of “context” cosmetic
- “set_analytics_provider” reworded the description of “context” cosmetic
- “set_custom_code” reworded the description of “context” cosmetic
- “set_experiment_note” reworded the description of “context” cosmetic
- “set_item_status” reworded the description of “context” cosmetic
- “set_primary_custom_domain” reworded the description of “context” cosmetic
- “share_section” reworded the description of “context” cosmetic
- “start_edit_session” reworded the description of “context” cosmetic
- “start_test” reworded the description of “handsOff” cosmetic
- “structure_site_apply” reworded the description of “context” cosmetic
- “update_site” reworded the description of “context” cosmetic
- “update_site” reworded the description of “signature” cosmetic
- “submit_feedback” reworded the description of “context” cosmetic
- “decline_suggestion” reworded the description of “context” cosmetic
- “get_report” reworded the description of “context” cosmetic
- “claim_site” reworded the description of “guestToken” cosmetic
- “list_form_submissions” reworded the description of “context” cosmetic
- “revert_change” reworded the description of “context” cosmetic
- “import_site_from_url” reworded the description of “context” cosmetic
- “list_votes” reworded the description of “context” cosmetic
- “approve_suggestion” reworded the description of “context” cosmetic
- “get_account_context” reworded the description of “workspace” cosmetic
- “apply_changeset” reworded the description of “guestToken” cosmetic
- “support_inbox” reworded the description of “context” cosmetic
- “preview_page” reworded the description of “context” cosmetic
- “bulk_put_content” reworded the description of “context” cosmetic
- “reply_to_report” reworded the description of “context” cosmetic
- “adapt_site_apply” reworded the description of “context” cosmetic
- “list_versions” reworded the description of “context” cosmetic
- “publish_site” reworded the description of “feedback” cosmetic
- “list_goals” reworded the description of “context” cosmetic
- “get_adapt_status” reworded the description of “context” cosmetic
- “get_site_outline” reworded the description of “context” cosmetic
- “get_content” reworded the description of “context” cosmetic
- “reapply_custom_domain_oauth” reworded the description of “context” cosmetic
- “get_form_submission” reworded the description of “context” cosmetic
- “get_site” reworded the description of “guestToken” cosmetic
- “list_content” reworded the description of “guestToken” cosmetic
- “update_collection” reworded the description of “context” cosmetic
- “structure_site_analyze” reworded the description of “context” cosmetic
- “get_account_context” reworded the description of “context” cosmetic
- “inspect_collection” reworded the description of “context” cosmetic
- “get_menu” reworded the description of “context” cosmetic
- “list_suggestions” reworded the description of “context” cosmetic
- “wait_for_custom_domain” reworded the description of “context” cosmetic
- “patch_route” dropped the optional parameter “nav” cosmetic
- “patch_route” dropped the optional parameter “navLabel” cosmetic
- “put_route” dropped the optional parameter “nav” cosmetic
- “put_route” dropped the optional parameter “navLabel” cosmetic
- “remove_votes” dropped the optional parameter “guestToken” cosmetic
- “get_structure_status” dropped the optional parameter “guestToken” cosmetic
- “graduate_site” dropped the optional parameter “guestToken” cosmetic
- “get_collection_schema” dropped the optional parameter “guestToken” cosmetic
- “get_adapt_status” dropped the optional parameter “guestToken” cosmetic
- “put_collection_schema” dropped the optional parameter “guestToken” cosmetic
- “delete_content” dropped the optional parameter “guestToken” cosmetic
- “optimize_assets” dropped the optional parameter “guestToken” cosmetic
- “structure_site_analyze” dropped the optional parameter “guestToken” cosmetic
- “inspect_collection” dropped the optional parameter “guestToken” cosmetic
- “set_custom_code” dropped the optional parameter “guestToken” cosmetic
- “start_test” dropped the optional parameter “guestToken” cosmetic
- “review_changes” dropped the optional parameter “guestToken” cosmetic
- “list_ideas” dropped the optional parameter “guestToken” cosmetic
- “list_assets” dropped the optional parameter “guestToken” cosmetic
- “delete_asset” dropped the optional parameter “guestToken” cosmetic
- “reindex_collection” made “context” optional cosmetic
- “patch_route” made “context” optional cosmetic
- “add_custom_domain” made “context” optional cosmetic
- “list_ideas” made “context” optional cosmetic
- “get_site_manifest” made “context” optional cosmetic
- “inspect_collection” made “context” optional cosmetic
- “rename_content” made “context” optional cosmetic
- “get_site_outline” made “context” optional cosmetic
- “promote_experiment” made “context” optional cosmetic
- “update_collection” made “context” optional cosmetic
- “refresh_custom_domain” made “context” optional cosmetic
- “put_menu_doc” made “context” optional cosmetic
- “verify_page” made “context” optional cosmetic
- “preflight_site” made “context” optional cosmetic
- “get_adapt_status” made “context” optional cosmetic
- “start_test” made “context” optional cosmetic
- “adapt_site_apply” made “context” optional cosmetic
- “merge_suggestion” made “context” optional cosmetic
- “add_idea” made “context” optional cosmetic
- “put_menu_item” made “context” optional cosmetic
- “put_post” made “context” optional cosmetic
- “get_activity” made “context” optional cosmetic
- “publish_site” made “context” optional cosmetic
- “list_goals” made “context” optional cosmetic
- “patch_content” made “context” optional cosmetic
- “get_board” made “context” optional cosmetic
- “search_content” made “context” optional cosmetic
- “put_route” made “context” optional cosmetic
- “decline_suggestion” made “context” optional cosmetic
- 31 Oct 26 +1
We did not load change detail this far back for this component, so this day may have recorded more than is shown.
- 29 Oct 26 +1
We did not load change detail this far back for this component, so this day may have recorded more than is shown.
- 27 Oct 26 +1
We did not load change detail this far back for this component, so this day may have recorded more than is shown.
- 26 Oct 26 +5
We did not load change detail this far back for this component, so this day may have recorded more than is shown.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 5 Nov 2026 · Probed https://mcp.dotsy.ai/mcp
TLS valid
Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .
| Subject | Issuer | Valid from | Valid until | Key | Signature | Serial |
|---|---|---|---|---|---|---|
| CN=dotsy.ai | CN=WE1,O=Google Trust Services,C=US | 5 Oct 2026 | 3 Jan 2027 | ECDSA 256 | ECDSA-SHA256 | 62cefc9561d94387134b2a26d7b70486 |
| SANs: dotsy.ai, *.dotsy.ai | ||||||
| CN=WE1,O=Google Trust Services,C=US (CA) | CN=GTS Root R4,O=Google Trust Services LLC,C=US | 13 Dec 2023 | 20 Feb 2029 | ECDSA 256 | ECDSA-SHA384 | 7ff31977972c224a76155d13b6d685e3 |
| CN=GTS Root R4,O=Google Trust Services LLC,C=US (CA) | CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE | 15 Nov 2023 | 28 Jan 2028 | ECDSA 384 | SHA256-RSA | 7fe530bf331343bedd821610493d8a1b |
Background: What to check on a remote MCP endpoint →
DNSSEC insecure
Validation of mcp.dotsy.ai. — Not signed
| Zone | DS | Keys | Algorithms | Outcome |
|---|---|---|---|---|
| . | trust_anchor | 20326, 38696 | 8, 8 | Verified |
| ai. | present | 1814, 3799 | 8, 8 | Verified |
| dotsy.ai. | absent | Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation |
Authentication Enforced and verified
The endpoint asked for a token and published valid RFC 9728 metadata describing how to get one.
| Result | Enforced and verified |
|---|---|
| Enforced | On tool calls |
| HTTP status | 200 |
WWW-Authenticate challenge Bearer resource_metadata="https://mcp.dotsy.ai/.well-known/oauth-protected-resource/mcp"
Bearer resource_metadata="https://mcp.dotsy.ai/.well-known/oauth-protected-resource/mcp" Protected resource metadata
| Document | https://mcp.dotsy.ai/.well-known/oauth-protected-resource/mcp |
|---|---|
| Retrieved | Yes |
| Resource | https://mcp.dotsy.ai/mcp |
| Authorisation server | https://app.dotsy.ai |
Background: How OAuth 2.1 works in the 2026 MCP spec →
Transports 2 probes
| Transport | URL | Outcome | Status | Location |
|---|---|---|---|---|
| streamable-http | https://mcp.dotsy.ai/mcp | Verified | 200 | |
| http (plaintext) | http://mcp.dotsy.ai/mcp | HTTPS enforced | 301 | https://mcp.dotsy.ai/mcp |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
adapt_site_analyze ~174
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.
| Name | Type | Req | Description |
|---|---|---|---|
| adapters | array | – | Which adapters to analyze (default: both). |
| context | string | – | Why you're calling this (activity log). |
| full | boolean | – | Return the full per-member harvest report (default: compacted for the token budget). |
| options | object | – | – |
| refreshProposal | boolean | – | Replace an existing UNCONSUMED proposal (otherwise re-analyze 409s proposal_exists). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
adapt_site_apply ~209
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.
| Name | Type | Req | Description |
|---|---|---|---|
| adapters | array | yes | Which analyzed adapters to apply. |
| context | string | – | Why you're calling this (activity log). |
| dryRun | boolean | – | Full computation, would-write set + previews, ZERO writes, no undo. |
| force | string | – | An undo record from a prior apply exists (409 adapt_undo_exists): defer-discard it — the prior record is dropped only when this apply SUCCEEDS; a partial-failure rollback reinstates it. Prefer adapt… |
| ifMatch | string | yes | The proposal etag from analyze (or GET …/adapt/proposal / status). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
adapt_site_revert ~71
Atomically restore everything the last adapt_site_apply wrote (fragments, the menu doc when the op touched it, index, member configs, routes).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
add_custom_domain ~108
Connect apex and/or www on a paid plan; starts a DNS connect session.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| domain | string | – | Bare domain when hosts omitted — apex expands to apex + www; a subdomain connects as-is. |
| hosts | array | – | 1–2 hostnames: apex (example.com) and/or www (www.example.com). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
add_idea ~127
Add an idea from outside the site (draft board item or inbox suggestion). Idempotent on externalRef.
| Name | Type | Req | Description |
|---|---|---|---|
| area | string | – | – |
| asSuggestion | boolean | – | – |
| board | string | – | – |
| context | string | – | Why you're calling this (activity log). |
| description | string | yes | – |
| externalRef | object | – | – |
| requester | object | – | – |
| site | string | yes | Site slug, e.g. acme-studio |
| source | string | yes | – |
| status | string | – | – |
| title | string | yes | – |
No output schema declared.
No examples provided.
apply_changeset ~286
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.
| Name | Type | Req | Description |
|---|---|---|---|
| atomic | boolean | – | All or nothing: every writes[].ifMatch and deletes[].ifMatch is checked before anything is written. One stale key writes nothing and the call fails with 409 changeset_conflict listing `conflicts`. De… |
| context | string | – | Why you're calling this (activity log). |
| deletes | array | – | Keys to delete: a key, or { key, ifMatch } (the hash you read) so a page changed since is not deleted (listed in conflicts). |
| guestToken | string | – | Guest token from start_site (pgg_…). Omit when signed in with OAuth. |
| message | string | – | – |
| site | string | yes | Site slug, e.g. acme-studio |
| writes | array | – | – |
No output schema declared.
No examples provided.
batch_patch_content ~109
patch_content on multiple keys; all-or-nothing validation. Preferred edit path for pages over 60KB. replace-string value/replace ≤60KB; whole call ≤80KB.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| guestToken | string | – | Guest token from start_site (pgg_…). Omit when signed in with OAuth. |
| items | array | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
bulk_put_assets ~234
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.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| items | array | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
bulk_put_content ~110
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.
| Name | Type | Req | Description |
|---|---|---|---|
| content | array | yes | – |
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
| title | string | – | – |
No output schema declared.
No examples provided.
claim_site ~61
Move the guest draft onto your signed-in dotsy account. Requires OAuth Connect; pass the guestToken from start_site.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| guestToken | string | yes | Guest token from start_site (required). |
No output schema declared.
No examples provided.
create_site ~211
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.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| editingMode | string | – | How the editor's Save behaves. 'live' (default) publishes each save immediately; 'staged' keeps saves as drafts until publish_site. Prefer 'staged' when an agent will hand the editor to a person (see… |
| keyConvention | string | – | – |
| onSlugTaken | string | – | – |
| purpose | string | – | – |
| slug | string | yes | – |
| title | string | – | – |
| workspace | string|null | – | Workspace org id or slug (multi-workspace only; omit if one workspace). |
No output schema declared.
No examples provided.
delete_asset ~124
Delete a static asset by key. The editor and draft preview drop it at once; the published site drops it at the next publish.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| key | string | yes | Path after /assets/ on the site — e.g. photos/hero.webp or style.css. Do not prefix with assets/ or /. Uploaded files are live in the editor and draft preview at once; the published site picks them u… |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
delete_content ~83
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.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| key | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
delete_draft_test ~65
Remove a draft A/B test (releases variant bodies; does not publish).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| experimentId | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
delete_menu_item ~65
Remove one item from a menu (page stays live).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| id | string | yes | – |
| menu | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
delete_route ~52
Remove a route by path.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| path | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
delete_site ~58
Permanently delete site; confirmSlug must equal slug.
| Name | Type | Req | Description |
|---|---|---|---|
| confirmSlug | string | yes | – |
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
detach_section ~222
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).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| dryRun | boolean | – | Default true: report what would change and write nothing. false: stage the change as a draft (publish_site makes it live). |
| guestToken | string | – | Guest token from start_site (pgg_…). Omit when signed in with OAuth. |
| ifMatch | string | – | The page's content hash. If the page changed since, nothing is written. |
| name | string | yes | Section name. Its file is fragments/<name>.html, placed with <dotsy-fragment name="<name>">. |
| pageKey | string | yes | Content key of the page that gets its own copy, e.g. 'pricing.html'. |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
discard_drafts ~114
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.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| key | string | – | – |
| keys | array | – | – |
| menus | boolean | – | – |
| routes | array | – | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
edit_page ~87
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).
| Name | Type | Req | Description |
|---|---|---|---|
| path | string | – | Route path (default /). |
| site | string | yes | Site slug. |
| stage | string | – | Preview stage. Default draft; published is planned but not supported yet. |
No output schema declared.
No examples provided.
estimate_test ~70
Estimate days to reach promote readiness for a page (traffic baseline). Read-only.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| path | string | yes | Route path, e.g. /pricing |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
find_replace ~115
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.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| expectPerKey | integer | – | – |
| find | string | yes | – |
| keys | array | – | – |
| replace | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
form_recipients ~221
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.
| Name | Type | Req | Description |
|---|---|---|---|
| action | string | yes | – |
| context | string | – | Why you're calling this (activity log). |
| string | – | The address (required for status, request, revoke) | |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_account_context ~63
Account, user, memberships[]. Pass workspace on writes when memberships.length > 1.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| workspace | string|null | – | Workspace org id or slug (multi-workspace only; omit if one workspace). |
No output schema declared.
No examples provided.
get_activity ~212
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.
| Name | Type | Req | Description |
|---|---|---|---|
| actor | string | – | Actor id or me. |
| context | string | – | Why you're calling this (activity log). |
| guestToken | string | – | Guest token from start_site (pgg_…). Omit when signed in with OAuth. |
| id | string | – | Event id — returns diff for this change instead of the list. |
| key | string | – | Content key when id is set (default first key in the event). |
| limit | integer | – | Page size (default 20). |
| since | string | – | ISO date (default 7 days, plan retention floor). |
| slug | string | yes | Site slug, e.g. acme-studio |
| state | string | – | needs_review = agent drafts awaiting a person's publish. |
| who | string | – | Default all. |
No output schema declared.
No examples provided.
get_adapt_status ~76
Read adapt state: proposal summary + proposalEtag (+ applied/consumed flag), undo-record presence, active or queued job progress. Use to resume in a fresh session.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_analytics ~180
Read-only traffic overview (default) or full breakdowns via include[]; optional bot id for crawler page drill-down.
| Name | Type | Req | Description |
|---|---|---|---|
| bot | string | – | Crawler bot id (e.g. googlebot, gptbot) → that bot's top crawled pages under `crawlerBotPages`. |
| context | string | – | Why you're calling this (activity log). |
| include | array | – | Full breakdown sections to add under `detail`: pages, sources, countries, devices, browsers, os, utm, goals, series, crawlers, experiments, events, helpful (all-time "Was this helpful?" yes/no per pa… |
| range | string | – | Time window; default 30d. |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_asset ~158
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.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| key | string | yes | Path after /assets/ on the site — e.g. photos/hero.webp or style.css. Do not prefix with assets/ or /. Uploaded files are live in the editor and draft preview at once; the published site picks them u… |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_board ~85
List board items with status, stamp fields, and baked vote counts (draft overlay included). Live vote totals: site host GET /__dotsy/votes.
| Name | Type | Req | Description |
|---|---|---|---|
| collection | string | – | Board collection (default "roadmap"). |
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_collection_schema ~127
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.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_content ~127
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.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| guestToken | string | – | Guest token from start_site (pgg_…). Omit when signed in with OAuth. |
| key | string | yes | – |
| published | boolean | – | – |
| selector | string | – | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_custom_code ~99
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`.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_custom_domain_connect ~75
Current connect session and nextAction (browser URL or manual DNS guide).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| sessionId | string | – | Connect session id from add_custom_domain; omit to resume pending. |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_draft_status ~64
Pending draft changes: content keys and routes with status. May include requiredDecision (publish_confirm) before publish_site.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_form_submission ~74
Read one form submission with the full field payload (explicit PII access — use only when needed).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| id | string | yes | Submission id from list_form_submissions |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_menu ~64
Read a menu's draft items and etag; menu rules → get_skill('nav').
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| menu | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_menu_doc ~118
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.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
| source | string | – | Which doc to read. Default draft. |
No output schema declared.
No examples provided.
get_plan ~65
Read-only workspace plan and pooled usage; pass slug for this site's add-ons. Call before a large build.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| slug | string | – | Optional site slug — adds a per-site add-ons segment to the summary. |
No output schema declared.
No examples provided.
get_report ~75
Your dotsy bug reports. Omit id for the list; pass id for one ticket and its public replies.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| cursor | string | – | – |
| id | integer | – | Omit for your list; pass a ticket id for one report and its replies. |
No output schema declared.
No examples provided.
get_route ~81
Get one route by path (home is '/').
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| guestToken | string | – | Guest token from start_site (pgg_…). Omit when signed in with OAuth. |
| path | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_site ~200
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.
| Name | Type | Req | Description |
|---|---|---|---|
| brief | boolean | – | Include parsed brief head (default true). |
| context | string | – | Why you're calling this (activity log). |
| guestToken | string | – | Guest token from start_site (pgg_…). Omit when signed in with OAuth. |
| pages | boolean | – | Return the full pages[] array instead of the default ~25-entry head (server-capped at 1000 either way). Default false. |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_site_build_progress ~68
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.
| Name | Type | Req | Description |
|---|---|---|---|
| site | string | yes | Site slug. |
No output schema declared.
No examples provided.
get_site_manifest ~104
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.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| cursor | string | – | – |
| limit | integer | – | – |
| mode | string | – | – |
| routes | boolean | – | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_site_outline ~141
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).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_skill ~72
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.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | Skill id or synonym from list_skills, e.g. intake, clone, list, menu |
No output schema declared.
No examples provided.
get_structure_result ~74
Last structure apply job result (structuredKeys, conflicts, partial).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| full | boolean | – | Return the full manifest/detail (default: compacted for the token budget). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
get_structure_status ~61
Flat vs structured page counts; informs user — do not auto-run analyze/apply while requiredDecision pending.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
graduate_site ~349
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.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| force | boolean | – | Proceed past the incomplete-KV-snapshot 409 only — not the unsupported-backend or strictDrafts blocks, which force does nothing for. Read the blocked response's `reason` + `audit` first; the flip is… |
| site | string | yes | Site slug, e.g. acme-studio |
| strictDrafts | boolean | – | Block on unpublished drafts or unrecovered KV content rows (default true — publish/discard first, or pass false to proceed anyway). |
No output schema declared.
No examples provided.
import_site_from_url ~210
Import URL to draft. On complete, response may include requiredDecision — preview then ask mirror vs editable before structure_*.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| keyConvention | string | – | Content key shape: directory = Astro dist (about/index.html); default flat |
| mode | string | – | Default auto — per-page mirror with silent render escalation |
| onSlugTaken | string | – | – |
| pages | array | – | Explicit page list; omit to import sourceUrl as index.html |
| segments | array | – | Split-origin segments — each expands into pages by fetching its own `sitemap`. A segment without `sitemap` imports only its pathPrefix hub page (with a warning), not the whole prefix. |
| site | string | yes | Site slug, e.g. acme-studio |
| sourceUrl | string | yes | – |
| workspace | string|null | – | Workspace org id or slug (multi-workspace only; omit if one workspace). |
No output schema declared.
No examples provided.
infer_collection_schema ~131
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.
| Name | Type | Req | Description |
|---|---|---|---|
| collection | string | yes | Collection key exactly as list_collections returned it, e.g. "blog/" or "posts". |
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
How do I install the dotsy MCP server?
dotsy is a hosted endpoint at https://mcp.dotsy.ai/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
remote · mcp.dotsy.ai
claude mcp add --transport http ai-dotsy-mcp 'https://mcp.dotsy.ai/mcp'
What is the dotsy MCP server?
dotsy is an MCP server listed in the public MCP registry as ai.dotsy/mcp. Build and publish static sites on dotsy with draft-first MCP tools, OAuth Connect, and API keys. This page covers its hosted endpoint (https://mcp.dotsy.ai/mcp).
Is the dotsy MCP server safe to use?
dotsy scores 90 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the dotsy MCP server expose?
dotsy exposes 117 tools: create_site, get_site, update_brief, get_plan, get_analytics, and 112 more. Their descriptions and schemas cost roughly 18,091 tokens of context every time the server is loaded.
Does the dotsy MCP server require authentication?
Yes. dotsy asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.
Is the dotsy MCP server still maintained?
dotsy is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.