Control your AI coding agents from your phone when you're away from your desk
Project description
Tether
The open source infra layer between your local coding agents and messaging apps.
Tether runs on your machine and turns agent runs into something you can supervise from anywhere: a mobile friendly web UI plus messaging bridges (Telegram, Slack, Discord) with approvals, input prompts, and live output streaming.
If you're running Claude Code, Codex, OpenCode, or Pi locally and you want supervision (logs, state, diffs, approvals) in the places you already work, this is that layer.
Claude Code / Codex / OpenCode / Pi / custom agent
| (adapter, MCP, or REST)
v
Tether (local control plane)
| |
v v
Web UI (PWA) Telegram/Slack/Discord
How it works
1. Start Tether on your machine (or a VM you control)
2. Open the web UI, or connect a messaging bridge
3. Run an agent session (Claude / Codex / custom)
4. Stream output + state in real time (web + messaging threads)
5. Approve tool use, provide input, or interrupt when needed
What you get
- A single place to observe every agent session (state, logs, diffs, approvals)
- Messaging native control: per session threads with approve and reject controls
- Human in the loop gates for risky operations (file writes, shell commands, etc.)
- A stable interface for agents: run via built in adapters, or connect via MCP or REST
Features
- Local first: runs on your machine, your data stays yours
- Human in the loop: approve tool use, provide input, review diffs
- Observable: live streaming output and explicit session state (web and messaging)
- Messaging bridges: Telegram, Slack, and Discord with approvals and auto approve
- Multi adapter: Claude Code (OAuth or API key), Codex via sidecar, OpenCode via sidecar, Pi coding agent, plus LiteLLM (experimental)
- External agent API: MCP server and REST API for custom agents and integrations
- Mobile first UI: PWA dashboard for monitoring and controlling sessions (experimental)
- CLI client: manage sessions, attach external agents, and send input from your terminal
Quick Start
pipx install tether-ai
tether init
tether start
Then open http://localhost:8787.
The init wizard generates an auth token, detects your claude CLI, and optionally
configures a messaging bridge. Config is saved to ~/.config/tether/config.env.
Typical uses
- Keep long running agent work accountable: audit output, diffs, and approvals after the fact
- Run an agent on a workstation or VM and supervise from your phone (web UI or messaging)
- Put approvals where your team already lives (Slack or Discord) instead of in a terminal
- Plug in your own agent: use MCP or REST to emit events and request approvals
From source
git clone https://github.com/larsderidder/tether.git
cd tether
make install
cp .env.example .env
make start
External Agent API (for your own agents)
Any AI agent can connect to Tether to get human in the loop supervision. Two interfaces are available. Use whichever fits your agent tooling:
MCP (recommended for Claude Code and other MCP capable agents)
The MCP server exposes Tether as tools that any agent can call to register a session, stream output, and request human approval:
tether-mcp
# or: python -m tether.mcp_server.server
Tools: create_session, send_output, request_approval, check_input.
Add to your agent's MCP config:
{
"mcpServers": {
"tether": {
"command": "tether-mcp"
}
}
}
Install: pip install tether-ai[mcp]
REST
For agents that don't support MCP, the same workflow is available via REST:
# Create a session
curl -X POST http://localhost:8787/api/sessions \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "My Task", "agent_type": "custom"}'
# Push output
curl -X POST http://localhost:8787/api/sessions/{id}/events \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"type": "output", "data": {"text": "Hello from agent"}}'
# Poll for human input
curl http://localhost:8787/api/sessions/{id}/events/poll?since_seq=0 \
-H "Authorization: Bearer $TOKEN"
See docs/API_REFERENCE.md for full endpoint documentation.
Adapters (built in runners)
Set TETHER_DEFAULT_AGENT_ADAPTER in .env:
claude_auto: Auto detect (prefer OAuth, fallback to API key)claude_subprocess: Claude via Agent SDK in subprocess (OAuth or API key)codex_sdk_sidecar: Codex via TypeScript sidecaropencode: OpenCode via TypeScript sidecar (auto-managed, uses the OpenCode SDK)pi_rpc: Pi coding agent via JSON-RPC subprocesslitellm: Any model via LiteLLM (DeepSeek, Gemini, OpenRouter, etc.), experimental
Sessions can override the default adapter at creation time. Multiple adapters can run simultaneously.
The Codex and OpenCode sidecars share a common infrastructure layer (sidecar-common) and are built as
npm workspace packages. When using managed mode (the default for OpenCode), Tether starts and stops the
sidecar process automatically.
Note: The Codex and OpenCode adapters require Node.js on your PATH. The sidecar bundles are included in the PyPI package and started automatically.
Messaging Bridges
Connect a messaging platform so you can monitor and control sessions from your phone. Configure
credentials in .env. The bridge starts automatically.
Platforms:
- Telegram:
TELEGRAM_BOT_TOKENplusTELEGRAM_FORUM_GROUP_ID(supergroup with topics) - Slack:
SLACK_BOT_TOKENplusSLACK_APP_TOKENplusSLACK_CHANNEL_ID - Discord:
DISCORD_BOT_TOKENplusDISCORD_CHANNEL_ID
How to use it (2 minutes)
- Set the platform env vars above (or run
tether initand let it guide you). - Start Tether:
tether start - In Telegram: run
/list, then/attach <number> - In Slack/Discord: run
!list, then!attach <number>
That creates a per session thread (topic or thread) where output streams live and approvals show up as buttons or text prompts.
Bridge features:
- Live output streaming to threads (one per session)
- Approval request controls with approve, reject, and always approve
- Auto approve with configurable tool patterns and duration
- Session listing, status updates, and input forwarding
Install bridge dependencies:
pip install tether-ai[telegram] # or [slack] or [discord]
CLI
tether init # Interactive setup wizard
tether start # Start the server
tether start --dev # Dev mode (no auth required)
tether start --port 9000 --host 127.0.0.1
# Client commands (talk to a running server)
tether status # Server health + session summary
tether open # Open web UI in browser
tether list # List Tether sessions
tether list -s running # Filter by state
tether list -d . # Filter by directory
tether list --external # Discover Claude Code / Codex / OpenCode / Pi sessions
tether attach <external-id> # Attach an external session to Tether
tether attach # Pick from external sessions in current dir
tether attach <id> -p discord # Attach and create a Discord thread
tether input <session-id> "message" # Send input to a session
tether interrupt <session-id> # Interrupt a running session
tether delete <session-id> # Delete a session
tether sync <session-id> # Pull new messages from an attached external session
Session IDs accept short prefixes (first few characters are enough as long as they are unique).
Running in the background
Tether does not have a built in daemon mode. To run it in the background:
nohup tether start > ~/.local/share/tether/tether.log 2>&1 &
echo $! > ~/.local/share/tether/tether.pid
# Later, to stop it:
kill $(cat ~/.local/share/tether/tether.pid)
Or use your system's service manager (systemd, launchd, etc.).
Configuration
Tether loads config from layered sources (highest precedence first):
- Environment variables
- Local
.envfile (working directory) ~/.config/tether/config.env(created bytether init)
Key settings:
TETHER_DEFAULT_AGENT_ADAPTER=claude_auto # Agent adapter
TETHER_AGENT_TOKEN= # Protect the API/UI with bearer auth
TETHER_AGENT_HOST=0.0.0.0 # Bind address (default: 0.0.0.0)
TETHER_AGENT_PORT=8787 # Port (default: 8787)
See .env.example for the complete reference including adapter-specific settings, session
timeouts, logging, and bridge configuration.
Development
make install # Install Python + Node dependencies
make start # Build UI and run agent
make dev-ui # Run UI dev server (hot reload); run agent separately
make test # Run pytest
make verify # Health check
See AGENTS.md for full developer docs and docs/ for architecture documentation.
License
Apache 2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tether_ai-0.3.3.tar.gz.
File metadata
- Download URL: tether_ai-0.3.3.tar.gz
- Upload date:
- Size: 693.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55a4b79ee6633163ab8aa575cd6ae7fa8469dc7ba1c3ccd7d8efbdaee027a73c
|
|
| MD5 |
b14cfb61284901711ec3c23d9a3c2db2
|
|
| BLAKE2b-256 |
042eb5461bace2d6eea0e0c98732152c988c18de4c92b1360c0afe193582f135
|
Provenance
The following attestation bundles were made for tether_ai-0.3.3.tar.gz:
Publisher:
publish.yml on larsderidder/tether
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tether_ai-0.3.3.tar.gz -
Subject digest:
55a4b79ee6633163ab8aa575cd6ae7fa8469dc7ba1c3ccd7d8efbdaee027a73c - Sigstore transparency entry: 991521661
- Sigstore integration time:
-
Permalink:
larsderidder/tether@f34354bc7af6ca21184a0cb7cd7881856a07b373 -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/larsderidder
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f34354bc7af6ca21184a0cb7cd7881856a07b373 -
Trigger Event:
release
-
Statement type:
File details
Details for the file tether_ai-0.3.3-py3-none-any.whl.
File metadata
- Download URL: tether_ai-0.3.3-py3-none-any.whl
- Upload date:
- Size: 658.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1b6b0229d52059db779c1c16dce168b949adbfa6de3203674cf308d902c4ad5
|
|
| MD5 |
e7bd57fa6fb58f9dc3a5bbe34228450f
|
|
| BLAKE2b-256 |
b0de576304c055508fed3ea343d3f4a09412796114bee21162bfed659df21683
|
Provenance
The following attestation bundles were made for tether_ai-0.3.3-py3-none-any.whl:
Publisher:
publish.yml on larsderidder/tether
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tether_ai-0.3.3-py3-none-any.whl -
Subject digest:
a1b6b0229d52059db779c1c16dce168b949adbfa6de3203674cf308d902c4ad5 - Sigstore transparency entry: 991521666
- Sigstore integration time:
-
Permalink:
larsderidder/tether@f34354bc7af6ca21184a0cb7cd7881856a07b373 -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/larsderidder
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f34354bc7af6ca21184a0cb7cd7881856a07b373 -
Trigger Event:
release
-
Statement type: