Open two ports to your own devices, and one port to the internet only if claude.ai or ChatGPT needs it.
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.
Steps
Who does them
1
Only you, if Postern runs on a computer you are not sitting at.
2 and 3
Anyone who wants their own devices to reach Postern. Most people stop here.
4 to 6
Only if claude.ai or ChatGPT must reach Postern. These open one port to the internet.
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.
--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:
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.
tailscale funnel --bg --https=443 http://127.0.0.1:8788tailscale funnel status
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 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:
cd posterndocker compose restart app
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.
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 & keys → Set 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.
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:
tailscale funnel --https=443 off
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:
cd posterndocker compose restart app
Confirm no funnel remains. The output must contain no AllowFunnel anywhere:
The internet reaches eight addresses on one port. Seven are the sign-in machinery and hold no data of yours; the eighth is /mcp, which needs a key. The Console is not among them. The full list.