@agentapprove/pi
Agent Approve extension for Pi - approve or deny AI agent tool calls from your iPhone and Apple Watch
Package details
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_callblocking 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_BEHAVIORcan make the fail behaviour stricter (allow, thenask, thendeny), never looser.AGENTAPPROVE_E2E_ENABLED=truecan turn encryption on.falsecannot turn it off, with or without a config file: only~/.agentapprove/envcan.AGENTAPPROVE_PRIVACYcan reduce what event history keeps (full, thensummary, thenminimal), never increase it.AGENTAPPROVE_TIMEOUTcan lengthen the approval wait, never shorten it. The value is always kept between 30 and 300 seconds.AGENTAPPROVE_TOKEN,AGENTAPPROVE_APIandAGENTAPPROVE_API_VERSIONare ignored when the file holds a token. That includes anAGENTAPPROVE_APIthat 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.