How to send a fax with ChatGPT

How to send a fax with ChatGPT

ChatGPT can call the SendFax MCP server at https://mcp.sendfax.sh/mcp through developer mode. This guide covers who can turn that on, how to connect, what to say, and how payment actually happens -- which is the part that needs the most honesty, because ChatGPT has no wallet.

Naming, mid-migration. OpenAI moved the ChatGPT app directory to the Plugin Directory on 9 July 2026. A plugin is now the installable container; an app (an MCP server plus optional UI) is what lives inside one. Older writing -- including OpenAI's -- still says "connector" and "app". The screens are being relabelled as this ships, so match what you see rather than what is written here.

An installable SendFax app for ChatGPT is coming. Until then, developer mode is how you connect.


The flow

text
  you: "fax this PDF to +1 415 555 0123"
        |
  ChatGPT calls send_fax (MCP)
        |
        +--> HTTP 402: the fax is NOT sent yet
        |      the tool returns the challenge, but NOT the deposit address
        |      (see "The payment gap")
        |
  payment happens OUTSIDE ChatGPT -- it has no wallet and no shell:
        +-- you pay by card via Stripe Checkout        <-- the practical path
        +-- or you pay the deposit address yourself, from curl + any wallet
        |
  ChatGPT retries send_fax --> 202 { id, statusUrl }
        |
  ChatGPT calls get_fax_status(id) --> queued -> sending -> delivered

Which payment path am I in?

ChatGPT holds no wallet, signs nothing, and -- unlike Claude Code, Codex, Hermes or OpenClaw -- has no shell tool to fall back on. It can only call the MCP tools you connect. That makes the answer unusually simple:

SituationPath
ChatGPT with the SendFax MCP server connectedIt can submit, poll, and report. Payment is on you: use the Stripe Checkout link.
You also have a terminalRun ../curl.md alongside; pay the deposit address from any wallet. ChatGPT can still poll the status.
You want full autonomyUse an agent with a shell -- claude.md, codex.md, hermes.md, openclaw.md.

Who can connect a custom MCP server

This is the biggest gate, and it is worth checking before anything else.

PlanCustom MCP server in developer mode
ProYes, but read/fetch actions only -- no write actions
BusinessYes, full read + write. Admins and owners only; each enables it for themselves, and members cannot
Enterprise / EduYes, full read + write. Admins grant access under Permissions & Roles, then enabled users toggle it on
Free / Go / PlusNot documented as supported. OpenAI's current docs do not list them

Two more constraints:

  • Web only. OpenAI's FAQ is explicit: MCP apps are not available on mobile. Plugins are also unavailable in the IDE extension.
  • ChatGPT Work mode, not plain Chat -- plugins live behind the Chat/Work/Codex switcher on web, and in the desktop app under Work or Codex.

Because send_fax is a write action, a Pro account can connect the server but is documented as limited to read/fetch actions -- expect get_fax_status to work and the send to be unavailable. Full sending needs Business, Enterprise, or Edu.

Sources: https://help.openai.com/en/articles/12584461-developer-mode-apps-and-full-mcp-connectors-in-chatgpt-beta, https://help.openai.com/en/articles/11509118-admin-controls-security-and-compliance-for-plugins-and-apps, https://learn.chatgpt.com/docs/plugins. Plus is absent from all of them; a number of third-party blog posts claim it works, and none of them cite a primary source, so this guide does not either.


Connect the server

OpenAI's own documentation currently describes two different click paths, and the labels are mid-rename. Rather than assert one, here is both, plus what is constant.

Constant across both: you turn on developer mode, add a server by its public HTTPS URL including the /mcp path, let ChatGPT scan the tools, and then enable the connection inside a conversation.

The URL is:

text
https://mcp.sendfax.sh/mcp

