Skip to main content
Glama
oborseth

Official Porkbun MCP Server

Register Domain

register_domain
Idempotent

Spends account credit, or pays directly by card (pay_with_card) or in USDC (pay_with_usdc). Registers a new domain on the authenticated Porkbun account.

Instructions

Spends account credit, or pays directly by card (pay_with_card) or in USDC (pay_with_usdc). Registers a new domain on the authenticated Porkbun account. The cost_cents parameter must exactly match the current registration price returned by check_domain (in cents) — Porkbun rejects mismatched quotes. Workflow: call check_domain first to get availability + price, confirm the spend with the user, then call this. The order is idempotency-safe: retries within 24 hours via the same Idempotency-Key return the original response without re-charging. Premium domains, .uk, and a handful of registry-specific TLDs cannot be registered via API and must be done on the website. The account's email and phone number must be verified. A single API registration cannot exceed $100 (ORDER_TOO_LARGE); above that the user has to register on the website. Every registration includes a free trial email mailbox: after registering, setup_mailbox gives it an address at no cost (don't create_mailbox for the first one). Internationalized names (IDNs, e.g. café.com or xn--caf-dma.com) need idn_language: check_domain lists the accepted ones as idnLanguages; without it the call returns IDN_LANGUAGE_REQUIRED with that list and nothing is charged.

How a purchase is paid. From prepaid account credit by default; a card saved at Porkbun is never charged by a purchase itself. Or directly, for this one purchase: pay_with_card: true (the user's card from their Stripe Link agent wallet, held and charged only if the purchase succeeds) or pay_with_usdc: true (USDC on Base over x402). If the credit is short, the call fails with INSUFFICIENT_FUNDS carrying cost, balance, shortfall, topUpAvailable and usdcAmountToCover (dry_run: true reports the same without charging). Ways forward, simplest first, always telling the user the dollar amount and getting their OK: (1) if they use Stripe Link, retry this exact call with pay_with_card: true; (2) if you can pay x402 (a wallet tool, or this server has PORKBUN_X402_PRIVATE_KEY), retry with pay_with_usdc: true; (3) when topUpAvailable is true a card is saved: top_up_account_credit (amount_cents at least topUpAmountToCover, or omit it for their configured amount), then retry; (4) add credit with top_up_with_card_mpp (Link) or top_up_with_usdc (for usdcAmountToCover, which allows for Coinbase's ~1% fee), then retry; (5) the user adds credit at https://porkbun.com/account/credit. If a purchase fails with VERIFICATION_REQUIRED, the phone (send_phone_verification_code then confirm_phone_verification) and the email (send_email_verification_code then confirm_email_verification) can both be verified without leaving the conversation, the user reading out each code. Suggest configure_auto_topup if they want credit refilled automatically. Money parameters are integer cents: state amounts to the user in dollars (cost_cents: 1108 is $11.08). If you do not move money on a user's behalf, hand it back instead: tell them the shortfall and that they can add it with buy account credit at https://porkbun.com/account/credit, then retry once they have.

Buying for a new or unfunded account: the whole path, including what only the human can do, is at https://porkbun.com/llms/guides/buy-a-domain-from-an-agent. Paying directly in USDC (no account credit needed): set pay_with_usdc: true. If this server has a wallet configured (PORKBUN_X402_PRIVATE_KEY, local installs only), the payment is signed and the purchase completes in this one call. Otherwise the result is status: PAYMENT_REQUIRED with a checkoutId, an x402Url and a payUrl, and nothing is charged: pay the x402Url with a wallet tool that pays x402 URLs (for example Coinbase's awal x402 pay <x402Url> --scheme auth-capture), or have the user pay the payUrl page, then call this tool again with the same arguments plus usdc_checkout_id. Tell the user the dollar amount first. If the purchase fails after payment, the payment is NOT returned to the wallet: it stays on the Porkbun account as credit (the error says keptAsCredit: true with the new balance), so retry without pay_with_usdc to buy from that credit.

