Documentation — Build features and crates
Reference · Runtime

Build features and crates

agentd decides most of its capability at compile time: each cargo feature adds a protocol, a credential mechanism or an operator surface, and a build without it refuses the configuration that needs it. This page lists every feature, what the release binaries carry, which configuration needs which feature, and the crates the workspace publishes. It is for operators choosing a binary and for integrators building from source.

What the release binaries carry

Every release ships static Linux binaries for x86_64 and aarch64 (musl, static-PIE on x86_64), a SHA256SUMS file, and a multi-arch OCI image, ghcr.io/agentd-dev/agentd, signed with cosign (keyless) and carrying an SPDX SBOM attestation. The image is FROM scratch plus the binary, run as uid 65532.

All of them are built with the default feature tls plus this list, taken from .github/workflows/release.yml:

a2a,metrics,cron,otel,hot-reload,config-watch,aauth,oauth,cel,sign,oci,decrypt,mcp-events,mock-models

mock-models is the built-in mock model endpoint: mock:final and mock:file:<playbook.json> answer from a script instead of a provider, so you can try an agent or a workflow in the released agentd with no provider account.

Two features are never in a release binary:

  • exec, the local command runner. agentd's default posture is that it runs no local code; you opt in at build time and again at run time.
  • internal-mocks, the test scaffolding: the mock MCP servers and crash points the test suites drive. It includes mock-models. Debug builds carry it automatically, so cargo run and the test suites need no flag.

Features

FeatureDefaultReleaseAdds cratesEnables
tlsyesyesrustls (with the ring provider), webpki-rootsDirect https:// to models, MCP servers and peers; an https:// listener; mTLS client identities; security.tls_ca. The bundled roots mean a scratch image trusts public CAs with no system bundle.
a2anoyesthe A2A project's official Rust SDK (a2a-lf, a2a-pb, a2a-server-lf), tokio, axum, hyper, hyper-util, tokio-rustls, tower, chrono, async-trait, tokio-stream, futures-utilThe A2A listener and everything served on it, outbound A2A peers, and the webhook listener. Implies tls.
cronnoyesnoneFive-field UTC cron expressions on schedule start nodes.
oauthnoyesnoneOAuth 2.1 credentials (device, authorization code with PKCE, client credentials, refresh, OIDC discovery) for models, MCP servers and peers; agentd --login.
metricsnoyesnone/metrics (Prometheus text), /healthz and /readyz on observability.metrics_addr.
otelnoyesnoneOTLP over HTTP/JSON: run traces with GenAI attributes, and log export.
hot-reloadnoyesnoneReload on SIGHUP: validate, stage, apply whole or refuse.
config-watchnoyesnoneAn inotify watch that triggers the same reload (lifecycle.watch_config). Implies hot-reload.
celnoyescel-interpreter and its dependencies (22 crates)CEL expressions: workflow when, until and filter, computed values, goal.check.condition, security.policies[].match.args, template expressions beyond bare paths.
aauthnoyesnone new (reuses ring)An Ed25519 agent identity that signs outbound MCP requests (RFC 9421). Implies tls.
signnoyesnone newSignature verification for instruction documents (agent.instruction.trust). Implies aauth.
ocinoyesnone new (reuses ring)oci:// instruction sources, including cosign verification. Implies tls.
decryptnoyesnoneEncrypted instruction envelopes: age v1 and JWE compact. Implies sign.
mcp-eventsnoyesnoneMCP Events: bindings, grants, wait subscriptions, the events.* tools and instruction updates by event. The extension is a draft (SEP-3415).
execnonononeThe guarded local exec tool, also gated by security.exec.enabled.
mock-modelsnoyesnoneThe mock model endpoint: mock:final and mock:file:<playbook.json>, scripted chat and decision answers.
internal-mocksnonononeTest scaffolding: the mock MCP servers and crash points. Implies mock-models.

Of the seventeen features, fourteen add no crate of their own: they gate code written in this repository, or reuse ring, which every build already links. Beyond the default tls, the dependency cost of the release set comes from a2a and cel; see Crate counts.

Configuration that needs a feature

A release binary carries everything in this table except exec. In a build from source, the right-hand column is what you see when the feature is missing.

