Hooks
Agent Notifier ships one canonical Python hook runner for AI coding assistants: hooks/agent_notifier_hook.py. The runner turns lifecycle events into POST /v1/messages requests and can turn permission hooks into blocking POST /v1/approvals requests.
For agentic development, this is the core harness: while the agent works, hooks send progress, failures, approvals, links, explicit uploads, and completion states to your phone.
Flow
Agent event → uv run --script hooks/agent_notifier_hook.py → POST /api/v1/messages → APNs push → iOS feed
Permission event → uv run --script hooks/agent_notifier_hook.py → POST /api/v1/approvals → phone decision → rendered allow/deny JSON on stdout
Supported clients
- GitHub Copilot CLI workspace hooks
- Claude Code hooks
- CI/shell automation that invokes
hooks/agent_notifier_hook.pywith hook JSON - Direct API callers using
POST /api/v1/messages
One-click project install
Create an account API key in https://notifier.aicrew.in/app, choose a project label, then run this from the target repo:
export AGENT_NOTIFIER_API_KEY="an_key_REPLACE_WITH_YOUR_KEY"
export AGENT_NOTIFIER_PROJECT="my-repo"
curl -fsSL https://notifier.aicrew.in/install.sh | bash
The hosted installer downloads hooks/create-hook.sh, hooks/agent_notifier_hook.py, and scripts/lib/url-guard.sh from the public repository, then scaffolds project-local Copilot and Claude hook config. It writes the key and project name to .env.local, creates .env.local.agent-notifier.example, and appends a short Agent Notifier instruction block to CLAUDE.md when one is not already present.
Share https://notifier.aicrew.in/skill.md with an agent when you want the agent to perform the install for you. The skill instructs agents to ask for the API key/project name, keep secrets local, and notify at task start, major milestones, blockers, and completion.
Environment variables
| Variable | Required | Purpose |
|---|---|---|
AGENT_NOTIFIER_API_KEY | Yes | Account-scoped API key for X-API-Key; legacy project-scoped keys still work but bind all sends to that one project. |
AGENT_NOTIFIER_URL | No | Site base URL. Defaults to https://notifier.aicrew.in. |
AGENT_NOTIFIER_API_PATH | No | API path prefix. Defaults to /api/v1. |
AGENT_NOTIFIER_PROJECT | No | Project label for grouping. |
AGENT_NOTIFIER_SESSION | No | Local human-readable session label appended to text. |
AGENT_NOTIFIER_API_SESSION_ID | No | Existing server-side Agent Notifier session UUID. |
AGENT_NOTIFIER_PROGRESS | No | Default progress value from 0.0 to 1.0. |
AGENT_NOTIFIER_IMAGE_URL | No | Default image_url. |
AGENT_NOTIFIER_MEDIA_FILE_PATH, AGENT_NOTIFIER_MEDIA_FILE_PATHS | No | Explicit local file path(s) to upload to /v1/media before sending the message. Uploads become a structured attachment; image uploads also populate legacy image_url for compatibility. |
AGENT_NOTIFIER_UPLOAD_FILE_PATH, AGENT_NOTIFIER_UPLOAD_FILE_PATHS | No | Alias for explicit media uploads. |
AGENT_NOTIFIER_ATTACHMENT_PATH, AGENT_NOTIFIER_ATTACHMENT_PATHS | No | Alias for explicit media uploads. |
AGENT_NOTIFIER_BUTTONS_JSON | No | JSON array of up to 4 button labels. |
AGENT_NOTIFIER_TTL | No | Default TTL seconds. |
AGENT_NOTIFIER_DEVICE | No | Target device name. |
AGENT_NOTIFIER_HOOK_INCLUDE_DETAILS | No | Sensitive opt-in for bounded, redacted prompt/command/tool excerpts. Default is summary-only. |
AGENT_NOTIFIER_APPROVAL_MODE | No | Set to permission for permission-only blocking approvals or block/always to require approval for every pre-tool event. Default is off. |
AGENT_NOTIFIER_APPROVAL_TIMEOUT_SECONDS | No | Phone decision wait for approval mode. Defaults to 300 seconds and is capped at 600. |
AGENT_NOTIFIER_APPROVAL_RESPONSE_FORMAT | No | Override the renderer; defaults from hook source/event, such as copilot_cli.permissionrequest or claude_code.pretooluse. |
AGENT_NOTIFIER_METADATA_JSON | No | Safe JSON object of string metadata merged into the metadata API field. |
AGENT_NOTIFIER_HOOK_SOURCE should use stable values such as github.copilot, claude.code, or cursor. If it is omitted, the runner infers the source from AGENT_NOTIFIER_HOOK_PATH (.github/..., .claude/..., or .cursor/...) so clients can show a friendly GitHub Copilot, Claude Code, or Cursor chip.
Blocking permission approvals
Set AGENT_NOTIFIER_APPROVAL_MODE=permission on permission-capable hooks (PermissionRequest, permission-style Notification, and Claude/Cursor PreToolUse). The runner sends /v1/approvals with wait=block, default decisions Allow and Deny, and prints the server-rendered response_payload to stdout so the agent can continue or deny the operation.
If the API key is missing, the network is unavailable, or approval mode cannot reach the backend, the runner fails open by printing an allow payload in the selected response format and logging the failure category locally. This keeps tools from deadlocking when a notification service is down.
Direct Python runner usage
printf '%s\n' '{"cwd":"/path/to/repo","tool_name":"Bash","tool_input":{"command":"go test ./..."}}' \
| AGENT_NOTIFIER_HOOK_EVENT=PreToolUse \
AGENT_NOTIFIER_HOOK_SOURCE=github.copilot \
AGENT_NOTIFIER_HOOK_PATH=.github/hooks/hooks.json \
uv run --script ./hooks/agent_notifier_hook.py >/dev/null || true
Event mapping guidance
| Event | Message type | Suggested priority |
|---|---|---|
| Session started | session_start | 0 |
| Session ended successfully | session_end | 0 |
| Tool or command failed | alert | 1 |
| Tests passed | alert | 0 |
| Tests failed | alert | 1 |
| File modified / progress update | progress | -1 |
| Agent needs input | alert | 1 |
Substance fields and structured metadata
Hook notifications send human-readable text for backwards compatibility, but current clients should prefer the top-level substance fields for primary rendering:
| Field | Purpose |
|---|---|
event | Raw lifecycle event, such as UserPromptSubmit, PreToolUse, PostToolUse, SubagentStart, or SessionEnd. |
tool_name | Tool name for tool events. |
command | Redacted command/tool input for UI display when detail mode is enabled. |
prompt | Redacted prompt text for UI display when detail mode is enabled. |
file_paths | Up to 12 referenced files. |
parent_id | Prior notification ID for collapsible parent/subagent rendering. |
subagent_id | Opaque subagent/thread label. |
status | Short status word such as running, success, or failure. |
metadata remains the safe auxiliary/back-compat contract. The stable schema marker is agent_notifier_schema=hook.v1.
file_paths is metadata-only. The canonical runner never uploads ordinary file_path tool parameters because those often point at source files the agent merely inspected or edited. To attach bytes, use explicit JSON fields (media_file_path, media_file_paths, upload_file_path, attachment_path) or the explicit environment variables above.
| Key group | Fields |
|---|---|
| Source | hook_source, hook_scope, hook_path, hook_script |
| Event and status | hook_event, hook_event_type, hook_tool, hook_subject_hash, hook_status, hook_error_present, hook_exit_code, hook_duration_ms |
| Project/session | hook_project, hook_project_id, hook_cwd, hook_session_id, hook_session_hash, hook_api_session_id |
| Files and tool params | hook_file_path, hook_file_path_count, hook_tool_input_keys |
| Prompt | hook_prompt_length, hook_prompt_hash, optional hook_prompt_excerpt |
| Command | hook_command_length, hook_command_hash, optional hook_command_excerpt |
| Tool input | hook_tool_input_length, hook_tool_input_hash, optional hook_tool_input_excerpt |
| Tool response/output | hook_tool_response_length, hook_tool_response_hash, optional hook_tool_response_excerpt |
| Thinking/reasoning | hook_thinking_length, hook_thinking_hash, optional hook_thinking_excerpt |
| Error | hook_error_length, hook_error_hash, optional hook_error_excerpt |
| Media upload | hook_media_upload_count, hook_media_upload_kind, hook_media_upload_error_count, hook_media_upload_error |
Excerpt fields and top-level prompt/command substance exist only when a hook explicitly opts into details. They are bounded, locally redacted, and omitted from local proof logs unless the operator intentionally records redacted detail JSON.
Known hook_event_type values include session_start, session_end, user_prompt, tool_start, tool_success, tool_failure, test_passed, test_failed, file_modified, todo_update, subagent_start, subagent_stop, context_compaction, approval_needed, error, hook_event, and field_validation. Clients should treat unknown values as ordinary notifications instead of hiding or dropping them.
Safe logging
Proof logs should include request status, titles, and notification IDs only. They must not include API keys, bearer tokens, passwords, or raw secret-bearing request headers.