npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

claude-remote-approver

v0.7.3

Published

Approve or deny Claude Code permission prompts remotely from your phone via ntfy.sh

Readme

claude-remote-approver

Approve or deny Claude Code permission prompts from your phone.


Problem

Claude Code asks for permission before running tools like Bash, Write, and Edit. These prompts require you to be sitting at your terminal. If you step away, Claude Code stalls until you come back and press "y".

claude-remote-approver sends each permission prompt as a push notification to your phone via ntfy.sh. You tap Approve or Deny, and Claude Code continues immediately -- no terminal required.

How it works

Claude Code
  │
  │  PermissionRequest hook (stdin JSON)
  ▼
cli.mjs hook
  │
  ├──POST──▶ ntfy.sh/<topic>          ──push──▶  Phone (ntfy app)
  │                                                 │
  │                                     Approve / Always Approve / Deny tap
  │                                                 │
  └──SSE───▶ ntfy.sh/<topic>-response  ◀──POST──┘
  │
  │  stdout JSON: allow / deny / ask (CLI fallback)
  ▼
Claude Code continues or stops
  1. Claude Code invokes the hook, piping the tool request as JSON to stdin.
  2. cli.mjs hook sends a notification to your ntfy topic with Approve, Always Approve, and Deny action buttons.
  3. The hook subscribes to a response topic (<topic>-response) via server-sent events.
  4. When you tap a button on your phone, ntfy.sh publishes your decision to the response topic.
  5. The hook reads the decision and writes {"behavior":"allow"} or {"behavior":"deny"} to stdout. If the notification fails or times out, the hook returns {"behavior":"ask"} so Claude Code falls back to the CLI prompt.
  6. Claude Code proceeds accordingly.

AskUserQuestion support

When Claude Code calls the AskUserQuestion tool, the hook sends the question to your phone as a notification. Each option appears as an action button you can tap. If the question has more than 3 options, they are split across multiple notifications. If no response is received before the timeout, the hook falls back to the CLI prompt so you can answer at your terminal.

Always Approve

When Claude Code sends a permission_suggestions field with the hook request (indicating the tool can be auto-approved in future), the notification shows three buttons: Approve, Always Approve, and Deny.

  • Approve -- Allow this one request.
  • Always Approve -- Allow this request and tell Claude Code to auto-approve this tool in future sessions. Claude Code adds the permission rule to its settings so it won't ask again.
  • Deny -- Reject this request.

If the hook request does not include permission_suggestions, only the standard Approve and Deny buttons are shown.

Quick Start

# 1. Install the ntfy app on your phone
#    iOS: https://apps.apple.com/app/ntfy/id1625396347
#    Android: https://play.google.com/store/apps/details?id=io.heckel.ntfy

# 2. Install claude-remote-approver
npm install -g claude-remote-approver

# 3. Run setup
claude-remote-approver setup

Setup prints a QR code. Scan it with the ntfy app to subscribe, then start a new Claude Code session. The hook is loaded at session startup, so any session that was already running before installation will not have the hook active.

Installation

npm install -g claude-remote-approver

Requires Node.js 18 or later.

Setup

claude-remote-approver setup

This command does three things:

  1. Generates a unique topic -- a random string like cra-a1b2c3d4e5f6... (128 bits of entropy).
  2. Creates a config file at ~/.claude-remote-approver.json with your topic and default settings. The file is created with permission 0600 (owner read/write only).
  3. Registers the hook in Claude Code's ~/.claude/settings.json under hooks.PermissionRequest. If a previous hook entry from this tool exists, it is replaced.

After running setup, scan the QR code displayed in the terminal with the ntfy app on your phone. You can also manually subscribe using the URL printed below the QR code.

Usage

setup

Configure the tool and register the hook with Claude Code.

claude-remote-approver setup
# Setup complete. Topic: cra-<hex>
#
# Scan this QR code in the ntfy app to subscribe:
#
# ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
# █ ▄▄▄▄▄ █ █ ▄▄▄▄▄ █
# ...
#
# Subscribe URL: https://ntfy.sh/cra-<hex>

test

Send a test notification to verify your setup is working.

claude-remote-approver test
# Test notification sent successfully.

If you see the notification on your phone, everything is configured correctly.

status

Display the current configuration.

claude-remote-approver status
# Topic:   cra-a1b2c3d4...
# Server:  https://ntfy.sh
# Timeout: 120s
# Auth:    not configured

enable

Re-enable the hook after it has been disabled.

claude-remote-approver enable
# Hook enabled.

This reads the existing configuration and re-registers the hook in Claude Code's settings. You must have run setup at least once before using this command.

disable

Temporarily disable the hook without removing your configuration.

claude-remote-approver disable
# Hook disabled. Run 'claude-remote-approver enable' to re-enable.

