Open source, Apache-2.0. The source and releases are public.

Your agent's own endpoint. On your machine.

hdtp-gateway is the open-source HDTP node, two static binaries — the node and its limits sidecar — or one Docker image. It gives your agent an address other people's agents can reach, a certificate you issued, and a channel both people approved. Nobody in the middle, and nothing leaves your machine that you did not send.

your gateway · Inbox
MCMaya Chen· Dinner on Thursday?root sha256:9fJ…kQ2 pinned
MC
Maya's agent agent 2:01 pm
Maya would like dinner next week. When are you free Thursday evening?
Y
Your agent agent 2:01 pm
Three times work: 7:00, 7:30 or 8:00 pm.
check_availability → 3 slots, not your calendar
MC
Maya's agent agent 2:02 pm
7:30 is perfect. Could you book Harbor & Vine for two?
Y
You human 2:04 pm
Go ahead and confirm.
Y
Your agent agent 2:05 pm
Booked Thursday at 7:30 pm. The invite is in both calendars.
book_slot → booking_id + ics
Message Maya's agent…

Two people, two nodes, one line between them.

Alice's agent
owner MCP
Alice's nodeon Alice's machine
Bob's agent
owner MCP
Bob's nodeon Bob's machine

Each person's address and certificate travel once, in a contact card, the vCard format your phone already reads. After that the two nodes talk directly.

No server in this picture has to be trusted by both people. Bob's node decides what Alice's agent may do, Alice's decides what Bob's may do, and each holds its own keys.

What makes it different.

Sealed end to end

A tunnel or edge sees which key a message is for, when, and how big. Never who sent it, never what it says.

A switch for every contact

Every tool sits behind a per-contact switch, and a caller only sees the tools switched on for them.

A certificate, not an account

Your identity is a root in your own wallet. Change hosts and your contacts still know you.

Reachable from behind anything

Any of these carries it. None of them is a relay that would see every sender, recipient and time.

Two binaries, or one image

The node and its limits sidecar. No cluster, no broker, no queue.

Every call on the record

A hash-chained audit trail that records refusals as loudly as successes, and cannot be quietly edited.

Attacks it refuses, by default.

The live intrusion battery builds each of these 27 and sends it to a running node. A run passes only when every one is refused and one control message that must get through does, so a node that refused everything fails it.

Point at a tile, or tap it, to see the attack.

StrangersForged chainsReplays and timingTamperingThe control, let through
All 27 attacks, by name

Strangers who aren't your contacts 4

  • A stranger naming a certificate nobody holds
  • The same stranger’s message, sent twice
  • A stranger calling a tool only contacts may call
  • A stranger asking which tools you have

Forged identity chains 7

  • A lone certificate with no root behind it
  • No certificate at all
  • A chain with a certificate too many
  • The chain in the wrong order
  • A root pretending to be its own host
  • A host certificate pretending to be the root
  • An intermediate posing as the root

Replays and bad timing 7

  • A certificate that is not valid yet
  • An expired certificate
  • A message an hour old
  • A message five and a half minutes old
  • A message dated five and a half minutes ahead
  • A message asking to be remembered for a year
  • Timestamps written as text

Tampering and downgrades 9

  • A signature that was altered
  • A message sealed to a key this node never held
  • A header field the protocol does not define
  • The wrong encryption suite for the recipient’s key
  • One byte moved from the key into the ciphertext
  • A header claiming version 2, which does not exist
  • A header claiming version 3, which does not exist
  • A message with no id
  • A reply dressed up as a request

And in the node itself.

Each of these is held by a named test in the node's gate, which runs before every push.

What it does not claim.

Stated plainly, as the specification does, because trade-offs do not disappear by going unmentioned.

Edges see metadata
Which node is called, how much and when. Sealed content stays ciphertext; the fact of a conversation does not.
No forward secrecy at the envelope layer
A stolen host key opens messages recorded while it was current, bounded by that certificate's life: at most 398 days, shorter if you renew.
Lose your root, lose that identity
It lives in your wallet and nowhere else, so nobody can mint you another. Losing a host's key is different: your wallet issues a new one.
Card trust is channel trust
A card handed over a hostile channel is a hostile card. The fingerprint is the thing to check.

Your data stays on your machine.

Where a self-hosted node keeps things is simple: where you run it.

  • Contacts, conversations and the audit trail live in SQLite on your disk, or in a Postgres you run
  • Secrets are sealed at rest; the sealing key is on the same machine, so disk encryption is yours to turn on
  • No telemetry: the node contacts nothing you did not configure. No phone-home, no crash reporter, no build flag that turns one on
  • Export your contacts and chats at any time, in a file you keep

Run it.

Docker with Compose, Rust (cargo) for the first command, and the hdtp wallet CLI from hdtp-identity. The source is public and anyone can run it. The quickstart walks through the setup with screenshots, and the portal's setup token appears in the log.

# fetch the limits sidecar's crates, then start the node
make limitd-vendor
docker compose up -d
docker compose logs hdtp-gateway | grep -A2 "setup"

# then check what an outside caller would see
docker compose exec hdtp-gateway hdtp-gateway doctor

A public IP or a VPS

direct · callers' certificates reach your node

A Tailscale account

tailscale · direct

An frp server you run

frp · direct, passed through

A paid ngrok plan

ngrok · direct

A Cloudflare account

cloudflare · edge: TLS ends there, so every call is sealed

Nothing inbound at all? One of these, or a host holding a certificate you issue. There is no relay. doctor reports the mode it derived.

Run it yourself, or let us run it.

hdtp-gateway
Self-hosted Source public
The open-source node, Apache-2.0.
  • Two static binaries — the node and its limits sidecar — or one Docker image; SQLite by default, Postgres when you want it
  • Passkey-only portal, and an owner MCP for your own agent
  • Invites, contact book, per-contact switchboard, hash-chained audit trail
  • No telemetry, ever. Your keys and data never leave your machine
Get the node
BatonDeck
Managed Private beta
The same protocol, run for you, under a certificate your wallet issues.
  • A reachable address in minutes, EU or US
  • Integrations with consent per tool
  • Backups, and an export of your contacts and chats, so you can leave
  • Your root never leaves your wallet
About BatonDeck

Questions, answered straight.

Is HDTP open?

Yes, both halves. The protocol is specified openly at hdtp.io. hdtp-gateway, the reference node, is Apache-2.0 and public: the source is on GitHub, with release binaries for Linux and macOS.

What stops spam?

Structure, not filters. There is no directory, contacts are approved by a person on each side, and an unknown caller can only redeem an invite you issued or ask to be a contact. Nothing else is reachable.

Does it need a server with a public IP?

No. A tailnet, frp, ngrok or Cloudflare works, and so does letting a host hold a certificate you issue. What it will not use is a relay.

Can I move to BatonDeck later, or back?

Yes. Your identity is the root in your wallet; moving is a new certificate for the new host, and your contacts and chats come with you.

Where is the source code?

On GitHub, at humandelegatedtrustprotocol/hdtp-gateway. It is public, Apache-2.0, and each release carries binaries, checksums and an SBOM.

Run your agent's own endpoint.

This registers your interest in hdtp-gateway, and nothing more: we never email you from it. You do not need it to run the node. Privacy.