Agent Host Protocol client — CLI and Node.js library for managing AHP server connections, sessions, and agent interactions.
ahpx is a client for the Agent Host Protocol (AHP) — a WebSocket-based JSON-RPC protocol for managing AI agent sessions. Use ahpx to connect to AHP servers, create sessions, send prompts, stream responses, and handle tool confirmations, either from the command line or programmatically as a Node.js library.
- 🔌 Connect to AHP servers via WebSocket with saved connection profiles
- 💬 Interactive and one-shot prompting with streaming output
- 📡 Multi-session management — concurrent sessions on a single connection
- 🔄 Event forwarding — webhook and WebSocket targets for dashboards and pipelines
- 🏗️ Fleet management — health checks, status monitoring, and server tagging
- 💾 Session persistence — resume sessions, export/import history
- 📦 Use as CLI or Node.js library with full TypeScript types
- 🔒 Configurable permission modes — approve-all, approve-reads, deny-all, autopilot
- 🔑 Automatic auth — token resolution from env vars, CLI, or interactive prompt
- 🌐 Dev Tunnel support — connect to remote agent hosts via Dev Tunnels
- ⚙️ Session config — agent-specific settings (auto-approve, isolation, mode)
- 🧩 Customizations — auto-discovered agent and skill files from
.github/
npm install -g @tylerl0706/ahpx
# Add a server
ahpx server add local --url ws://localhost:8082 --default
# Start prompting
ahpx "what files are in this directory?"Or use exec for one-shot tasks that create and dispose of a session automatically:
ahpx exec "summarize this repo"| Command | Description |
|---|---|
ahpx <text> |
Send a prompt (implicit — any text that isn't a command) |
ahpx prompt <text> |
Send a prompt to an existing session |
ahpx exec <text> |
One-shot: create a temp session, prompt, dispose |
ahpx cancel |
Cancel the active turn in a session |
Prompt options: -s <server>, -n <session-name>, -S <session-id>, -f <file>, --cwd <dir>, --config <key=value> (repeatable), --approve-all, --approve-reads, --deny-all, --idle-timeout <seconds>, --tag <key=value>, --forward-webhook <url>, --forward-ws <url>, --forward-filter <types>, --forward-headers <json>
Use -S <session-id> to target a session by its ID instead of name — useful for scripting and automation.
exec also accepts: -p <provider>, -m <model>, --config <key=value>
| Command | Description |
|---|---|
ahpx server add <name> --url <url> |
Save a named connection profile |
ahpx server list |
List saved connections |
ahpx server remove <name> |
Remove a saved connection |
ahpx server test <target> |
Test connectivity to a server |
ahpx server status |
Health check all saved servers |
ahpx server health <name> |
Detailed health check for a single server |
server add options: --token <token>, --default, --tag <tag> (repeatable), --tunnel <tunnel-id>
Connect to remote AHP agent hosts via Dev Tunnels. Discovers tunnels tagged with protocolv5. Requires GITHUB_TOKEN, GH_TOKEN, or gh auth token.
| Command | Description |
|---|---|
ahpx tunnel list |
List remote agent hosts |
ahpx tunnel connect <tunnel-id> |
Connect to a remote agent host |
# Save a tunnel as a named server connection
ahpx server add my-remote --tunnel <tunnel-id>
# Use the remote server for sessions
ahpx session new -s my-remote -n remote-session --cwd C:/Users/me/project
ahpx prompt -s my-remote -n remote-session "fix the bug"| Command | Description |
|---|---|
ahpx session new |
Create a new agent session |
ahpx session list |
List sessions (default: active only) |
ahpx session show [id] |
Show session details |
ahpx session close [id] |
Close a session (keeps record for history) |
ahpx session history [id] |
Show turn history for a session |
ahpx session active |
Show all active sessions on the server (live query) |
ahpx session config |
View session configuration |
ahpx session config set <key> <value> |
Set a mutable config property |
ahpx session customization list |
List customizations on a session |
ahpx session customization toggle <uri> |
Toggle a customization on/off |
ahpx session export <id> |
Export a session record to JSON |
ahpx session import <file> |
Import a session record from JSON |
session new options: -s <server>, -p <provider>, -m <model>, -n <name>, --cwd <dir>, -t <timeout>, --config <key=value> (repeatable), --no-customizations
Set agent-specific configuration at session creation or modify it on an active session.
ahpx session new -n my-session --cwd /path/to/repo --config autoApprove=autopilot --config isolation=worktree
ahpx session config -n my-session # view config
ahpx session config set autoApprove autopilot -n my-session # update configAvailable config keys depend on the agent. For copilotcli: autoApprove (default/autoApprove/autopilot), isolation (folder/worktree), mode (interactive/plan), branch, permissions.
ahpx automatically discovers .github/agents/*.md and .github/skills/*/SKILL.md files in the workspace and loads them into the agent session. Use --no-customizations to skip discovery.
ahpx session customization list -n my-session
ahpx session customization toggle <uri> -n my-session| Command | Description |
|---|---|
ahpx config show |
Print resolved config with source annotations |
ahpx config init |
Create ~/.ahpx/config.json with defaults |
| Command | Description |
|---|---|
ahpx connect [target] |
Connect to a server and print server info |
ahpx agents |
List available agents and models on the server |
ahpx content <uri> |
Fetch content by URI from the server |
ahpx model <model-id> |
Switch the model for a session |
ahpx watch [id] |
Attach to a session as an observer and stream activity |
ahpx browse [directory] |
Browse server filesystem |
ahpx completions bash|zsh|fish |
Generate shell completion scripts |
| Flag | Description |
|---|---|
--format <format> |
Output format: text, json, or quiet (default: text) |
--json-strict |
Suppress non-JSON stderr output (use with --format json) |
-v, --verbose |
Enable debug logging to stderr |
--version |
Print version |
--help |
Show help |
ahpx exports a full TypeScript API. Install it as a dependency:
npm install @tylerl0706/ahpximport { AhpClient } from '@tylerl0706/ahpx';
const client = new AhpClient({ initialSubscriptions: ['ahp-root://'] });
const result = await client.connect('ws://localhost:8082');
console.log('Agents:', result.agents);
console.log('Connected:', client.connected);
await client.disconnect();import { AhpClient, ActionType } from '@tylerl0706/ahpx';
import { randomUUID } from 'node:crypto';
const client = new AhpClient({ initialSubscriptions: ['ahp-root://'] });
await client.connect('ws://localhost:8082');
// Create a session
const sessionUri = `copilot:/${randomUUID()}`;
await client.createSession(sessionUri, { provider: 'copilot' });
await client.subscribe(sessionUri);
// Listen for streaming events
client.on('action', (envelope) => {
const { action } = envelope;
switch (action.type) {
case ActionType.SessionDelta:
process.stdout.write(action.content);
break;
case ActionType.SessionTurnComplete:
console.log('\n--- Turn complete ---');
break;
case ActionType.SessionError:
console.error('Error:', action.error);
break;
}
});
// Send a prompt
client.dispatchAction({
type: ActionType.SessionTurnStarted,
session: sessionUri,
turnId: randomUUID(),
userMessage: { text: 'Fix the failing test' },
});import { AhpClient, AuthHandler } from '@tylerl0706/ahpx';
const client = new AhpClient();
const auth = new AuthHandler(client, { token: process.env.MY_TOKEN });
client.on('notification', async (notification) => {
if (notification.type === 'authRequired') {
await auth.handleAuthRequired(notification.resource);
}
});
await client.connect('ws://localhost:8082');const client = new AhpClient();
await client.connect('ws://localhost:8082');
// Root state (agents, active sessions)
console.log('Agents:', client.state.root.agents);
// Session state (after subscribing)
const session = client.state.getSession('copilot:/my-session');
console.log('Title:', session?.summary?.title);
console.log('Active turn:', session?.activeTurn);import { AhpClient, RpcError, RpcTimeoutError } from '@tylerl0706/ahpx';
const client = new AhpClient();
try {
await client.connect('ws://localhost:8082');
} catch (err) {
if (err instanceof RpcTimeoutError) {
console.error(`Request ${err.method} timed out after ${err.timeoutMs}ms`);
} else if (err instanceof RpcError) {
console.error(`RPC error ${err.code}: ${err.message}`);
}
}SessionHandle— per-session wrapper with scoped event listeners and lifecycle managementConnectionPool— connection reuse across multiple sessions to the same serverWebhookForwarder/WebSocketForwarder— forward NDJSON events to external targetsHealthChecker— fleet-level health monitoring across saved servers
See the exported TypeScript declarations for the full API reference.
ahpx uses semantic exit codes so scripts and automation can react to failures:
| Code | Meaning | Description |
|---|---|---|
0 |
Success | Command completed successfully |
1 |
Runtime error | Unexpected error during execution |
2 |
Usage error | Bad CLI arguments or missing required flags |
3 |
Timeout | Connection or request timed out |
4 |
No session | Session not found — run session new first |
5 |
Permission denied | All permission requests were denied |
130 |
Interrupted | Process was interrupted (Ctrl+C) |
See docs/errors.md for the full error reference.
ahpx uses a layered configuration system. Settings are resolved in order of precedence:
- CLI flags — highest priority (e.g.
--format json) - Project config —
.ahpxrc.jsonin the current directory or git root - Global config —
~/.ahpx/config.json - Defaults — built-in fallback values
# Initialize global config
ahpx config init
# View resolved config with source annotations
ahpx config showahpx resolves auth tokens automatically, checked in order:
- Connection profile token (from
ahpx server add --token) AHPX_TOKENenv varGITHUB_TOKENenv varGH_TOKENenv vargh auth tokenCLI output- Interactive prompt
No explicit login command is needed — just ensure one of the above is available.
When an agent calls a tool, ahpx handles approval based on the tool's confirmation status:
- Server-confirmed tools — show
[auto-approved]and proceed without prompting. - Unconfirmed tools — show
Allow Tool: ...? (y/N):and wait for user input.
Override with flags or session config:
ahpx exec --approve-all "fix the tests" # skip all prompts
ahpx exec --config autoApprove=autopilot "fix the tests" # server-side auto-approval| Document | Description |
|---|---|
| PUBLISHING.md | Publishing setup — OIDC trusted publishers, auto-bump pipeline, first-time config |
| docs/quick-reference.md | One-page command cheat sheet |
| docs/user-guide.md | Comprehensive user guide — CLI reference, SDK API, architecture |
| docs/roadmap.md | v0.2 roadmap with phase details and acceptance criteria |
| docs/errors.md | Error catalog and exit code reference |
| docs/george-integration.md | Integration guide for George agent dispatch |
| docs/protocol-feedback.md | AHP protocol gap analysis and workarounds |
Requires Node.js ≥ 20.
npm install # Install dependencies
npm run build # Build with tsup
npm run dev # Watch mode
npm run typecheck # Type check with tsc
npm run lint # Lint with Biome
npm test # Run tests with VitestAll four quality gates must pass before committing:
npm run typecheck && npm run lint && npm test && npm run buildProject knowledge lives in .github/ so both humans and agents can find it:
.github/skills/ahp-protocol/— AHP protocol fundamentals.github/skills/ahpx-architecture/— Codebase architecture and design.github/agents/team-lead.md— Team lead agent with quality gates and workflow
Read the relevant skill docs before making changes — they'll save you time.
MIT