Skip to main content

🛞 steerd

Approve, reject — or correct — your AI coding agent's actions from your phone.

License: MIT Python 3.10+

Claude Code keeps asking for permission, so you either babysit the terminal or approve everything blindly. steerd lets you hold the reins from your phone: when the agent wants to run a tool, you get a push notification, tap a link, and Approve, Reject with a correction, or even edit the command — then it keeps going.

No native app. No forking Claude Code. It plugs into Claude Code's built-in PreToolUse hook and relays the decision through a tiny self-hosted server.

⚠️ Alpha / work in progress. Core scaffold is in place; see HANDOFF.md for status and the build plan.


How it works

Claude Code (laptop)
  └─ PreToolUse hook → steerd relay → push to your phone
       └─ you tap: ✅ Approve · ❌ Reject (+ correction) · ✏️ Edit command
  └─ decision returns to Claude → it proceeds, stops, or adjusts
  • Approve → the tool runs.
  • Reject + correction → blocked, and your note is fed back to Claude as guidance.
  • Edit input → rewrites the command before it runs (updatedInput).
  • Auto-allow read-only tools (Read/Glob/Grep) so you're only pinged for the risky stuff.

Quickstart (local loop)

# Recommended: install globally with pipx (isolated deps, command on PATH)
pipx install steerd        # or: pip install --user steerd

# 1. run the relay
steerd-relay

# 2. register the hook in ~/.claude/settings.json (see examples/)
#    ⚠️ use the ABSOLUTE path to the hook — see note below

# 3. get phone pushes via ntfy (free, no account):
export STEERD_NTFY_TOPIC="your-unique-topic-name"
#    install the "ntfy" app and subscribe to that topic

Use the absolute path for the hook command in settings.json. The Claude Desktop app spawns hooks with a limited PATH, so a bare steerd-hook can fail to resolve there. Find the real path with which steerd-hook (e.g. ~/.local/bin/steerd-hook after a pipx install) and use that exact path in the hook's command.

Now run Claude Code — when it wants to run a tool, your phone buzzes; tap the link and decide.

📱 Using a real phone (not localhost)? See DEPLOY.md for exposing the relay via Tailscale / Cloudflare Tunnel / ngrok — and always set STEERD_TOKEN when you do.

Config (env vars)

Var Default Purpose
STEERD_TOKEN — shared secret protecting the relay — set this before exposing the relay beyond localhost
STEERD_RELAY_URL http://127.0.0.1:8787 where the hook reaches the relay
STEERD_PUBLIC_URL = relay url public link used in the push (use a tunnel/VPS for a remote phone)
STEERD_TIMEOUT 300 seconds to wait for a decision (keep < hook's 600s)
STEERD_ON_TIMEOUT deny fallback if no answer: deny or allow
STEERD_NTFY_TOPIC — ntfy topic for push
STEERD_TELEGRAM_BOT_TOKEN / _CHAT_ID — Telegram backend (alt to ntfy)
STEERD_AUTO_ALLOW Read,Glob,Grep,LS tools approved without pinging the phone

Where to enable it (scope)

Install once, run one relay — then where you register the hook decides what it guards. It plugs into Claude Code's PreToolUse hook and works with both the Claude Desktop app and the CLI (both read these settings).

Put the hook in… Guards Use for
~/.claude/settings.json (global) every session, every project supervise all agent shell commands
<project>/.claude/settings.json (project) only sessions opened in that project guard one repo (prod / infra / trading)
<project>/.claude/settings.local.json (local) that project, just you (uncommitted) personal, per-repo
  • A session loads hooks at startup, and only from its project root — not subfolders. Open the session in the folder whose settings has the hook, and restart after editing settings.
  • Only Bash is gated by the example matcher; read-only tools are auto-approved — so you're pinged for shell commands, not every file read.
  • Recommended: per-project on sensitive repos for day-to-day work; global when you're letting an agent run on its own.

Gotchas

  • Long-running servers block. Approving npm run dev makes Claude's terminal wait on a process that never exits — that's normal, not steerd. Ask Claude to start servers in the background.
  • Keep the relay up. If it's down, gated commands fall back to Claude's normal in-app prompt (graceful, not broken). For always-on, run the relay as a service — see DEPLOY.md.

Why not just…

  • --dangerously-skip-permissions? That approves everything, blind. This keeps you in control of the risky calls only.
  • Allowlists in settings.json? Great for known-safe commands — use both. steerd covers the unpredictable calls you can't pre-list, while away from the keyboard.
  • A mobile app? Unnecessary — a push + web page does the job and stays installable in seconds.

Status & roadmap

Core relay + hook are scaffolded. Next: tests + CI, a remote-tunnel guide, an auth token on the relay, and a demo. See HANDOFF.md.

  • End-to-end tested in Claude Code with phone approval
  • Auth token on relay endpoints
  • Tunnel/VPS guide for remote phones
  • Demo GIF
  • Support more agents (Cursor, Cline) via the same relay

License

MIT © Kannan Dharmalingam

Metadata

Release files for steerd 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for steerd 0.1.0
File Size Uploaded Provenance
steerd-0.1.0.tar.gz 16.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for steerd 0.1.0
File Interpreter ABI Platform
steerd-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 27.9 kB

Release files / steerd-0.1.0.tar.gz

Download URL steerd-0.1.0.tar.gz
Size 16.2 kB
Tags Source
SHA-256 checksum
How to use checksums
12edf489ab6733ea8f7df3b5a57ae1d1f74cad071610b4bab68a5d57905fb29c
BLAKE2b-256 checksum
How to use checksums
bcad363cb8b4f79f549e7f19c738d82d0fc116a75085e67c91d640beea593cec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / steerd-0.1.0-py3-none-any.whl

Download URL steerd-0.1.0-py3-none-any.whl
Size 11.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
42c171463d90144aeba89a3ad61614b0476d2fa5923b265e804ad48c445b69dc
BLAKE2b-256 checksum
How to use checksums
c7f5488facb377af3e31deb11fe81fa68a5ea216d2725b98157edeb20ad2670a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Security for steerd 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page