Paying directly by card, with a hold (no account credit needed): set pay_with_card: true when the user pays with Stripe Link. The result is status: PAYMENT_REQUIRED with a payUrl and a cardPaymentId; nothing is charged. Pay the payUrl with an MPP wallet tool. With Link's CLI that is two commands: link-cli mpp pay <payUrl> -X POST --context "..." (context at least 100 characters) creates a spend request the user approves in Link; once approved, complete it with link-cli mpp pay <payUrl> --spend-request-id <lsrq_id> -X POST. That only authorizes the card. If link-cli answers NOT_AUTHENTICATED, run link-cli auth login first (a one-time device login the user approves). Then call this tool again with the same arguments plus card_payment_id: if the purchase succeeds the card is charged, and if it fails the hold is released and nothing is charged. The link works until expiresAt; if that passes before it is paid, call this tool again without card_payment_id for a fresh link instead of paying the old one.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
costNoDeprecated alias of `cost_cents`, same unit (integer US cents). Send `cost_cents` instead.
domainYesFully qualified domain name to register, e.g. `example.com`. An internationalized name may be given in Unicode (`café.com`) or punycode.
dry_runNoIf true, validate everything (availability, price match, eligibility, funds, the monthly spend limit) and return a preview with `dryRun: true` and `wouldSucceed` WITHOUT registering or charging. Use to safely confirm before committing.
cost_centsNoRegistration price. Must match the value returned by `check_domain` for this domain (multiplied by years if duration > 1). Required. Integer US cents: 803 means $8.03, not $803.
idn_languageNoFor an internationalized domain name only: the language it is written in, as a `code` (or `name`) from the `idnLanguages` that `check_domain` returns for it, e.g. `FRE` for French under .com. Ask the user if the language is not obvious from the name. Ignored for plain ASCII names.
pay_with_cardNoPay for this purchase by card from the user's Stripe Link agent wallet (MPP), with a hold: charged only if the purchase succeeds. Tell the user the amount first.
pay_with_usdcNoPay for this purchase directly in USDC on Base (x402) instead of from account credit. Tell the user the amount first.
card_payment_idNoThe cardPaymentId from an earlier PAYMENT_REQUIRED (pay_with_card), once its payUrl has been paid. Send it with the same arguments as that call.
usdc_checkout_idNoThe checkoutId from an earlier PAYMENT_REQUIRED result, once its x402Url or payUrl has been paid. Send it with the same arguments as that call.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv0.51.1
    • addedInput schema / properties / card_payment_id
      Added value: +{
      +  "description": "The cardPaymentId from an earlier PAYMENT_REQUIRED (pay_with_card), once its payUrl has been paid. Send it with the same arguments as that call.",
      +  "type": "string"
      +}
    • changedInput schema / properties / domain / description
      Previous value: -"Fully qualified domain name to register, e.g. `example.com`"New value: +"Fully qualified domain name to register, e.g. `example.com`. An internationalized name may be given in Unicode (`café.com`) or punycode."
    • addedInput schema / properties / idn_language
      Added value: +{
      +  "description": "For an internationalized domain name only: the language it is written in, as a `code` (or `name`) from the `idnLanguages` that `check_domain` returns for it, e.g. `FRE` for French under .com. Ask the user if the language is not obvious from the name. Ignored for plain ASCII names.",
      +  "type": "string"
      +}
    • addedInput schema / properties / pay_with_card
      Added value: +{
      +  "description": "Pay for this purchase by card from the user's Stripe Link agent wallet (MPP), with a hold: charged only if the purchase succeeds. Tell the user the amount first.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / pay_with_usdc
      Added value: +{
      +  "description": "Pay for this purchase directly in USDC on Base (x402) instead of from account credit. Tell the user the amount first.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / usdc_checkout_id
      Added value: +{
      +  "description": "The checkoutId from an earlier PAYMENT_REQUIRED result, once its x402Url or payUrl has been paid. Send it with the same arguments as that call.",
      +  "type": "string"
      +}
  2. Changed1 schema field changedv0.43.6
    • changedInput schema / properties / dry_run / description
      Previous value: -"If true, validate everything (availability, price match, eligibility, funds, spend limit) and return a preview with `dryRun: true` and `wouldSucceed` WITHOUT registering or charging. Use to safely confirm before committing."New value: +"If true, validate everything (availability, price match, eligibility, funds, the monthly spend limit) and return a preview with `dryRun: true` and `wouldSucceed` WITHOUT registering or charging. Use to safely confirm before committing."
  3. Changed6 schema fields changedv0.39.4
    • changedInput schema / properties / cost / description
      Previous value: -"Registration price in cents. Must match the value returned by `check_domain` for this domain (multiplied by years if duration > 1)."New value: +"Deprecated alias of `cost_cents`, same unit (integer US cents). Send `cost_cents` instead."
    • removedInput schema / properties / cost / exclusiveMinimum
      Removed value: -0
    • addedInput schema / properties / cost / minimum
      Added value: +-9007199254740991
    • addedInput schema / properties / cost_cents
      Added value: +{
      +  "description": "Registration price. Must match the value returned by `check_domain` for this domain (multiplied by years if duration > 1). Required. Integer US cents: 803 means $8.03, not $803.",
      +  "exclusiveMinimum": 0,
      +  "maximum": 9007199254740991,
      +  "type": "integer"
      +}
    • addedInput schema / properties / dry_run
      Added value: +{
      +  "description": "If true, validate everything (availability, price match, eligibility, funds, spend limit) and return a preview with `dryRun: true` and `wouldSucceed` WITHOUT registering or charging. Use to safely confirm before committing.",
      +  "type": "boolean"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "domain",
      -  "cost"
      -]New value: +[
      +  "domain"
      +]
  4. First observedv0.4.1

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (idempotentHint=true, destructiveHint=false), the description discloses the $100 ORDER_TOO_LARGE limit, the 24-hour Idempotency-Key semantics, verification prerequisites (email/phone), and the failure refund behavior ('payment is NOT returned... keptAsCredit: true'). This is far more than the annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is very long, with payment modes introduced in the overview and then re-explained in dedicated sections, which creates some redundancy. However, bold headers and a workflow-first ordering keep it navigable, and the length is largely justified by the multiple payment/failure paths a caller must handle.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by describing return states (PAYMENT_REQUIRED with checkoutId/x402Url/payUrl, dryRun preview, error codes like INSUFFICIENT_FUNDS, VERIFICATION_REQUIRED). Nothing an agent needs to invoke it correctly across success, dry-run, and payment-required flows is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds real meaning: cost_cents must exactly match check_domain's quote, idn_language is required for IDNs and must come from idnLanguages, and card_payment_id/usdc_checkout_id must be resent with the same arguments after a PAYMENT_REQUIRED. That goes beyond the schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states a specific verb and resource ('Registers a new domain on the authenticated Porkbun account') and the bolded lead about spending credit or paying by card/USDC immediately clarifies the money-moving nature. It is clearly distinguishable from siblings like renew_domain, transfer_domain, and buy_closeout.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit workflow ('call check_domain first... confirm the spend with the user, then call this') and explicit exclusions ('Premium domains, .uk, and a handful of registry-specific TLDs cannot be registered via API'). It also enumerates fallback alternatives for short credit and legal hand-off paths when the agent cannot move money.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools