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.
axum-apcore
Expose Axum routes as AI-perceivable modules.
Axum integration for the apcore AI-Perceivable Core ecosystem.
axum-apcore automatically scans your Axum routes and exposes them as apcore modules — with full execution, context mapping, MCP serving, and OpenAI tool export. Define your routes once, and both code and AI can discover, understand, and invoke them through enforced schemas and behavioral annotations.
Features
- Route scanning — Discover Axum routes via the native metadata registry or OpenAPI (utoipa) specs
ap_handler!macro — Register route metadata at compile time with zero boilerplateApContextextractor — Extract apcoreContext(identity, trace context) from Axum requests viaFromRequestParts- Module execution — Call any registered module programmatically with
call(),stream(), orcancellable_call() - Async task management — Submit background tasks with status tracking, cancellation, and cleanup
- MCP server — Serve registered modules as MCP tools (stdio, streamable-http, SSE transports)
- OpenAI export — Export modules as OpenAI-compatible tool definitions
- Access control — Enforce caller authorization via an apcore ACL file (
APCORE_ACL_PATH) - YAML bindings — Auto-discover modules from YAML binding files
- CLI — Scan, serve, export, manage tasks, list/describe modules, shell completions, man pages, and module scaffolding
- HTTP proxy CLI — Generate a full CLI where each command forwards requests to the running API via HTTP (
create_cli()) - Configuration —
APCORE_*environment variables for all settings - Observability — Tracing middleware, metrics collection, and structured logging via
tracing
API Overview
Core
| Type | Description |
|---|---|
AxumApcore |
Unified entry point — init, scan, register, call, stream, export |
ApcoreSettings |
Configuration from APCORE_* env vars with validation |
ApContext |
Axum extractor for apcore Context<Value> |
RequestIdentity |
Identity struct for auth middleware to inject into request extensions |
AxumContextFactory |
Creates apcore contexts from Axum request parts |
Scanning
| Type | Description |
|---|---|
NativeAxumScanner |
Scans routes from the compile-time metadata registry |
OpenAPIScanner |
Scans routes from a utoipa-generated OpenAPI spec (requires openapi feature) |
ap_handler! |
Macro for declarative route metadata registration |
Engine
| Type | Description |
|---|---|
AxumRegistryWriter |
Registers scanned modules into apcore's Registry |
AxumDiscoverer |
Discovers modules from YAML binding files |
AxumModuleValidator |
Validates module IDs against apcore constraints |
TaskManager |
Async task submission, tracking, and cancellation |
Requirements
- Rust >= 1.75
- Tokio async runtime
- Axum 0.8+
Installation
Add to your Cargo.toml:
[]
= "0.1"
= { = "0.8", = ["json"] }
= { = "1", = ["full"] }
= "1"
= "0.3"
Feature flags
| Feature | Description | Dependencies |
|---|---|---|
cli |
CLI commands + HTTP proxy CLI + shell completions | clap, clap_complete, apcore-cli, apcore-toolkit/http-proxy |
mcp |
MCP server and OpenAI tools export | apcore-mcp |
openapi |
OpenAPI spec scanning via utoipa | utoipa |
all |
Enable all optional features | — |
= { = "0.1", = ["all"] }
Quick Start
Register routes and call modules
use ;
use ;
use ;
use Arc;
// Define a handler
async
async
Register executable handlers
use ;
use ;
use Arc;
async
async
OpenAPI scanning
use OpenAPIScanner;
use json;
let scanner = new;
let spec = json!;
let modules = scanner.scan_spec.unwrap;
println!; // "users.get_user.get"
Cancellable execution with timeout
use Duration;
let result = apcore
.cancellable_call
.await;
Background tasks
// Submit a task
let task_id = apcore.submit_task.unwrap;
// Check status
let info = apcore.get_task_status;
// Get result when complete
let result = apcore.get_task_result;
// Cancel a running task
apcore.cancel_task;
HTTP proxy CLI
Generate a CLI where each command forwards requests to the running API via HTTP:
use ;
let apcore = new;
let config = CreateCliConfig ;
let cmd = apcore.create_cli.await?;
CLI Reference
The CLI provides both framework-specific commands and apcore-cli commands (requires cli feature):
Framework Commands
| Command | Description |
|---|---|
scan |
Scan Axum routes and generate module definitions |
serve |
Start MCP server exposing registered modules |
export |
Export modules as OpenAI-compatible tool definitions |
tasks list |
List async tasks (with optional --status filter) |
tasks cancel |
Cancel a running task by ID |
tasks cleanup |
Clean up old completed tasks |
scan
| Option | Default | Description |
|---|---|---|
--source |
native |
Scanner: native or openapi |
--output |
registry |
Output: registry or yaml |
--dir |
— | Directory for YAML output |
--dry-run |
— | Preview without writing |
--include |
— | Regex: only include matching module IDs |
--exclude |
— | Regex: exclude matching module IDs |
--verify |
— | Verify registration after writing |
serve
| Option | Default | Description |
|---|---|---|
--transport |
from settings | Transport: stdio, streamable-http, sse |
--host |
from settings | Host to bind to |
--port |
from settings | Port to listen on |
--explorer |
— | Enable MCP explorer UI |
--jwt-secret |
$APCORE_JWT_SECRET |
JWT secret for authentication |
--approval |
auto |
Approval mode: auto, deny, manual |
--tags |
— | Comma-separated module tag filter |
--prefix |
— | Module ID prefix filter |
export
| Option | Default | Description |
|---|---|---|
--format |
openai-tools |
Export format |
--strict |
— | Use strict mode for OpenAI tools |
--embed-annotations |
— | Embed annotations in definitions |
--tags |
— | Comma-separated module tag filter |
--prefix |
— | Module ID prefix filter |
apcore-cli Commands
These commands are delegated to the apcore-cli library:
| Command | Description |
|---|---|
list |
List available modules (with --tag filter, --format table/json) |
describe MODULE_ID |
Show schema and annotations for a module |
completion SHELL |
Generate shell completion script (bash, zsh, fish, elvish, powershell) |
man [COMMAND] |
Generate a roff man page |
init module MODULE_ID |
Scaffold a new module (with --style, --dir, --description) |
Examples
# List all modules in table format
# List modules filtered by tag, output as JSON
# Describe a specific module
# Generate bash completions
# Generate man page for the program
# Scaffold a new module with binding style
Configuration
All settings are read from environment variables with the APCORE_ prefix:
| Variable | Default | Description |
|---|---|---|
APCORE_MODULE_DIR |
apcore_modules |
Directory for YAML binding files |
APCORE_AUTO_DISCOVER |
true |
Auto-discover modules on startup |
APCORE_BINDING_PATTERN |
*.binding.yaml |
Glob pattern for binding files |
APCORE_SCANNER_SOURCE |
native |
Scanner: native or openapi |
APCORE_SERVE_TRANSPORT |
streamable-http |
MCP transport: stdio, streamable-http, sse |
APCORE_SERVE_HOST |
127.0.0.1 |
MCP server host |
APCORE_SERVE_PORT |
9090 |
MCP server port |
APCORE_SERVER_NAME |
axum-apcore |
MCP server name |
APCORE_JWT_SECRET |
— | JWT secret for MCP auth |
APCORE_ACL_PATH |
— | Path to an ACL YAML file; enables module access control (see below) |
APCORE_TRACING |
false |
Enable tracing middleware |
APCORE_METRICS |
false |
Enable metrics collection |
APCORE_TASK_MAX_CONCURRENT |
10 |
Max concurrent background tasks |
APCORE_TASK_MAX_TASKS |
100 |
Max total tasks in queue |
Access control (ACL)
Set APCORE_ACL_PATH (or ApcoreSettings::acl_path) to an ACL YAML file to have
apcore enforce caller authorization on every call() / stream(). The executor
runs apcore's acl_check pipeline step; a denied call returns
ErrorCode::ACLDenied, which maps to HTTP 403 Forbidden.
ACL rules match on the caller id, which is apcore's module-level identity —
not the request's RequestIdentity/JWT subject:
- a top-level request (your HTTP route invoking a module) is checked as the
@externalcaller; - a module calling another module is checked under the calling module's id.
# acl/global_acl.yaml
default_effect: allow
rules:
- callers: # all top-level (HTTP-originated) calls
targets:
effect: deny
description: "External callers cannot reach the admin delete module."
APCORE_ACL_PATH=acl/global_acl.yaml
Use ACL for module-level / external-entry authorization. For per-user HTTP authz
(roles, ownership), keep using the Axum middleware / JWT layer — that identity is
available on ApContext but is independent of the ACL caller id. A malformed or
missing ACL file is logged and treated as "no ACL" rather than crashing startup.
Examples
The examples/ directory contains runnable demos. Run any example with:
| Example | Description |
|---|---|
basic |
Full Axum app with ap_handler!, ApContext extractor, and server startup |
handler_registration |
Register executable handlers, call modules with call() and call_anonymous() |
async_tasks |
Submit background tasks, poll status, cancel, and list tasks |
openapi_scanner |
Scan a utoipa-generated OpenAPI spec with include/exclude filters |
mcp_server |
Create an MCP server and export OpenAI-compatible tool definitions |
cli_proxy |
Generate an HTTP proxy CLI with create_cli() |
Tests
Run all tests (unit + integration):
Run only unit tests:
Run only integration tests:
Run a specific test by name:
Run with output visible:
Development
Prerequisites
Install Rust via rustup:
|
Clone and build
Quality gates
All of these must pass before committing:
Lint and format
Build documentation
Architecture
axum-apcore follows the same module structure as fastapi-apcore:
| Rust Module | FastAPI Module | Purpose |
|---|---|---|
client |
client.py |
AxumApcore unified entry point |
config |
engine/config.py |
ApcoreSettings from APCORE_* env vars |
context |
engine/context.py |
ApContext extractor + AxumContextFactory |
scanner/native |
scanners/native.py |
Route metadata registry scanning |
scanner/openapi |
scanners/openapi.py |
utoipa OpenAPI spec scanning |
engine/registry |
engine/registry.py |
Singleton Registry/Executor management |
engine/extensions |
engine/extensions.py |
Discoverer + ModuleValidator |
engine/observability |
engine/observability.py |
Tracing/metrics/logging setup |
engine/tasks |
engine/tasks.py |
Async task management |
output/registry_writer |
output/registry_writer.py |
ScannedModule → Registry registration |
cli |
cli.py |
clap CLI (scan/serve/export/tasks) + apcore-cli (list/describe/completion/man/init) |
License
Apache-2.0
Links
- Core SDK: aiperceivable/apcore-rust
- Toolkit: aiperceivable/apcore-toolkit-rust
- Reference: aiperceivable/fastapi-apcore
- Website: aiperceivable.com
- Issues: GitHub Issues