Spaceship MCP Connector connects your AI assistant (such as Claude) to your Spaceship account. Through it, the assistant can check domain availability and prices, manage domain contacts and nameservers, and read or edit DNS records on your behalf — you just ask in plain language, and the assistant calls the right tools.
Spaceship MCP Connector does not buy domains. The assistant can check whether a name is available and what it costs, but the purchase itself happens on spaceship.com.
You need a Spaceship account. Spaceship MCP Connector is available at https://connector-mcp.spaceship.com/mcp.
Claude (web and desktop) — open Settings, choose Connectors, find Spaceship in the connectors directory, and add it. Anthropic's Claude is currently the client we have verified Spaceship MCP Connector to work with.
Other MCP clients — add a remote MCP server and point it at https://connector-mcp.spaceship.com/mcp. Other clients may work, but we haven't verified them yet.
When you connect, you'll be asked to sign in to Spaceship and grant the assistant access to your account. Which tools the assistant can use depends on the access you approve — if a tool is rejected because access wasn't granted, reconnect and approve the access it needs.
Tool: contacts_save
What it does: Save contact details and get a contact ID
Tool: contacts_get
What it does: Read a saved contact by its ID
Tool: contacts_list
What it does: List all saved contacts to find and reuse one
Tool: domains_list
What it does: List your domains, or look up one domain
Tool: domains_check_availability
What it does: Check if domains are available to register, and their price
Tool: domain_set_contacts
What it does: Assign contacts to a domain you own
Tool: domain_set_nameservers
What it does: Switch a domain to basic or custom nameservers
Tool: dns_records_get
What it does: Read DNS records for a domain
Tool: dns_records_save
What it does: Add DNS records or update their TTL
Tool: dns_records_delete
What it does: Delete DNS records
Tool: async_operation_get
What it does: Check the status of a long-running operation
None of these tools charges your account.
Wherever a contact is required (domain_set_contacts), each role takes a contactId string — never inline contact details. Save the contact first with contacts_save (which returns its contactId), then pass that id where the contact is accepted. There is no inline auto-save; a role cannot receive a full contact object. You may also reuse a contactId from a contacts_list result or one you read off a domains_list result.
A contactId is a string of 27–32 alphanumeric characters. Just pass it back where a contact is accepted.
Several tools are designed to be used together: the output of one becomes the input of the next.
domains_check_availability — check the name(s) you want. Each available name includes the USD price to register it (standard and premium alike), or priceUnavailableReason when it can't be determined, plus minRegisterPeriodInYears and maxRegisterPeriodInYears — the terms that TLD allows. Note the price covers price.pricedYears years, which is the TLD's shortest allowed term and is not always 1.
Buy it on spaceship.com. No tool registers a domain or produces a checkout link, so the assistant cannot complete the purchase or say that a domain was registered from the conversation. Once the purchase is done, domains_list shows the new domain.
domain_set_contacts — assign contacts to the domain by contactId (save them with contacts_save first if needed). This completes immediately and returns a verificationStatus: verification means the registrant must confirm their email address before the change fully applies (an email is sent to them), success means it's already confirmed, and null means no confirmation is required for that domain.
domains_list — find the domain and see its current nameservers ({ provider, hosts }).
domain_set_nameservers — switch it to Spaceship's default nameservers with provider: "basic" (no hosts), or point it at your own with provider: "custom" and a list of 2–12 hosts. It returns the resulting { provider, hosts }, and a subsequent domains_list reflects the change. Re-applying the state a domain is already in returns a validation error rather than a no-op — treat that as expected, not a failure to retry.
domains_list — find the domain you want to manage (or pass its name directly if you know it).
dns_records_get — read the current records for the domain.
dns_records_save or dns_records_delete — add, update, or remove records. Records returned by dns_records_get have the same shape the save and delete tools accept (delete just omits ttl), so the assistant can read, adjust, and write back. Matching is case-insensitive except for TXT records, which are case-sensitive.
domains_list — page through all your domains with sorting, or fetch a single domain by name. Each domain includes its expiration date, auto-renew setting, status, nameservers, privacy protection, and assigned contact IDs.
contacts_list — page through all the contacts saved on your account to find and reuse an existing one (by its contact ID) instead of creating a duplicate.
contacts_get — look up the details behind any contact ID you see on a domain or in a contacts_list result.
Every tool returns its result as structured JSON, and every tool completes immediately.
Contacts are the people or organizations attached to a domain registration (registrant, admin, tech, billing). A contact is referenced everywhere by its contact ID — an opaque string.
contacts_save — Save ContactSaves contact details and returns the generated contact ID. Validation of some fields (such as stateProvince and postalCode) depends on the selected country.
Parameter: firstName
Required: Yes
Type & constraints: String, 1–64 chars. May include hyphens and apostrophes.
Parameter: lastName
Required: Yes
Type & constraints: String, 1–64 chars. May include hyphens and apostrophes.
Parameter: email
Required: Yes
Type & constraints: Valid email address, max 254 chars.
Parameter: address1
Required: Yes
Type & constraints: Address line 1. String, 1–128 chars.
Parameter: city
Required: Yes
Type & constraints: String, 1–64 chars.
Parameter: country
Required: Yes
Type & constraints: Two-letter country code (ISO 3166-1 alpha-2), e.g. US.
Parameter: phone
Required: Yes
Type & constraints: International format +CountryCode.Number, e.g. +1.2025551234. Max 32 chars.
Parameter: organization
Required: No
Type & constraints: Organization/company name. 1–128 chars.
Parameter: address2
Required: No
Type & constraints: Address line 2. 1–128 chars.
Parameter: stateProvince
Required: No
Type & constraints: State/province name, 1–64 chars. May be required depending on the country.
Parameter: postalCode
Required: No
Type & constraints: 1–16 chars. May be required depending on the country.
Parameter: phoneExt
Required: No
Type & constraints: Phone extension, 1–16 chars.
Parameter: fax
Required: No
Type & constraints: Fax number, same +CountryCode.Number format, max 32 chars.
Parameter: faxExt
Required: No
Type & constraints: Fax extension, 1–16 chars.
Parameter: taxNumber
Required: No
Type & constraints: Tax number, 1–32 chars.
Returns
{ "contactId": "..." }
contactId (27–32 alphanumeric characters) is what you pass to domain_set_contacts and contacts_get.
contacts_get — Get ContactReads the details of a saved contact by its contact ID. Contact IDs come from contacts_save, contacts_list, or the contacts field of domains_list results.
Parameter: contactId
Required: Yes
Type & constraints: Contact ID, 27–32 alphanumeric characters.
Returns — { contact } with:
Field: firstName, lastName, email, address1, city, country, phone, postalCode
Type: String
Field: organization, address2, stateProvince, phoneExt, fax, faxExt, taxNumber
Type: String or null
contacts_list — List ContactsLists all contacts saved under your account, so you can find and reuse an existing contact (by its contact ID) instead of creating a duplicate or hunting through your domains. The list is paginated and sortable, consistent with domains_list.
Parameter: take
Required: No
Type & constraints: Items per page, 1–100. Default 10.
Parameter: skip
Required: No
Type & constraints: Items to skip, 0 or more. Default 0.
Parameter: orderBy
Required: No
Type & constraints: Up to 8 sort keys: name, email, organization; prefix with - for descending (e.g. -name).
Returns — { items, total } where total is the number of unique contacts on the account (deduplicated by contact ID, not the page size), and each item carries enough to tell contacts apart without a follow-up call. If the account has duplicate entries for the same contact ID they are collapsed to one, so total counts distinct contacts rather than raw server-side rows:
Field: contactId
Type: String (27–32 alphanumeric). Pass to contacts_get or domain_set_contacts.
Field: name
Type: String — the contact's name.
Field: email
Type: String or null when the contact has no email on record.
Field: organization
Type: String or null when the contact has no organization on record.
{"items": [{ "contactId": "1anq5bsl9haBy21rOV9aeDWrARBsV", "name": "Ada Lovelace", "email": "ada@example.com", "organization": "Analytical Engines" }],"total": 1}
Domain name inputs (domain/domainName) accept Unicode (IDN) or ASCII (A-label) — either way, the tool normalizes the name to punycode automatically before use. domains_check_availability additionally requires a TLD Spaceship supports for registration: a domain whose TLD isn't supported is reported as not available rather than checked. The other domain tools (domains_list, domain_set_contacts, domain_set_nameservers) and the DNS tools normalize the name only and never reject on TLD support.
domains_list — List DomainsRetrieves a paginated list of your domains. Pass domain to fetch a single domain by name instead (pagination and ordering are then ignored, and the result includes a note saying so if they were supplied).
Parameter: domain
Required: No
Type & constraints: Fully qualified domain name to fetch a single domain. Accepts Unicode (IDN) or ASCII (A-label) — normalized to punycode automatically.
Parameter: take
Required: No
Type & constraints: Items per page, 1–100. Default 10.
Parameter: skip
Required: No
Type & constraints: Items to skip, 0 or more. Default 0.
Parameter: orderBy
Required: No
Type & constraints: Up to 8 sort keys: name, unicodeName, registrationDate, expirationDate; prefix with - for descending (e.g. -expirationDate).
Returns — { items, total } where each item describes a domain:
Field: name / unicodeName
Meaning: Domain name in ASCII and Unicode form.
Field: isPremium
Meaning: Whether the domain is a premium name.
Field: autoRenew
Meaning: Whether auto-renew is enabled.
Field: registrationDate / expirationDate
Meaning: Registration and expiration timestamps.
Field: lifecycleStatus
Meaning: creating, registered, grace1, grace2, or redemption.
Field: verificationStatus
Meaning: verification, success, failed, or null when not applicable.
Field: eppStatuses
Meaning: Registry status codes (e.g. transfer locks).
Field: suspensions
Meaning: Active suspensions, each with a reasonCode.
Field: privacyProtection
Meaning: { level: "public" | "high", contactForm: boolean }.
Field: nameservers
Meaning: { provider: "basic" | "custom", hosts: [...] }.
Field: contacts
Meaning: Contact IDs: registrant, plus admin/tech/billing (may be null) and attributes (a list of extended-attribute contact IDs, or null). Readable via contacts_get.
Spaceship MCP populates every field above — including contacts, eppStatuses, suspensions, verificationStatus, nameservers, a real autoRenew, and a distinct unicodeName where the domain has one — for both the multi-item list and single-domain fetches.
domains_check_availability — Check Domain AvailabilityChecks whether one or more domain names are available to register. Uses the single-domain endpoint for one name and the bulk endpoint for multiple. A domain whose TLD isn't supported for registration is not sent to the availability check at all — it's returned immediately as tldNotSupported.
Parameter: domains
Required: Yes
Type & constraints: 1–20 fully qualified domain names. Each accepts Unicode (IDN) or ASCII (A-label) — normalized to punycode automatically.
Returns — { results }, one entry per requested name:
Field: domain
Meaning: The checked name.
Field: result
Meaning: available, taken, invalidDomainName, tldNotSupported, or unexpectedError.
Field: premiumPricing
Meaning: For premium names: list of { operation, price, currency } where operation is register, transfer, renew, or restore. Empty for regular names.
Field: price
Meaning: For available names (standard and premium): the USD price to register the domain for the shortest term the TLD allows — { amount, currency: "USD", pricedYears?, pricePerYear?, icannFee?, isPremium }. amount is the payable total for that whole term; pricedYears states how many years it covers. No pre-discount or "was" price is reported. icannFee is the ICANN fee (USD) already included in amount, returned separately so the breakdown can be explained; it appears only when the TLD carries a fee.
Field: pricePerYear
Meaning: Inside price: amount divided by pricedYears, so a yearly figure is always available for comparison. When pricedYears is 1 it is the real one-year price; above that it is a per-year average of the term, not a term you could buy.
Field: minRegisterPeriodInYears / maxRegisterPeriodInYears
Meaning: For available names: the shortest and longest registration period that TLD actually permits, as two plain numbers. They tell the customer which terms they can buy the domain for. Both omitted when the allowed period could not be determined.
Field: priceUnavailableReason
Meaning: Present instead of price when the price could not be determined for an available name. The check itself still succeeds.
Only available names are priced; taken/invalid results carry neither price nor priceUnavailableReason.
Most TLDs allow one year, but some do not. .ai, for example, has a two-year minimum. For those, price.amount is the total for the minimum term — not a one-year price you could act on — and price.pricedYears says so:
{"domain": "example.ai","result": "available","premiumPricing": [],"price": { "amount": 159.96, "currency": "USD", "pricedYears": 2, "pricePerYear": 79.98, "isPremium": false },"minRegisterPeriodInYears": 2,"maxRegisterPeriodInYears": 10}
pricePerYear is present here — 159.96 divided by the two years it covers gives 79.98. This is the total divided by the term, not a price you could pay for a single year (a one-year .ai registration cannot be bought). Always show amount together with pricedYears ("$159.96 for 2 years"), never amount alone. For an ordinary TLD, pricedYears is 1 and pricePerYear equals amount.
domain_set_contacts — Set Domain ContactsChanges the contacts assigned to a domain you own. Completes immediately (no operation to poll).
Parameter: domainName
Required: Yes
Type & constraints: Fully qualified domain name. Accepts Unicode (IDN) or ASCII (A-label) — normalized to punycode automatically.
Parameter: registrant
Required: Yes
Type & constraints: contactId string (27–32 alphanumeric), from contacts_save.
Parameter: admin
Required: No
Type & constraints: contactId string (27–32 alphanumeric) or null.
Parameter: tech
Required: No
Type & constraints: contactId string (27–32 alphanumeric) or null.
Parameter: billing
Required: No
Type & constraints: contactId string (27–32 alphanumeric) or null.
Parameter: attributes
Required: No
Type & constraints: Array of extended-attribute contact ids (up to 5); required only for certain TLDs, omit or null otherwise.
Returns
{ "verificationStatus": "verification" }
The returned verificationStatus reflects ICANN RAA email verification: verification — the registrant must confirm their email address (a confirmation email is sent); success — already confirmed; null — RAA verification does not apply to this domain.
domain_set_nameservers — Set Domain NameserversChanges a domain's registrar-level nameservers. Completes immediately (no operation to poll). The change is reflected by domains_list afterwards.
Parameter: domainName
Required: Yes
Type & constraints: Fully qualified domain name. Accepts Unicode (IDN) or ASCII (A-label) — normalized to punycode automatically.
Parameter: provider
Required: Yes
Type & constraints: basic (Spaceship's default nameservers) or custom (your own hosts).
Parameter: hosts
Required: Conditional
Type & constraints: Required when provider is custom: 2–12 nameserver hostnames (each a valid FQDN, 4–255 chars). Must be omitted when provider is basic.
Returns
{ "provider": "custom", "hosts": ["ns1.example.com", "ns2.example.com"] }
Re-applying the state a domain is already in (e.g. setting basic when it is already basic) returns a validation error rather than a no-op success — treat that as an expected result, not a failure to retry.
The domainName these tools take accepts Unicode (IDN) or ASCII (A-label) and is normalized to punycode automatically; TLD support is not enforced here.
dns_records_get — Get DNS RecordsRetrieves a paginated list of DNS resource records for a domain.
Parameter: domainName
Required: Yes
Type & constraints: The domain whose records to fetch.
Parameter: take
Required: No
Type & constraints: Items per page, 1–500. Default 100.
Parameter: skip
Required: No
Type & constraints: Items to skip, 0 or more. Default 0.
Parameter: orderBy
Required: No
Type & constraints: Up to 8 sort keys: type, -type, name, -name.
Returns — { items, total }. Each item is a record as described in Record shapes, plus an optional group field indicating where the record comes from (custom — created by you, product — managed by a Spaceship product, personalNs — personal nameservers).
dns_records_save — Save DNS RecordsAdds custom DNS records or updates the TTL of existing ones. Records are matched case-insensitively, except TXT records (case-sensitive).
Parameter: domainName
Required: Yes
Type & constraints: The domain whose records to update.
Parameter: records
Required: Yes
Type & constraints: 1–500 records — see Record shapes. Each may include an optional ttl.
Parameter: force
Required: No
Type & constraints: Boolean. Skips the conflict-resolution check and forces the zone update.
Returns — { "saved": <number> }, the count of submitted records. A successful response means all records were accepted; if any record fails, the whole call returns an error instead.
dns_records_delete — Delete DNS RecordsDeletes custom DNS records. Deletions cannot be undone. Records are matched case-insensitively, except TXT records (case-sensitive).
Parameter: domainName
Required: Yes
Type & constraints: The domain whose records to delete.
Parameter: records
Required: Yes
Type & constraints: 1–500 records identifying existing records — same shapes as save, but without ttl.
Returns — { "deleted": <number> }, the count of submitted records. If any record cannot be matched, the whole call fails and nothing is deleted.
Every record has:
type — one of the 13 supported types below.
name — the record name excluding the domain: use @ for the domain itself (apex) and * for a wildcard.
ttl (save only, optional) — cache time in seconds, 60–3600.
Type-specific fields:
Type: A
Fields: address — IPv4 address.
Type: AAAA
Fields: address — IPv6 address.
Type: CNAME
Fields: cname — canonical domain name (max 253 chars).
Type: ALIAS
Fields: aliasName — canonical domain name; CNAME-like behavior for the apex, where CNAME isn't allowed.
Type: NS
Fields: nameserver — nameserver name.
Type: PTR
Fields: pointer — domain name for the given IP address.
Type: TXT
Fields: value — text value (matched case-sensitively).
Type: MX
Fields: exchange — mail server; preference — priority (0–65535, lower preferred).
Type: CAA
Fields: flag — 0 or 128 (critical bit); tag — issue, issuewild, or iodef; value — CA identifier with optional parameters.
Type: SRV
Fields: service (e.g. _sip); protocol (e.g. _tcp); priority and weight (0–65535); port (1–65535); target — server domain name.
Type: TLSA
Fields: usage, selector, matching (each 0–255); port — * or _<1–65535>; protocol (e.g. _tcp); associationData — certificate hash or data.
Type: HTTPS
Fields: svcPriority (0–65535; 0 = AliasMode); targetName — FQDN or .; optional port (* or _<1–65535>), scheme (must be _https when port is set), svcParams.
Type: SVCB
Fields: svcPriority (0–65535; 0 = AliasMode); targetName — FQDN or .; optional port, scheme (e.g. _tcp), svcParams.
async_operation_get — Get Async Operation StatusChecks a long-running operation on your account by its operationId. Call it repeatedly until status is success or failed.
Parameter: operationId
Required: Yes
Type & constraints: Alphanumeric string, max 36 chars, returned by the tool that started the operation.
Returns
Field: operationId
Meaning: The polled operation.
Field: status
Meaning: pending, success, or failed.
Field: type
Meaning: Operation type, or null.
Field: details
Meaning: Extra details about the operation, or null.
Field: createdAt / modifiedAt
Meaning: When the operation was created / last updated (modifiedAt may be null).
When a call fails, the tool returns an error with a code and a human-readable detail explaining what went wrong — for example invalid input (a malformed domain name or contact ID), a domain or contact that doesn't exist, or a conflict with the current state. If a tool is rejected because the assistant wasn't granted access to it, reconnect Spaceship MCP and approve the access it asks for.