Skip to main content
Before you start
  • A Tailscale account, and admin access to Tailscale’s admin console. The free Personal plan covers a household. Sign up at tailscale.com.
  • Postern installed, and the Console open in your browser. Step 1 opens it if Postern runs on another computer.
  • About 20 minutes, once. Postern takes ports 8443 and 10000 on your tailnet. Port 443 goes to the internet only if you do step 4.
  • Your password manager open. In step 6, Postern shows you an agent key one time only.
  • A Mac or a Linux computer. Postern runs under Docker, so Windows should work. Nobody has run this page there. In PowerShell, curl means something else, so type curl.exe in the checks below.
Your tailnet is the private network Tailscale builds between the devices signed into your account. Nothing else can reach it. Not every step here is for everyone. Read this first, then do the steps that apply to you, in order. None of this is on until you turn it on. Turn the public port off shuts it again whenever you want.
1

Open the Console over SSH, if Postern runs on another computer

Skip this if you sit at the machine Postern runs on. The Console only answers on the machine it runs on. Run this on your own computer, not on the machine Postern runs on:
Replace YOUR_MACHINE with however you reach that computer: a name, a user@host, or an IP address. The terminal prints nothing and does not return to a prompt. That is the command at work, not a hang. Leave that window open, then open http://localhost:8787. Press Control-C when you want to stop. Open the Console carries the long version.A tunnel does not move the Console off that machine: port 8787 has no password, and its address stands in for one.
2

Install Tailscale and turn on two switches

Install Tailscale on the machine Postern runs on, and on every device you want to reach it from (tailscale.com/download). Sign them all into the same Tailscale account.On the machine Postern runs on, run tailscale up, then follow what it prints to sign that machine in.
On a Mac, the App Store and desktop builds leave tailscale off your PATH, so which tailscale returns nothing. It sits inside the app, with a capital T. Run this once, in the same terminal:
Then put $TS in front of every tailscale command below. Close that terminal and $TS is gone. Linux packages put tailscale on your PATH.
Two settings in Tailscale’s admin console decide whether any address below ever answers. Turn them on in this order.
HTTPS certificates put this machine’s name on the Certificate Transparency log: a public list of every secure-website certificate ever issued. Anyone can read it, and entries cannot be removed. Rename the machine to something dull first, and never treat its name as protection.
Open login.tailscale.com/admin/dns. Turn on MagicDNS, which lets your devices reach each other by name. Then turn on HTTPS certificates. Tailscale’s own instructions walk both, in that order: Enabling HTTPS. Both must be on. If either is off, the failure is silent: the port never answers, and no log names the cause.Get this machine’s Tailscale name from tailscale status on that machine. Tailscale’s admin console lists it too, on the page its documentation calls Machines. The name looks like gateway.example-tailnet.ts.net, and every command below needs it.
3

Open two ports to your own devices

Never open port 8787, the Console port, whole to any network. Anything that reaches it holds full control of Postern, and no password stands behind it. The first command below opens one address on that port and nothing else. Reachability is the authentication.
Run both on the machine Postern runs on:
--bg keeps Tailscale in the background and gives your prompt back. Without it the terminal is stuck. Both commands work on Tailscale 1.98.9, and --set-path is current syntax there.Your own devices now reach two addresses, and the internet reaches neither:
  • https://gateway.example-tailnet.ts.net:8443/api/ingest/<connection-id> — your iPhone pushes Apple Health data here.
  • https://gateway.example-tailnet.ts.net:10000/mcp — an agent on your own devices connects here, with an agent key.
Check it from a second computer on your tailnet. It needs Tailscale, the same account, and a terminal, so a phone will not do. Substitute your own machine name. This prints only the three-digit answer code:
It must print 404 — nothing is there, because the first command opened /api/ingest alone. 200 means the whole port is open: stop, and run both commands again exactly. Nothing at all means MagicDNS or HTTPS certificates is off (step 2).The second check needs a connection id, and none exists until you press Create your ingest endpoint on the Apple Health card. Then this must print 401 — the address answers, and it wants its secret:
4

Open one port to the internet for a hosted agent

Do this only for a hosted agent: an AI app that runs on a company’s servers, like claude.ai or ChatGPT. It can never reach your home network on its own, and it connects out on port 443 only. Open 443, pointed at port 8788, the agent port. Never point it at 8787.Your tailnet policy must let this machine run a funnel. Tailscale keeps that policy in its admin console, on the page its documentation calls Access controls. Tailscale’s own instructions cover the funnel permission: Tailscale Funnel. Scope the permission to this machine’s own tag, never to the whole tailnet. serve and funnel are last-command-wins per port. A mistyped command on any machine that holds the permission can open something to the internet (the whole argument). This page does not walk Tailscale’s policy file. If the permission is not there, the command below refuses out loud and prints a link that turns it on. Open that link, then run the command again.
Run the command below once, and get it right first time. Repeated serve and funnel commands re-issue certificates, and the free certificate service limits how often it will issue one for a name. Past that limit you lose your own hostname for hours. Retry in step 5, never here.
In tailscale funnel status, the 443 line must read (Funnel on), and every other line (tailnet only).Now tell Postern its address. In the Console, click Settings in the left sidebar, then find Remote access. In the row headed Public · the address this gate answers on, press Set the address….A field labelled Your gate’s public address appears, with the placeholder https://your-mac.tailnet.ts.net. Type https:// and this machine’s Tailscale name, with nothing after it — not the /mcp address you hand an agent. Postern builds that one itself, and it refuses an address that carries a path.Postern does not save the address until you confirm it. Press Publish this gate on the bar headed Publish this gate to the public internet?. That bar lists what it costs you. The row then reads restart to apply, and a message reads Saved — restart the gateway to start publishing.
Settings → Remote access: the Public row reads off, with a Set the address button.