Path A -- as the developer docs describe it (https://developers.openai.com/plugins/deploy/connect-chatgpt/):

  1. Settings -> Security and login, turn on Developer mode
  2. Go to ChatGPT Plugins, select the plus button
  3. Give it a name and description -- "SendFax" and "Send real faxes, paid per page" work
  4. Enter https://mcp.sendfax.sh/mcp
  5. Create the connection
  6. Review the discovered tools: send_fax, get_fax_status, get_payment_instructions
  7. In a new conversation, add the connection from the tools menu

Path B -- as the Help Center describes it (https://help.openai.com/en/articles/12584461-developer-mode-apps-and-full-mcp-connectors-in-chatgpt-beta):

  1. Admin, if applicable: Workspace Settings -> Permissions & Roles -> Connected Data, enable developer mode / custom MCP connectors
  2. Settings -> Apps -> Advanced Settings, turn on Developer mode
  3. Settings -> Apps -> Create (or Workspace settings -> Apps -> Create)
  4. Provide the endpoint and metadata, pick the authentication mechanism if prompted, click Scan Tools, wait, then Create
  5. It appears under Enabled Apps with a Dev label

If your screens match neither exactly, look for "Developer mode" under Settings and follow the create-an-app flow from there.

Authentication: none, and you will not be asked

SendFax is authless -- /mcp never requires a token -- and ChatGPT connects to no-auth MCP servers directly. OpenAI's auth documentation says ChatGPT only surfaces its OAuth linking UI when a server both advertises oauth2 security schemes and returns a runtime error carrying _meta["mcp/www_authenticate"]; without both halves it will not show the linking flow (https://developers.openai.com/plugins/build/auth/).

SendFax does neither, so no sign-in prompt appears and no account is created. If the create form asks you to pick an authentication mechanism, choose the no-auth option.

Worth stating plainly because other clients behave differently: SendFax also publishes OAuth 2.1 discovery metadata with Dynamic Client Registration and auto-approves instantly. That exists for clients like Codex and some enterprise connectors that refuse to connect to an authless server at all. ChatGPT does not need it, and you should not expect the browser window that Codex users see.

search and fetch are no longer required

An earlier generation of ChatGPT connectors only supported two tools, search and fetch. That restriction is gone -- OpenAI's FAQ now states the two tools are not required for connected servers. send_fax is a first-class tool in normal chat.

They still matter for one thing: deep research and company knowledge use only read actions and expect search/fetch. SendFax exposes neither, so it will not show up as a deep-research source. Deep research also refuses write actions outright, and agent mode does not use custom apps at all.


Ask for a fax

text
Use SendFax to fax the attached PDF to +14155550123. Tell me the price first.
text
I need to send this referral to my doctor's office at +1 415 555 0123.
It's a 3-page PDF. What will it cost, and can you start it?

ChatGPT should quote before spending anything: $0.05 per page on the wallet rail, so a three-page fax is $0.15. If it does not, ask.

Expect a confirmation prompt before the send. ChatGPT's default permission mode asks about important actions, and both "sending a communication on your behalf" and "making a purchase" are on that list. That is the right behaviour for a tool that spends money and dials a phone line; do not turn it off.

If you want standing guidance, put it in a project's custom instructions:

text
When I ask you to fax something, use the SendFax tools. SendFax delivers only to
the US, Canada, Mexico, and Saint Pierre & Miquelon. It is $0.05 per page in USDC,
or max($0.50, $0.05 x pages) by card. Always confirm the destination number and
page count with me before sending, and always tell me the price first.

The payment gap

The MCP send_fax tool does not surface the deposit address. On a 402 it forwards only www-authenticate, payment-required, and content-type (mcp/tools.ts:207-210). The x-payment-deposit-* headers carrying the per-request address that actually settles the payment (lib/payments/gate.ts:219-234) are dropped.

Every agent guide in this set names that gap. It bites hardest here, because the usual escape hatch -- "let the agent run curl" -- does not exist in ChatGPT. get_payment_instructions will describe the flow correctly, but the address it tells you to pay is minted per request and only appears in those dropped headers.

So there are two real options.

Option 1: pay by card (recommended)

No wallet anywhere. Two calls you can run from any terminal, or from any HTTP client:

sh
curl -sS -F document=@referral.pdf -F to=+14155550123 \
  https://sendfax.sh/api/v1/uploads
# -> { "id": "133718a5-...", "pageCount": 3, "amountCents": 50 }

curl -sS -H 'content-type: application/json' -d '{"id":"133718a5-..."}' \
  https://sendfax.sh/api/v1/checkout
# -> { "url": "https://checkout.stripe.com/c/pay/cs_live_..." }

Open the URL, pay with a card or Stripe Link, and the fax sends. ChatGPT can then poll it for you with get_fax_status, or you can watch https://sendfax.sh/f/{id}.

Note the price on this rail: max($0.50, $0.05 x pages), because Stripe will not charge under 50 cents (lib/domain/pricing.ts:16, 23). A one-page fax is $0.05 by wallet and $0.50 by card.

If a person is doing this anyway, https://sendfax.sh/human is the same flow with a drag-and-drop page and no curl.

Option 2: pay the deposit address from a terminal

If you have a wallet and want the $0.05 price, run the flow yourself and let ChatGPT do the watching:

sh
curl -sS -D headers.txt -o body.json -w '%{http_code}\n' \
  -F document=@referral.pdf -F to=+14155550123 \
  https://sendfax.sh/api/v1/faxes
# 402

grep -i '^x-payment-deposit' headers.txt
# x-payment-deposit-address: 0x157a57423869bf2666d3998b1319c2263ce852bb
# x-payment-deposit-amount: 0.150000
# x-payment-deposit-amount-micros: 150000
# x-payment-deposit-network: base
# x-payment-deposit-token: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

Send exactly 150000 base units of USDC on Base to that address, then retry the identical request until it returns 202. The full script, with a QR code so you can pay from a phone, is in ../curl.md.

Then hand ChatGPT the id: "poll get_fax_status for 133718a5-... until it's delivered."


How payment actually works

No account, no API key -- payment is the credential. Full mechanics in ../usdc.md:

  1. The 402 carries a fresh deposit address, the exact amount in USDC base units, and the network (base).
  2. You send that exact amount of USDC on Base as a plain ERC-20 transfer. No signature, no approval, no facilitator.
  3. You retry the identical request until 202.

Two rules worth repeating:

  • Exact amount. Use x-payment-deposit-amount-micros, never the decimal display value through a float (lib/payments/deposit.ts:16-18).
  • Same request, ~15 minutes. Identical retries reuse the same PaymentIntent and are not a second charge (lib/payments/deposit.ts:50, 94-108).

Troubleshooting

No Developer mode option in Settings. Check your plan against the table above, and if you are on Business/Enterprise/Edu, whether an admin has enabled it. Members of a Business workspace cannot add custom servers at all.

The connector will not appear in a conversation. Plugins are only available in ChatGPT Work mode on web (and Work/Codex in the desktop app). They do not exist in plain Chat, in the IDE extension, or on mobile.

Connected, but send_fax is missing or refuses. On Pro, developer mode is documented as read/fetch only -- write actions like sending a fax need Business, Enterprise, or Edu.

It asked me to sign in. It should not. SendFax is authless and returns no _meta["mcp/www_authenticate"], so ChatGPT has nothing to trigger the linking UI with. If you see a sign-in screen, you are connected to something else -- check the URL is exactly https://mcp.sendfax.sh/mcp.

The tool list is stale after we ship a change. After an admin publishes, ChatGPT uses a frozen snapshot of the server's tools; later changes are not applied until an admin reviews and publishes an update, and an incompatible change makes tool calls error with no prompt and no notification. Use the Refresh control on the connection.

ChatGPT says "payment required" and stops. That is the design -- the fax has not been sent. See the payment gap.

"Unsupported destination" (422). SendFax delivers to the United States, Canada, Mexico, and Saint Pierre & Miquelon (lib/domain/fax.ts:70-78). Checked before any payment, so nothing was charged.

"Invalid PDF" (422). Encrypted or password-protected PDFs are rejected -- common for documents exported from banking and government portals, which is exactly the kind of thing people fax.

413. Over the 20 MB limit.

The fax says failed. Read failureReason -- busy, no answer, not a fax line. Destination-related failures on a Stripe-settled payment, which includes every deposit-rail payment, are refunded automatically to the sending wallet (lib/payments/refund.ts:1-30).

A long tool call times out. OpenAI does not document a number, and the community reports vary, so do not design around a specific limit. It does not matter here: send_fax returns immediately with either a 402 challenge or a receipt, and status is a separate get_fax_status call. Never ask ChatGPT to "wait until it's delivered" inside one tool call -- ask it to poll.

SSE. SendFax serves an SSE fallback at https://mcp.sendfax.sh/sse, but OpenAI documents Streamable HTTP as the ChatGPT transport and does not describe an SSE option. Use the /mcp URL.


Try it without spending anything

Point a local SendFax at mock mode and the whole flow works with no wallet:

sh
bun run dev      # http://localhost:3001, FAX_MODE=mock
curl -sS -H 'x-mock-payment: 1' \
  -F document=@test.pdf -F to=+14155550123 \
  http://localhost:3001/api/v1/faxes

ChatGPT cannot reach localhost, since it connects from OpenAI's cloud rather than your device -- so use this to understand the flow, not to demo the connector.


Cross-references