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

@pushary/claude-agent-sdk

v0.3.0

Published

Phone approvals for Claude Agent SDK agents. Your agent asks, your user taps Approve or Deny.

Readme

@pushary/claude-agent-sdk

Phone approvals for Claude Agent SDK agents. Your agent asks, your user taps Approve or Deny.

What you need

  • A Pushary Partner plan, from $99 a month.
  • An API key from Partner onboarding.
  • Your users install the free Pushary app (iPhone, Android) and open your connect link once. They never sign up or pay.

Install

npm i @pushary/claude-agent-sdk @anthropic-ai/claude-agent-sdk
export PUSHARY_API_KEY=pk_xxx.sk_xxx

Gate every tool call on a person

import { query } from '@anthropic-ai/claude-agent-sdk'
import { pusharyCanUseTool } from '@pushary/claude-agent-sdk'

for await (const message of query({
  prompt: 'Refund order 1234',
  options: { canUseTool: pusharyCanUseTool({ externalId: user.id }) },
})) {
  if (message.type === 'result') console.log(message.subtype)
}

When the agent wants to run a tool that needs permission, the SDK calls canUseTool. Pushary sends the question to that user's phone and waits. Approve runs the tool with its input unchanged. Deny, or nobody answering, returns a denial the model can read, and the tool does not run. Cancelling the run stops the wait and denies at once.

Tools you already allow with allowedTools never reach canUseTool, so the person only sees the calls that need them. See the SDK's own permissions guide.

Connect a user's phone once

import { connect } from '@pushary/claude-agent-sdk'

const { universalLink } = await connect({ apiKey: process.env.PUSHARY_API_KEY! }, user.id)

Show universalLink to the signed-in user as a button or QR code. They open it on their phone once.

Who answers

externalId is your own id for the user. Pass a string to bind every call to one person, or a function to pick one per call. The function also runs for AskUserQuestion:

pusharyCanUseTool({ externalId: (toolUse) => ownerOf(toolUse.toolName) })

Never take the person from the tool input. The model writes the tool input, so a prompt injection could send the approval to someone else.

Clarifying questions

When Claude calls AskUserQuestion, the same canUseTool puts each question on the person's phone as a choice between Claude's options, with each option's description, one question at a time, and returns their picks as the answers. Each question waits up to timeoutMs. If a question goes unanswered, it is taken off the phone before the call is denied, and Claude is told not to assume an answer. If Pushary cannot take it back within five seconds, the reason goes to console.warn and the question expires on its own.

The phone takes one choice per question, so a multi-select question says "(choose one)" and comes back with the one option the person picked. Your rules are not asked about questions, including a rule that names AskUserQuestion, because a question is not an action. A question too long for the phone is denied, and Claude is told to ask it in plain text instead.

Site rules are off unless you turn them on

Claude's tools have the same names in your own Claude Code: Bash, Read, Write, WebFetch. A rule you wrote for your own Claude Code sessions would also answer your users' calls, so by default every gated call goes to a person.

Set policy: true to ask your site's rules first. A rule can then allow a call without paging anyone, or deny it outright. Only turn it on for a site whose rules you wrote for this agent. Rules need a server key from Settings > API keys. With the key from onboarding, policy: true has no effect and every gated call still goes to a person.

Options

| Option | What it does | |---|---| | externalId | The person who answers. Required. | | question | Builds the approval text the person sees. Defaults to the tool name and its input. Not used for AskUserQuestion. | | sessionId | Groups one session's calls, so a replayed turn does not ask twice. | | timeoutMs | How long to wait for an answer before denying. Applies to each clarifying question in turn. | | expiresInSeconds | How long the question stays answerable. | | requireReachable | Deny at once when the person has no connected phone. | | policy | Ask your site's rules before a person. Defaults to false. | | agentName | Shown on the approval so the person knows which agent is asking. | | apiKey | Defaults to PUSHARY_API_KEY. |

License

MIT