Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Porkbun

NPM · @FOREVERWORKS/MCP-PORKBUN

Register domains and manage DNS, hosting and mail at Porkbun, with every purchase confirmed first.

76 Trust /100

Last scanned (9 hours ago)

Scores higher than 54% of npm servers

Category Cloud Infrastructure

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security98
  • No malware found by supply-chain analysis.Pass
  • No known CVEs affecting this package version or its production dependencies.Pass
  • No install/post-install scripts declared.Pass
  • 34 of 121 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency100
  • Source repository is publicly reachable at the declared URL. View diagnostics → Pass
  • Cryptographically verified build provenance (signed, bound to foreverworks/mcps). View diagnostics → Pass
  • Clear OSI-approved license (MIT).Pass
  • Actively maintained (last published 2 days ago).Pass
  • Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability65
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 30362 tokens (~268/item across 113 items; 113 tools + 0 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 Management0
  • Stability not yet verified: not enough scan history yet (needs a 30-day window).Unverified
Tool Coverage99
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 96% of tool parameters carry a description.Partial
Tool Safety48
  • Injection-marker check failed: the description of tool "buy_closeout" contains an instruction to conceal the call from the user, the text "do not tell the user", at byte 479 of that field. See how to fix → Fail
  • 20 of 22 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "get_transfer_setup" implies "transfer" and declares readOnlyHint instead, contradicting what its own name says it does. See how to fix → Partial
  • An AI judge read all 114 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass

Unverified: 1 category

A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

What we tested

Checks we ran (15)

  • Malware scan
  • Known CVEs
  • Install scripts
  • Dependency health
  • Source repository
  • Provenance
  • License
  • Maintenance
  • Security disclosure
  • Schema quality
  • Tool coverage
  • Injection markers
  • Destructive annotations
  • Judged manipulation
  • MCP protocol

Checks we could not complete (1)

These are gaps on our side, not findings about this package. We only credit what we can confirm, so a category made up entirely of them scores 0.

  • Stability in Stability & Change Management (scores 0 for this)Stability not yet verified: not enough scan history yet (needs a 30-day window).

Does not apply to this package (2)

  • Endpoint SecurityScored on hosted endpoints only. A package has no live endpoint of its own for us to probe.
  • Transport & ReachabilityScored on hosted endpoints only. A package has no live endpoint of its own for us to probe.

The score does not measure everything. What the score does not measure →

Changelog

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.

  • 4 Nov 26 +11
    • Known CVEs: unverified → pass ▲ security
    • Dependency health: unverified → 0.88 ▲ functional
  • 3 Nov 26 65

    First indexed and scored.

Diagnostics

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 · Analysed npm/@foreverworks/mcp-porkbun@0.1.2

Provenance Verified

A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.

Result Verified
Ecosystem npm
Reason Verified
Discovered via Registry attestation endpoint
Source repo foreverworks/mcps
Certificate issuer https://token.actions.githubusercontent.com
Certificate SAN https://github.com/foreverworks/mcps/.github/workflows/release.yml@refs/tags/release-2026-11-03.2
Rekor log index 3658021299
Predicate type SLSA build provenance https://slsa.dev/provenance/v1
Subject digest sha512:cb04e5ba2b270821a5840eea536eee09090a71e3b5aab5da1b4b184c62a92fd0716d47b36e1646bd908c214e2bbfb244ad7ad4e8a2d901b791e6321e7

Background: How many MCP packages publish verified provenance →

Dependencies 121 packages
Packages resolved 121
Stale 34
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 113 exposed · ~30,154 tokens

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 →

Tool Tokens
buy_closeout ~1,176

**Spends account credit, or pays directly by card (`pay_with_card`).** Buys a closeout at its current price and claims the name. Confirm the total with the user first. `cost_cents` must equal `totalPrice` from get_closeout exactly — any other value is refused, so you cannot accidentally charge a price the user did not agree to. Use dry_run with cost 0 to quote without charging. **The domain is reserved, not delivered.** The provider releases it over the following days, so do not tell the user it is in their account: poll list_domains or watch the domain.registered webhook. Every post-charge failure refunds automatically and reports refunded:true. Losing the race to another buyer (CLOSEOUT_UNAVAILABLE) is not worth retrying on the same name — closeouts are first-come at a fixed price. CLOSEOUT_NOT_ELIGIBLE means support has blocked this account from auctions and closeouts over past-due invoices or an auction terms violation — do not retry, tell the user to contact support. There is no account-age or order-history requirement: eligibility is the same as registering a domain, plus verified email and phone. **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 by card, 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). Paying in USDC over x402 is not offered on this server. If the credit is short, the call fails with `INSUFFICIENT_FUNDS` carrying `cost`, `balance`, `shortfall` and **`topUpAvailable`** (`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) when `topUpAvailable` is true a card is saved: `top_up_account_credit` (`amount_cents` at least `topUpAmountToCover`, or omit it for their configured amount), th…

NameTypeReqDescription
card_payment_idstring–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.
costinteger–Deprecated alias of `cost_cents`, same unit (integer US cents). Send `cost_cents` instead.
cost_centsinteger–Exact totalPrice from get_closeout. Use 0 only with dry_run. Required. Integer US cents: 803 means $8.03, not $803.
domainstringyesDomain to buy, e.g. `example.com`
dry_runboolean–Validate and price without charging or claiming.
pay_with_cardboolean–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.

No output schema declared.

No examples provided.

cancel_transfer ~159

**Cancels a paid inbound transfer and refunds the order.** Confirm with the user first. The order is deliberate: mark cancelled locally, withdraw at the registry, verify the registry accepted the withdrawal, then refund. If the registry state cannot be confirmed it restores the transfer and returns TRANSFER_STATE_UNCONFIRMED rather than refunding something that may still be live — escalate to support in that case rather than retrying. The response reports withdrawnAtRegistry, registryResultCode, refunded and refundAmount. Moves money or makes a legal document: the client asks the user to approve each call.

NameTypeReqDescription
domainstringyesDomain whose pending inbound transfer should be cancelled.
dry_runboolean–Preview what would happen without cancelling or refunding.

No output schema declared.

No examples provided.

check_domain ~299

Check whether a single domain is available for registration and what it costs. Returns availability (`avail: yes|no`), registration price, renewal price, transfer price, and (for premium domains) extended pricing details. Pricing is in USD. An internationalized name (IDN) also returns `idnLanguages`, the languages its registry accepts; `register_domain` needs one of them as `idn_language`. For a domain already in the user's account the result has `inYourAccount: true`: the top-level `price` is still the registration price, and the renewal price is `additional.renewal.price` (use that, or a `renew_domain` dry run, before renewing). For a domain registered to someone else it adds `aftermarketSearch`: the name may be for sale, so call `search_aftermarket` before telling the user it is unavailable. Use this BEFORE register_domain to confirm cost — Porkbun rejects registrations whose `cost_cents` doesn't match the current quote. **Checking more than one name? Use `check_domains` instead** — it takes up to 25 in a single call and draws on a separate, more generous budget (200 domains/minute against 10 checks/10s here), because Porkbun chunks checks per registry and a batch costs less than the same names one at a time.

NameTypeReqDescription
domainstringyesFully qualified domain name to check, e.g. `example.com`

No output schema declared.

No examples provided.

check_domains ~442

Check up to 25 domains for availability and price in ONE call. Prefer this over calling `check_domain` in a loop whenever you have more than one name: Porkbun chunks availability checks per registry, so a batch is materially less work than the same names individually, and it draws on a separate budget of 200 domains per 60 seconds (counted per domain, not per call) rather than the single check's 10 per 10 seconds. **Read all three result lists — they mean different things.** `domains` is keyed by domain name and each value has the same shape as `check_domain`'s response. `invalid` holds entries that are not checkable at all (not a domain, unsupported TLD); one bad entry does NOT fail the call, so the other names still come back answered. `unresolved` holds domains the registry did not answer for — these are **neither available nor taken**, and reporting them as unavailable would be wrong. Retry those. Duplicates are removed before the budget is charged. More than 25 names returns BULK_CHECK_TOO_MANY and checks nothing, rather than silently truncating, so split longer lists yourself. Synchronous, no polling — 25 mixed TLDs answers in roughly three seconds. One exception to watch: a few registries accept only a few domains per command and .de accepts exactly one, so a batch heavy in those TLDs returns BULK_CHECK_TOO_SLOW without checking anything. Group .de names into their own small calls. RATE_LIMIT_EXCEEDED with `reason: SUSTAINED_BULK_CHECKING` means the account has been checking at scanning volume (hundreds of names an hour, few registrations) and is held to 50 names per 5 minutes for a day. Do not retry in a loop: check only names the user might actually buy, wait `retryAfter`, or tell the user support can raise the limit for a legitimate high-volume use.

NameTypeReqDescription
domainsarrayyesFully qualified domain names to check, e.g. [`example.com`, `example.net`]. Max 25; duplicates are ignored.

No output schema declared.

No examples provided.

configure_auto_topup ~483

Set the top-up amount, and/or turn auto top-up on or off. `amount_cents` (integer US cents) is what a top-up adds, and it stands on its own: `top_up_account_credit` charges this same figure on demand, so setting it without enabling automation is a normal thing to do. Capped at $500 (50000) with a $5 floor when set through the API; a larger figure has to be set by the account holder at https://porkbun.com/account/api and is honoured as-is. `enabled: true` (with `threshold_cents`) additionally makes it fire by itself: an order that drops the balance below `threshold_cents` charges the saved payment method for the amount and adds it — the way to stop an unattended workflow dead-ending on INSUFFICIENT_FUNDS. `enabled: false` stops it firing on a threshold but KEEPS the amount on file. Confirm the numbers with the user before calling: this authorises charges to their card. No card is added or changed here, and none can be added over the API. Supports dry_run. Moves money or makes a legal document: the client asks the user to approve each call.

NameTypeReqDescription
amountinteger–Deprecated alias of `amount_cents`, same unit (integer US cents). Send `amount_cents` instead.
amount_centsinteger–What a top-up adds, 500-50000 when set via the API. Can be sent on its own. E.g. 10000 = $100. Integer US cents: 803 means $8.03, not $803.
dry_runboolean–If true, validate only — returns wouldSucceed and changes nothing.
enabledboolean–True to switch auto top-up on (threshold required, plus an amount either here or already on file), false to switch it off. Omit it to change only the amount.
thresholdinteger–Deprecated alias of `threshold_cents`, same unit (integer US cents). Send `threshold_cents` instead.
threshold_centsinteger–Balance below which a top-up fires. Required when enabling. E.g. 2000 = $20. Integer US cents: 803 means $8.03, not $803.

No output schema declared.

No examples provided.

confirm_email_verification ~117

Verify the account's email address with the code from the verification email (`send_email_verification_code`, or any verification email from the last 3 days). On success, retry what failed with VERIFICATION_REQUIRED; `phoneVerified: false` means the phone still needs `send_phone_verification_code`. EMAIL_CODE_INVALID means a wrong or expired code, or one from an older email: check it against the newest email, or send a new one.

NameTypeReqDescription
codestringyesThe verification code from the email, exactly as written.

No output schema declared.

No examples provided.

confirm_phone_verification ~132

Verify the account's phone number with the code the user received from `send_phone_verification_code`. On success, retry what failed with VERIFICATION_REQUIRED; `emailVerified: false` in the response means the email still needs verifying: `send_email_verification_code`, then `confirm_email_verification` with the code the user reads out (or they click the link in that email). PHONE_CODE_INVALID means a wrong or expired code: check it with the user, or send a new one.

NameTypeReqDescription
codestringyesThe code the user received, exactly as texted (case does not matter).

No output schema declared.

No examples provided.

connect_domains_to_cloudflare ~245

Queue domains to move into the customer's own Cloudflare account: Porkbun creates the zone there, copies over the DNS records it holds, and repoints the registry nameservers at Cloudflare. ASYNCHRONOUS — a successful call means QUEUED, never connected; the work runs in the background over the next few minutes, so poll get_cloudflare_queue afterwards. Results are PER DOMAIN: each name comes back under `queued`, `skipped` or `alreadyQueued` with its own reason. A non-empty `skipped` is a NORMAL outcome (DNSSEC live, custom nameservers, already connected), NOT a failed call — report the reasons rather than calling the whole thing an error. Eligibility is re-checked right before each domain is acted on, so a queued domain can still be skipped later. Requires the Cloudflare account to be connected first (see get_cloudflare_connection). Use dry_run to preview verdicts without queueing. Max 500 domains per call.

NameTypeReqDescription
domainsarrayyesDomain names to move into the customer's Cloudflare account.
dry_runboolean–Preview the per-domain verdicts without queueing anything.

No output schema declared.

No examples provided.

create_cloudflare_record ~339

Create a DNS record in a domain's Cloudflare zone. IMPORTANT: for a domain that has been moved to Cloudflare this is the tool that changes what actually resolves — create_dns_record writes Porkbun's zone, which no longer answers for it. `name` accepts "@" for the apex or a bare label like "www". `ttl: 1` means Cloudflare-automatic. MX requires `priority`. `proxied` (orange cloud) applies to A/AAAA/CNAME only. Record types Cloudflare models as structured objects (SRV, CAA, …) need a `data` object instead of `content`. Supports dry_run.

NameTypeReqDescription
commentstring–Note stored on the record.
contentstring–The value the record points at. Required unless `data` is given.
dataobject–Structured value for SRV/CAA/etc, shaped as Cloudflare documents it.
domainstringyesDomain whose Cloudflare zone to write to.
dry_runboolean––
namestring–"@" for the apex, a bare label like "www", or a full hostname. Defaults to the apex.
priorityinteger–Required for MX; lower is preferred.
proxiedboolean–Route through Cloudflare's proxy. A/AAAA/CNAME only.
ttlinteger–1 = automatic (default), otherwise 60-86400.
typestringyesA, AAAA, CNAME, TXT, MX, NS, PTR or SPF for a plain value; structured types need `data`.

No output schema declared.

No examples provided.

create_dns_record ~598

Create a DNS record on a domain in the authenticated account. Returns the new record's `id` so it can be referenced by `update_dns_record` and `delete_dns_record`. For the `name` field: omit or pass empty string for the apex/root, otherwise pass the subdomain prefix only (e.g. `www`, not `www.example.com`). For MX and SRV records, set `prio` (priority). Free, doesn't spend account credit. If a record with this exact name, type and content already exists the call fails with `DUPLICATE_RECORD` and returns that record's id in `existingId` — use it rather than retrying or creating a variant. If a CNAME would share a name with another record type (forbidden by RFC 1034) the call fails with `RECORD_CONFLICT` and lists the blocking rows in `conflictingRecords`; delete those or pick another name. **Check `warnings` in the response and pass it on.** Porkbun keeps a DNS zone for every domain in the account whether or not the domain is delegated to Porkbun's nameservers, so this write succeeds either way. If the domain points somewhere else, the response is still `SUCCESS` but carries a `warnings` string naming the nameservers that actually answer — the record exists and nothing resolves differently. Do not report plain success in that case: either make the change at the provider that runs those nameservers, or offer `update_nameservers` to point the domain at Porkbun. On this server a TXT record's content is checked before anything is sent: a DKIM key record (v=DKIM1, or p= under _domainkey) must hold a public key that parses (an RSA key of 1024 bits or more, or an ed25519 key), and an SPF record (v=spf1) must have no obvious mistake (an unknown mechanism, a bad address, a term after all, more than 10 lookups). One that fails is refused with what is wrong.

NameTypeReqDescription
contentstringyesRecord value (e.g. an IP for A, a hostname for CNAME, the text body for TXT).
domainstringyesDomain to add the record to, e.g. `example.com`
dry_runboolean–If true, validate only — returns wouldSucceed without creating the record.
namestring–Subdomain prefix (no domain). Empty string or omitted = apex. Examples: `www`, `mail`, `api.staging`.
priointeger–Priority — required for MX and SRV records, ignored otherwise.
ttlinteger–Time-to-live in seconds. Minimum 60. Defaults to 600 if omitted.
typestringyesRecord type. Common: A, AAAA, CNAME, MX, TXT.

No output schema declared.

No examples provided.

create_dnssec_record ~735

Submit a DNSSEC DS record to the registry for a domain. Use when you sign DNS yourself (custom nameservers running BIND/Knot/PowerDNS/etc.) and need to publish the chain-of-trust at the parent zone. Required: keyTag, algorithm, digestType, digest. Optional key-data fields for registries that require full DNSKEY (rare). Algorithms and digest types are validated per registry, not globally: registries are retiring the values deprecated by RFC 9904/9905/9906 on their own schedules, so a value one registry has already dropped may still be accepted by another. A refused value returns DNSSEC_ALGORITHM_DEPRECATED naming a replacement, and retrying the same values will not help. Use alg 8 (RSA/SHA-256) or 13 (ECDSA/SHA-256) with digestType 2 (SHA-256) to be accepted everywhere. A SUCCESS response may carry a warnings array when a value still works but is being retired: the record WAS created. Deprecation never affects list_dnssec_records or delete_dnssec_record. On this server the four DS fields may come from dnskey instead, which is safer: the zone's DNSKEY record as the signer prints it (`example.com. 3600 IN DNSKEY 257 3 13 <base64>`, or just `257 3 13 <base64>`). The DS is computed from it (RFC 4034: the key tag, its algorithm, a SHA-256 digest unless digestType says 1 or 4), and any of keyTag, alg, digestType and digest also given must agree with it. Without dnskey all four are required and checked before anything is sent: keyTag 0-65535, a known algorithm number, a hex digest of its type's length (40 for type 1, 64 for 2, 96 for 4). The answer adds ds, the record as sent.

NameTypeReqDescription
algstring–Algorithm number, e.g. `13` for ECDSA P-256 SHA-256, `8` for RSA SHA-256. Algorithms 1, 3, 5, 6, 7 and 12 are deprecated (RFC 9904/9905/9906) and are already refused by some registries.
digeststring–Hex-encoded DS digest value.
digestTypestring–Digest type, e.g. `2` for SHA-256, `4` for SHA-384. Digest types 1 (SHA-1) and 3 (GOST R 34.11-94) are deprecated and are being refused registry by registry; 2 is accepted everywhere.
dnskeystring–The zone's DNSKEY record (a zone-file line, or flags protocol algorithm key), usually the key-signing key (257). The DS is computed from it.
domainstringyesDomain to add the DS record to.
keyDataAlgostring–DNSKEY algorithm (optional).
keyDataFlagsstring–DNSKEY flags (optional — typically 256 or 257).
keyDataProtocolstring–DNSKEY protocol (optional — almost always 3).
keyDataPubKeystring–Base64-encoded public key (optional).
keyTagstring–DNSSEC key tag (16-bit identifier of the key).
maxSigLifestring–Maximum signature lifetime in seconds (registry-specific, optional).

No output schema declared.

No examples provided.

create_email_forward ~291

Forward an address at the domain (e.g. `info@example.com`) to another mailbox. Free, up to the domain's limit. No catch-all or wildcard forwards, and an address that is an email hosting mailbox cannot also be a forward. Setting up forwarding puts Porkbun's MX records (and SPF include) at the domain apex. **If that would delete MX records for another mail service or rewrite the domain's SPF record, the call returns `DNS_CHANGE_CONFIRMATION_REQUIRED` with `dnsChanges` listing exactly what would change, and nothing is changed: tell the user (deleting another provider's MX stops that mail service receiving), and only with their OK call again with `confirm_dns_changes: true`.** Use `dry_run: true` to preview, including whether confirmation will be needed.

NameTypeReqDescription
addressstringyesThe address to forward: the part before the @ (`info`) or the whole address (`info@example.com`).
confirm_dns_changesboolean–Set only after the user has agreed to the DNS changes a `DNS_CHANGE_CONFIRMATION_REQUIRED` result described.
domainstringyesDomain the address belongs to, e.g. `example.com`
dry_runboolean–If true, validate and report the DNS changes without making any.
forward_tostringyesThe mailbox to deliver to, e.g. `me@gmail.com`.

No output schema declared.

No examples provided.

create_glue_record ~152

Create a glue record for a host on a domain. Used when running your own nameservers on the same domain they serve (e.g. `ns1.example.com` serving `example.com`). The `subdomain` is just the host part (e.g. `ns1`), not the full FQDN. Provide IPs as an array of IPv4 and/or IPv6 addresses. Idempotent.

NameTypeReqDescription
domainstringyesParent domain, e.g. `example.com`
ipsarrayyesArray of IPv4 and/or IPv6 addresses to associate with the host.
subdomainstringyesHost portion only (no domain), e.g. `ns1`.

No output schema declared.

No examples provided.

create_hosting ~1,340

Provision hosting for a domain in the account — Secure Static Hosting OR Cloud for WordPress (a managed WordPress site), chosen by `sku`. The domain's FIRST provision starts a 15-day FREE trial that auto-renews at the plan price ($3/mo or $30/yr) when it ends; a re-provision after deprovision is charged to account credit (one free trial per domain). Provisioning switches the domain to Porkbun nameservers if it isn't already — set `agree_to_nameserver_change: true` to allow that. You MUST echo the price in `acknowledged_cost_cents` (300 monthly / 3000 yearly) so the human is told about the auto-renew/charge. Use `dry_run` to preview. Provisioning can be async: `status` may be PENDING — poll get_hosting until ACTIVE before deploying. For a WordPress plan, the file tools (deploy_site/list_hosting_files/…) do NOT apply — manage the site through WordPress instead, using create_wp_credentials to get REST API credentials. A paid re-provision is a purchase like any other: **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 by card, 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). Paying in USDC over x402 is not offered on this server. If the credit is short, the call fails with `INSUFFICIENT_FUNDS` carrying `cost`, `balance`, `shortfall` and **`topUpAvailable`** (`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) 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; (3) add credit with `top_up_with_card_mpp` (Link), then retry; (4) the user adds credit at https://porkbun.com/account/credit. If a…

