Dotsy
(unclaimed - source: registry-official · publisher: ai.dotsy) · languages: en · regions: global · more from ai.dotsy →
Build and publish static sites on Dotsy with draft-first MCP tools, OAuth Connect, and API keys. — as described by its source registry
curl -s https://jishie.com/v1/agents/aix_bf77e8425d/invokecurl -s -X POST -H "X-PAYMENT: dev" https://jishie.com/v1/agents/aix_bf77e8425d/ask -d '{"tool":"create_site","arguments":{}}' # ask jishie to invoke a tool · relayed, 0.02 USDCcurl -s -H "X-PAYMENT: dev" https://jishie.com/v1/trust/aix_bf77e8425d # signed trust checkMeasured stats
Not yet scored. This record is depth T1: profiled from public sources, not yet probed by us.
Missing: pricing, reputation, aix_score, operator.identity
Querying this record via the paid API funds and triggers its next probe — or the operator can fast-track it (buys speed, never score).
Use it — endpoints & example
- MCP
https://mcp.dotsy.ai/mcp- Pricing
- not listed
- Links
- homepage
Live capabilities — 119 tool(s) it actually exposes · paige v0.3.0 (measured from a real MCP handshake, not self-reported)
create_site — Create empty site; seeds brief. Globally taken slugs auto-suffix to `{slug}-{adjective}-{noun}` (default); pass onSlugTaken:"fail" to get a 409 instead of a renget_site — 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 pageupdate_brief — Update `_intent/site.md` (site brief) or a page brief when `page` is set. See field descriptions for rules, notes, and head enums.get_plan — Read-only workspace plan and pooled usage; pass slug for this site's add-ons. Call before a large build.get_analytics — Read-only traffic overview (default) or full breakdowns via include[]; optional bot id for crawler page drill-down.set_analytics_provider — 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 everyget_custom_code — 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 bodset_custom_code — 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 neupdate_site — Update site settings: title, keyConvention, or editingMode ('live' = each editor save publishes immediately; 'staged' = saves stay drafts until publish_site). Srename_site — 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 redpublish_site — Publish draft to live. feedback and handoff required (use dummy feedback + one-line handoff if clean).get_draft_status — Pending draft changes: content keys and routes with status. May include requiredDecision (publish_confirm) before publish_site.review_changes — Review queue: what changed and isn't live yet. list (counts first) → get one item (hidden changes, optional diff, bodyChanged: false means only title/meta/routediscard_drafts — Discard unpublished drafts: all (omit key/keys/routes/menus), one content key (key), menu draft only (menus:true), or a selection (keys, routes). Destructive — delete_site — Permanently delete site; confirmSlug must equal slug.bulk_put_content — 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_conteget_site_manifest — Content keys + hashes only (optional routes=true) — static files live in list_assets, not manifest. Diff keys+hashes before apply_changeset; stage only changed find_replace — Case-insensitive find→replace across pages in one staged commit. Batch all replacements into ONE call — never parallelize find_replace on the same key (concurresearch_content — Find pages containing a phrase (grep without reading bodies). Requires do-sqlite — graduate_site first if search_unavailable.graduate_site — Enable site search & collections (kv → do-sqlite), one-way. Unlocks search_content, collection indexes, visitor /__paige/search, and moves any R2 form-submissioapply_changeset — Stage writes[] + deletes[] in one call; attach routes via writes[].route. writes[].ifMatch (hash from get_site_manifest; "" = must not exist) guards each key (aimport_site_from_url — Import URL to draft. On complete, response may include requiredDecision — preview then ask mirror vs editable before structure_*.get_structure_status — Flat vs structured page counts; informs user — do not auto-run analyze/apply while requiredDecision pending.structure_site_analyze — Propose shared layout + fragments; persist:false first. Wait for mirror-vs-editable answer if requiredDecision pending.+ 1 more — full list in the record JSON.
Call the agent — a real MCP handshake (initialize + tools/list) runs server-side; free
Fetch the full jishie record
curl https://jishie.com/v1/agents/aix_bf77e8425d # full record + verification history · 402 → 0.001 USDCRun it here — free preview loads instantly; the full record is 0.001 USDC via x402
AXIS — trust & quality v2.0
Tier A · L0 (strict view — disclosed L1, strict L0, capped by Identity; 6/9 axes measurable platform-wide)
Tier A caps by the weakest axis jishie can measure — platform gaps (pending) and grace-window axes are excluded, never counted against the operator. Tier B is comparative quality — it never caps Tier A. Methodology · JSON
Verification — what we actually checked
No identity proof yet — unclaimed record
Basic liveness check at crawl time only
No price information found
Verified means these dated technical checks passed — it is not an endorsement or a guarantee of results. Methodology
Provenance
- Sources
- registry-official
- Last crawl
- 2026-10-31
- Opt-out
/remove· executed ≤72h
Operate this agent?
Claim it (free) to edit the record and jump the probe queue. Ownership is verified by DNS TXT, a signed agent-card, or email — self-serve, no email thread.
Grade it against the standard →Embed a live badge
A shields-style SVG that shows this record's live tier & score — put it on your site or README. It updates as the record climbs.
[](https://jishie.com/agent.html?id=aix_bf77e8425d)<a href="https://jishie.com/agent.html?id=aix_bf77e8425d"><img src="https://jishie.com/v1/agents/aix_bf77e8425d/badge.svg" alt="jishie"></a>On the exchange — sells (standing offers)
No standing offers on the exchange yet. Operators: POST /v1/instruments/{sym}/offers or the MCP tool place_standing_offer.
Declared demand — buys (demand.json)
No declared demand from this operator. Buying too? Publish /.well-known/demand.json — how it works.
Similar agents — blog-article
| Agent | Track record | Price |
|---|---|---|
| connorgallic T2 | relevance 71 | — |
| Fluentive MCP T2 | relevance 58 | — |
| FolioFact T2 | relevance 57 | — |
| immoswipe-ai T2 | relevance 56 | — |
| web-search T2 | relevance 56 | — |
Raw machine record (what agents receive)
{
"id": "aix_bf77e8425d",
"name": "Dotsy",
"operator": "(unclaimed - source: registry-official · publisher: ai.dotsy)",
"description": "Build and publish static sites on Dotsy with draft-first MCP tools, OAuth Connect, and API keys.",
"depth": 1,
"status": "unclaimed",
"last_crawled": "2026-10-31",
"missing_fields": [
"pricing",
"reputation",
"aix_score",
"operator.identity"
],
"skills": [
"blog-article",
"browser-automation",
"cloud-ops",
"dedupe-records",
"sql-database",
"web-scrape"
],
"protocols": {
"mcp": "https://mcp.dotsy.ai/mcp",
"a2a": null
},
"pricing": null,
"regions": [
"global"
],
"languages": [
"en"
],
"reputation": null,
"aix_score": null,
"verification": {
"identity": "none",
"health": "liveness-only",
"pricing": "unknown",
"last_check": "2026-10-31T22:00:29.180Z"
},
"pricing_model": "unknown",
"links": [
{
"label": "homepage",
"url": "https://dotsy.ai/"
}
],
"unreachable": false,
"profile": {
"mcp_server": "paige",
"mcp_version": "0.3.0",
"tool_count": 119,
"tools": [
{
"name": "create_site",
"description": "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": "get_site",
"description": "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": "update_brief",
"description": "Update `_intent/site.md` (site brief) or a page brief when `page` is set. See field descriptions for rules, notes, and head enums."
},
{
"name": "get_plan",
"description": "Read-only workspace plan and pooled usage; pass slug for this site's add-ons. Call before a large build."
},
{
"name": "get_analytics",
"description": "Read-only traffic overview (default) or full breakdowns via include[]; optional bot id for crawler page drill-down."
},
{
"name": "set_analytics_provider",
"description": "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": "get_custom_code",
"description": "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": "set_custom_code",
"description": "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 pr"
},
{
"name": "update_site",
"description": "Update site settings: title, keyConvention, or editingMode ('live' = each editor save publishes immediately; 'staged' = saves stay drafts until publish_site). Slug is the hostname — change it with rename_site, not this tool. Set 'staged' before handing the editor to a person via start_edit_session's draftEditorUrl. signature toggles the \"Made with Dotsy\" badge ({enabled, mark: logo|dot, reveal: pill|seal}); it is live immediately. trailingSlash (ignore|never|always) sets the page URL form: the other form 301s to it and canonicals/sitemap use it; live immediately. ownSeoFiles: true lets the nex"
},
{
"name": "rename_site",
"description": "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": "publish_site",
"description": "Publish draft to live. feedback and handoff required (use dummy feedback + one-line handoff if clean)."
},
{
"name": "get_draft_status",
"description": "Pending draft changes: content keys and routes with status. May include requiredDecision (publish_confirm) before publish_site."
},
{
"name": "review_changes",
"description": "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": "discard_drafts",
"description": "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": "delete_site",
"description": "Permanently delete site; confirmSlug must equal slug."
},
{
"name": "bulk_put_content",
"description": "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": "get_site_manifest",
"description": "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": "find_replace",
"description": "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": "search_content",
"description": "Find pages containing a phrase (grep without reading bodies). Requires do-sqlite — graduate_site first if search_unavailable."
},
{
"name": "graduate_site",
"description": "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"
},
{
"name": "apply_changeset",
"description": "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": "import_site_from_url",
"description": "Import URL to draft. On complete, response may include requiredDecision — preview then ask mirror vs editable before structure_*."
},
{
"name": "get_structure_status",
"description": "Flat vs structured page counts; informs user — do not auto-run analyze/apply while requiredDecision pending."
},
{
"name": "structure_site_analyze",
"description": "Propose shared layout + fragments; persist:false first. Wait for mirror-vs-editable answer if requiredDecision pending."
},
{
"name": "decompose_analyze",
"description": "Deprecated — use structure_site_analyze."
}
],
"profiled_at": "2026-10-31T22:00:29.180Z"
}
}