Skip to main content

Approve, reject, or correct your AI coding agent's actions from your phone — a remote-approval relay for Claude Code's PreToolUse hook.

Project description

🛞 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 rootnot 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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

steerd-0.1.0.tar.gz (16.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

steerd-0.1.0-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file steerd-0.1.0.tar.gz.

File metadata

  • Download URL: steerd-0.1.0.tar.gz
  • Upload date:
  • Size: 16.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for steerd-0.1.0.tar.gz
Algorithm Hash digest
SHA256 12edf489ab6733ea8f7df3b5a57ae1d1f74cad071610b4bab68a5d57905fb29c
MD5 5339c9f8f8d3c9c3e58f28b0102fb4a0
BLAKE2b-256 bcad363cb8b4f79f549e7f19c738d82d0fc116a75085e67c91d640beea593cec

See more details on using hashes here.

File details

Details for the file steerd-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: steerd-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for steerd-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 42c171463d90144aeba89a3ad61614b0476d2fa5923b265e804ad48c445b69dc
MD5 1ab4ca0433aae7a67cef3d3c86e81e12
BLAKE2b-256 c7f5488facb377af3e31deb11fe81fa68a5ea216d2725b98157edeb20ad2670a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page