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

acp-probe

v0.0.1

Published

Probe any ACP-compatible agent for its capabilities (models, modes, configOptions, prompt capabilities, auth methods, MCP transports). No real prompt required; no token cost.

Readme

acp-probe

Probe any Agent Client Protocol agent for its capabilities — models, modes, configOptions, prompt capabilities, auth methods, MCP transports — without sending a real prompt.

npm

[!WARNING] Alpha software. This package is in active development. The public API may change between minor versions without notice until 1.0.0. Pin exact versions; expect rough edges.

What it does

Given an ACP-compatible agent (built-in like claude / codex / gemini or any custom adapter you can spawn), acp-probe performs the ACP initialize + session/new handshake, then optionally pings session/set_config_option to test whether the agent implements that method — agents like gemini-cli that don't implement it respond with the standard JSON-RPC "method not found" error, which the probe catches to flip supportsConfigOption: false in the result. Finally the agent is torn down. The result is a typed, schema-stable AgentProbeResult you can feed into a settings UI, picker, or downstream AcpRuntimeOptions call.

No LLM tokens are consumed. session/new is free; we never call session/prompt.

Install

bun add acp-probe
# or
npm install acp-probe

The only hard dependency is @agentclientprotocol/sdk. acpx is an optional peer — installed, it lets you use the built-in { agent: 'claude' } shorthand; absent, you pass { command } or { argv } yourself.

Quickstart

import { probeAgent } from 'acp-probe'

// Custom ACP command — the canonical entry point. Zero acpx
// involvement; works with any agent you can spawn.
const result = await probeAgent({
  command: 'my-acp-agent --stdio',
})

console.log(result.models)         // ProbedModel[]
console.log(result.modes)          // ProbedMode[]
console.log(result.configOptions)  // ProbedConfigOption[]
console.log(result.reasoning)      // { configId, values, defaultValue } | null
console.log(result.capabilities.promptCapabilities)
//        => { image: boolean, audio: boolean, embeddedContext: boolean }

// Built-in shorthand — requires acpx to be installed.
const claude = await probeAgent({ agent: 'claude' })

Result shape

interface AgentProbeResult {
  agent: {
    id: string | null
    command: string
    argv: readonly string[]
    probedAt: string  // ISO timestamp
    durationMs: number
  }
  protocolVersion: number
  agentInfo: { name; title?; version? } | null
  capabilities: {
    loadSession: boolean
    promptCapabilities: { image; audio; embeddedContext }
    mcpCapabilities: { http; sse; meta? }
    sessionCapabilities: { close; list; resume; fork; additionalDirectories }
    experimental?: { auth; nes; providers; positionEncoding }
  }
  authMethods: AuthMethod[]
  models: Array<{ id; name?; description? }>
  modes: Array<{ id; name?; description? }>
  configOptions: ProbedConfigOption[]
  /** Derived pointer to the configOption with category='thought_level'. */
  reasoning: { configId; values; defaultValue? } | null
  /**
   * True iff the agent implements `session/set_config_option`. False
   * when the agent responds with JSON-RPC "method not found" to a
   * no-op set call — that's how gemini-cli (and similar adapters that
   * skip configOptions support) signal the method is unimplemented.
   */
  supportsConfigOption: boolean
  error?: ProbeError
  /** Verbatim init + session/new responses for callers that need _meta. */
  raw: { initialize; newSession }
}

Errors

Two distinct error surfaces:

  • AgentResolveError (thrown sync): caller passed { agent: <id> } but acpx isn't installed / doesn't recognise the id. Includes resolveCause: 'acpx_not_installed' | 'acpx_incompatible' | 'unknown_agent'.
  • AgentProbeResult.error (returned, not thrown): probe ran but couldn't complete cleanly. Includes code: 'spawn_failed' | 'initialize_timeout' | 'session_new_timeout' | 'auth_required' | 'protocol_mismatch' | 'agent_crashed' | 'unknown' plus stderr for debugging.

Options

| option | type | default | notes | |---|---|---|---| | agent | string | — | Built-in agent id (requires acpx). | | command | string | — | Raw command, shell-split. | | argv | readonly string[] | — | Pre-split argv (takes precedence over command). | | cwd | string | process.cwd() | Working dir for the spawned agent. | | env | Record<string, string> | {} | Merged into the spawned process's env. | | authPolicy | 'skip' \| 'fail' | 'skip' | 'skip': record authMethods and continue. 'fail': don't call session/new. | | timeoutMs | number | 30_000 | Hard cap on the full probe lifecycle. |

Exactly one of agent, command, or argv is required.

Captured fixtures (2026-05-14)

The repo ships recorded initialize + session/new responses for claude / codex / gemini under test/fixtures/. They power the unit test suite and document the per-agent capability matrix at the time of capture.

End-to-end probes against real agents

An opt-in suite under test/e2e/ runs the probe against the locally-installed claude / codex / gemini CLIs to catch upstream adapter drift the fixture tests can't see. Each agent is probed twice — once via { agent: <id> } (acpx resolution) and once via { command: <hardcoded> } (the no-acpx path) — and the two results are asserted to be structurally identical.

# Run all three agents
bun run test:e2e

# Or pick one
PROBE_E2E=claude bun test test/e2e

Not run in CI. Zero LLM tokens consumed. See the suite's README for per-agent setup notes.

Relationship to acpx

acp-probe is upstream of acpx in the data flow: probe → capabilities → feed AcpRuntimeOptions. The probe doesn't depend on acpx at runtime unless you use the { agent: <id> } shorthand, in which case it lazy-imports acpx/runtime to resolve via acpx's built-in agent registry. Custom-agent users never touch acpx.

License

MIT — see LICENSE.