@agentapprove/pi

Agent Approve extension for Pi - approve or deny AI agent tool calls from your iPhone and Apple Watch

Packages

Package details

extension

Install @agentapprove/pi from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@agentapprove/pi
Package
@agentapprove/pi
Version
0.1.15
Published
Nov 12, 2026
Downloads
4,421/mo · 1,657/wk
Author
jbeno
License
SEE LICENSE IN LICENSE
Types
extension
Size
112.6 KB
Dependencies
0 dependencies · 0 peers
Pi manifest JSON
{
  "extensions": [
    "./dist/index.js"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

@agentapprove/pi

Agent Approve extension for Pi. Approve or deny Pi tool calls from your iPhone or Apple Watch. Get the app on the App Store.

Install

Run the Agent Approve installer and select Pi:

npx agentapprove

If Agent Approve is already paired on this machine, you can install the Pi package directly:

pi install npm:@agentapprove/pi@0.1.15

What It Covers

  • tool_call blocking approval
  • native tool completion events
  • MCP tool approvals and completion events grouped by MCP server
  • prompt, response, thinking, compaction, stop, and session-end events
  • optional follow-up input from Agent Approve when Pi finishes a turn

Runtime Mapping

Pi event Agent Approve event
session_start session_start
before_agent_start user_prompt
tool_call blocking approval request
tool_result command_executed, tool_complete, or mcp_complete
tool_execution_end completion fallback if tool_result was not observed
message_end thought, response, or plan_generated
session_compact context_compact
agent_end stop, with optional follow-up input
session_shutdown session_end

Approval requests include:

{
  agent: "pi",
  hookType: "tool_call",
  toolName: string,
  toolType: string,
  toolInput?: object,
  command?: string,
  conversationId: string,
  generationId?: string,
  toolCallId?: string,
  model?: string,
  mcpServer?: RuntimeMcpServer,
  metadata: {
    sessionId: string,
    piEventName: "tool_call",
    cwd?: string,
    workspaceRoots?: string[],
    turnId?: string,
    messageId?: string,
    provider?: string,
    model?: string,
    toolCallId?: string
  },
  timestamp: number
}

Events use the same Agent Approve event envelope with agent: "pi", eventType, conversationId, optional generationId, optional tool metadata, optional mcpServer, optional sessionStats, metadata, and timestamp.

Configuration

The extension reads the standard Agent Approve config from ~/.agentapprove/env, the file npx agentapprove writes when you pair.

Setting Default Description
AGENTAPPROVE_API https://api.agentapprove.com Agent Approve API URL
AGENTAPPROVE_API_VERSION v001 API version
AGENTAPPROVE_TOKEN keychain or config token CLI API token
AGENTAPPROVE_PRIVACY full minimal, summary, or full
AGENTAPPROVE_FAIL_BEHAVIOR ask allow, deny, or ask if Agent Approve is unreachable (see below)
AGENTAPPROVE_AGENT_NAME Pi Display name for this Pi agent
AGENTAPPROVE_PI_NAME Pi Legacy Pi-specific display name fallback

The privacy tier controls stored history only. Approval requests always carry the full command and tool input (encrypted when E2E is on), so your policy and your phone see what will actually run.

If Agent Approve cannot be reached

AGENTAPPROVE_FAIL_BEHAVIOR applies only when Agent Approve cannot be reached: the connection cannot be made (DNS, connection refused, connect timeout, TLS), or the server answers with a 5xx error that carries no decision. Nothing else counts as unreachable.

  • allow: the action runs without approval.
  • deny: the action is blocked.
  • ask: the action is blocked, it is not run. Pi has no approval prompt of its own at this point, so the tool call is refused with "Agent Approve could not be reached, so this action was not approved. Nothing was run. Try again shortly."

Blocked whatever this setting is:

  • any other answer from the server: a response that is not an explicit approval, an approval on any status other than 200, a non-200 response that carries a decision, every 401, 402 or 403, and any other status that is not a 5xx (a 400 or a 404, for example: the request was not evaluated);
  • an action too large for Agent Approve to evaluate (a request over 256 KiB is refused before it is sent), or one the plugin cannot serialise;
  • approvals that are still rate limited after one short retry;
  • a request that got no answer once the connection was made: the upload failed, the connection was reset, or no decision arrived in time;
  • a request that cannot be sent safely: end-to-end encryption is required but its key is missing or is not 64 hex characters, the API URL is not a valid URL or is neither HTTPS nor this machine, or the config file is broken.

With no token configured the plugin cannot ask anyone, and this setting decides: allow runs the action, ask and deny block it.

Environment variables

~/.agentapprove/env is written by npx agentapprove when you pair, and it is authoritative. AGENTAPPROVE_* variables in the process environment do not override it. They can only tighten it:

  • AGENTAPPROVE_FAIL_BEHAVIOR can make the fail behaviour stricter (allow, then ask, then deny), never looser.
  • AGENTAPPROVE_E2E_ENABLED=true can turn encryption on. false cannot turn it off, with or without a config file: only ~/.agentapprove/env can.
  • AGENTAPPROVE_PRIVACY can reduce what event history keeps (full, then summary, then minimal), never increase it.
  • AGENTAPPROVE_TIMEOUT can lengthen the approval wait, never shorten it. The value is always kept between 30 and 300 seconds.
  • AGENTAPPROVE_TOKEN, AGENTAPPROVE_API and AGENTAPPROVE_API_VERSION are ignored when the file holds a token. That includes an AGENTAPPROVE_API that points at this machine. To use a local API, pair against it (AGENTAPPROVE_API=http://localhost:3000 npx agentapprove): the installer writes that URL into the file.

An ignored variable is reported once.

With no ~/.agentapprove/env at all, the environment supplies the token, the API URL and the settings. There is then no file to say that encryption is off, so the plugin requires an E2E key at ~/.agentapprove/e2e-key. Without that key no approval request is sent and every tool call is blocked; events are sent without their content.

A line in the file that cannot be parsed is not skipped: one containing $ or ;, for example, or one that names a setting but is not written as KEY=value or export KEY=value at the start of the line. The plugin takes the stricter reading of that setting, and a token or API line that cannot be parsed blocks approvals until you run npx agentapprove.

Config sync is separate from the environment: settings you change in the Agent Approve app are written to this file by the plugin, and the server's account settings are authoritative for it. A sync can loosen a setting as well as tighten it. It never writes the token or the API URL. A sync cannot lift a content hold: while end-to-end encryption is required and its key is missing or invalid, "turn encryption off" is ignored and approvals stay blocked until npx agentapprove restores the key.

Security

Requests are signed with Agent Approve HMAC headers and include the SHA256 hash of the installed package bundle. The API allowlists published bundle hashes by hook version.