Your topic and settings are preserved. Use enable to re-activate.

uninstall

Remove the hook and delete all configuration.

claude-remote-approver uninstall
# Uninstalled. Hook removed and configuration deleted.

This removes the hook entry from Claude Code's settings.json and deletes ~/.claude-remote-approver.json. To use the tool again, run setup.

hook

Internal command. Claude Code calls this automatically via the registered hook. It reads a JSON payload from stdin and writes a decision to stdout. You do not need to run this manually.

Flags

--help, -h       Show usage information
--version, -v    Print version number

Configuration

Config file location: ~/.claude-remote-approver.json

{
  "topic": "cra-a1b2c3d4e5f67890abcdef1234567890",
  "ntfyServer": "https://ntfy.sh",
  "timeout": 120,
  "planTimeout": 300,
  "autoApprove": [],
  "autoDeny": []
}

| Field | Type | Default | Description | |---|---|---|---| | topic | string | "" | Your unique ntfy topic. Generated by setup. | | ntfyServer | string | "https://ntfy.sh" | The ntfy server URL. Change this if you self-host. | | timeout | number | 120 | Seconds to wait for a response before falling back to CLI. | | planTimeout | number | 300 | Seconds to wait for ExitPlanMode (plan approval) responses. Plan reviews need more reading time. | | autoApprove | string[] | [] | Reserved for future use. | | autoDeny | string[] | [] | Reserved for future use. | | ntfyUsername | string | "" | Username for ntfy Basic Auth. Set this if your ntfy server requires authentication. | | ntfyPassword | string | "" | Password for ntfy Basic Auth. Set this if your ntfy server requires authentication. |

Using a self-hosted ntfy server

Edit ~/.claude-remote-approver.json and set ntfyServer to your server URL:

{
  "ntfyServer": "https://ntfy.example.com"
}

Then subscribe to the topic on your self-hosted server in the ntfy app.

Using authenticated topics

If you are running a self-hosted ntfy server that requires authentication, you can configure Basic Auth credentials. If you are using the public ntfy.sh server, you do not need this — select "n" when prompted during setup.

Option 1: Interactive setup

claude-remote-approver setup
# ... after topic generation, you will be asked:
# Use authenticated topics? (only for self-hosted ntfy servers) (y/n): y
# Username: myuser
# Password: mypassword

Option 2: Edit ~/.claude-remote-approver.json

{
  "ntfyServer": "https://ntfy.example.com",
  "ntfyUsername": "myuser",
  "ntfyPassword": "mypassword"
}

Option 3: Environment variables

export NTFY_USERNAME=myuser
export NTFY_PASSWORD=mypassword

Environment variables take priority over settings.json values. Credentials are included as Authorization: Basic <base64> headers in all requests to the ntfy server, including action button callbacks.

How ntfy.sh works

ntfy.sh is a simple HTTP-based pub-sub notification service. Any client can publish a message to a topic by sending a POST request, and any client subscribed to that topic receives the message as a push notification.

claude-remote-approver uses two topics:

  • <topic> -- The hook publishes permission requests here. Your phone receives these as notifications with action buttons.
  • <topic>-response -- When you tap Approve or Deny, the ntfy app sends an HTTP POST to this topic. The hook subscribes to it via SSE (server-sent events) and reads your decision.

No account is required. Topics are identified by name only, which is why the generated topic contains 128 bits of randomness.

For more details, see the ntfy documentation.

Security

Topic entropy

The topic name is generated using crypto.randomBytes(16), producing 128 bits of randomness (32 hex characters). This makes the topic effectively unguessable.

File permissions

The config file (~/.claude-remote-approver.json) is written with mode 0600 -- only the file owner can read or write it. This prevents other users on the system from reading your topic name.

Self-hosting recommendation

The public ntfy.sh server is convenient but means your permission request details (tool names, commands, file paths) pass through a third-party server. For sensitive work, consider self-hosting ntfy and setting ntfyServer in your config to your own server.

Timeout behavior

If no response is received within the configured timeout (default: 120 seconds), the hook falls back to the CLI prompt (ask), so you can still respond at your terminal.

Disclaimer

Use at your own risk. This tool automates permission control for Claude Code. Misuse or misconfiguration may result in unintended code execution, file modification, or data loss.

The authors are not responsible for any damages or losses arising from the use of this tool, including but not limited to:

  • Accidental approval of dangerous commands (e.g., mistapping Approve on your phone)
  • Unintended CLI fallback when away from terminal (e.g., timeout, network issues)
  • Security breaches if the topic name is compromised

Not a substitute for careful review. The push notification shows the tool name and a brief summary, but not the full context of what Claude Code is doing. Always review what you are approving.

This software is provided "AS IS" without warranty of any kind, as stated in the MIT License.

Requirements

License

MIT