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 (13 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 →
inspect_collection ~318
Collection state — count, server.mode, sample entries, tag (membershipKind, match=) when discovered; plus name, noun, URL pattern, layout, where it's listed, and post fields used. Pass status/q/cursor/limit (any one, even empty) for a full items[] page instead: status draft = never published; a published post with unpublished edits is status published with hasChanges:true (never draft) and shows its staged title/date/tags/author; scheduled = future visibleAt. Never-published drafts come from staged content (no extra reads, no publish needed to see them); published/scheduled come from the index. limit defaults to 50, clamped 1-200. Omit all four for just the base inspect (no items[]).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| cursor | string | – | Resume from a prior response's nextCursor. |
| limit | integer | – | Items per page (default 50, max 200). |
| prefix | string | yes | Collection id or prefix, e.g. "posts" or "blog/" — use the key exactly as list_collections returned it. |
| q | string | – | Case-insensitive title search within items[]. |
| site | string | yes | Site slug, e.g. acme-studio |
| status | string | – | Filter items[] by status (see the tool description for what each means). Providing this (or q/cursor/limit) is what makes the response include items[]. |
No output schema declared.
No examples provided.
install_product_kit ~75
Add a roadmap, changelog and/or help centre to a site as drafts (never overwrites; rerun finishes a partial install).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| parts | array | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
list_assets ~105
CMS uploads under assets/ only — not mirrored clone CDN (get_site mirroredAssets or import warmJob). Not content — use list_content. Uploaded files are live in the editor and draft preview at once; the published site picks them up at the next publish.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| cursor | string | – | – |
| limit | integer | – | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
list_collections ~102
Collections on the site — name, noun, item count (or 'not published yet'), URL pattern, and whether any member is staged. Includes a collection only a draft page lists. Returns a bare array (not wrapped in an object) — pass each row's key verbatim to inspect_collection/update_collection.
| 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.
list_content ~262
List content keys (HTML/md); not assets — use list_assets. Defaults to 50 keys per page — raise limit (max 1000) or pass cursor (from nextCursor) to page through the rest. Per-row `size`/`missing` are measured automatically only on pages of ≤100 rows; past that they're ABSENT (not measured, never `null`) unless you pass withSize:true, which forces measurement at a cost of one storage read per returned row. Only `size: null` + `missing: true` means the page's stored bytes are gone.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| cursor | string | – | Resume from a prior response's nextCursor. |
| guestToken | string | – | Guest token from start_site (pgg_…). Omit when signed in with OAuth. |
| limit | integer | – | Keys per page (default 50, max 1000). |
| site | string | yes | Site slug, e.g. acme-studio |
| withSize | boolean | – | Force size/missing measurement on a page bigger than 100 rows (costs one storage read per returned row). Default false — rows in a ≤100-row page are measured either way. |
No output schema declared.
No examples provided.
list_custom_domains ~52
List all custom hostnames and connection status for the 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.
list_form_submissions ~128
List form submissions (metadata + bounded field preview — not full PII). Works on kv and do-sqlite backends.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| cursor | string | – | – |
| form | string | yes | Form id from dotsy-config, e.g. contact |
| fromMs | integer | – | – |
| limit | integer | – | – |
| q | string | – | Search reply-to email (indexed) |
| site | string | yes | Site slug, e.g. acme-studio |
| toMs | integer | – | – |
No output schema declared.
No examples provided.
list_goals ~57
List site conversion goals (pageview paths and form submits). Required before start_test.
| 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.
list_ideas ~68
Search draft/published board items and open suggestions by title token overlap.
| Name | Type | Req | Description |
|---|---|---|---|
| board | string | – | – |
| context | string | – | Why you're calling this (activity log). |
| q | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
list_my_sites ~106
List your dotsy sites. Renders a site-picker for humans; agent reads structuredContent. Use to choose a site — not for editing content (use edit_page) or verify-only checks (use preview_page). Defaults to your active workspace; pass workspace (org id or slug from get_account_context memberships) to list another workspace's sites without switching the dashboard session.
| Name | Type | Req | Description |
|---|---|---|---|
| workspace | string|null | – | Workspace org id or slug (multi-workspace only; omit if one workspace). |
No output schema declared.
No examples provided.
list_notifications ~121
Account notification inbox (Needs you · Updates). Summary-first: tab counts plus compact rows with nextAction (MCP tool or dashboard URL). OAuth person only — not API keys.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| scope | string | – | Scope filter (default all workspaces you belong to). |
| slug | string | – | Site slug — required when scope is site. |
| tab | string | – | Tab filter (default: both classes in one list). |
| unreadOnly | boolean | – | When true, only unread rows. |
No output schema declared.
No examples provided.
list_pages ~328
List pages on a site — route settings (path/title/navLabel/purpose) by default, one row per route. Renders a page-picker for humans (redirect and worker routes left out there — nothing to open in edit_page); agent reads structuredContent. Use after picking a site — not for editing (use edit_page) or verify-only checks (use preview_page). Pass view:'pages' to group by layout instead — adds layout/noLayout/q filters, what each page places, and indexing progress; use that for 'what pages use this layout' or 'is this page indexed yet', not for route settings. Paginated — pass cursor (from nextCursor) for more; partial:true means this page is a window, not the full route set.
| Name | Type | Req | Description |
|---|---|---|---|
| cursor | string | – | Resume from a prior response's nextCursor. |
| layout | string | – | Only with view:'pages'. Layout file key (e.g. layouts/store.html, or bare 'store') — only pages using it. Exclusive with noLayout. |
| limit | integer | – | Pages per page (server default applies when omitted). |
| noLayout | boolean | – | Only with view:'pages'. Only pages with no layout (routeless keys included). Exclusive with layout. |
| q | string | – | Only with view:'pages'. Case-insensitive substring match on path or title. |
| site | string | yes | Site slug. |
| view | string | – | pages: group by layout — enables layout/noLayout/q below, adds page-structure fields and indexing progress. Omit for the default per-route listing. |
No output schema declared.
No examples provided.
list_skills ~32
Paige build skills (id + whenToUse). Pull get_skill on demand — do not duplicate in tool text.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
list_suggestions ~66
List form suggestions awaiting moderation (duplicate hints against the board).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| site | string | yes | Site slug, e.g. acme-studio |
| status | string | – | Filter by status (default "new"). |
No output schema declared.
No examples provided.
list_versions ~90
List the site's published versions, newest first (who, when, pages, live, restorable). Use before restore_version.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| cursor | string | – | nextCursor from the previous call. |
| limit | integer | – | Page size (default 20). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
list_votes ~83
List voters on one board item (voter id + source only — no email).
| Name | Type | Req | Description |
|---|---|---|---|
| collection | string | yes | Board collection id. |
| context | string | – | Why you're calling this (activity log). |
| item | string | yes | Content key, e.g. roadmap/my-feature.html |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
mark_notifications_read ~95
Mark Update notifications read (ids or all). Needs-you Actions refuse with 422 action_not_markable — fix the cause (it clears itself); only the person can dismiss them in the dashboard.
| Name | Type | Req | Description |
|---|---|---|---|
| all | boolean | – | Mark every Update read across all your workspaces. |
| context | string | – | Why you're calling this (activity log). |
| ids | array | – | Update row ids from list_notifications (max 100). |
No output schema declared.
No examples provided.
moderate_suggestion ~176
Decide one form suggestion from list_suggestions: approve (new draft board item; stages content, does not publish), merge (into an existing board item, subscribes the voter/email) or decline (no board item).
| Name | Type | Req | Description |
|---|---|---|---|
| body | string | – | approve only. |
| context | string | – | Why you're calling this (activity log). |
| decision | string | yes | – |
| id | string | yes | – |
| itemKey | string | – | merge: the existing board item's key (required). |
| reason | string | – | decline: note kept with the suggestion. |
| site | string | yes | Site slug, e.g. acme-studio |
| slug | string | – | approve only. |
| status | string | – | approve: initial board status. |
| title | string | – | approve: item title (default: the suggestion's). |
No output schema declared.
No examples provided.
new_post_template ~122
Read-only scaffold for a new post — suggested key/path, membership meta, blank or duplicate body. Then put_post (+ optional put_route).
| Name | Type | Req | Description |
|---|---|---|---|
| collection | string | yes | Collection id or prefix, e.g. "posts" or "blog/" |
| context | string | – | Why you're calling this (activity log). |
| mode | string | – | blank (default) or duplicate full body |
| site | string | yes | Site slug, e.g. acme-studio |
| templateKey | string | – | Exemplar content key; default = most recent member |
No output schema declared.
No examples provided.
optimize_assets ~235
Shrink heavy images in place (0.98): JPEG/PNG/still GIF → WebP at the same address, so no HTML changes. keys = site paths from verify_page health.assets[].ref — /assets/… uploads or clone paths like /wp-content/… (1–50 per call; batch keys from several entries). Skips animated images, already-small files and non-images (`skipped`); idempotent. The replaced file is kept under .originals (never served). Spends the daily image budget like an upload — dryRun:true reports the saving without spending it. The draft serves the smaller file at once. Your live site shows the smaller file after you publish (some imported files sooner).
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| dryRun | boolean | – | Report before/after sizes only; writes nothing and spends no budget. |
| keys | array | yes | Site paths of the images, e.g. /assets/hero.jpg or /wp-content/uploads/photo.png. |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
patch_content ~109
Edit one content key via ops[] (selector ops or replace-string; wrap/unwrap/move restructure siblings). Stages draft; op shapes in schema.
| 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 | – |
| ops | array | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
patch_route ~434
Partial route update (only sent fields change; an OMITTED field is left alone). On a field that accepts null (contentKey, redirectTo, redirectStatus, preserveQuery), sending null CLEARS it back to its default — different from omitting it. To set redirectTo/redirectStatus, include purpose: "redirect" in the SAME call — the check looks only at what's sent, not the route's stored purpose, so a PATCH that sets redirectTo without repeating purpose: "redirect" (even on a route that's already a redirect) 400s invalid_body.
| Name | Type | Req | Description |
|---|---|---|---|
| contentKey | – | – | Explicit content key (defaults to a path-derived key when omitted). null clears an explicit key back to that path default — same as omitting it, but usable on a PATCH to undo a prior set. |
| context | string | – | Why you're calling this (activity log). |
| experiment | – | – | – |
| guestToken | string | – | Guest token from start_site (pgg_…). Omit when signed in with OAuth. |
| layout | string|null | – | Layout NAME, bare: "default" for layouts/default.html — not the file key. It must already exist as layouts/<name>.html (400 layout_not_found otherwise). null removes the layout. |
| noindex | boolean|null | – | Exclude from sitemap/RSS; inject noindex meta (0.69). |
| path | string | yes | – |
| preserveQuery | boolean|null | – | Append the visitor's original query string to the redirect target (default true on a redirect). null clears an explicit override. |
| purpose | string|null | – | – |
| redirectStatus | – | – | 301 permanent / 302 or 308 temporary (default 301 on a redirect). null clears an explicit override. |
| redirectTo | – | – | Redirect target, a root-relative path (/…). Required when purpose is "redirect". null clears it — only valid once purpose stops being "redirect" (a redirect route always needs a target). |
| site | string | yes | Site slug, e.g. acme-studio |
| title | string|null | – | – |
| vars | – | – | – |
No output schema declared.
No examples provided.
preflight_site ~102
Plan check before publish or large build (counts, route soft limit, seo suggestions). When ok is false, blocking lists the failed suggestion codes. Read-only.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| requiredAssets | integer | – | How many assets you plan to upload |
| requiredRoutes | integer | – | How many routes you plan to add |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
preview_page ~178
Verify-only composed HTML check; home preview may include requiredDecision — ask mirror vs editable before structure_*.
| Name | Type | Req | Description |
|---|---|---|---|
| contains | array | – | Assert substrings present in composed HTML. |
| context | string | – | Why you're calling this (activity log). |
| guestToken | string | – | Guest token from start_site (pgg_…). Omit when signed in with OAuth. |
| notContains | array | – | Assert absent — e.g. `<dotsy-` for unresolved template tags. |
| path | string | – | – |
| selector | string | – | Return matched elements only (tag/attrs/text). |
| site | string | yes | Site slug, e.g. acme-studio |
| variant | string | – | A/B variant arm to compose (e.g. "b") — same as ?dotsy-variant= on the public URL. |
No output schema declared.
No examples provided.
promote_experiment ~96
Promote a winning A/B variant to live — explicit user instruction only; see get_skill('verify') § A/B.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| experimentId | string | yes | – |
| loserDisposition | string | – | – |
| site | string | yes | Site slug, e.g. acme-studio |
| variantId | string | yes | Winning variant arm id (usually "b"). |
No output schema declared.
No examples provided.
publish_site ~235
Publish draft to live. handoff required; feedback optional.
| Name | Type | Req | Description |
|---|---|---|---|
| acknowledgeSeoWarnings | boolean | – | Required when brief.priorities.seo is must and verify_page reported SEO errors (not warnings). User must have explicitly chosen to publish despite errors. |
| confirmedDraftFingerprint | string | – | Required when get_draft_status returned requiredDecision (publish_confirm). Must match the current draft fingerprint from get_draft_status. |
| context | string | – | Why you're calling this (activity log). |
| feedback | object | – | Optional session feedback; tool intents are attached automatically. |
| handoff | string | yes | One sentence: decisions, preferences, or open threads for the next session (appended to the brief). |
| onlyReady | boolean | – | Publish only changes marked ready (server hashes). Incompatible with pages. Skips publish_confirm fingerprint when set. |
| pages | array | – | Publish only these pages — use when a publish returns rules_not_fully_checked; publish the rest in further batches (≤50 route paths, e.g. /pricing). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
put_collection_schema ~351
Replace the whole field schema (draft; publish makes it live). Read it with get_collection_schema first and send it back edited. Collection keys exactly as list_collections returns them ("blog/" or an id). Field: { key, type, label?, help?, required?, unique?, inCard?, default? } — type text (multiline, minLength, maxLength) | number (min, max, integer) | boolean | option (options[] required) | multiOption (options[] required, max) | link | email | phone | color. Keys: letter then letters/digits/_ (≤40), not a built-in post field (title, date, excerpt, tags, image, url, slug, …; author only as text), not secret-looking. ≤60 fields per collection. settings.defaultSort: date:desc|date:asc|title:asc|slug:asc. Removing a collection's entry drops its definitions (values stay on the posts). Values live in put_post meta.custom; writes then return fieldWarnings (soft, never blocking). 400 invalid_collection_schema lists issues; 409 conflict = stale ifMatch.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| ifMatch | string|null | – | hash from get_collection_schema (stale → 409 conflict). null = the schema must not exist yet. Omit to write unconditionally. |
| schema | object | yes | Whole schema file: { "v": 1, "collections": { "<key>": { "fields": [...], "settings"?: {...} } } }. |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
put_content ~187
Stage one content key. Body ≤60KB. Larger pages: stage_content_chunk + apply_changeset bodyStaging, dotsy push, or PUT content-raw. Edits to an existing large page: batch_patch_content.
| Name | Type | Req | Description |
|---|---|---|---|
| body | string | yes | – |
| contentType | string | – | – |
| 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 | Content key: a page (about.html, blog/post.html), a layout (layouts/<name>.html) or a fragment (fragments/<name>.html). A <dotsy-fragment name> tag and a route's layout use the bare name, not the key. |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
put_goals ~67
Create or replace all site conversion goals (≤50). Required before start_test when no goal exists.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| goals | array | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
put_menu_doc ~100
Replace the whole menu doc (ifMatch from get_menu_doc required). Each item may omit menu — the enclosing menu key in doc is used.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| doc | object | yes | – |
| ifMatch | string | yes | Whole-doc etag from get_menu_doc. Required (sent as If-Match). |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
put_menu_item ~222
Partial upsert one menu item: provided fields overwrite; omitted html/childTemplate/childShell/attrs/data are preserved. To remove those keys, use put_menu_doc. A brand-new id dedupes by (menu, ref) — reuses an existing item linking the same target instead of creating a duplicate. An id that already names an item always updates that exact item, even if another item links the same page.
| Name | Type | Req | Description |
|---|---|---|---|
| attrs | object | – | – |
| childShell | string|null | – | – |
| childTemplate | string | – | – |
| context | string | – | Why you're calling this (activity log). |
| data | object | – | – |
| html | string | – | – |
| id | string | yes | – |
| kind | string | yes | – |
| label | string | yes | – |
| menu | string | yes | – |
| newTab | boolean | – | – |
| parent | string|null | yes | – |
| ref | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
| sort | integer | yes | – |
No output schema declared.
No examples provided.
put_post ~148
Stage a blog post via structured meta+body (?format=post). Key e.g. blog/my-post.html. Declared membership: meta.collections; schedule: meta.visibleAt; SEO title override: meta.seoTitle (card always shows meta.title); custom fields: meta.custom (typed per collection by get_collection_schema; the response's fieldWarnings flag values that don't fit — soft, never blocking).
| Name | Type | Req | Description |
|---|---|---|---|
| body | string | yes | – |
| context | string | – | Why you're calling this (activity log). |
| head | array | – | – |
| key | string | yes | – |
| meta | object | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
put_route ~359
Create/replace route; contentKey derived from path if omitted. On a field that accepts null (contentKey, redirectTo, redirectStatus, preserveQuery), sending null clears it back to its default.
| Name | Type | Req | Description |
|---|---|---|---|
| contentKey | – | – | Explicit content key (defaults to a path-derived key when omitted). null clears an explicit key back to that path default — same as omitting it, but usable on a PATCH to undo a prior set. |
| context | string | – | Why you're calling this (activity log). |
| experiment | – | – | – |
| guestToken | string | – | Guest token from start_site (pgg_…). Omit when signed in with OAuth. |
| layout | string|null | – | Layout NAME, bare: "default" for layouts/default.html — not the file key. It must already exist as layouts/<name>.html (400 layout_not_found otherwise). null removes the layout. |
| noindex | boolean|null | – | Exclude from sitemap/RSS; inject noindex meta (0.69). |
| path | string | yes | – |
| preserveQuery | boolean|null | – | Append the visitor's original query string to the redirect target (default true on a redirect). null clears an explicit override. |
| purpose | string|null | – | – |
| redirectStatus | – | – | 301 permanent / 302 or 308 temporary (default 301 on a redirect). null clears an explicit override. |
| redirectTo | – | – | Redirect target, a root-relative path (/…). Required when purpose is "redirect". null clears it — only valid once purpose stops being "redirect" (a redirect route always needs a target). |
| site | string | yes | Site slug, e.g. acme-studio |
| title | string|null | – | – |
| vars | – | – | – |
No output schema declared.
No examples provided.
reapply_custom_domain_oauth ~57
Re-apply DNS with stored Cloudflare OAuth grant (no browser).
| 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.
refresh_custom_domain ~68
Poll one hostname until DNS/cert propagates.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| host | string | yes | Hostname to refresh, e.g. www.example.com |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
reindex_collection ~56
Build/finish collection indexes after publish returns collectionDataPending or collectionSqlPending.
| 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.
remove_custom_domain ~59
Remove one custom hostname from the site.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| host | string | yes | Hostname to remove |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
remove_votes ~75
Remove one voter's vote and drop their release subscription for that item.
| Name | Type | Req | Description |
|---|---|---|---|
| collection | string | yes | – |
| context | string | – | Why you're calling this (activity log). |
| item | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
| voterId | string | yes | – |
No output schema declared.
No examples provided.
rename_content ~372
Re-key a page by slug (draft or published static). Server-side hash copy — no body round-trip. Default deletes static routes (obscure-URL); movePath:true repoints the route, rewrites menu refs and other redirects aimed at the old path, rewrites root-relative and https://{slug}.dotsy.site/ hrefs in draft HTML (always linksRewritten; not custom-domain absolutes or script/code samples; linksRewriteTruncated when scan caps at 100 HTML keys (500 on sites with full content search); publish to ship), and — only for an already-PUBLISHED page — leaves a 301 there too (leaveRedirect, default true; no effect on a never-published page, or when movePath is false). Retry-safe: a part-way failure (409 rename_failed) rolls everything back, so resend the same call. On fragments/<name>.html it also rewrites every <dotsy-fragment name> reference and hide marker in the same all-or-nothing commit. Then publish_site.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| key | string | yes | Current content key, e.g. dashboard.html |
| leaveRedirect | boolean | – | With movePath:true on an already-published page, leave a 301 at the old path (default true). false removes the old path outright — old links break. No effect when movePath is false, or on a page that… |
| movePath | boolean | – | false (default): delete routes bound to old key. true: move static route path to match slug. |
| newSlug | string | yes | New filename stem; directory prefix preserved (blog/foo → blog/bar) |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
rename_page ~374
Change a page's URL: moves its route from `from` to `to`. Menu links and other redirects that pointed at the old path retarget automatically; a 301 is left at the old path by default (leaveRedirect). Root-relative and https://{slug}.dotsy.site/ hrefs in draft page, layout and fragment HTML are rewritten (always linksRewritten; not custom-domain absolutes or script/code samples; linksRewriteTruncated when scan caps at 100 HTML keys (500 on sites with full content search); publish to ship). Retry-safe (resend the same call after any error). Errors: 404 route_not_found (from isn't a route); 400 reserved_route (to is under /__dotsy/) or invalid_body (missing/malformed from or to); 422 rename_same_path (from equals to already), rename_pattern_route (from or to contains a :param segment — pattern routes can't be renamed this way), rename_redirect_route (from is itself a different redirect — edit its redirectTo instead); 409 rename_experiment_running (an A/B test is running on from — end it first) or rename_target_exists (to is already a different route — unless to already serves the exact content from would, which is treated as already done and returns 200). Then publish_site.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| from | string | yes | Current route path, e.g. /old-page |
| leaveRedirect | boolean | – | Leave a 301 from the old path to the new one (default true). false removes the old path outright — old links break. |
| site | string | yes | Site slug, e.g. acme-studio |
| to | string | yes | New route path, e.g. /new-page |
No output schema declared.
No examples provided.
rename_site ~182
Rename the site slug (public hostname {slug}.dotsy.site). Owner-only. After success: use the returned slug in every later tool. Published site: the old slug redirects on the API (301 for reads, 308 for writes) while it stays reserved; the old host 301s and stays reserved until delete or rename-back. Never published: the old slug 404s on the API and the old hostname is released (no 301; create_site can reuse it). Analytics history stays on the old slug. HTML absolute URLs are not rewritten — publish_site refreshes sitemap; find_replace if stored HTML must change.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| newSlug | string | yes | New site slug (lowercase hostname stem) |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
reorder_menu ~82
Set final menu order. Pass ifMatch from get_menu; stale → 409 with current items.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| ifMatch | string | – | – |
| menu | string | yes | – |
| orderedIds | array | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
reply_to_report ~79
Add information or answer dotsy's question on your own report.
| Name | Type | Req | Description |
|---|---|---|---|
| attachments | array | – | Ids from POST /api/v1/support/attachments. No file bytes. |
| context | string | – | Why you're calling this (activity log). |
| id | integer | yes | – |
| requestIds | array | – | – |
| text | string | yes | – |
No output schema declared.
No examples provided.
report_bug ~241
Report a dotsy bug, or ask a support question (kind question — AI answer from the help centre). Bugs attach recent errors and return a ticket id.
| Name | Type | Req | Description |
|---|---|---|---|
| actual | string | yes | What happened. |
| attachments | array | – | Ids from POST /api/v1/support/attachments. No file bytes. |
| context | string | – | Why you're calling this (activity log). |
| expected | string | – | – |
| kind | string | – | bug (default) files a ticket. question runs the help-centre AI turn (use actual as the question text). |
| model | string | – | Self-declared, display only. |
| operationId | string | – | – |
| page | string | – | Route path or content key. |
| reportedBy | string | yes | user = the human asked you to report it. |
| requestIds | array | – | – |
| severity | string | yes | – |
| site | string | – | Site it happened on. Omit for an account-level issue. Stored as about.site; the ticket is filed in dotsy's inbox. |
| steps | array | – | – |
| title | string | yes | – |
| tool | string | – | – |
No output schema declared.
No examples provided.
restore_version ~237
Bring an earlier published version back as unpublished changes (page content only — routes, menus, images and settings stay). version: a number from list_versions, or "previous". dryRun: show what would change. Then review and publish_site, or discard_drafts to undo; publish:true makes it live at once.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| dryRun | boolean | – | Only list what would change; writes nothing. |
| keys | array | – | Restore only these content keys (single-page restore: CORE workspaces). Default: the whole version. |
| publish | boolean | – | Publish exactly the restored pages at once (live-mode sites). Default false: they stay unpublished changes. |
| removeAdded | boolean | – | Remove pages added since the version. Default true. |
| replaceDrafts | boolean | – | Replace unpublished changes on the pages the restore touches. Without it such a restore answers 409 drafts_pending. |
| site | string | yes | Site slug, e.g. acme-studio |
| version | – | yes | A version from list_versions, or "previous" (the one before live). |
No output schema declared.
No examples provided.
revert_change ~145
Undo one activity event by staging the prior version as draft only — call publish_site to go live. Respects AI access.
| 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. |
| id | string | yes | Activity event id from get_activity. |
| keys | array | – | Undo only these keys of the change. Default: every key. |
| reason | string | – | Why — shown next to 'Reverted by …'. Visible to everyone on the site. |
| slug | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
review_changes ~257
Review queue: what changed and isn't live yet. list (counts first) → get one item (hidden changes, optional diff, bodyChanged: false means only title/meta/route fields changed — review hidden, not the visible page) → mark_ready / unmark (≤50 ids). Then publish_site onlyReady:true. Drafts-only sites: a person marks.
| Name | Type | Req | Description |
|---|---|---|---|
| action | string | – | list (default) · get one item · mark_ready · unmark |
| all | boolean | – | unmark: clear every ready mark |
| context | string | – | Why you're calling this (activity log). |
| cursor | string | – | list pagination (full only) |
| detail | string | – | list detail (default summary) |
| diff | boolean | – | get: include first diff rows |
| dryRun | boolean | – | mark_ready / unmark: preview only |
| id | string | – | get: item id from list (p:/path, s:key, m:menus) |
| ids | array | – | mark_ready / unmark: item ids from list (≤50) |
| site | string | yes | Site slug, e.g. acme-studio |
| state | string | – | list filter (default all) |
No output schema declared.
No examples provided.
search_content ~78
Find pages containing a phrase (grep without reading bodies). Requires do-sqlite — graduate_site first if search_unavailable.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| limit | integer | – | – |
| q | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
No output schema declared.
No examples provided.
set_analytics_provider ~265
Connect a third-party analytics provider (GA4, Plausible, Fathom, Umami) or remove it (provider 'none'). dotsy adds the provider's script to the <head> of every live page — live immediately, no publish needed. Replaces any earlier provider (one per site). Use this instead of pasting a GA4 gtag snippet into a layout. Other tags (Google Tag Manager, ads pixels, Clarity, search-console verification <meta>) go in set_custom_code.
| Name | Type | Req | Description |
|---|---|---|---|
| context | string | – | Why you're calling this (activity log). |
| domain | string | – | Plausible only: the site domain registered in Plausible, e.g. example.com. |
| host | string | – | Umami only: https origin of the Umami instance, e.g. https://umami.example.com. |
| measurementId | string | – | GA4 only: measurement ID, e.g. G-ABC123XYZ. |
| provider | string | yes | – |
| site | string | yes | Site slug, e.g. acme-studio |
| siteId | string | – | Fathom only: site ID (uppercase letters/digits). |
| websiteId | string | – | Umami only: website ID (UUID). |
No output schema declared.
No examples provided.
set_custom_code ~314
Set site-wide custom code: `head` goes before </head> and `body` before </body> on every page, on every layout. It is saved as a draft and goes live with the next publish_site (on a live-mode site the dashboard publishes only the code). It never runs in the editor. Up to 20,000 characters per box, stored as sent; `warnings` flags likely mistakes (unclosed <script>, <html>/<head>/<body> tags, a canonical or robots tag, GA4 already connected) without rejecting. Send only the boxes you change; "" clears a box. `runOn` ('live' = live site only, default; 'live-and-preview' = also in the editor's preview) applies at once — agents limited to drafts can't set it. Use for tag managers (GTM), Clarity, ads pixels, chat widgets and verification tags. For plain GA4, Plausible, Fathom or Umami prefer set_analytics_provider.
| Name | Type | Req | Description |
|---|---|---|---|
| body | string | – | Code for before </body> on every page. "" clears it. |
| context | string | – | Why you're calling this (activity log). |
| head | string | – | Code for before </head> on every page. "" clears it. |
| runOn | string | – | Where it runs: 'live' (live site only) or 'live-and-preview'. Applies at once. |
| 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.