Ony.ai
The on-call layer for AI coding agents. When your agent needs you, Ony.ai calls your phone - answer from anywhere and the agent keeps moving.
Your coding agent (Claude Code, OpenAI Codex, OpenCode) hits a decision it cannot make alone: a risky command, a permission prompt, a question with three options. Normally it stalls until you are back at a screen. With Ony.ai, a hook holds the action and raises a handoff: the Ony.ai server classifies the risk, places a real phone call, and reads the situation out. You decide on the keypad. The verdict comes back signed and the agent proceeds or is blocked - and when the agent asks a multiple-choice question, Ony.ai reads the options as a phone menu and delivers your choice back as the answer.
It is built for developers who let agents run long tasks and leave the desk: a phone call reaches you on a walk, a commute, or in a meeting, when every screen-bound approval flow does not. Risk classification keeps calls rare and worth answering.
Open-core. This repository is the complete open-source product (AGPL-3.0): self-host it with your own domain, telephony provider, models, and database. The hosted service at ony.ai is a separate offering built on this core. See LICENSING.md and docs/04-self-hosting.md.
Quickstart (30 seconds, no Docker)
The Lite tier runs a full Ony.ai server on SQLite - no Docker, Postgres, or Redis. Requires Python 3.12+.
pip install ony
ony up
# Ony is running at http://127.0.0.1:8001 (dashboard + API)
Open http://127.0.0.1:8001 and create your account, then from your project directory:
ony init # enrolls this machine + wires Claude Code (/ony command, gate, hooks)
ony away # phone me for every step Claude would stop on
That is the whole loop: the agent hits a step that needs you, Ony.ai raises a handoff, you decide, the agent keeps going.
Out of the box ony up uses the built-in mock carrier, so no phone actually rings yet: handoffs
surface in the dashboard, where you approve or deny (the Overview page's "Simulate a handoff"
button walks the whole flow with no agent or phone at all). Real calls start once you add a
telephony provider (SignalWire, Twilio, Telnyx, or Plivo) in Integrations -> Telephony and
verify your number. So you can try the loop end to end first, then flip on real calls.
Production: Docker all-in-one
For a team or a public host: Postgres 18 + Valkey + API + dashboard behind one origin, migrations applied on start.
cp .env.example .env # set ONY_SIGNING_SECRET (telephony is optional - add it in the dashboard)
docker compose --project-directory . -f deploy/docker-compose.prod.yml up -d --build
# GET http://localhost:8080/health -> {"status": "ok", ...}
# Dashboard at http://localhost:8080 - create your account there.
The --project-directory . flag makes Compose read the root .env for ${...} interpolation. For
automatic HTTPS on a public host, use the Caddy edge stack in
deploy/PROXMOX-RUNBOOK.md. See
docs/04-self-hosting.md for telephony setup and production configuration,
and docs/06-security-hardening.md before going to production.
What works today
| Agent | What you get | Status |
|---|---|---|
| Claude Code | Full blocking gate: risky tool calls hold until your phone decision; multiple-choice questions become phone menus; /ony modes. Wire a project with ony init, or install the marketplace plugin. |
Works today |
| OpenAI Codex | Deny-only hook (ony hooks codex): a phone denial blocks the tool, an approval defers to Codex's own flow. An app-server bridge and a forwarding proxy additionally route VS Code and desktop-app approvals through Ony.ai with full allow/deny. Details in clients/codex/. |
Hook: beta, verified live against codex-cli 0.144.5 (note: Codex requires a one-time hook trust approval). Bridge/proxy: experimental, pinned against codex-cli 0.142.x (handshake re-verified on 0.144.5) |
| OpenCode | Attach to your running opencode serve with ony opencode --url http://127.0.0.1:4096; each permission ask is answered by phone, one decision at a time, never a standing grant. |
Works today |
| SMS / Telegram / Slack fallback | Escalation channels when the call goes unanswered (ADR 0009), behind ONY_ESCALATION_ENABLED. |
SMS is carrier-dependent: US numbers require 10DLC campaign approval before SMS delivers |
Claude Code alternative install, as a marketplace plugin (the connector must be enrolled first:
pip install ony then ony enroll --url <your server>):
/plugin marketplace add ony-ai/ony
/plugin install ony@ony-ai
The /ony modes
Set the mode inside Claude Code (/ony away, or /ony:ony away with the marketplace plugin) or
from any terminal (ony away):
off- Ony.ai does nothing.on- phone only for high-risk actions.away- phone for every step Claude would stop on.here- back to high-risk only.
ony status shows the current mode and checks connectivity; ony doctor checks the wiring end to end.
How it works
- A hook in your agent blocks the pending action and raises a handoff to the Ony.ai server.
- The server classifies the action's risk from a closed taxonomy - the agent's own risk hint is never trusted (ADR 0007).
- Your phone rings; Ony.ai reads out the action, or the question and its options.
- You decide on the keypad, never by voice.
- A signed, expiring verdict bound to that specific action returns to the hook; the agent proceeds or is blocked, and the exchange lands in a tamper-evident audit chain.
Security model in one line: the server is authoritative for risk, every decision is a signed per-action verdict (never a standing grant), and unresolved gates on risky actions do not fail into silent approval - the full analysis is in the threat model.
Repository layout
apps/api/ony_api/ FastAPI control plane (handoffs, telephony webhooks, agent decision API)
apps/web/ React dashboard (sessions, handoffs, audit, settings)
packages/ony_core/ Domain models, risk map, state machines, policy, telephony engine
packages/ony/ The `ony` CLI + agent hooks: ony up, ony init, modes, daemon
clients/ Agent integrations: Claude Code plugin, Codex hook + bridge + proxy
docs/ Architecture, ADRs, self-hosting, security
deploy/ docker-compose stacks, runbooks, monitoring, backups
Documentation
Architecture & design - architecture review · ADRs
Deploy & operate - self-hosting · Proxmox bring-up · operations runbook · backups & DR · monitoring · scaling & HA · incident response
Security & compliance - security hardening · threat model · data handling & privacy · vulnerability disclosure
Features - SSO (OIDC) · telephony setup · editions & pricing
Contributing
Dev setup, test gates, and the engineering rules live in CONTRIBUTING.md and AGENTS.md. The short version:
python -m venv venv
venv/bin/python -m pip install -e ".[dev]" # venv\Scripts\python on Windows
venv/bin/python -m pytest # in-memory SQLite, no Docker needed
License
AGPL-3.0-or-later for the open-source core. A separate commercial license is available for organizations that cannot meet the AGPL's terms. See LICENSE and LICENSING.md.
Metadata
Release files for ony 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ony-0.4.0.tar.gz | 911.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ony-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.9 MB
Release files / ony-0.4.0.tar.gz
| Download URL | ony-0.4.0.tar.gz |
|---|---|
| Size | 911.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5296727dc465308409054781eabb1878a26a9e7af9c3c8a2fb44fd96558f5993
|
|
BLAKE2b-256 checksum How to use checksums |
b324c374d58537d968072cfc7008f8ba3cc66c89018eaf619f44780448f5af8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / ony-0.4.0-py3-none-any.whl
| Download URL | ony-0.4.0-py3-none-any.whl |
|---|---|
| Size | 1.0 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9ae40686181d0373f703c7f97f24d69429c7dedf49cd6b9b42579c3c219e0af5
|
|
BLAKE2b-256 checksum How to use checksums |
a1c0eacf4e7a1486dc8f4c585c98c03258255f67737bc8a1ead9dfc9ff5e3575
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|