Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
apexe
Outside-In CLI-to-Agent Bridge — automatically wraps existing CLI tools into governed apcore modules, served via MCP.
What is apexe?
apexe scans any CLI tool on your system (e.g., git, curl, ls, jq), deterministically extracts its command structure, flags, and arguments — then exposes them as governed MCP tools that AI agents can invoke safely.
No LLM required for scanning. No changes to the CLI tools. Zero-config governance.
Key capabilities
- Scan — Three-tier deterministic engine (--help → man pages → shell completions) with 4 built-in parsers (GNU, Click, Cobra, Clap)
- Schema — Generates JSON Schema with type mapping, format hints (
path,uri), defaults, enums, and required fields - Serve — MCP server via apcore-mcp (stdio / streamable-http / SSE) with an Explorer UI, plus an A2A agent server via apcore-a2a. Servers bind localhost by default; transport authentication is available via the apcore library API
- Govern — Behavioral annotations (readonly/destructive/idempotent), flag boosting (
--force→ requires_approval), fail-closed default-deny ACL, a JSONL audit trail of executions and ACL allow/deny decisions (input hashed, log0o600),Module::preview()dry-run for destructive commands - Isolate — every wrapped subprocess runs with the environment scrubbed to a base allowlist (secrets don't leak to tools), no shell (direct argv + injection filtering), output capped at 64 MiB, and a hard timeout that actually kills the process (
kill_on_drop); circuit breaker + retry middleware on by default, optional/metrics+/usage - AI Guidance — Every error includes
ai_guidanceto help agents self-correct; non-zero exit codes return stderr context
Built on the apcore ecosystem
| Crate | Role |
|---|---|
| apcore 0.26 | Module trait, Registry, ACL, ModuleError, Context |
| apcore-toolkit 0.10 | ScannedModule, YAMLWriter, DisplayResolver |
| apcore-mcp 0.17 | MCP server with middleware, auth, Explorer UI |
| apcore-a2a 0.4 | A2A agent server sharing the same governed Executor |
| apcore-cli 0.10 | AuditLogger |
Installation
Prebuilt binary
No Rust toolchain required. Download the archive for your platform from the
Releases page, verify the
checksum, and put the apexe binary on your PATH:
Available targets: x86_64-apple-darwin, aarch64-apple-darwin,
x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu.
From source
Requires Rust 1.75+ and Cargo.
Platform support
apexe scans Unix CLIs. What you get depends on the host:
| Host | Scanning | Curated overlays |
|---|---|---|
| macOS | Full — all four tiers | 21 commands (bsd, apple) |
| Linux | Full — install man-db for tier 2 |
21 commands (gnu) |
| FreeBSD | Full | bsd overlays apply |
| OpenBSD / NetBSD / DragonFly | Full | none — falls back to scanning |
| Other Unix (Solaris, illumos, AIX) | Tiers 1–2 | none |
| Windows | Not supported | none |
The GNU overlays carry no platform condition — they are selected by probing the
binary — so they apply anywhere GNU tools are installed, including WSL and a
macOS box with Homebrew coreutils. The BSD overlays declare macos and
freebsd, which is why the other BSDs fall back to scanning: their tools are
separately evolved code, not the same source, so claiming otherwise would be a
guess.
On Windows apexe runs but produces little. Tier 2 shells out to man and
tier 3 to zsh; both are absent, so both return nothing rather than failing
loudly. Tier 1 still runs --help, but the parsers target Unix conventions
while Windows help is /? output with /X switches. Expect near-empty results,
not an error message. Native Windows support means a PowerShell reflection path
and a /? parser, and is not implemented.
Quick Start
# Scan git — extracts commands, flags, types, annotations
# See what was generated
# Start MCP server (Claude Desktop / Cursor)
# Or HTTP with browser-based tool explorer
Claude Desktop integration
# Copy output to ~/Library/Application Support/Claude/claude_desktop_config.json
# Restart Claude Desktop — git commands appear as MCP tools
Cursor integration
# Add to Cursor's MCP settings
Commands
apexe scan <TOOLS>...
Scan CLI tools and generate binding files + ACL rules.
Tool variants and overlays
A command name does not identify a program: macOS /bin/ls is BSD, Linux
/usr/bin/ls is GNU coreutils, Alpine is BusyBox, and Homebrew coreutils puts
GNU ls on a macOS box. Every scan probes the binary (<binary> --version) and
records the result as variant, then looks for a curated overlay matching
(command, variant, version_range).
The vocabulary is bsd, gnu, apple, busybox, unknown. gnu is the
whole GNU family, not just coreutils — diffutils, tar, sed and bash are
separate projects, and the specific package is recorded in provenance.package
and pinned, where it matters, in match.probe.output_contains. apple covers
Apple's own ports, whose banner names Apple rather than BSD (macOS sort
reports 2.3-Apple (197), git reports (Apple Git-155)).
match.platform, by contrast, is an open string taken verbatim from Rust's
std::env::consts::OS — macos, linux, freebsd, openbsd, netbsd,
dragonfly, solaris and anything else a host reports. Operating systems are
not an enumerable set, so naming a new one needs no apexe change. There is
deliberately no Linux distribution dimension: GNU coreutils ls has the same
83 flags on Debian, Ubuntu and Fedora across three different releases, while
BusyBox ls has 21 — divergence tracks the implementation, which variant
already captures.
The classification order is load bearing: BSD is tested before GNU, because
macOS grep reports grep (BSD grep, GNU compatible) 2.6.0-FreeBSD and is a
BSD tool advertising GNU compatibility rather than a GNU tool. Apple is tested
only after <arch>-apple-<os> target triples are stripped, because
curl 8.7.1 (x86_64-apple-darwin25.0) is not an Apple port. See
Authoring Tool Overlays.
An overlay is a reviewed description of one variant of one command. In
authoritative mode it replaces the scan's flags, positional args and
subcommands entirely; in merge mode it overrides matching flags and adds
missing ones. Overlays are the only source that can state conflicts_with,
because no help or man page format expresses mutual exclusion machine-readably.
Overlays are loaded from, in increasing precedence: the built-ins compiled into
apexe (overlays/), ~/.apexe/overlays/*.{json,yaml}, and --overlay <PATH>.
The format is defined by schemas/tool-overlay.schema.json.
Every emitted flag carries sources and a derived confidence:
verified (overlay) > high (completion spec) > medium (two independent
heuristic sources agree) > low (a single unconfirmed source).
An overlay flag may also declare long_running: true — "this option may make
the command never terminate on its own", which is why tail -f hangs an agent
until the harness timeout. It reaches the emitted contract as the JSON Schema
extension keyword x-apexe-long-running, so an executor can bound the timeout
or refuse instead of blocking. The claim is possibility, not certainty: BSD
tail -f returns immediately when its input is a pipe.
Writing one. An overlay claiming confidence: verified must carry a
provenance block recording how it was checked — which build was consulted,
which document was read (man-page / help / vendor-docs), and when. The
schema rejects a verified overlay without it, because a verified +
authoritative overlay replaces the entire scan result with an assertion
nobody can re-check.
Read the flag list off the tool itself, never from memory:
|
There is deliberately no apexe overlay verify command. A tool can compare
flag names, but not descriptions, conflicts_with, types or enum values — and
those are the reason overlays exist. A green check covering only the mechanical
half would read as "this overlay is correct".
See Authoring Tool Overlays for the full procedure,
including how to cross-check a draft against a reference installation and the
traps already hit in practice (of the 38 flags ls shares between its BSD and
GNU variants, zero have identical descriptions — never copy one across).
apexe serve
Start MCP server for scanned tools.
apexe a2a
Start an A2A agent server for scanned tools. Shares governance (ACL, logging, audit) with apexe serve via the same Executor.
A2A has no interactive elicitation transport, so there is no
--enable-approvalflag onapexe a2a(it's available onapexe serve, and on A2A only via the libraryApprovalStoreAPI). Seedocs/user-manual.md.
apexe list
List registered modules.
apexe config
Show or initialize configuration.
How It Works
CLI Tool Binary
|
v
+--------------------+
| Scanner Engine | <-- Tier 1: --help (GNU/Click/Cobra/Clap)
| | <-- Tier 2: man pages (DESCRIPTION + OPTIONS)
| | <-- Tier 3: shell completions (subcommand discovery)
+---------+----------+
| ScannedCLITool
v
+--------------------+
| Adapter Layer | <-- module IDs, JSON Schema, annotations, display metadata
+---------+----------+
| ScannedModule (apcore-toolkit)
|
+-----+-----+
| |
v v
+--------+ +------------------+
| Output | | MCP Server |
| .yaml | | apcore-mcp |
| ACL | | stdio/http/sse |
| Audit | | middleware+auth |
+--------+ +------------------+
Behavioral annotations
| Signal | Inference |
|---|---|
Command list, show, status, get |
readonly: true, cacheable: true |
Command delete, rm, kill, destroy |
destructive: true, requires_approval: true |
Flag --force, -f, --hard |
Escalates to requires_approval: true |
Flag --dry-run, --check, --simulate |
idempotent: true |
Schema generation
| CLI Type | JSON Schema |
|---|---|
--message "hello" |
"type": "string" |
--count 5 |
"type": "integer" |
--config /path |
"type": "string", "format": "path" |
--url https://... |
"type": "string", "format": "uri" |
--format json|yaml |
"type": "string", "enum": ["json","yaml"] |
--include a --include b |
"type": "array", "items": {"type":"string"} |
Configuration
Resolved in 4 tiers (highest wins): CLI flags > env vars > config file > defaults
| Env Variable | Default | Description |
|---|---|---|
APEXE_MODULES_DIR |
~/.apexe/modules |
Binding file storage |
APEXE_CACHE_DIR |
~/.apexe/cache |
Scan cache |
APEXE_LOG_LEVEL |
info |
Log level |
APEXE_TIMEOUT |
30 |
CLI subprocess timeout (seconds) |
APEXE_SCAN_DEPTH |
2 |
Subcommand recursion depth |
File Locations
| Path | Purpose |
|---|---|
~/.apexe/config.yaml |
Configuration |
~/.apexe/modules/*.binding.yaml |
Generated tool bindings |
~/.apexe/cache/ |
Scan result cache |
~/.apexe/acl.yaml |
Access control rules |
~/.apexe/audit.jsonl |
Audit trail |
Examples
See examples/README.md for full details.
| Example | Description | Run |
|---|---|---|
| basic | Shell script: scan → list → serve | ./examples/basic/run.sh |
| programmatic | Rust library: scan → convert → export OpenAI tools → build MCP server | cargo run --example programmatic |
| acl_demo | Rust library: role-based ACL rules on CliModule calls via Executor |
cargo run --example acl_demo |
Developer Guide
Build & Test
Adding a Custom Parser
Implement the CliParser trait in src/scanner/protocol.rs:
Logging
RUST_LOG=debug
Releasing
apdev-rs release handles tagging, the GitHub Release, and publishing to
crates.io; pushing the rust/vX.Y.Z tag it creates automatically triggers
.github/workflows/release.yml, which builds
the prebuilt binaries described in Installation and attaches
them to that release. No separate step is needed for a normal release.
To backfill binaries onto a release that's missing them (e.g. one published before this workflow existed), dispatch it manually against the existing tag:
Documentation
| Document | Description |
|---|---|
| Quick Start | Get running in 30 seconds |
| User Manual | Full reference — commands, config, scanning, schema generation, annotations, governance, MCP server, AI integration, error handling |
| Authoring Tool Overlays | How to write and verify a curated overlay — required reading before adding one |
| Examples | Shell script walkthrough + Rust library API usage |
| Changelog | Release history and migration notes |
Architecture & Design
| Document | Description |
|---|---|
| Technical Design | v0.1.0 architecture with apcore ecosystem integration |
| Feature Manifest | Module map, crate dependencies, project status |
| Feature Specs | Detailed specifications for features F1-F7 |
Feature Specs
| Spec | Description |
|---|---|
| F1: Scanner Adapter | ScannedCLITool → ScannedModule conversion |
| F2: Module Executor | apcore Module trait for CLI subprocess execution |
| F3: Binding Output | apcore-toolkit YAMLWriter integration |
| F4: MCP Server | apcore-mcp server builder |
| F5: Governance | ACL + AuditLogger + Sandbox wrappers |
| F6: Error Migration | ApexeError → ModuleError conversion |
| F7: Config Integration | apcore Config integration |
License
Apache-2.0