# Spaicely > Ask Claude, ChatGPT or Gemini to build your website. Spaicely registers your domain, puts your site online and keeps it secure. No WordPress, no updates. Spaicely is a European hosting provider for static websites that the customer's own AI assistant (Claude, ChatGPT, Gemini, Claude Code, Cursor) builds, publishes and maintains through the Model Context Protocol. Sites run on the customer's own domain; Spaicely does not hand out chosen subdomains, though every paid site also gets a random address under spaicely.site. Customers always use Spaicely's DNS, and the customer is always the registrant of their domain. Status: open since 1 November 2026. People sign up at https://app.spaicely.com/session/new?start=1 (passkey, a link by email, or Google, Apple or Microsoft), or their AI connects to https://mcp.spaicely.com/mcp and the person signs up during the connection. ## Product - [How it works](https://spaicely.com/en-gb/#how): Your AI finds an available domain name and tells you the price. Your AI registers it only once you agree. The domain is always in your name. Your AI designs the site: text, photos, forms. Your site is live at your own address straight away. Every version is kept, so you can always go back. - [Security](https://spaicely.com/en-gb/): Your site is made of plain HTML files. There is no PHP, no database and no plugin that springs a leak tonight. A WordPress vulnerability cannot touch you. - [Web designers and agencies](https://spaicely.com/en-gb/#designers): You build the site in your own account and hand it over with a link. Your client becomes the owner and the domain is in their name. Want to keep doing the maintenance? You keep that role, and your client always sees what you change. - [Pricing](https://spaicely.com/en-gb/#prices): Site € 9 / £8 / $11, Pro € 19 / £17 / $22, Shop € 39 / £34 / $45 per month, excluding VAT. Launch prices. - [Domain search](https://spaicely.com/en-gb/domain-names/): check which extensions are free for a name, without an account. - [Full text of the site](https://spaicely.com/llms-full.txt): everything on the English page in one Markdown file. ## For AI assistants - MCP endpoint: https://mcp.spaicely.com/mcp (Streamable HTTP, stateless, OAuth 2.1). - Protected resource metadata: https://mcp.spaicely.com/.well-known/oauth-protected-resource/mcp - Authorization server metadata: https://app.spaicely.com/.well-known/oauth-authorization-server - Clients register themselves with dynamic client registration and use PKCE (S256). There are no client secrets. - The person chooses the account, the sites and the scopes on the consent screen. A token never allows more than the person's own role on a site. - Spaicely adds tools over time; refresh the tool list regularly. If a tool named here is missing from your list, ask the person to reconnect the connector (in claude.ai: Settings > Connectors), which loads the current list. - Start with the tool `account.whoami`. Purchases always take two calls: a quote with a confirmation token, and the confirmed purchase after the person agreed. The person chooses per kind of action whether you may do it yourself, must ask first or may not (`ai_permissions` in `account.whoami`); a call that must be asked first answers with `approval_required` and a link for the person, and `approvals.status` gives its answer once they approved it in Spaicely. - Command line: the open-source Spaicely CLI (https://github.com/spaicely/cli) is an MCP client of the same server. Coding assistants that run shell commands can use it instead of the connector: `npx spaicely login`, `spaicely init`, `spaicely serve` (preview locally), `spaicely deploy` (upload a folder, such as a Jekyll `_site`), `spaicely publish`, `spaicely domains search|register|connect`, `spaicely dns ls|add|rm`, and `spaicely call ''` for any tool. Install: `brew install spaicely/tap/spaicely`, `npm i -g spaicely` or `curl -fsSL https://spaicely.com/install.sh | sh`. - Developer reference, generated from the code: https://spaicely.com/developers/ (JSON: https://spaicely.com/developers/api.json). ## Changing a site A new site starts with `sites.create` (a name; the account owns and pays for it). A version is the full file list with SHA-256 (`sites.deploy`), then the missing files (`sites.files.put`); an image already on the web can be listed with its `source_url` instead and we fetch it. Or one tar.gz to `sites.upload_url`; `sites.publish` puts it live for everyone at once and can roll back. We keep the files as uploaded (`sites.files.get`) and serve visitors a minified copy. A role can be limited to paths and to marked regions of a page: `...` may change freely, `...` only takes additions. `sites.files.list` shows the regions; `sites.region.update` changes one region on top of the live version. If someone published in between, publishing merges both versions' changes and reports a conflict per path when they touched the same file or region. ## MCP tools on https://mcp.spaicely.com/mcp - `account.whoami` (account:read): Returns the person and account you act for, your scopes, and per site your role and what you may do. - `approvals.status` (account:read): A call of a kind of action the person set to `ask` (see `ai_permissions` in account.whoami) does not run at once: it answers with `approval_required`, an `approval` id and a `url` for the person. - `account.members` (access:manage): Lists the people on the account you act for, with their role (owner or member) and the open invitations. - `account.billing` (billing:write): Shows the billing details of the account you act for: whether it is a business, VAT number, address and country, and changes them with the fields you pass. - `account.invoices` (billing:write): Lists Spaicely's invoices to the account you act for, newest first (at most 50): number, date, amounts in euro cents and a `url` where the person reads and prints it. - `domains.register` (domains:buy): Registers a domain in the name of the customer account you act for; that account becomes the holder. - `domains.propose` (domains:buy): For a partner working on a customer's site (as admin, maintainer or designer): proposes a domain for that site. - `domains.transfer` (domains:buy): Moves a domain that is registered elsewhere to Spaicely, in the name of the customer account you act for; that account is the holder. - `domains.auto_renew` (domains:buy): Shows whether a domain held by the account you act for renews automatically, and switches it on or off with `on`. - `domains.renew` (domains:buy): Gives a link where the person pays for the renewal of a domain registered through Spaicely now, instead of waiting for automatic renewal (domains.auto_renew); the domain renews after payment, for the period in the answer. - `domains.holder` (domains:buy): Shows the holder of a domain registered through Spaicely, as the registry knows it, and changes it with the fields you pass. - `domains.lock` (domains:buy): Switches the transfer lock of a domain registered through Spaicely on or off. - `domains.nameservers` (domains:buy): Sets the nameservers of a domain registered through Spaicely. - `domains.transfer_code` (domains:buy): Asks for the transfer code (auth code) of a domain registered through Spaicely, to move it to another provider. - `sites.create` (content:write): Makes a new, empty site on the account you act for, owned and paid for by that account. - `sites.update` (access:manage): Gives a site another name, at most 80 characters. - `sites.delete` (access:manage): Deletes a site for good: it goes offline at once, and every version, form and the shop disappear. - `sites.subscription` (billing:write): Shows the hosting plan of a site: plan, status, the date it renews or ends, the paying account, and whether a consumer can still withdraw. - `sites.versions` (sites:read): Lists the versions (deployments) of a site, newest first: number, status (draft, ready, publishing, live, failed), files and who made it. - `sites.deploy` (content:write): Starts a new version of a site. - `sites.files.put` (content:write): Sends the contents of files that sites.deploy listed as missing, at most 50 files and 2 MB per call. - `sites.upload_url` (content:write): Returns a one-time URL, valid 10 minutes, that takes the finished site as one tar.gz archive with index.html at its root. - `sites.publish` (sites:publish): Puts a ready version live; visitors switch over at once, never to a mix of two versions. - `sites.review.request` (content:write): For a person who may change files but not publish (sites.publish refuses them): asks the people who may publish to approve a ready version. - `sites.review.reject` (sites:publish): Sends back a version someone asked approval for with sites.review.request, with a `note` that tells them what to change; they get it by mail. - `sites.files.list` (sites:read): Lists the files of the live version of a site, or of `deployment`: path, SHA-256 and size. - `sites.files.get` (sites:read): Returns the contents of up to 20 files (1 MB together) of the live version of a site, or of `deployment`, exactly as they were uploaded. - `sites.region.update` (content:write): Makes a new version that differs from the live one in one region of one page: the block between and (or spaicely:append). - `sites.stats` (sites:read): How much a published site is visited, per day over the last 7, 30 or 90 `days` (default 30), counted by the CDN without cookies or scripts on the site, in total and in `per_day`: `requests` (every file served: pages, images, styles; not people), `bytes` sent, `not_found` (addresses that do not exist, a hint at broken links) and the CDN `regions` that served them, close to the visitors. - `sites.domains.connect` (dns:write): Connects a domain to a site, so the site answers on https:// and www sends people on to it. - `sites.domains.disconnect` (dns:write): The site stops answering on the domain and on its www. - `domains.status` (domains:read): Shows whether a domain is connected to its site, what is still needed (records to confirm, nameservers at the registrar, DNSSEC to switch off, the certificate) and the DNS records Spaicely serves for it. - `domains.dns.update` (dns:write): Adds or deletes DNS records of a domain that is connected to a site, or of a domain of the account on no site (one registered through Spaicely then gets Spaicely DNS, which only answers once its nameservers are ours), such as MX and TXT for mail or a CNAME for a service on a subdomain. - `mail.forward.status` (mail:write): Whether mail to a domain connected to a site is forwarded, its addresses (info@, or * for every address) and where each goes, with the state of each destination (pending until the address clicked the confirmation link we mailed it), and the mail held back in the last 30 days as possible spam (subject, sender, reason, id for mail.forward.release). - `mail.forward.enable` (mail:write): Lets Spaicely receive the mail of a domain connected to a paid site, so its addresses can be forwarded to mailboxes the person already has (mail.forward.add). - `mail.forward.disable` (mail:write): Stops forwarding for a domain: its addresses go, held-back mail is deleted, the MX and the other forwarding records leave Spaicely's DNS and the addresses are no longer billed. - `mail.forward.add` (mail:write): Forwards an address of the domain (address: the part before the @, such as info, or * for every address without one of its own) to up to 5 mailboxes. - `mail.forward.remove` (mail:write): Removes a forwarded address of the domain (address: info, or *), or with destination only that one mailbox. - `mail.forward.release` (mail:write): Sends a message that was held back as possible spam on to its destinations after all (id from mail.forward.status). - `scripts.list` (sites:read): Lists the forms (scripts) of a site: form_id, kind (contact, signup, download or coupon), status (active, waiting_for_recipient, waiting_for_file, waiting_for_codes, disabled), the endpoint on scripts.spaicely.com, counts (for coupon: codes left and given out) and the HTML to put in a page. - `scripts.enable` (scripts:write): Adds a form to a site, handled by Spaicely on https://scripts.spaicely.com. - `scripts.configure` (scripts:write): Changes a form made with scripts.enable: only the settings you pass. - `scripts.subscribers` (scripts:write): Lists who signed up with a signup form: email, name, when they signed up and confirmed, and an unsubscribe_url to put in every mail sent to them. - `scripts.subscribers.update` (scripts:write): For a signup form: `action` unsubscribe keeps the address on the list as unsubscribed, so it gets no more mail; remove erases everything about them, for instance when they ask to be forgotten. - `scripts.leads` (scripts:write): Lists what visitors sent through a contact, download or coupon form that keeps leads (keep_leads true in scripts.configure): when, the fields in the order of the form, the page and the code a coupon form gave. - `scripts.leads.remove` (scripts:write): Removes leads a form kept (scripts.leads): the ones in `ids`, or every lead with `all: true`, for instance when a visitor asks to be forgotten. - `scripts.remove` (scripts:write): Removes a form made with scripts.enable, with everything it kept: signups, leads and codes. - `shop.setup` (scripts:write): Sets up checkout for a web shop on a site with the Shop plan. - `shop.orders` (sites:read): Lists the latest paid orders (at most 50) of the shop of a site: when, buyer name and email, shipping address, lines, total in cents and Spaicely's commission. - `access.list` (sites:read): Lists the owner account, the paying account and everyone with a role on a site: people (name, email) and partner accounts, with role, whether they may publish and their file rules (ADR 0006: actions on glob paths, optionally limited to marked regions). - `access.update` (access:manage): Gives a person a role on a site, changes it, or with role `none` takes them off. - `sites.handover` (partner:manage): For a partner account that owns a site: mails the customer a link, valid for 14 days, to take the site onto their own account. - `sites.handover.revoke` (partner:manage): Takes back a handover sent with sites.handover that the customer has not accepted yet: the link in their mail stops working and the site stays with the partner. ## HTTP API - `GET https://app.spaicely.com/api/domains/search/{names}/{extensions}` (none): Quick check (DNS only) whether domains are free: comma-separated names or full domains, then optional extensions, at most 50 domains. - `GET https://app.spaicely.com/api/domains/verify/{names}/{extensions}` (none): Deep check of at most 10 domains: DNS, then our registrar (checked_via registrar) or else the registry over RDAP. - `GET https://app.spaicely.com/api/domains/extensions` (none): The extensions people ask for most (extensions, the default for a bare name), all 718 Spaicely sells (all), the most domains per request, and which extensions a deep check can settle (verifiable), and a price class per extension (price_classes: 0 cheap to 4 dear), and our prices (prices: per extension create, renew and transfer in euro cents before VAT, each for the whole term paid up front: months for create, renew_months and transfer_months, 12 for most and 24 for .ai; transfer_months null means a move adds no term, as for .nl, and then often costs nothing; add VAT where it applies), and euro_rates: euros per GBP and per USD, the rate at which an account in the United Kingdom (pounds) or outside Europe (dollars) pays those prices. - `PUT https://app.spaicely.com/uploads/{token}` (one-time URL): Upload a whole site as one tar or tar.gz (index.html at the root, plain files only, at most 200 MB) to the URL that sites.upload_url returned. - `POST https://scripts.spaicely.com/f/{form_id}` (Origin: the site's connected domain): A contact form made with scripts.enable posts here: urlencoded from a plain HTML form, or JSON with fetch. - `POST https://scripts.spaicely.com/s/{form_id}` (Origin: the site's connected domain): A signup form made with scripts.enable posts here, with email and optionally name. - `POST https://scripts.spaicely.com/l/{form_id}` (Origin: the site's connected domain): A download form made with scripts.enable posts here, with email and any other fields. - `POST https://scripts.spaicely.com/k/{form_id}` (Origin: the site's connected domain): A coupon form made with scripts.enable posts here, with email and any other fields. - `GET https://{site domain}/_download/{token}` (the link from a download form): The link a visitor gets from a download form, on the site's own domain; it never shows where the file lives. - `POST https://app.spaicely.com/forms/{form_id}/checkout` (Origin: the site's connected domain or its address): A download or coupon form with price_cents posts here instead of to the scripts service: a plain form (urlencoded) or fetch as JSON with email, start_now and any other fields. - `GET https://app.spaicely.com/forms/{form_id}/progress` (none, open to every origin): What a donation form raised, for a progress bar on the site: {"raised_cents", "donors", "goal_cents", "ends_at", "open", "donations": [{"name", "message", "at"}]} with paid donations only and the last 20 names and messages donors chose to show. - `POST https://app.spaicely.com/shop/{shop_id}/checkout` (Origin: the site's connected domain or its address): A web shop made with shop.setup sends an order here, from a plain form (a buy button, urlencoded items[0][id], items[0][quantity], shipping) or with fetch as JSON {"items": [{"id": ..., "quantity": ...}], "shipping": ...}. - `POST https://mcp.spaicely.com/mcp` (OAuth 2.1 bearer): MCP server for signed-in clients (Streamable HTTP, stateless; GET and DELETE answer 405). - `POST https://mcp.spaicely.com/mcp/public` (none): MCP server without an account: domains.search and the prompt domain_brainstorm. - `GET https://mcp.spaicely.com/.well-known/mcp/server-card.json` (none): MCP server card: name, endpoints, authentication and tools. - `GET https://mcp.spaicely.com/.well-known/oauth-protected-resource/mcp` (none): Protected resource metadata (RFC 9728) for the MCP server: which authorization server and scopes. - `GET https://app.spaicely.com/.well-known/oauth-authorization-server` (none): Authorization server metadata (RFC 8414). - `POST https://app.spaicely.com/oauth/register` (none): Dynamic client registration (RFC 7591). - `GET https://app.spaicely.com/oauth/authorize` (browser session): Authorization code flow with PKCE S256. - `POST https://app.spaicely.com/oauth/token` (client_id + PKCE): Exchanges the code, or a refresh token, for an access token (1 hour). - `POST https://app.spaicely.com/oauth/revoke` (client_id): Revokes an access or refresh token (RFC 7009). Every tool with its parameters: https://spaicely.com/llms-full.txt and https://spaicely.com/developers/ (machine-readable: https://spaicely.com/developers/api.json). ## Web shop A site on the Shop plan can sell: the owner links a Stripe account once (the page in `connect_url`), you put the products in `data/products.json` (`{"products": [{"id": "mok", "name": "Blue mug", "price": 1495, "image": "/img/mok.jpg"}], "shipping": [{"id": "nl", "name": "Shipping in the Netherlands", "price": 495, "countries": ["NL"]}]}`, prices in cents including VAT) and `shop.setup` switches the shop on and says what it still waits for. Buy buttons are plain forms, a cart posts JSON with fetch, both to `POST https://app.spaicely.com/shop/{shop_id}/checkout`; the buyer pays on Stripe Checkout, straight to the owner, and Spaicely takes 2% commission. Prices always come from the live `data/products.json`, never from the page. `shop.orders` lists the paid orders. A file holds at most 500 products. Paid forms and donations go the same way; see Forms and donations. ## Forms and donations `scripts.enable` adds a form handled by Spaicely and returns the HTML for a page; it works on the site's own domain and its address. Kinds: `contact` mails each message to the owner (another recipient confirms by mail first); `signup` keeps a list with double opt-in (`scripts.subscribers`); `download` mails the visitor's details to the owner and gives the visitor a link to a file under `_private/`, which never goes to the CDN; `coupon` does the same with a discount code: one code for everyone, a list of codes that each go out once, or `dated_codes` with a window (a shared code per week, or unique codes that expire). A download or coupon form with `price_cents` is paid: the visitor pays the owner on Stripe and gets the link or code by mail. `donation` takes donations on every plan: amount buttons and a free amount, paid to the owner's own Stripe account, a thank-you mail to the donor and a mail per donation to the owner; donors may show their name and message. `GET https://app.spaicely.com/forms/{form_id}/progress` gives the total, the number of donors and the names shown, open to any origin, for a progress bar towards a goal. What comes in is the owner's, also when a goal is not reached; not for investments or loans. Payments carry 2% commission plus VAT. Mail to a connected domain can be forwarded to an inbox the person already has, such as info@ to their Gmail: `mail.forward.enable` points the domain's MX to Spaicely (it asks first when the domain already has mail elsewhere), `mail.forward.add` creates an address (`*` catches everything else) with up to 5 destinations, each of which confirms by mail first. EUR 1.50 (GBP 1.30, USD 1.75) a month per address, excl. VAT, billed with the plan: Site 1 address, Pro 5, Shop 10. Mail that looks like spam, fraud or a risky attachment is withheld; `mail.forward.status` lists it and `mail.forward.release` sends it on. `mail.forward.remove` and `mail.forward.disable` stop it. Replying as info@ is not possible yet. ## Accounts, plans and the dashboard People sign in with a passkey, a link by mail, or Google, Apple or Microsoft; there are no passwords. Everything the AI does can also be done without one at https://app.spaicely.com: create a site, upload a folder or zip, put versions live, connect a domain, edit DNS records, set up forms and see visits. Every paid site also has its own address, `