NameTypeReqDescription
acknowledged_costinteger–Deprecated alias of `acknowledged_cost_cents`, same unit (integer US cents). Send `acknowledged_cost_cents` instead.
acknowledged_cost_centsinteger–The chosen plan's price — take the `price` field of the SAME row you took `sku` from in list_hosting_plans (e.g. 300 static monthly, 3000 static yearly, 1200 WordPress Starter monthly, 12000 WordPres…
agree_to_nameserver_changeboolean–Set true to allow switching the domain to Porkbun nameservers (required when it isn't already on them).
agree_to_termsstringyesMust be "yes".
card_payment_idstring–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.
domainstringyesDomain to provision hosting for, e.g. `example.com`.
dry_runboolean–Validate + preview without provisioning or charging.
pay_with_cardboolean–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.
skustringyesThe hosting plan SKU to provision. Discover the provisionable SKUs (and each one's price/interval/trial) via list_hosting_plans, then pass the row's `sku`. Secure Static Hosting: `PIXIESECURESTATICM2…

No output schema declared.

No examples provided.

create_mailbox ~1,443

**Spends account credit, or pays directly by card (`pay_with_card`).** Buy one email hosting mailbox ($36.00 a year, renewing automatically; the current price is `price` in `list_mailboxes`) and set it up in the same call. Check `list_mailboxes` first: if a mailbox is already waiting (the free trial every registration includes), `setup_mailbox` is free. Tell the user the price and that it renews yearly before buying. `cost_cents` must equal the price; `dry_run: true` with `cost_cents: 0` quotes it and checks everything without charging. If the charge succeeds but setup does not, the result says `setupComplete: false` with a `mailboxId`: finish with `setup_mailbox`, do not buy again. Leave `password` out and Porkbun generates a strong one and returns it ONCE in `password`: give it to the user straight away, it is not shown again (it can be changed later with `set_email_password`). If you pass one, it needs 12-72 characters with an upper case letter, a lower case letter, a number and a special character. A mailbox needs Porkbun's MX records and SPF include at the domain apex (the same records as email forwarding), and the call puts them in place. **If that would delete MX records for another mail service or rewrite the domain's SPF record, it returns `DNS_CHANGE_CONFIRMATION_REQUIRED` with `dnsChanges` and changes (and charges) nothing: tell the user what will change, and only with their OK call again with `confirm_dns_changes: true`.** The answer includes `clientSettings` (IMAP/SMTP hosts and ports) for setting up a mail app. DKIM and DMARC are set up on the website. Needs a verified account email and phone. **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 by card, 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). Paying in USDC over x402 is not offered on this server. If the…

NameTypeReqDescription
addressstringyesThe mailbox address: the part before the @ (`me`) or the whole address.
card_payment_idstring–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.
confirm_dns_changesboolean–Set only after the user agreed to the DNS changes a `DNS_CHANGE_CONFIRMATION_REQUIRED` result described.
cost_centsintegeryesThe mailbox price, 3600 for $36.00 a year. Must match exactly. Integer US cents: 803 means $8.03, not $803.
domainstringyesDomain for the mailbox, e.g. `example.com`.
dry_runboolean–If true, validate everything and return a preview without buying.
passwordstring–Optional. Omit to have a strong password generated and returned once.
pay_with_cardboolean–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.

No output schema declared.

No examples provided.

create_url_forward ~307

Add a URL forwarding rule for a domain. Forwards a subdomain (or apex if `subdomain` is empty/omitted) to an arbitrary destination URL. Useful for redirects without setting up a web server. Free.

NameTypeReqDescription
domainstringyesDomain to add the forward to, e.g. `example.com`
includePathstringyes`yes` appends the request URI path to the forward target; `no` always sends to the bare destination.
locationstringyesDestination URL to forward visitors to, e.g. `https://newsite.example.com`
redirect_typestring–Optional exact redirect type; takes precedence over `type`. 301 = permanent, 302 or 307 = temporary (pass 307 here to get a 307), masked = URL masking. Omit to derive from `type` (temporary→302, perm…
subdomainstring–Subdomain prefix to forward. Empty/omitted = the apex (root domain). Examples: `www`, `shop`.
typestringyes`permanent` = HTTP 301; `temporary` = HTTP 302 (default); `masked` = loads the destination in a frame (URL masking). For a precise code — including a 307 temporary redirect — use `redirect_type`.
wildcardstringyes`yes` also forwards all sub-subdomains; `no` forwards only the exact subdomain.

No output schema declared.

No examples provided.

create_webhook ~364

Register a webhook endpoint. Porkbun will POST a signed JSON payload to `url` whenever a subscribed event occurs. Returns the new endpoint including its `secret` — store it securely; it's used to verify the `X-Porkbun-Signature` header (HMAC-SHA256 over `{timestamp}.{rawBody}`). `url` must be a publicly reachable HTTPS endpoint: `https://` on port 443, no credentials embedded in the URL, and a hostname that resolves to a public internet address. Private, loopback (including tricks like `127.0.0.1.sslip.io`), link-local, CGNAT and reserved addresses are rejected with `INVALID_WEBHOOK_URL` — do not try to point this at localhost or an internal host. For local development use a public HTTPS tunnel (ngrok, Cloudflare Tunnel) or a sandbox key with sandbox_trigger_webhook. A hostname that does not resolve yet is accepted so you can register before the receiver is deployed, but the rules are re-checked before every delivery. Omit `events` (or pass `['*']`) to subscribe to all event types; you can also pass prefix wildcards like `dns.*`. Moves money or makes a legal document: the client asks the user to approve each call.

NameTypeReqDescription
eventsarray–Event types to subscribe to, e.g. `['domain.registered','dns.*']`. Omit or use `['*']` for all events. Call get_webhook_event_types for the catalog.
urlstringyesPublicly reachable HTTPS URL Porkbun will POST event payloads to. Port 443 only; the hostname must resolve to a public internet address (private/loopback/reserved targets are rejected).

No output schema declared.

No examples provided.

create_wp_credentials ~358

CLOUD FOR WORDPRESS ONLY. Mint a WordPress Application Password for a domain's managed WordPress site so you can drive it over the WP REST API at https://<domain>/wp-json/ using HTTP Basic auth. The password is returned ONCE (WordPress stores only a hash) — save it immediately. Defaults to a dedicated least-privilege `porkbun-agent` user with the `editor` role (created on first use), which can manage content but cannot install code. `role: "administrator"` grants FULL site control including plugin installation (i.e. arbitrary code execution on the site) and therefore requires `acknowledge_full_access: true` — only request it if the user explicitly asked for admin-level access. The site must be provisioned and ACTIVE (poll get_hosting) — this works on any Cloud for WordPress site in the account however it was provisioned, but free $0 preview sites are excluded. Revoke any time with delete_wp_credentials. Rate limit: 20 mints per account per hour. Moves money or makes a legal document: the client asks the user to approve each call.

NameTypeReqDescription
acknowledge_full_accessboolean–Required when role=administrator: confirms the user understands the credential can run arbitrary code on the site.
domainstringyesDomain whose WordPress site to mint credentials for.
dry_runboolean–Validate without creating anything.
namestring–Label shown in wp-admin (letters, digits, dashes), e.g. `Acme-Agent`.
rolestring–`editor` (default) = content only, recommended for agents. `administrator` = full control incl. plugin install; requires acknowledge_full_access.

No output schema declared.

No examples provided.

delete_cloudflare_record ~126

Delete a DNS record from a domain's Cloudflare zone. This changes live DNS for a domain Cloudflare is authoritative for, so confirm with the user first — deleting the wrong record can take a site or its mail offline. Get `record_id` from get_cloudflare_records. The record is read before deletion, so the response reports exactly what was removed. Supports dry_run.

NameTypeReqDescription
domainstringyesDomain whose Cloudflare zone to write to.
dry_runboolean––
record_idstringyesCloudflare record id from get_cloudflare_records.

No output schema declared.

No examples provided.

delete_dns_record ~230

Delete a single DNS record by its numeric `record_id` (obtained from `list_dns_records`). Idempotent: deleting an already-deleted record returns success. Free. **Check `warnings` in the response and pass it on.** Porkbun keeps a DNS zone for every domain in the account whether or not the domain is delegated to Porkbun's nameservers, so this write succeeds either way. If the domain points somewhere else, the response is still `SUCCESS` but carries a `warnings` string naming the nameservers that actually answer — the record exists and nothing resolves differently. Do not report plain success in that case: either make the change at the provider that runs those nameservers, or offer `update_nameservers` to point the domain at Porkbun.

NameTypeReqDescription
domainstringyesDomain the record belongs to, e.g. `example.com`
dry_runboolean–If true, validate only — confirms the record exists and is deletable, returns wouldSucceed without deleting it.
record_idstringyesNumeric record ID (as a string).

No output schema declared.

No examples provided.

delete_dnssec_record ~85

Remove a DNSSEC DS record from the registry for a domain, identified by key tag. Use when retiring a key. Idempotent: deleting a non-existent key tag returns success.

NameTypeReqDescription
domainstringyesDomain to remove the DS record from.
keyTagstringyesKey tag of the DS record to remove (from `list_dnssec_records`).

No output schema declared.

No examples provided.

delete_email_forward ~139

Delete one email forward, named by its `address` and `forward_to` (from `list_email_forwards`; an address can forward to several mailboxes, so both are needed). When it was the domain's last forward and there are no email hosting mailboxes, Porkbun's forwarding MX and SPF records are removed too (`dnsRecordsRemoved: true`), so mail to the domain stops being accepted.

NameTypeReqDescription
addressstringyesThe forwarded address, `info` or `info@example.com`.
domainstringyesDomain the forward belongs to.
forward_tostringyesThe destination mailbox of the forward to delete.

No output schema declared.

No examples provided.

delete_glue_record ~67

Delete a glue record by host on a domain. Idempotent: deleting a non-existent glue record returns success.

NameTypeReqDescription
domainstringyesParent domain, e.g. `example.com`
subdomainstringyesHost portion only, e.g. `ns1`.

No output schema declared.

No examples provided.

delete_hosting ~69

Deprovision (cancel) Secure Static Hosting for a domain; teardown is scheduled by Porkbun. Note: the domain has already used its one free trial, so provisioning it again later will be charged (no second free trial).

NameTypeReqDescription
domainstringyesDomain to deprovision hosting for.

No output schema declared.

No examples provided.

delete_hosting_file ~208

Delete a file or directory at `path` in a domain's Secure Static Hosting space. Idempotent: a path that is already gone succeeds with `alreadyAbsent: true`, so there is no need to re-check before retrying. A directory that still has files fails with `HOSTING_DIR_NOT_EMPTY` and lists its `contents`; pass `recursive: true` to delete a directory with everything in it in one call (up to 2,000 items; the site root can never be deleted). To clear out a site, delete its top-level entries with `recursive: true` rather than file by file. Calls the Porkbun Hosting API (https://porkbun.com/llms/hosting).

NameTypeReqDescription
domainstringyesDomain whose hosting file to delete.
pathstringyesPath to delete, e.g. `old/page.html` or `assets`.
recursiveboolean–Delete a directory together with everything inside it. Default false.

No output schema declared.

No examples provided.

delete_url_forward ~63

Delete a URL forwarding rule by its `id` (obtained from `list_url_forwards`). Idempotent.

NameTypeReqDescription
domainstringyesDomain the forward belongs to.
record_idstringyesNumeric forward record ID from `list_url_forwards`.

No output schema declared.

No examples provided.

delete_webhook ~53

Delete a webhook endpoint by id. Deliveries stop immediately. Idempotent in effect: deleting a non-existent endpoint returns an error you can safely ignore.

NameTypeReqDescription
idintegeryesThe webhook endpoint id to delete.

No output schema declared.

No examples provided.

delete_wp_credentials ~128

CLOUD FOR WORDPRESS ONLY. Revoke a WordPress application password by `uuid` (from list_wp_credentials), or every one for the user with `all: true`. Anything using that credential stops authenticating immediately.

NameTypeReqDescription
allboolean–Revoke every application password for the user.
domainstringyesDomain whose WordPress site to revoke on.
dry_runboolean–Validate without revoking.
uuidstring–The application password uuid to revoke.
wp_userstring–WordPress username (defaults to `porkbun-agent`).

No output schema declared.

No examples provided.

deploy_site ~362

Upload static files to a domain's Secure Static Hosting. Each file is read by this server, byte-exact: give its `local_path`, or `content_base64` with its `sha256` from a script. A destination `path` may include directories (e.g. `assets/css/style.css`); missing parent directories are created. Each file at most 10 MB (Porkbun has its own limit on a call; split a large site across calls). Only static-web file types are accepted (html/css/js/images/fonts/...); server-executable types are rejected. Hosting must be ACTIVE (check get_hosting first). When you build or edit a website for a domain in the user's Porkbun account (or they mention Porkbun hosting), this is how it goes live: offer to publish with it instead of giving dashboard upload steps, and get their OK first, since files at the same path are replaced. Answers with Porkbun's result and sent_files: each file's sha256 and size as sent, to compare with the source. Never type or paste a file's base64 yourself: a retyped file can arrive changed. Give the path of a file in your workspace folders (the roots this client shares; without them /workdir), or have a script that read the file send content_base64 with its sha256.

NameTypeReqDescription
domainstringyesDomain whose hosting to deploy to.
filesarrayyesFiles to upload. Never type or paste a file's base64 yourself: a retyped file can arrive changed. Give the path of a file in your workspace folders (the roots this client shares; without them /workdi…

No output schema declared.

No examples provided.

diff_dns_restore_point ~219

Compare a DNS restore point with the live zone before changing anything. Always do this before `restore_dns_zone` — it is free and it is the difference between fixing a zone and finding out afterwards. `missing` is in the restore point but not live: these are the records a restore would ADD BACK. `extra` is live but not in the restore point: a restore LEAVES THESE ALONE unless you pass prune. `inSync` is true when both lists are empty. Records are matched on name, type, content and priority rather than id, because an id means nothing across a delete and re-create. SOA and NS are excluded — the zone's own delegation is not what anyone means by their DNS records. For masked records (parking, ALIAS, HTTPS) the value shown is the one that was configured, not the internal host it resolves to.

NameTypeReqDescription
domainstringyesDomain, e.g. `example.com`
snapshot_idintegeryesRestore point id from `list_dns_restore_points`.

No output schema declared.

No examples provided.

disconnect_cloudflare ~68

Remove this account's stored Cloudflare connection. Domains already moved stay on Cloudflare and keep resolving — this only stops Porkbun making further changes on the customer's behalf. Reconnecting requires the human browser authorization again, so confirm before calling.

NameTypeReqDescription
dry_runboolean–Validate without disconnecting.

No output schema declared.

No examples provided.

edit_cloudflare_record ~193

Update a DNS record in a domain's Cloudflare zone. Partial: fields you omit keep their current value. Get `record_id` from get_cloudflare_records. The response includes both the new record and the previous one, so you can tell the user exactly what changed. Supports dry_run.

NameTypeReqDescription
commentstring––
contentstring––
dataobject––
domainstringyesDomain whose Cloudflare zone to write to.
dry_runboolean––
namestring–"@" for the apex, or a bare label.
priorityinteger––
proxiedboolean–A/AAAA/CNAME only.
record_idstringyesCloudflare record id from get_cloudflare_records.
ttlinteger–1 = automatic, otherwise 60-86400.
typestring––

No output schema declared.

No examples provided.

export_dns_zone ~220

Save a domain's DNS records as a BIND zone file (RFC 1035) in this server's outbox: every record list_dns_records returns, under `$ORIGIN <domain>.`, host names absolute, MX and SRV with their priority, TXT text quoted in 255-byte strings, each record's notes as a comment. Porkbun answers with its own SOA, so the file has none. The answer gives the file's path, size and sha256, and how many records of each type it holds. Use it as a backup before a large change, or to move the zone to another DNS host; import_dns_records takes the file back with `zone_file`. This server has no outbox yet (PORKBUN_OUTBOX_DIR), so the call fails until one is set.

NameTypeReqDescription
domainstringyesA domain in the account, e.g. `example.com`.
save_dirstring–A folder inside the outbox to save into (created if missing). Default: the outbox itself.

No output schema declared.

No examples provided.

get_api_settings ~178

Get the account's API spend controls and the limits actually enforced, in cents. `spendLimit` caps everything bought over the API in a calendar month (registrations, renewals, transfers, closeouts, paid hosting): `limit`, `source` (`account` = set by the account holder, `default` = none set so $100 applies, `none` = no cap), `spent` and `remaining`. `topupLimit` caps credit added over the API (card, auto top-up, MPP, USDC together): `limit`, `source`, `added`. `settings` is what the account holder configured. Check `remaining` before an expensive operation: a purchase over it fails with MONTHLY_SPEND_LIMIT_EXCEEDED, and only the account holder can raise the limit, on the website.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

get_auto_topup ~105

Read the account's auto top-up configuration: whether it is on, the balance threshold that triggers it, the amount added, whether a payment method is actually on file, and `effectiveAmount` — what `top_up_account_credit` would charge right now. If `paymentMethodOnFile` is false the settings are inert: nothing can be charged and auto top-up will never fire, and a card can only be saved on porkbun.com, never through the API.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

get_balance ~167

Get the available account credit balance for the authenticated Porkbun account. Returns the balance in cents (integer) and a human-readable display string (e.g. `$12.34`). Call it before offering to buy anything: a purchase is paid from this prepaid balance, not charged to a card, so this number decides whether a registration, renewal or transfer goes through as-is. If it is short and the account has a saved card, `top_up_account_credit` adds credit in one call (ask the user first, with the amount); `get_auto_topup` reports whether a card is on file. Without a card, or if you do not charge cards on a user's behalf, the user adds credit with **buy account credit** at https://porkbun.com/account/credit.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

get_closeout ~131

Get one closeout plus `totalPrice` — the binding amount, which is the closeout price plus the registration year that comes with it. Always call this before buy_closeout: totalPrice is what you must pass as `cost_cents`, and it cannot be derived from search results because a name already at Porkbun is renewed while anything else is transferred in, and those price differently. `available: false` means somebody already claimed it. Quote the user totalPrice, never the search `price`.

NameTypeReqDescription
domainstringyesDomain offered as a closeout, e.g. `example.com`

No output schema declared.

No examples provided.

get_cloudflare_connection ~138

Check whether this Porkbun account is connected to a Cloudflare account, and which one. THIS IS THE POLL TARGET for the connect flow. Connecting is a HUMAN action: Cloudflare's consent screen must be completed in a browser and the authorization is bound to the Porkbun web session that starts it, so it cannot be driven over the API. When `connected` is false the response includes a `connectUrl` — show that URL to the user, ask them to authorize, then call this tool again every few seconds until `connected` is true. Everything else in the Cloudflare flow is fully automatable once this is true.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

get_cloudflare_domain_status ~70

Get the Cloudflare move status for ONE domain, including the Cloudflare zone id once created and the nameservers Porkbun replaced (kept so the move can be undone). Returns NOT_QUEUED if the domain has never been queued.

NameTypeReqDescription
domainstringyesDomain to check.

No output schema declared.

No examples provided.

get_cloudflare_queue ~56

List every Cloudflare move this account has requested, with per-domain status and message. Use this to poll progress after connect_domains_to_cloudflare. Queue rows are never deleted, so this is also the audit trail of past moves.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

get_cloudflare_records ~105

List a domain's LIVE DNS records as Cloudflare holds them, each with its orange-cloud (`proxied`) state and whether it is `proxiable` at all. Once a domain has moved to Cloudflare THIS is the authoritative record set — list_dns_records reads the Porkbun zone, which is no longer answering queries for it. Returns ZONE_NOT_READY if the zone does not exist yet.

NameTypeReqDescription
domainstringyesDomain whose Cloudflare zone to inspect.

No output schema declared.

No examples provided.

get_cloudflare_zone ~118

Get what CLOUDFLARE currently says about a domain's zone (status, paused, its nameservers, activation date) rather than what Porkbun's queue row remembers. These drift: if someone repoints the nameservers elsewhere after the move, the Porkbun row still says done while Cloudflare has stopped serving the domain. The response includes the live public nameservers and a `nameserversDrifted` boolean so you don't have to diff them yourself.

NameTypeReqDescription
domainstringyesDomain whose Cloudflare zone to inspect.

No output schema declared.

No examples provided.

get_cloudflare_zone_settings ~133

Read the Cloudflare zone settings that matter after a move: ssl mode, always_use_https, automatic_https_rewrites, min_tls_version, development_mode, cache_level. Warns when SSL mode is `off` or `flexible`, which means Cloudflare fetches the origin over plain HTTP while visitors still see a padlock. If this returns CLOUDFLARE_REAUTHORIZE_REQUIRED the customer's Cloudflare connection predates this permission — show them the connectUrl and ask them to reconnect (one click; domains already moved are unaffected).

NameTypeReqDescription
domainstringyesDomain whose zone settings to read.

No output schema declared.

No examples provided.

get_contacts ~67

Get the four contacts (registrant, admin, tech, billing) for a domain in the authenticated account, with their current field values (name, organization, address, phone, email). Read-only.

NameTypeReqDescription
domainstringyesFully qualified domain name, e.g. `example.com`

No output schema declared.

No examples provided.

get_domain ~140

Get the metadata for a single domain in the authenticated account: status, TLD, create date, expire date, security lock, WHOIS privacy, auto-renew, API access opt-in, and (optionally) labels. Returns an error with code `DOMAIN_NOT_FOUND` if the domain isn't in the account; the error's `account` field names the account the key belongs to, so a domain in a different account is easy to tell from a missing one.

NameTypeReqDescription
domainstringyesFully qualified domain name in the account, e.g. `example.com`
include_labelsboolean–Include user-defined domain labels in the response.

No output schema declared.

No examples provided.

get_hosting ~60

Get Secure Static Hosting status for a domain (plan, server, trial, expiry, auto-renew), or null if the domain has no hosting. When ACTIVE, deploy_site publishes site files to it.

NameTypeReqDescription
domainstringyesDomain to check.

No output schema declared.

No examples provided.

get_invoice ~154

Get one invoice as data: who it is billed to, how it was paid (card brand and last four only), each line with its product, term, resulting domain expiry and status, and the gross, refunded and net totals in cents. The same figures as the PDF. `url` and `pdfUrl` open it on porkbun.com (the user must be signed in); `downloadUrl` downloads the PDF without signing in for 15 minutes, which is the link to hand a user who wants the file. Invoice IDs come from `list_invoices`; an ID not on this account returns `INVOICE_NOT_FOUND`.

NameTypeReqDescription
invoice_idintegeryesInvoice (order) ID from `list_invoices`.

No output schema declared.

No examples provided.

get_invoice_pdf ~204

Save an invoice PDF, the same document as Download PDF on porkbun.com, in this server's outbox. The bytes are checked to be a PDF of the size Porkbun states before anything is written. The answer gives the file's path, size and sha256, with Porkbun's own fields: `filename`, `sizeBytes`, and `downloadUrl`, a link that downloads it without signing in until `downloadExpires` (15 minutes). Invoice IDs come from `list_invoices`; an ID not on this account returns `INVOICE_NOT_FOUND`. This server has no outbox yet (PORKBUN_OUTBOX_DIR), so the call fails until one is set; `get_invoice` still gives the `downloadUrl`.

NameTypeReqDescription
invoice_idintegeryesInvoice (order) ID from `list_invoices`.
save_dirstring–A folder inside the outbox to save into (created if missing). Default: the outbox itself.

No output schema declared.

No examples provided.

get_nameservers ~116

Get the current nameservers configured for a domain in the authenticated account. Returns an array of nameserver hostnames, read live from the registry. Read-only complement to `update_nameservers`. **Treat the result as an unordered set** — registries return nameservers in whatever order they like, so this will often not match the order passed to `update_nameservers`. Order is meaningless in DNS; never report a reordering as a change.

NameTypeReqDescription
domainstringyesFully qualified domain name, e.g. `example.com`

No output schema declared.

No examples provided.

get_pricing ~173

Get current Porkbun pricing: registration, renewal and transfer prices per TLD in USD. No authentication required. **Pass `tlds` whenever you know which TLDs matter** (e.g. `["com", "io"]`): without it the response lists every TLD Porkbun sells, around 900 of them. Case, a leading dot and IDN form are handled. A TLD Porkbun does not sell comes back in `unsupported` instead of being priced, and if none of them are sold the call fails with INVALID_TLD. Standard pricing only: premium names have their own per-domain price, reported by check_domain.

NameTypeReqDescription
tldsarray–TLDs to price, e.g. ["com", "io", "dev"]. Omit for every TLD.

No output schema declared.

No examples provided.

Install

How do I install the Porkbun MCP server?

Porkbun runs locally as an npm package, launched with npx -y @foreverworks/mcp-porkbun. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

npm · @foreverworks/mcp-porkbun

# add to Claude Code
claude mcp add com-foreverworks-porkbun -- npx -y @foreverworks/mcp-porkbun
Common questions

What is the Porkbun MCP server?

Porkbun is an MCP server listed in the public MCP registry as com.foreverworks/porkbun. Register domains and manage DNS, hosting and mail at Porkbun, with every purchase confirmed first. This page covers its npm package (@foreverworks/mcp-porkbun).

Is the Porkbun MCP server safe to use?

Porkbun scores 76 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. 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 Porkbun MCP server expose?

Porkbun exposes 113 tools: buy_closeout, cancel_transfer, check_domain, check_domains, configure_auto_topup, and 108 more. Their descriptions and schemas cost roughly 30,154 tokens of context every time the server is loaded.

Is the Porkbun MCP server still maintained?

Porkbun 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.

What licence is the Porkbun MCP server under?

Porkbun declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

What did VerifyMCP test on the Porkbun MCP server?

VerifyMCP ran 15 checks on Porkbun, covering Malware scan, Known CVEs, Install scripts, Dependency health and 11 more. One item could not be completed, a gap on our side rather than a finding about Porkbun: Stability. One category scores 0 for that reason, because we only credit what we can confirm. Endpoint Security and Transport & Reachability do not apply to an npm package, so they were not tested. The score does not measure everything, and the scoring documentation lists what it leaves out.