Settings → Remote access. The Public row reads off until you set an address. Recorded on a gateway whose Plaid source was in Sandbox, so ignore any Plaid detail in this shot.

Restart Postern from the folder that holds docker-compose.yml — the postern folder you made in Install Postern:
The restart is not optional: Postern reads the address once, at start-up. The Public row then reads published, and the OAuth bridge row reads On — published at your address. That bridge is on exactly when Postern has an address, and off otherwise. There is no separate switch.
5

Check it from a device that is not on your tailnet

A device on your tailnet cannot prove this: from inside, a funnel and a private serve look identical. Use a device off your tailnet that can run these commands — a laptop on a phone’s cellular hotspot does it. Substitute your own machine name. All three must print 200, 401 and 404, in that order:
200 means it answered. 401 means it answered and wants a key. 404 means nothing is there. On the third line that is the answer you want: the Console port did not come with it. Touch no agent app until all three read correctly.
claude.ai remembers what it found here for about five minutes, failures included. Change one thing, wait five minutes, then try once.
6

Connect claude.ai or ChatGPT

First create the key. In the Console, click Agents & keys in the left sidebar, then click Mint a key. Three fields:
  • Name — what you will call this agent.
  • Grant which sectors — six areas of your life: finance, mail, calendar, contacts, health, home. The form says Nothing is granted until you pick it.
  • Expires — four chips: Never, 30 days, 60 days and 90 days. Once you have set a public address, the form starts on 90 days.
Mint your first key walks the whole form.
Pick anything but Never. Postern refuses a key with no expiry at the hosted sign-in page: This agent key never expires. Keys used with a cloud client must have an expiry — mint or rotate a key with a 30/90/365-day expiry in the Console, then try again. The Console has no 365-day chip, and 90 days is its longest. Never dead-ends you at the last step of this page.
Press Mint the key. A screen headed Agent key — shown once appears, with a Copy button. Copy the key into your password manager now. Postern cannot show you this key again. It keeps a scrambled copy it can check against, never the key itself. Lose it and you create another.
The next Copy button replaces whatever is on your clipboard — the agent key too. Store the key first.
The address you hand the agent is your published address plus /mcp. The Console prints the exact value under Agents & keysSet up the bridge →, with its own Copy button.In claude.ai, open its settings and find its connectors. Add a connector of your own. Paste the address into it. If it asks for a client id or a client secret, leave both empty. Postern issues neither.claude.ai then sends you to a page your own Postern serves, headed Authorize agent access. Paste the agent key under Paste an agent key from the Console. Press Approve. claude.ai holds a token that rotates from then on. ChatGPT takes a longer path: Connect ChatGPT.Revoke a key and every token made from it dies with it. Postern denies the agent’s next call.

Turn the public port off

This is not a step. It undoes Open one port to the internet, whenever you want that port shut again. Nothing here touches your own devices. Three acts. Do all three. Any two leave you half-off — a funnel with no address, an address with no funnel, or Postern still on the old one. On the machine Postern runs on:
In the Console, click Settings, then find Remote access. In the Public row, press Stop publishing…, then press Stop publishing on the bar headed Stop publishing this gate?. A message reads Stopped — it stays reachable until the gateway restarts.
If .env on the machine Postern runs on holds an MCP_PUBLIC_URL line, the Console refuses, and says so: The box publishes this gateway: MCP_PUBLIC_URL is set in its environment, and the box wins over anything saved here. Delete that line from .env first. .env is the settings file beside docker-compose.yml.
Then restart:
Confirm no funnel remains. The output must contain no AllowFunnel anywhere:
Nothing about Open two ports to your own devices changes. Your own devices still reach Postern.

Confirm it works

  • Tailscale’s admin console → DNS: MagicDNS on, HTTPS certificates on.
  • From a second computer on your tailnet, /api/agents on port 8443 prints 404.
  • tailscale funnel status: the 443 line reads (Funnel on), every other line (tailnet only).
  • Console → Settings → Remote access: the Public row reads published, not restart to apply.
  • Console → Settings → Remote access: the OAuth bridge row reads On — published at your address.
  • From a device off your tailnet, the three checks in step 5 print 200, 401 and 404.
  • Console → Agents & keys lists your key, and its sub-line reads expires in 30d, expires in 60d or expires in 90d — never never expires.

If something went wrong

What you have now

Three costs stay with you:
  • a public hostname in a permanent certificate log
  • a Tailscale account to keep
  • an address that stays live until you turn it off

Next

Connect ChatGPT

a ChatGPT paid plan + a published address · about 10 minutes, once · witnessed end-to-end 2026-08-01

Connect Apple Health

Health Auto Export on your iPhone · about 10 minutes · push, not pull