// docs
c0x0 cli · v1.0.3 · node 18+
// install
npm install -g @0x0contact/c0x0
Or run without installing:
npx @0x0contact/c0x0 init
requires Node.js 18 or later.
// quick start
# 1. generate your number
c0x0 init
# 2. create a PIN
c0x0 pin new --label "for sale"
# 3. share your number + PIN, then chat
c0x0 chat 0x0-293-4471-0038 a3f9
# 4. done — revoke when finished
c0x0 pin revoke a3f9
Your number is generated locally and never sent to any server. The PIN is the key — share it only with who you want to connect with.
// setup
| c0x0 init | generate your number (first time setup) |
| c0x0 whoami | show your current number |
| c0x0 renew | generate a new number — resets all PINs |
// pin management
A PIN is a short code that lets others connect to you. Create one per context — marketplace, date, work. Revoke it when done.
| c0x0 pin new | create a new PIN |
| c0x0 pin new --label "label" | create with a label |
| c0x0 pin new --expires 24h | auto-expire after 24h (or 1w) |
| c0x0 pin list | list all active PINs |
| c0x0 pin rotate <pin> | change the PIN value |
| c0x0 pin revoke <pin> | permanently revoke |
c0x0 pin new --label "フリマ用" --expires 24h
// messaging
| c0x0 chat <number> <pin> | interactive chat session |
| c0x0 send <number> <pin> "msg" | send one message and exit |
| c0x0 inbox | view all inboxes |
| c0x0 read <pin> | read messages for a PIN |
| c0x0 listen | wait for incoming messages |
c0x0 chat 0x0-293-4471-0038 a3f9
// connected
// type :quit to exit
> hey
[14:32] you: hey
[14:33] peer: hi
// contacts
Save someone's number and PIN as a contact to message them again without re-entering their details.
| c0x0 contact add 0x0://NUMBER/PIN | add from URI |
| c0x0 contact add NUMBER PIN | add manually |
| c0x0 contact list | list all contacts |
| c0x0 contact label <id> "label" | set a label |
| c0x0 contact remove <id> | remove contact |
c0x0 contact add "0x0://0x0-293-4471-0038/a3f9" --label "Aさん"
// web UI
Starts a local web server with a full chat interface. Accessible from mobile browsers on the same WiFi.
| c0x0 web | open browser UI at localhost:3000 |
| c0x0 web --port 8080 | use a different port |
| c0x0 web --no-open | don't auto-open browser |
c0x0 web
// local
http://localhost:3000
// mobile (same wifi)
http://192.168.1.5:3000
The web UI requires the CLI to be running. It is a local interface — not a hosted service.
// URI scheme
Share a connection link as text, QR code, or NFC tag.
0x0://0x0-816-8172-8198/a3f9
| c0x0 qr <pin> | show QR code in terminal |
c0x0 qr a3f9
// 0x0://0x0-816-8172-8198/a3f9
█████████████████
█ ▄▄▄▄▄ █▀▄▀▄█ █
█ █ █ █▀▀▀▀█ █
█ █▄▄▄█ █▄ ██ ██
█▄▄▄▄▄▄▄█ ▀ ▀ ██
...
The other person scans the QR or pastes the URI and connects instantly.
// pipe mode
For AI agents and automation. Reads JSON commands from stdin, emits JSON events to stdout.
c0x0 pipe 0x0-293-4471-0038 a3f9
stdin
{"type": "message", "content": "task complete"}
{"type": "ping"}
{"type": "disconnect"}
stdout
{"type": "connected", "peer": "0x0-293-4471-0038", "pin": "a3f9"}
{"type": "message", "from": "0x0-293-4471-0038", "content": "got it"}
{"type": "disconnected"}
python example
import subprocess, json
proc = subprocess.Popen(
["c0x0", "pipe", "0x0-293-4471-0038", "a3f9"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
proc.stdin.write(
json.dumps({"type": "message", "content": "done"}).encode() + b"\n"
)
proc.stdin.flush()
for line in proc.stdout:
event = json.loads(line)
if event["type"] == "message":
print(event["content"])
// data & storage
Everything is stored locally in ~/.0x0/. Nothing is sent to any server.
~/.0x0/
├── identity.json # your number
├── pins.json # your PINs
└── messages/ # message history (per PIN)
To erase all traces:
rm -rf ~/.0x0/
Messages are stored in plaintext locally. The transport is encrypted via Noise protocol over Hyperswarm P2P.
// how it works
0x0 uses Hyperswarm — a DHT-based P2P network — to connect two devices directly. No server relays messages. No server stores them.
connection = sha256("0x0:{number}:{pin}:0x0-v1-2026") → Hyperswarm topic
transport: Hyperswarm DHT + Noise protocol (E2E encrypted)
storage: ~/.0x0/ (local only, never leaves your device)
Your number is generated locally on first run. It is never sent to any server or registered anywhere. The PIN you create becomes the shared secret that both sides use to find each other on the DHT.
Messages are stored in plaintext locally at ~/.0x0/messages/. The transport is encrypted end-to-end via Noise protocol. Delete ~/.0x0/ to remove all local data.
// connections
0x0 does not distinguish between human and agent endpoints. Any process that can run c0x0 or speak the pipe protocol can connect. The PIN is the only credential.
| human · human | Two people share a number and PIN. Either side can rotate or revoke the PIN to end the connection. |
| human · agent | A person runs an agent on a server and gives it a PIN. The agent stays connected 24/7; the person contacts it on demand. |
| agent · agent | Two automated processes connect via PIN for the duration of a task, then the PIN is rotated. Ephemeral channel, no logs. |
agent example
# server: agent waits for instructions
c0x0 listen
# or use pipe mode for JSON I/O
c0x0 pipe 0x0-816-8172-8198 ff2c
# client: send a task
c0x0 send 0x0-816-8172-8198 ff2c "run report"
# when done, rotate the PIN
c0x0 pin rotate ff2c
See pipe mode for the full JSON API used by AI agents and automation scripts.
// OpenClaw
OpenClaw is a local AI agent framework that connects to messaging platforms. Add 0x0 as a custom P2P channel — no Telegram account, no Slack workspace required. Just a PIN.
// 1. create a PIN for your agent
c0x0 pin new --label "my-agent"
# PIN: a3f9
c0x0 whoami
# 0x0-816-8172-8198
// 2. add to openclaw.json
{
"channels": {
"zx0": {
"number": "YOUR_NUMBER",
"pin": "YOUR_PIN"
}
}
}
// 3. start
openclaw start
// 0x0 channel active
// 0x0-816-8172-8198 / a3f9 → connected
The 0x0 channel for OpenClaw is a community integration built on pipe mode. For a custom implementation, see the pipe mode docs and the OpenClaw plugin guide.
// export from app
In the 0x0 app: PIN Menu → "Export for agent" → copy the config JSON directly into openclaw.json. No manual entry needed. Coming soon.