ConfigurationFeatureWithout the feature
an https:// endpoint, listener or peer; security.tls_catlsan https:// model endpoint passes validation and fails at the dial as unsupported
a2a.listen, a2a.peers, webhooks.listen, and so every webhook node and A2A starta2arefused at load: a2a.listen needs the a2a build feature, which this binary was built without — …
a schedule start with cron:cronrefused at load: cron schedules require the 'cron' build feature
any CEL expressioncelrefused at load: … uses an expression, which needs the 'cel' build feature (bare paths work without it)
any auth on a model connection; any auth or oauth block on an MCP server; agentd --loginoauthrefused at load: mcp.servers[].auth needs the oauth build feature, which this binary was built without — …
observability.metrics_addrmetricsrefused at load: observability.metrics_addr needs the metrics build feature, …
observability.otel.endpoint, observability.otel.logs: trueotelrefused at load: observability.otel needs the otel build feature, …
SIGHUP reloadhot-reloadSIGHUP keeps its default action and ends the process
lifecycle.watch_config: trueconfig-watchrefused at load: lifecycle.watch_config needs the config-watch build feature, …
security.aauth, mcp.servers[].aauth: trueaauthrefused at load: security.aauth needs the aauth build feature, …
agent.instruction.trustsigna pinned instruction refuses startup: … this build cannot verify signatures — rebuild with --features sign
an oci instruction, prompt or template sourceocirefused at load: … an oci:// source requires building with --features oci
agent.instruction.decrypt, or any encrypted envelopedecryptthe envelope is recognised and refused; ciphertext never reaches the model
mcp.servers[].events, event_grants, agent.instruction.mcp.events, wait {on: event, subscribe:}mcp-eventsrefused at load: mcp.servers[0]: MCP Events bindings and grants require building with --features mcp-events
security.exec.enabled: trueexecrefused at load: security.exec.enabled needs the exec build feature, …
mock: endpointsmock-models (or a debug build)refused at load: mock: intelligence needs a build with --features mock-models

Every path and its feature is in the Configuration reference.

Building from source

The release build is agentd-cli with the release feature list. With a Rust toolchain of at least 1.96 (edition 2024):

cargo build --release --locked -p agentd-cli --features "a2a,metrics,cron,otel,hot-reload,config-watch,aauth,oauth,cel,sign,oci,decrypt,mcp-events,mock-models"

Add exec for the local command runner, or internal-mocks to keep the test scaffolding in a release-profile build. --no-default-features drops tls; such a binary reaches https:// only through a TLS-terminating sidecar.

The release profile is opt-level = "z", lto = true, codegen-units = 1, strip = true and panic = "abort". The build needs a C compiler, because ring, the TLS crypto provider, compiles C. It needs no CMake: CI fails the build if the aws-lc provider enters the dependency tree.

Crates

The workspace publishes five crates to crates.io. A sixth, the conformance suite, is not published and links none of the others: it drives the binary from outside.

CrateLibrary nameVersion (v1.18.0)LicenceOwns
agentd-netnet2.0.0AGPL-3.0-onlyA blocking HTTP/1.1 and SSE client over any Read + Write, unix and TLS connects, the SSRF guard, X.509 field extraction.
agentd-mcpmcp3.0.0AGPL-3.0-onlyA blocking MCP client over the official rmcp SDK, on agentd's own credentialed Streamable-HTTP socket, plus a raw HTTP listener.
agentd-instructioninstruction_core0.3.0MIT OR Apache-2.0The reference implementation of the Instruction Specification: parser, validator, delivery, resolution manifest, signature verification.
agentd-coreagentd1.18.0AGPL-3.0-onlyThe engine: supervisor, agent loop, workflows, tool registry, configuration, durable state, A2A server.
agentd-clibinary agentd1.18.0AGPL-3.0-onlyThe binary: argument handling, exit codes, and the tui and ui launchers.
agentd-conformanceagentd_conformance1.7.0AGPL-3.0-onlyA black-box conformance suite. Not published.

Each crate's features map onto agentd-core's: agentd-cli's a2a turns on agentd-core/a2a, and so on. agentd-mcp and agentd-net have one feature each, tls; agentd-instruction has sign.

The package and library names differ on purpose. agentd on crates.io belongs to an unrelated project, so the engine is published as agentd-core with [lib] name = "agentd", and code still writes use agentd::…. The instruction crate is agentd-instruction because the specification belongs to instruction.md, not to agentd; it is the one crate under a permissive licence, so other implementations of the specification can link it.

Embedding the engine in your own Rust program is Embed agentd in Rust.

Crate counts

The number of distinct crates in the shipped dependency graph, counted as unique package names from cargo tree -p agentd-cli -e normal --prefix none (build and dev dependencies excluded):

BuildCratesNot from this repository
--no-default-features8277
default (tls)8984
default + cel111106
default + a2a146141
the release feature set163158

The right-hand column leaves out the five workspace crates the command lists. a2a and cel overlap in five crates; the other twelve release features add none. Measured with cargo 1.98.0 against the committed Cargo.lock of the v1.18.0 release (d167aba4). The same count holds for the x86_64-unknown-linux-musl target that ships.

Footprint

The binary size, download size, start-up time and idle memory of the release binaries are measured in one place, Engineering choices: the numbers. Each MCP connection and the A2A listener add threads of their own; the Architecture page explains where they come from.

Next steps