Command Spec
June 28, 2026 · View on GitHub
Status
This document describes the current implemented CLI contract.
Implemented and verified in the current codebase:
- live and deterministic transport workflows for
capture,send, andgenerate - file-backed
filterandstatsover candump capture logs - default
python-cansupport forcaptureandsend - deterministic
replay - live
gatewaybridging between CAN interfaces viapython-can - structured
exportfor capture files and saved sessions - DBC-backed
decode,encode, anddbc inspect - DBC provider workflows for
dbc provider list,dbc search,dbc fetch,dbc cache list,dbc cache prune, anddbc cache refresh - dataset provider workflows for
datasets provider list,datasets search,datasets inspect,datasets fetch,datasets cache list,datasets cache refresh,datasets convert,datasets stream, anddatasets replay - J1939
monitor,decode,pgn,spn,tp,dm1,faults,summary,inventory, andcompare - session
save,load, andshow - shell one-shot command execution
- initial text-mode
tuishell over the shared command layer - UDS
scan,trace, andservices - XCP (measurement/calibration)
scan,trace,read, andcommandsfor XCP-on-CAN - J1587/J1708
decodeandpidsfor legacy heavy-vehicle diagnostic captures - J2497 (PLC4TRUCKS)
decodeandmidsfor passive trailer power-line frame captures config showfor effective transport configuration inspectionre signals,re counters,re entropy,re correlate, andre anomaliesfor passive file-backed analysisre match-dbcandre shortlist-dbcfor provider-backed DBC candidate ranking against capturesre suggestfor heuristic signal-name suggestions (with an optional, off-by-default external-LLM enrichment)plugins list,plugins info,plugins enable, andplugins disablefor Python entry-point plugin inspection and togglesweb servefor the read-only browser dashboard over the JSONL event envelopecannelloni decodeandcannelloni sendfor cannelloni CAN-over-UDP wire-format interop- structured JSON and JSONL output
- explicit error schema and exit codes
Important current behavior:
- live transport-facing commands default to the
python-canbackend; setbackend = "scaffold"in~/.canarchy/config.tomlor exportCANARCHY_TRANSPORT_BACKEND=scaffoldfor deterministic offline behavior capture,send, andgatewayuse the selected transport backend, butgatewayspecifically requirespython-can- the default
python-caninterface issocketcan; setinterfacein the config file orCANARCHY_PYTHON_CAN_INTERFACEto change it - the default CAN interface/channel is optional; set
default_interfacein the config file orCANARCHY_DEFAULT_INTERFACEto let single-interface commands such ascapture,send,generate,uds scan, and live fuzz commands omit the interface argument - DBC-backed commands accept local paths and provider refs such as
opendbc:<name>orcomma:<name> - database-backed commands (
decode,encode,dbc inspect,dbc convert, …) also accept ARXML (.arxml), KCD (.kcd), and SYM (.sym) files in addition to DBC (.dbc); the format is selected by filename suffix through the cantools runtime, and the user-facing flag remains--dbc decode,encode, anddbc inspectincludedata.dbc_sourcein structured output so callers can see the provider, logical DBC name, pinned version, resolved local path, and databasekind(dbc/arxml/kcd/sym);dbc inspectadditionally reports the same value asdata.database.format- some protocol-oriented commands currently use explicit sample/reference providers rather than true transport-backed execution paths
- specialized text formatting exists for J1939 monitor and decode style output; other
--textoutput is generic key/value rendering - file-backed analysis commands support standard timestamped candump log files (
.candump,.log) and pcap/pcapng files (.pcap,.pcapng) with CAN SocketCAN (DLT 227) frames; selected commands also support--file -for candump text from stdin - commands that historically took positional capture paths (the
re *family andj1939 compare) also accept the--file <path>flag form (repeatable for multi-file commands); supplying both forms with different paths returnsCONFLICTING_FILE_ARGUMENTS
Command Structure
Commands follow one of these patterns:
canarchy <domain> <action> [args]
or
canarchy <action> <object>
Examples:
canarchy capture can0 --jsoncanarchy capture --jsonwhen[transport].default_interfaceis configuredcanarchy replay --file tests/fixtures/sample.candump --rate 2.0 --jsoncanarchy j1939 monitor --pgn 65262 --jsoncanarchy decode --file tests/fixtures/sample.candump --dbc tests/fixtures/sample.dbc --json
Implemented Commands
capture
Capture traffic from a local interface. Structured capture uses the selected transport backend. --candump is a live-only mode.
canarchy capture [interface] [--candump] [--json|--jsonl|--text]
Example:
canarchy capture can0 --json
canarchy capture vcan0 --candump
Notes:
--candumpis a live-only mode that requires thepython-canbackend (set in~/.canarchy/config.tomlor viaCANARCHY_TRANSPORT_BACKEND=python-can)- if
interfaceis omitted,captureuses[transport].default_interfaceorCANARCHY_DEFAULT_INTERFACE; without either, it returnsINTERFACE_REQUIRED --candumpkeeps running and printing frames until interrupted--candumpchanges the human-readable output path to acandump-style line format such as(0.100000) vcan0 18F00431#AABBCCDD--candump --jsonand--candump --jsonlkeep structured output for automation, but still require a live backend- default text output without
--candumpremains the generic key/value renderer
Supported file input today:
- file-backed commands consume standard timestamped candump logs in the form
(timestamp) interface frame#data - supported additional candump forms include classic RTR
id#R, CAN FDid##<flags><data>, and error frames using a CAN error-flagged identifier - supported CAN FD flags today are the BRS and ESI bits in the single-nibble candump flags field
- supported capture-file suffixes today are
.candump,.log,.pcap, and.pcapng;--file -reads candump text from stdin for commands that explicitly support it - pcap/pcapng support requires the file to use the CAN SocketCAN linktype (DLT 227); files with other linktypes are rejected with a clear error
- pcap/pcapng files are always fully scanned (no fast-scan estimation); the binary format does not support text-based head/tail estimation
- malformed log lines are skipped during capture parsing rather than falling back to fixture data; commands that require capture metadata or explicitly validate stdin emptiness return structured errors when no valid frames are available
send
Prepare an active transmit frame.
canarchy send [interface] <frame-id> <hex-data> [--dry-run] [--ack-active] [--json|--jsonl|--text]
Example:
canarchy send can0 0x123 11223344 --json
Notes:
--ack-activerequests an interactiveYESconfirmation before the frame is transmitted--dry-runreturns the planned frame without opening a transport or requiring confirmation- when active acknowledgement is required by configuration, omitting
--ack-activereturns a structuredACTIVE_ACK_REQUIREDerror - if
interfaceis omitted,senduses[transport].default_interfaceorCANARCHY_DEFAULT_INTERFACE; explicit command-line interfaces take precedence over the configured default
filter
Filter a capture source by a simple expression.
canarchy filter <expression> (--file <path> | --file - | --stdin) [--offset <n>] [--max-frames <n>] [--seconds <seconds>] [--json|--jsonl|--text]
Notes:
* `--file -` reads candump text from standard input instead of a file and still honors `--offset`, `--max-frames`, and `--seconds`
* `--stdin` reads JSONL `frame` events from standard input regardless of output format
* For `filter --stdin`, each line must be a valid `frame` event JSON object
* expression operands for `id==` / `pgn==` accept decimal, `0x`-prefixed hex, or bare hex, and all operators tolerate surrounding whitespace (e.g. `pgn == 61444`)
* supported atoms: `all`, `id==<id>`, `pgn==<pgn>`, `dlc><n>`, `data~=<hex>`, `extended`, `standard`, combined with `&&` / `||`
* on an invalid expression the JSON error envelope carries no `frames` / `frame_count` block, so an error can never read as a successful zero-match
### capture-info
Inspect a candump capture quickly before running deeper analysis.
```bash
canarchy capture-info --file <path> [--json|--jsonl|--text]
canarchy capture-info --file - [--json|--jsonl|--text]
Notes:
-
--file -reads candump text from standard input instead of a file -
Returns capture metadata only:
-
frame_count -
first_timestamp -
last_timestamp -
duration_seconds -
unique_ids -
interfaces -
suggested_max_frames -
suggested_seconds
stats
Summarize a capture source. The capture path may be given positionally or via --file (equivalent).
canarchy stats <path> [--top <n>] [--offset <n>] [--max-frames <n>] [--seconds <seconds>] [--json|--jsonl|--text]
canarchy stats --file <path> [--top <n>] [--offset <n>] [--max-frames <n>] [--seconds <seconds>] [--json|--jsonl|--text]
canarchy stats --file - [--top <n>] [--offset <n>] [--max-frames <n>] [--seconds <seconds>] [--json|--jsonl|--text]
The following passive analysis commands likewise accept a positional capture path as an alias for --file: stats, j1939 summary, j1939 faults, j1939 dm1, j1939 inventory, j1939 map, j1939 tp sessions, j1939 tp compare, j1587 decode, j2497 decode. Supplying both forms with different paths returns CONFLICTING_FILE_ARGUMENTS.
Notes:
--file -reads candump text from standard input instead of a file- beyond
total_frames/unique_arbitration_ids, the payload reportsduration_seconds, first/last timestamps, adlc_distribution, and abus_loadblock with total bits, bits/s, and load percentages at 250 k / 500 k / 1 M bit/s (frame overhead without stuff bits; a lower-bound estimate) top_idsdetails the highest-frequency arbitration ids (default 20, bounded by--top):arbitration_id_hex,frame_count,share,rate_hz, mean/min/max inter-frame gap,gap_jitter_ms, observed DLCs, and first/last seen
compare
Diff two or more plain CAN captures per arbitration ID against a baseline, the generic-CAN analogue of j1939 compare.
canarchy compare (<file> <file> [<file> ...] | --file <file> --file <file> ...) [--baseline <path>] \
[--top <n>] [--offset <n>] [--max-frames <n>] [--seconds <s>] [--json|--jsonl|--text]
Notes:
- this command is passive and file-backed; it accepts two or more captures positionally or via repeatable
--file, and requires at least two (COMPARE_NEEDS_FILESotherwise) - the baseline is the first file unless
--baseline <path>designates another; a--baselineoutside the compared set is folded in as the reference - each
comparisonentry reports, per arbitration ID, the per-fileframe_counts,rates_hz,mean_gap_ms, andmean_byte_entropyarrays, theframe_count_delta/rate_ratio/entropy_deltaversus the baseline, acycle_time_drift_ratio(reusing there corpusdrift formulation), a combinedchange_score, and aflagslist (new-vs-baseline,dropped-vs-baseline,rate-drop,rate-spike,entropy-collapse,timing-drift) - entries are ranked by
change_scoreand capped at--top(default 20;0for all);id_countreports the full total andreturned_countthe number returned - the
summaryblock lists the affected IDs by category (new_ids,dropped_ids,rate_drop_ids,rate_spike_ids,entropy_collapse_ids,timing_drift_ids); J1939 ids are annotated withpgn,pgn_label, andsource_address_name --offset,--max-frames, and--secondsbound each capture independently
generate
Generate CAN frames from explicit, random, or incrementing inputs.
canarchy generate [interface] [--id <hex|R>] [--dlc <0-8|R>] [--data <hex|R|I>] [--count <n>] [--gap <ms>] [--extended] [--dry-run] [--ack-active] [--json|--jsonl|--text]
Examples:
canarchy generate can0 --id 0x123 --dlc 4 --data 11223344 --count 2 --gap 100 --json
canarchy generate --id 0x123 --dlc 4 --data 11223344 --count 2 --dry-run --json
canarchy generate can0 --data I --count 4 --text
Notes:
--id,--dlc, and--dataacceptRfor random generation, and--data Ienables a deterministic incrementing payload pattern--dry-runemits the planned generated frame events without requiring an interface or opening a transport--ack-activerequests an interactiveYESconfirmation before generated frames are transmitted- when active acknowledgement is required by configuration, omitting
--ack-activereturns a structuredACTIVE_ACK_REQUIREDerror - generated JSON output includes an active-transmit alert followed by generated frame events
simulate
Emit a deterministic, profile-driven mix of classic CAN, J1939, and DM1 traffic without hardware or an external generator.
canarchy simulate [interface] --profile {heavy-truck,passenger-car} [--rate <hz>] \
[--duration <seconds>] [--seed <n>] [--dry-run] [--ack-active] [--json|--jsonl|--text]
Examples:
canarchy simulate --profile heavy-truck --duration 5 --dry-run --json
canarchy simulate vcan0 --profile passenger-car --rate 50 --seed 7 --ack-active --json
Notes:
- profiles are data-driven JSON resources (
canarchy/resources/simulate/profiles.json); frame mix, weights, and DM1 bursts are defined there, so new archetypes need no code changes - deterministic and seedable via
--seed; timestamps are spaced at1 / --rate --dry-runplans the frame mix without transmitting; live transmission honors the active-transmit safety model (--ack-active,YESconfirmation,[safety].require_active_ack)- reuses the existing transport backends, including
socketcanvirtual interfaces,udp_multicast, and stdout candump piping - structured errors:
SIMULATE_INVALID_RATE,SIMULATE_INVALID_DURATION
replay
Replay a capture source with deterministic timing derived from relative frame timestamps. By default this returns a replay plan (planning mode). When --interface is specified, frames are transmitted onto a live CAN bus with capture timing.
canarchy replay --file <path> [--interface <iface>] [--rate <factor>] [--dry-run] [--ack-active] [--json|--jsonl|--text]
Examples:
canarchy replay --file tests/fixtures/sample.candump --rate 2.0 --json
canarchy replay --file tests/fixtures/sample.candump --interface vcan0 --rate 1.0 --ack-active --json
canarchy replay --file tests/fixtures/sample.candump --interface vcan0 --dry-run --json
gateway
Bridge frames from one live CAN interface to another through the python-can backend.
canarchy gateway <src> <dst> [--src-backend <type>] [--dst-backend <type>] [--bidirectional] [--count <n>] [--dry-run] [--ack-active] [--json|--jsonl|--text]
Examples:
canarchy gateway can0 can1 --text
canarchy gateway can0 can1 --dry-run --json
canarchy gateway can0 239.0.0.1 --dst-backend udp_multicast --count 10 --json
Notes:
gatewayrequires thepython-canbackend (set in~/.canarchy/config.tomlor viaCANARCHY_TRANSPORT_BACKEND=python-can)--src-backendand--dst-backenddefault to the configuredinterfacevalue--dry-runreturns the forwarding plan without opening either transport--ack-activerequests an interactiveYESconfirmation before forwarding begins- default text output use candump-style forwarded frame lines with direction labels such as
[src->dst] --jsonreturns a standard command envelope;--jsonlemits one forwarded event per line forgateway
export
Export structured artifacts for later analysis.
canarchy export <source> <destination> [--json|--jsonl|--text]
Examples:
canarchy export tests/fixtures/sample.candump artifacts/sample.json --json
canarchy export tests/fixtures/sample.candump artifacts/sample.jsonl --json
canarchy export session:lab-a artifacts/session.json --json
Notes:
- capture file sources use
.candumpor.logpaths - saved sessions use the explicit
session:<name>source form - destination
.jsonwrites a full structured artifact envelope - destination
.jsonlwrites one serialized event per line and is only supported for event-capable sources such as capture files
decode
Decode frames from a capture source using a DBC file.
canarchy decode --file <file> --dbc <file> [--json|--jsonl|--text]
canarchy decode --stdin --dbc <file> [--json|--jsonl|--text]
Example:
canarchy decode --file tests/fixtures/sample.candump --dbc tests/fixtures/sample.dbc --json
Notes:
--dbcaccepts a local file path or a provider ref such asopendbc:<name>--stdinreads JSONLframeevents from standard input instead of a--filecapture source- structured output includes a
dbc_sourceobject describing the provider-backed or local DBC resolution that was used
encode
Encode a DBC message into a frame payload.
canarchy encode --dbc <file> <message> <signal=value>...
[--crc-algorithm stellantis|sae-j1850|fca-giorgio]
[--json|--jsonl|--text]
Example:
canarchy encode --dbc tests/fixtures/sample.dbc EngineStatus1 CoolantTemp=55 OilTemp=65 Load=40 LampState=1 --json
Notes:
--dbcaccepts a local file path or a provider ref such asopendbc:toyota_tnga_k_pt_generated--crc-algorithmoverrides checksum detection for DBC messages with an 8-bitCHECKSUMsignal; when omitted, CANarchy attempts DBC-name detection and otherwise uses the default supported CRC behavior- explicitly supplied
CHECKSUM=<value>signal assignments are preserved - structured output includes a
dbc_sourceobject describing the provider-backed or local DBC resolution that was used - message names resolve by exact DBC name, case/spacing-insensitive match, or SAE PGN label/name (e.g.
EEC1→ the DBC message carrying PGN 61444); signal names resolve by exact DBC name, case/spacing-insensitive match, or the bundled SAE SPN name — so names displayed bydecode/j1939re-encode directly (e.g.encode EEC1 "Engine Speed=1200") - when a PGN label matches several messages (same PGN, different source addresses), the supplied signal names break the tie; a remaining ambiguity returns
DBC_MESSAGE_NOT_FOUNDlisting the candidates - unsupplied signals default to the DBC initial value (else 0, clamped into range/choices) so single-signal encodes work; every default is reported under
data.resolution.filled_signalsand in a warning — review before transmitting (multiplexed messages are not auto-filled) - all non-exact resolutions are recorded under
data.resolution(message.via,signal_aliases) and warned about; misspelled names get closest-match suggestions in the error hint send --dbcapplies the same resolution and defaulting, with a transmission-specific warning
plot
Plot decoded signal time-series from a capture to PNG, SVG, or HTML.
canarchy plot --file <capture> --dbc <path|provider:ref> --signal <name> [--signal <name> ...] \
--out <path> [--format {png,svg,html}] [--offset <n>] [--max-frames <n>] [--seconds <s>] [--json|--jsonl|--text]
Example:
canarchy plot --file drive.candump --dbc truck.dbc --signal EngineSpeed --signal VehicleSpeed --out rpm.png --json
Notes:
- requires the optional plotting extra:
pip install canarchy[plot](matplotlib for PNG/SVG, plotly for HTML); a missing dependency returnsPLOT_DEPENDENCY_MISSINGwith the install hint --dbcaccepts a local database path or aprovider:ref(e.g.opendbc:<name>), resolved likedecode/encode; the envelope includesdbc_sourcedescribing the resolution, and a bad ref returns the standardDBC_*error- multiple
--signalflags overlay signals;--formatselects the renderer (defaultpng) - the envelope reports the output file path plus
signals_plottedanddata_points --offset,--max-frames, and--secondsbound the analysed window like the rest of the file-backed surface- structured errors:
PLOT_DEPENDENCY_MISSING,PLOT_ERROR,UNSUPPORTED_OUTPUT_FORMAT
cannelloni decode
Decode a captured cannelloni CAN-over-UDP datagram payload into CAN frames.
canarchy cannelloni decode --file <payload> [--json|--jsonl|--text]
Notes:
- reads one or more concatenated cannelloni datagrams (wire version 2) from a raw payload file and emits canonical
frameevents - passive and file-backed; supports classic CAN, extended, RTR, error, and CAN FD frames
- structured errors:
CANNELLONI_TRUNCATED,CANNELLONI_VERSION_UNSUPPORTED,CANNELLONI_INVALID_DLC,CANNELLONI_FILE_UNREADABLE
cannelloni send
Transmit a capture to a cannelloni endpoint as UDP datagrams.
canarchy cannelloni send <host:port> --file <capture> [--seq-no <n>] [--max-count <n>] \
[--rate <hz>] [--ack-active] [--dry-run] [--offset <n>] [--max-frames <n>] [--seconds <s>] \
[--json|--jsonl|--text]
Notes:
- active-transmit path gated by the active-transmit safety design (
--ack-active,YESconfirmation,[safety].require_active_ack) --dry-runplans the datagrams (returned as hex indata.datagrams) without opening a socket--max-countbounds frames per datagram (default 64);--mtubounds encoded bytes per datagram (default 1500, so a stock peer's MTU is not overrun by CAN FD frames;--mtu 0disables it);--ratepaces datagrams per second;--seq-nosets the starting cannelloni sequence number- CLI-only (not an MCP tool): active UDP egress to an arbitrary host
- structured errors:
CANNELLONI_INVALID_TARGET(exit 1),CANNELLONI_SEND_FAILED(exit 2)
web serve
Serve the read-only browser dashboard over HTTP + WebSocket.
canarchy web serve --file <capture> [--dbc <path|provider:ref>] [--bind <host:port>] \
[--rate <multiplier>] [--loop] [--offset <n>] [--max-frames <n>] [--seconds <s>] \
[--json|--jsonl|--text]
Example:
canarchy web serve --file tests/fixtures/j1939_heavy_vehicle.candump --dbc tests/fixtures/j1939_sample.dbc --json
Notes:
- streams the capture as canonical envelope events (
frame,j1939_pgnwith bundled PGN/source-address annotation,decoded_messagewhen--dbcis supplied,uds_transactionreassembled from the capture) to the bundled single-file SPA - the server is read-only: no active-transmit endpoints exist and non-GET requests return HTTP 405 with
WEB_READ_ONLY - default bind is
127.0.0.1:8474; port0selects an ephemeral port and the startup envelope reports the resolvedurl --ratescales timestamp pacing (0disables it; gaps are capped at 1 s);--looprestarts the stream when the capture ends, otherwise aSTREAM_COMPLETEalert closes it- structured errors:
WEB_BIND_INVALID/WEB_BIND_FAILED(exit 1) and the standard capture-file transport errors (exit 2) - the command runs until interrupted and is not exposed as an MCP tool (long-running front end, like
shell/tui)
dbc inspect
Inspect database, message, and signal metadata for a DBC file or provider ref.
canarchy dbc inspect <dbc> [--message <name>] [--signals-only] [--search <pattern>] [--layout] [--json|--jsonl|--text]
Examples:
canarchy dbc inspect tests/fixtures/sample.dbc --json
canarchy dbc inspect opendbc:toyota_tnga_k_pt_generated --message STEER_TORQUE_SENSOR --json
canarchy dbc inspect tests/fixtures/sample.dbc --message EngineStatus1 --layout --text
Notes:
<dbc>accepts a local file path or a provider ref such asopendbc:<name>orcomma:<name>- the database file may be DBC (
.dbc), ARXML (.arxml), KCD (.kcd), or SYM (.sym); the format is detected by suffix anddata.database.format/data.dbc_source.kindreport which loader was used - structured output includes
dbc_sourceprovenance alongside the inspection payload --layoutadds cantools-rendered per-messagelayout,signal_tree, andsignal_choicesstrings; text output renders those diagrams directly, while JSON/JSONL keep them as fields on each message payload
dbc convert
Convert a loaded database to another cantools-supported serialization format (DBC, KCD, or SYM).
canarchy dbc convert <dbc> --to {dbc,kcd,sym} [--out <path>] [--json|--jsonl|--text]
Examples:
canarchy dbc convert tests/fixtures/sample.dbc --to kcd --out sample.kcd
canarchy dbc convert opendbc:toyota_tnga_k_pt_generated --to sym --json
Notes:
<dbc>accepts a local file path or a provider ref such asopendbc:<name>; the source may be any format the cantools runtime can load- serialization uses the cantools
as_dbc_string/as_kcd_string/as_sym_stringemitters — no hand-rolled writers - with
--out, the converted database is written to the given path and the envelope reportsout,target_format,message_count, andsignal_count; without--out, the serializedcontentis returned in the envelope (and printed directly in--textmode) - structured errors cover unwritable output directories (
DBC_CONVERT_WRITE_FAILED) and serialization failures where the target format cannot express a source feature (DBC_CONVERT_FAILED)
dbc generate-c
Generate C source and header files from a database using the cantools C
source generator with pack/unpack structs and helpers.
canarchy dbc generate-c <dbc> [--out-dir <dir>] [--database-name <name>]
[--no-floating-point-numbers] [--bit-fields] [--use-float] [--node <name>]
[--use-round] [--json|--jsonl|--text]
Examples:
canarchy dbc generate-c tests/fixtures/sample.dbc --out-dir ./out --json
canarchy dbc generate-c opendbc:toyota_tnga_k_pt_generated --out-dir ./c_code --bit-fields --json
Notes:
<dbc>accepts a local file path or a provider ref such asopendbc:<name>; the source may be any format the cantools runtime can load--out-dirspecifies the output directory (default: current directory); it must already exist--database-namesets the prefix used for all defines, data structures, and functions in the generated code (default: derived from the source filename stem)- four files are generated per database:
.hheader,.csource,_fuzzer.cfuzzer source, and_fuzzer.mkfuzzer makefile - the envelope returns
out_dir,database_name,files(list of{path, kind, size_bytes}), andfile_count - structured errors cover missing output directories (
DBC_GENERATE_C_DIR_MISSING), write failures (DBC_GENERATE_C_WRITE_FAILED), and generation failures (DBC_GENERATE_C_FAILED) - MCP is not exposed — file generation is a developer action
dbc provider list
List registered DBC providers.
canarchy dbc provider list [--json|--jsonl|--text]
dbc search
Search DBC catalogs across enabled providers.
canarchy dbc search <query> [--provider <name>] [--limit <n>] [--json|--jsonl|--text]
Example:
canarchy dbc search toyota --provider opendbc --limit 5 --json
dbc fetch
Fetch and cache a DBC file from a provider.
canarchy dbc fetch <ref> [--json|--jsonl|--text]
Example:
canarchy dbc fetch opendbc:toyota_tnga_k_pt_generated --json
dbc cache list
List cached provider manifests.
canarchy dbc cache list [--json|--jsonl|--text]
dbc cache prune
Remove stale cached provider snapshots while keeping the pinned commit.
canarchy dbc cache prune [--provider <name>] [--json|--jsonl|--text]
dbc cache refresh
Refresh a provider catalog from upstream.
canarchy dbc cache refresh [--provider <name>] [--json|--jsonl|--text]
Notes:
- the default provider is
opendbc - refreshing updates the cached catalog manifest; individual DBC files are fetched on demand or through
dbc fetch - provider-backed decode, encode, and inspect commands return
DBC_CACHE_MISSby default when the provider cache is cold; enabling[dbc.providers.opendbc].auto_refresh = trueallows first-use refresh on resolution
skills provider list
List registered repository-backed skills providers.
canarchy skills provider list [--json|--jsonl|--text]
skills search
Search repository-backed skills catalogs by name, tag, or keyword.
canarchy skills search <query> [--provider <name>] [--limit <n>] [--json|--jsonl|--text]
Example:
canarchy skills search j1939 --provider github --json
skills fetch
Fetch and cache a repository-backed skill locally.
canarchy skills fetch <provider>:<skill> [--json|--jsonl|--text]
Example:
canarchy skills fetch github:j1939_compare_triage --json
skills cache list
List cached skills provider manifests.
canarchy skills cache list [--json|--jsonl|--text]
skills cache refresh
Refresh a skills provider catalog from upstream.
canarchy skills cache refresh [--provider <name>] [--json|--jsonl|--text]
Notes:
- the first provider implementation is GitHub-backed and consumes
.skill.yamlmanifests that follow the CANarchy skill manifest schema skills fetchreturns both the cached manifest path and the cached skill entry path- skills provider/cache commands are mirrored by MCP tools for search/fetch/cache workflows, but skills themselves are workflow descriptors rather than MCP prompts or resources
- agents should use skills as workflow descriptors: search, fetch, inspect compatibility/provenance, then run referenced CANarchy commands explicitly
plugins list
List registered Python entry-point plugins and built-in plugins.
canarchy plugins list [--json|--jsonl|--text]
Output includes each plugin's name, kind (processor, sink, or input), api_version, package version, source_distribution, entry_point_group, enabled, and configured_options fields.
plugins info
Show metadata and configured options for a registered plugin name.
canarchy plugins info <name> [--json|--jsonl|--text]
If the same name is registered in more than one plugin namespace, data.plugins contains each matching entry and data.match_count reports the count.
plugins enable / disable
Persist a plugin toggle in ~/.canarchy/config.toml under [plugins."<name>"].enabled.
canarchy plugins enable <name> [--json|--jsonl|--text]
canarchy plugins disable <name> [--json|--jsonl|--text]
Notes:
- enable/disable requires the plugin to be discovered by the current environment; unknown names return
PLUGIN_NOT_FOUND plugins_listandplugins_infoare mirrored by MCP tools; enable/disable is intentionally CLI-only because it writes user config
datasets provider list
List registered public CAN dataset providers.
canarchy datasets provider list [--json|--jsonl|--text]
datasets search
Search public CAN dataset provider catalogs by name, protocol, or keyword.
canarchy datasets search [query] [--provider <name>] [--limit <n>] [--verbose] [--json|--jsonl|--text]
datasets inspect
Show full metadata for a dataset ref.
canarchy datasets inspect <provider>:<dataset> [--json|--jsonl|--text]
Examples:
canarchy datasets search pivot
canarchy datasets inspect catalog:pivot-auto-datasets --json
Notes:
- JSON
datasets searchanddatasets inspectresults include stable machine fields:ref,is_replayable,is_index,default_replay_file,download_url_available, andsource_type catalog:pivot-auto-datasetsis a curated external source index, not a directly downloadable or replayable dataset- inspect linked source pages for per-dataset access terms, file formats, and conversion/replay suitability
datasets fetch
Record dataset provenance in the local cache. This does not download large dataset payloads.
canarchy datasets fetch <provider>:<dataset> [--json|--jsonl|--text]
Notes:
datasets fetchrecords provenance only — it does not download data. Usedatasets downloadto retrieve the actual file, ordatasets replayto stream it.- normal dataset entries return
download_instructionsplus anext_stepscross-link todatasets download/datasets replay - curated index entries return
is_index=trueandindex_instructions; there is no single dataset payload to download
datasets download
Download a dataset's actual data file to disk (where the manifest exposes a direct URL). Reuses the same manifest resolution as datasets replay, but writes the native file verbatim rather than streaming decoded frames.
canarchy datasets download <provider>:<dataset> --out <path> [--file <name>] [--platform <p>] [--json|--jsonl|--text]
canarchy datasets download <https-url> --out <path> [--json|--jsonl|--text]
Notes:
--fileselects a specific file from a multi-file dataset manifest (id or name);--platformfilters dynamic manifests- reports
out_path,bytes_written,source_format, and anext_stepshint forstats/datasets convert - a download/network failure returns a structured
DATASET_DOWNLOAD_FAILEDerror; a non-replayable index returnsDATASET_INDEX_NOT_REPLAYABLE - CLI-only operator action (writes bulk bytes to an arbitrary host path); not exposed as an MCP tool
datasets cache list
List cached dataset provider manifests and provenance records.
canarchy datasets cache list [--json|--jsonl|--text]
datasets cache refresh
Refresh the built-in dataset catalog manifest.
canarchy datasets cache refresh [--provider <name>] [--json|--jsonl|--text]
datasets convert
Convert a downloaded dataset file to a CANarchy-compatible capture format.
canarchy datasets convert <file> --source-format hcrl-csv|candump|comma-rlog|decoded-signal-csv --format candump|jsonl [--output <path>] [--json|--jsonl|--text]
datasets stream
Stream a downloaded dataset file to candump or JSONL without loading the full conversion into memory.
canarchy datasets stream <file> --source-format hcrl-csv|candump|comma-rlog|decoded-signal-csv --format candump|jsonl [--chunk-size <n>] [--max-frames <n>] [--provider-ref <ref>] [--output <path>] [--json]
Examples:
canarchy datasets stream sample.csv --source-format hcrl-csv --format jsonl --provider-ref catalog:hcrl-car-hacking
canarchy datasets stream sample.log --source-format candump --format jsonl --provider-ref catalog:candid
canarchy datasets stream rlog.zst --source-format comma-rlog --format jsonl --provider-ref catalog:comma-car-segments --max-frames 1000
canarchy datasets stream sample.csv --source-format hcrl-csv --format candump --output sample.candump
canarchy datasets stream sample.csv --source-format hcrl-csv --format jsonl --max-frames 1000
canarchy datasets stream sample.csv --source-format hcrl-csv --format jsonl --json
Notes:
datasets searchdefaults to a compact human-readable table with aTYPEcolumn (INDEXfor curated indexes,PLAYfor replayable datasets); use--verbosefor detailed result blocks with type labels, descriptions, source URLs, replay defaults, index notes, and access notes- without
--json, stream records are written directly to stdout or--output comma-rlogparses openpilot/commarlog.zstCAN events when optional openpilot LogReader support is installed (uv pip install git+https://github.com/commaai/openpilot.giton Python 3.12.x); missing support returnsCOMMA_RLOG_SUPPORT_UNAVAILABLEdecoded-signal-csvingests pre-decoded per-ID signal CSVs (e.g. SynCAN'sLabel,Time,ID,Signal1_of_ID,...): each row'sIDtoken maps to a deterministic arbitration ID (0x-hex, plain decimal, or trailing integer likeid10->10, else a stable hash) and present normalized signal values are packed into payload bytes as big-endian uint16 (round(value * 0xFFFF), clamped); empty signal cells are skipped, andTime/Labelare preserved (Labelsurfaces aspayload.labelin JSONL). Payload bytes are reconstructed, not captured verbatim — suitable for frame-level analysis (stats,re_*), not byte-exact ECU replay- JSONL stream records include
payload.dataset.provider_ref,frame_offset,chunk_index, andchunk_position --chunk-sizecontrols JSONL provenance chunk metadata and does not bound emitted frames--max-framesstops local dataset streaming after at most N emitted frames for candump and JSONL output- with
--json, stdout contains the standard result envelope and reportsframe_count,chunks, andmax_frames - live-bus replay from dataset streams is not part of this command; use explicit replay workflows after writing a capture file
datasets replay
Stream a remote candump dataset file directly to stdout with replay timing. The source may be a direct candump download URL or a replayable dataset ref such as catalog:candid.
canarchy datasets replay <dataset-ref-or-url> [--file <id-or-name>] [--platform <name>] [--limit <n>] [--list-files] [--format candump|jsonl] [--rate <multiplier>] [--max-frames <n>] [--max-seconds <seconds>] [--dry-run] [--json]
Examples:
canarchy datasets replay catalog:candid --rate 1.0
canarchy datasets replay catalog:candid --format jsonl --rate 10 --max-frames 1000
canarchy datasets replay catalog:candid --format jsonl --rate 10 --max-seconds 30
canarchy datasets replay catalog:candid --list-files --json
canarchy datasets replay catalog:candid --file 2_indicator_CAN.log --rate 1000 --max-frames 10 --json
canarchy datasets replay https://ndownloader.figshare.com/files/54551156 --rate 1000 --max-frames 10
canarchy datasets replay catalog:candid --rate 1000 --max-frames 10 --json
canarchy datasets replay catalog:candid --dry-run --json
canarchy datasets replay catalog:comma-car-segments --platform TESLA_MODEL_3 --list-files --limit 20 --json
canarchy datasets replay catalog:comma-car-segments --platform TESLA_MODEL_3 --file 0 --format jsonl --max-frames 1000
Notes:
- without
--json, replayed frames are written directly to stdout as candump or JSONL records for piping - JSONL replay frame events include
payload.dataset.provider_ref,source_url,replay_file,default_replay_file,frame_offset,source_format, andsource_type - with
--json, stdout contains a clean standard result envelope with replay metadata and no frame records --list-files --jsonreturns replay file entries with stableid,name,size_bytes,format, andsource_urlfields--fileaccepts a replay fileidorname; unknown files fail withDATASET_REPLAY_FILE_NOT_FOUNDcatalog:comma-car-segmentsbuilds a dynamic replay manifest from HuggingFacedatabase.json; use--platformto filter platforms such asTESLA_MODEL_3, and--limitto bound listed entries- commaCarSegments replay resolves HuggingFace LFS URLs only for active streaming;
--dry-runand--list-filesdo not open rlog payload streams - Curated indexes that cannot be replayed return
DATASET_INDEX_NOT_REPLAYABLE - Stdin pipeline: pipe
datasets replayoutput intostats --file -,capture-info --file -, orfilter --file -for analysis without temporary files - JSON summary output reports
stop_reason, includingeof,max_frames,max_seconds,broken_pipe, orinterrupted - replay downloads incrementally from the remote HTTP response and does not require a complete local dataset file
--dry-runresolves replay source metadata without opening the remote stream- replaying a curated index entry fails with
DATASET_INDEX_NOT_REPLAYABLE; other non-replayable datasets fail withDATASET_REPLAY_UNAVAILABLE catalog:candidcurrently resolves to the CANdid2_brakes_CAN.logFigshare file as its default replay source
session save
Save a named session with useful CLI context.
canarchy session save <name> [--interface <name>] [--dbc <file>] [--capture <file>] [--json|--jsonl|--text]
session load
Load a previously saved session and mark it active.
canarchy session load <name> [--json|--jsonl|--text]
session show
Show saved sessions and the active session.
canarchy session show [--json|--jsonl|--text]
shell
Run a single shell command through the shared parser, or start a minimal interactive shell loop.
canarchy shell [--command "capture can0 --text"] [--json|--jsonl|--text]
j1939 monitor
Inspect J1939 traffic and emit PGN-oriented structured events.
canarchy j1939 monitor [<interface>] [--pgn <id>] [--json|--jsonl|--text]
Example:
canarchy j1939 monitor --pgn 65262 --json
canarchy j1939 monitor can0 --pgn 65262 --json
Notes:
- without an interface, this command uses an explicit sample/reference provider
- with an interface, this command captures from the selected transport backend and filters to J1939 extended-ID traffic
j1939 decode,j1939 tp sessions,j1939 dm1,j1939 summary,j1939 inventory,j1939 compare, andj1939 mapremain file-backed;j1939 pgnandj1939 spnaccept an optional--fileand otherwise perform a built-in reference lookup
j1939 decode
Decode a capture source into J1939 PGN observations.
canarchy j1939 decode --file <file> [--dbc <path|provider-ref>] [--json|--jsonl|--text]
canarchy j1939 decode --stdin [--dbc <path|provider-ref>] [--json|--jsonl|--text]
Notes:
--stdinreads JSONLframeevents from standard input instead of a--filecapture source--dbcenriches J1939 results with DBC-backed decoded signal events when available
j1939 pgn
Inspect a specific PGN. With --file, reports matching events from the capture; without --file, returns the built-in reference definition (name, label, description, and the catalogued SPNs the PGN carries).
canarchy j1939 pgn <pgn> [--file <file>] [--dbc <path|provider-ref>] [--json|--jsonl|--text]
Example:
canarchy j1939 pgn 61444 --json
canarchy j1939 pgn 65262 --file tests/fixtures/sample.candump --json
j1939 spn
Inspect a specific SPN. With --file, runs the curated/DBC SPN decoder over recorded J1939 traffic; without --file, returns the built-in reference definition (name, owning PGN, units, resolution, offset, bit layout). An OEM SPN absent from the bundled catalog is resolved from a supplied/configured DBC.
canarchy j1939 spn <spn> [--file <file>] [--dbc <path|provider-ref>] [--json|--jsonl|--text]
Example:
canarchy j1939 spn 190 --json
canarchy j1939 spn 110 --file tests/fixtures/sample.candump --json
Notes:
- curated metadata is built in for common SPNs
--dbccan expand coverage for SPNs exposed through DBC signal metadata- unsupported SPNs return a structured
J1939_SPN_UNSUPPORTEDerror
j1939 tp sessions
Summarize J1939 transport-protocol sessions from a capture file. sessions is the default tp action, so j1939 tp --file <file> is equivalent to j1939 tp sessions --file <file>.
canarchy j1939 tp [sessions] <file> [--json|--jsonl|--text]
canarchy j1939 tp [sessions] --file <file> [--json|--jsonl|--text]
Notes:
- the implementation handles BAM and RTS/CTS transport sessions with packet reassembly
j1939 tp --file <file>defaults to thesessionsaction; a bare positional path (j1939 tp <file>) must still be disambiguated via the explicitsessions/compareaction or--file, since the next token is interpreted as the sub-action
j1939 dm1
Inspect DM1 fault traffic from direct J1939 frames and TP-reassembled payloads.
canarchy j1939 dm1 --file <file> [--dbc <path|provider-ref>] [--json|--jsonl|--text]
j1939 faults
Summarize active DM1 faults by ECU/source address, including lamp state and suspicious DTC markers.
canarchy j1939 faults --file <file> [--dbc <path|provider-ref>] [--json|--jsonl|--text]
j1939 inventory
Build a source-address inventory from a J1939 capture file, including top PGNs, component-identification strings, vehicle-identification strings, and DM1 presence.
canarchy j1939 inventory --file <file> [--json|--jsonl|--text]
Example:
canarchy j1939 inventory --file tests/fixtures/j1939_inventory.candump --json
Notes:
- inventory rows are grouped by source address
- printable TP payloads for component identification and vehicle identification are associated with the reporting source address when available
- DM1 presence is summarised per source address so initial triage does not require a second command
j1939 compare
Compare two or more J1939 capture files and highlight common versus capture-unique PGNs, source-address changes, DM1 differences, and printable TP identification changes.
canarchy j1939 compare (<file> <file> [<file> ...] | --file <file> --file <file> ...) [--json|--jsonl|--text]
Example:
canarchy j1939 compare tests/fixtures/j1939_inventory.candump tests/fixtures/j1939_compare_shifted.candump --json
Notes:
- this command requires at least two capture files
--max-frames,--seconds, and--offsetapply independently to each compared capture file- DM1 differences are grouped by source address and surface active-fault or lamp-state changes when present
- printable TP component-identification and vehicle-identification payloads are compared by source address and payload label
j1939 map
Build a passive network-topology map from a J1939 capture file: nodes (one per source address, carrying the SA name, decoded Address Claimed NAME fields when present, and component/vehicle identification strings) and edges (observed PGN flows from a source address to a destination, or to the broadcast/global address). The map is derived purely from captured frames — there is no active probing or address-claim solicitation.
canarchy j1939 map --file <file> [--json|--jsonl|--text]
Example:
canarchy j1939 map --file tests/fixtures/j1939_map.candump --json
Notes:
- nodes reuse the
j1939 inventorymachinery, so identification strings and source-address names match between the two commands - the 64-bit NAME from an Address Claimed message (PGN 60928) is decoded into its constituent fields (manufacturer code, function, identity number, industry group, arbitrary-address-capable flag, and the instance fields) when address-claim traffic is present in the capture
- edges aggregate repeated frames into a single per-(source, destination, PGN) flow with a frame count; PDU1 traffic addressed to the global address (0xFF) is reported as a broadcast, the same as PDU2 traffic
- the structured
nodes/edgesoutput is suitable for graphing and diffing
tui
Start the initial text-mode TUI shell.
canarchy tui [--command "<existing canarchy command>"]
Notes:
- the first implementation is a thin text-mode shell, not a full-screen terminal UI
- panes include bus status, live traffic, alerts, and command entry help
- command entry runs existing CANarchy commands through the shared parser and result path
- nested interactive front ends like
shellortuiare rejected from TUI command entry
uds scan
Inspect representative UDS responder discovery transactions.
canarchy uds scan <interface | doip://host:port?logical_address=0x0E80> [--ack-active] [--json|--jsonl|--text]
Notes:
- with the
python-canbackend, this command sends a single-frame functional DiagnosticSessionControl request and summarizes captured UDS responses after ISO-TP reassembly when needed - with the
scaffoldbackend, this command emits explicit sample/reference UDS transaction data - a
doip://<host>:<port>?logical_address=0x0E80target routes the scan over DoIP (Diagnostic over IP, ISO 13400-2): the command opens a TCP connection, performs routing activation, and probes the default / programming / extended diagnostic sessions, emitting the sameuds_transactionevents withtransport: doipin the envelope. Optional query parameters:source_address(tester address, default0x0E00),activation_type(default0x00),timeout(seconds, default2.0); port defaults to13400 - DoIP targets are an active network egress and are gated by the active-transmit safety model; structured errors include
DOIP_INVALID_TARGET(exit 1),DOIP_CONNECTION_FAILED/DOIP_TIMEOUT/DOIP_ROUTING_ACTIVATION_DENIED/DOIP_DIAGNOSTIC_NACK/DOIP_PROTOCOL_ERROR(exit 2) --ack-activerequests an interactiveYESconfirmation before the diagnostic request is sent- if a segmented response is truncated or arrives out of order, the emitted
uds_transactionevent keeps the partialresponse_dataand setscompletetofalse
uds trace
Inspect representative UDS request and response transactions.
canarchy uds trace <interface | doip://host:port?logical_address=0x0E80> [--ack-active] [--json|--jsonl|--text]
Notes:
- with the
python-canbackend, this command captures raw CAN frames and infers UDS request/response transactions from common diagnostic IDs, including ISO-TP multi-frame responses - with the
scaffoldbackend, this command emits explicit sample/reference UDS transaction data - a
doip://target routes the trace over DoIP: the command performs routing activation and a DiagnosticSessionControl + TesterPresent exchange, emitting the transactions withtransport: doip. Because DoIP is connection-oriented, this is an active exchange (not a passive sniff) and is gated by the active-transmit safety model; the same DoIP query parameters and error codes asuds scanapply - flow-control frames are used only for reassembly and are not emitted as transactions
- if a segmented response is truncated or arrives out of order, the emitted
uds_transactionevent keeps the partialresponse_dataand setscompletetofalse
uds services
Inspect the built-in UDS service catalog, or actively probe which services an ECU supports.
canarchy uds services [<interface>] [--request-id 0x7E0] [--response-id 0x7E8] \
[--probe-start 0x00 --probe-end 0xFF] [--max-requests N] [--timeout S] \
[--dry-run] [--ack-active] [--json|--jsonl|--text]
Notes:
- without an interface this is a reference command (
mode: reference): output includes service identifier, positive-response identifier, category, and subfunction expectations - with an interface this becomes an active probe (
mode: active, gated by the active-transmit safety model): each candidate service id is sent once to--request-id, and a service is reportedsupportedwhen it answers positively or with any negative response code other thanServiceNotSupported/ServiceNotSupportedInActiveSession --probe-start/--probe-endprobe a raw service-id range instead of the catalog;--max-requestscaps the probe count
uds subservices
Enumerate which subfunctions of a UDS service an ECU supports.
canarchy uds subservices <interface> --service 0x19 [--sub-start 0x00] [--sub-end 0xFF] \
[--request-id 0x7E0] [--response-id 0x7E8] [--timeout S] [--dry-run] [--ack-active] [--json|--jsonl|--text]
uds ecu-reset / uds tester-present
Send a single ECUReset (0x11) or TesterPresent (0x3E) request.
canarchy uds ecu-reset <interface> [--reset-type 0x01] [--ack-active] [--dry-run] [--json|--jsonl|--text]
canarchy uds tester-present <interface> [--suppress] [--ack-active] [--dry-run] [--json|--jsonl|--text]
uds security-seed
Collect SecurityAccess (0x27) seeds for an explicit session and level.
canarchy uds security-seed <interface> [--level 0x01] [--session 0x03] [--count N] \
[--max-duration S] [--ack-active] [--dry-run] [--json|--jsonl|--text]
Notes:
--levelmust be odd (the requestSeed subfunction);--sessionoptionally enters a diagnostic session first- output reports
collected,distinct_seeds, and the per-request seed bytes
uds dump-dids
Read a range of DataIdentifiers via ReadDataByIdentifier (0x22).
canarchy uds dump-dids <interface> [--did-start 0xF180] [--did-end 0xF1FF] [--limit 256] \
[--max-duration S] [--ack-active] [--dry-run] [--json|--jsonl|--text]
uds read-memory
Read a bounded memory range via ReadMemoryByAddress (0x23).
canarchy uds read-memory <interface> --address 0x080000 --size N [--chunk-size 4] \
[--address-bytes N] [--size-bytes N] [--output PATH] [--ack-active] [--dry-run] [--json|--jsonl|--text]
Notes:
- the request is chunked by
--chunk-size; the total size is bounded (max 65536 bytes) --outputwrites the reassembled memory bytes to a file when any bytes were read; provenance (address,size,chunk_size, request/response ids) is in the result data
uds auto
Bounded zero-knowledge active diagnostic reconnaissance: discover responders, probe services, optionally probe a bounded DID range.
canarchy uds auto <interface> [--request-start 0x7E0] [--request-end 0x7E7] [--no-services] \
[--probe-dids --did-start 0xF190 --did-end 0xF19F --did-limit 16] [--response-id ID] \
[--max-duration S] [--ack-active] [--dry-run] [--json|--jsonl|--text]
Notes:
- discovery sends a DiagnosticSessionControl request to each id in
[--request-start, --request-end]and notes responders;--response-idis auto (any responder id) unless pinned - per responder it enumerates supported services (unless
--no-services) and, with--probe-dids, reads a bounded DID range; the result reportscompletefor the scan budget - all
udsactive workflows (everything except the referenceuds servicescatalog) are CLI-only operator actions and are not exposed as MCP tools
xcp scan
Discover XCP responders by transmitting an XCP CONNECT command.
canarchy xcp scan <interface> [--request-id 0x3E0] [--response-id 0x3E1] [--ack-active] [--dry-run] [--json|--jsonl|--text]
Notes:
- XCP-on-CAN: sends a single CONNECT (
FF 00) on--request-idand reports each command-response object on--response-idas anxcp_transactionevent; a CONNECT positive response is parsed into resources, max-CTO, max-DTO, and protocol/transport versions - with the
scaffoldbackend, this command emits sample/reference XCP transaction data - this is an active command honouring the active-transmit safety model;
--ack-activerequests an interactiveYESconfirmation before the CONNECT is sent;--dry-runplans the CONNECT frame (reported asplanned_frame,mode: dry_run) without opening the transport or transmitting --request-id/--response-idaccept decimal or0xhex CAN ids (defaults 0x3E0 / 0x3E1; an extended 29-bit request id is transmitted as an extended frame); a malformed id returnsXCP_INVALID_ID- the
xcp_scanMCP tool is gated like other active-transmit tools: mandatoryack_active=truewithdry_rundefaulting to true
xcp info
Connect to an XCP slave and report its basic capabilities.
canarchy xcp info <interface> [--request-id 0x3E0] [--response-id 0x3E1] [--timeout S] [--ack-active] [--dry-run] [--json|--jsonl|--text]
Notes:
- sends CONNECT, then the optional GET_STATUS, GET_COMM_MODE_INFO, and GET_ID commands; the
capabilitiesblock reports the parsed CONNECT info (resources, max-CTO/DTO, byte order, versions) plus session status, comm-mode info, and identification mode/length - optional commands the slave does not implement are reported per-command as
status: unsupportedrather than failing the whole command - active command honouring the active-transmit safety model;
--dry-runplans the four commands without transmitting and needs no interface - a silent slave returns
XCP_NO_RESPONSEand a CONNECT rejection returnsXCP_ERROR_RESPONSE(exit 2)
xcp dump
Upload a bounded XCP memory range.
canarchy xcp dump <interface> --address 0x08000000 --size N [--chunk-size 4] [--address-extension 0x00] \
[--short-upload] [--output PATH] [--timeout S] [--ack-active] [--dry-run] [--json|--jsonl|--text]
Notes:
- CONNECT, then uploads the range in
--chunk-sizechunks (1–7 bytes, bounded by the slave's MAX_CTO-1) via SET_MTA + UPLOAD, or SHORT_UPLOAD with--short-upload - the total size is bounded (max 65536 bytes);
--outputwrites the assembled bytes when any were read; the envelope reportsbytes_read,complete, the per-chunk records, and the assembledmemoryhex - address byte order follows the slave's CONNECT comm-mode-basic byte order
- bounds errors (
XCP_INVALID_VALUE,XCP_DUMP_TOO_LARGE,XCP_INVALID_CHUNK_SIZE,XCP_CHUNK_EXCEEDS_MAX_CTO) exit 1;XCP_NO_RESPONSE/XCP_ERROR_RESPONSEexit 2 xcp infoandxcp dumpare CLI-only operator actions and are not exposed as MCP tools
xcp trace
Pair XCP command and response transactions from bus traffic.
canarchy xcp trace <interface> [--request-id 0x3E0] [--response-id 0x3E1] [--json|--jsonl|--text]
Notes:
- passive: pairs each command CTO on
--request-idwith the following response CTO on--response-id, naming the command and surfacing positive/error status (error codes resolve to ASAM names) - with the
scaffoldbackend, this command emits sample/reference XCP transaction data
xcp read
Surface raw DAQ measurement (DTO) payloads from a short capture.
canarchy xcp read <interface> [--response-id 0x3E1] [--json|--jsonl|--text]
Notes:
- passive: emits an
xcp_measurementevent (packet identifier plus raw bytes) for each DAQ DTO on--response-id; command-response objects (PID ≥ 0xFC) are skipped - signal-level decoding of DAQ payloads requires the slave's A2L description and is out of scope; raw ODT bytes are reported
xcp commands
Inspect the built-in XCP command catalog.
canarchy xcp commands [--json|--jsonl|--text]
Notes:
- this is a reference command and does not require an interface
- output includes the command code, name, and category (standard / calibration / daq / programming)
doip discovery
Discover reachable DoIP entities via a UDP vehicle-identification broadcast.
canarchy doip discovery [host] [--port 13400] [--timeout 2.0] [--ack-active] [--dry-run] [--json|--jsonl|--text]
Notes:
- broadcasts a DoIP VehicleIdentificationRequest (default host
255.255.255.255) and reports each responding entity's VIN, logical address, EID, and GID - active network egress honouring the active-transmit safety model;
--dry-runplans the broadcast without transmitting - a send failure returns
DOIP_CONNECTION_FAILED(exit 2)
doip services / ecu-reset / tester-present / security-seed / dump-dids
Active UDS diagnostic workflows over a DoIP session, addressing the ECU by logical address.
canarchy doip services <doip-uri> [--ack-active] [--dry-run] [--json|--jsonl|--text]
canarchy doip ecu-reset <doip-uri> [--reset-type 0x01] [--ack-active] [--dry-run] ...
canarchy doip tester-present <doip-uri> [--suppress] [--ack-active] [--dry-run] ...
canarchy doip security-seed <doip-uri> [--level 0x01] [--session 0x03] [--count N] [--ack-active] [--dry-run] ...
canarchy doip dump-dids <doip-uri> [--did-start 0xF180] [--did-end 0xF1FF] [--limit N] [--ack-active] [--dry-run] ...
Where <doip-uri> is doip://<host>:<port>?logical_address=0x0E80 (same query parameters as uds scan over DoIP).
Notes:
- each workflow activates routing, then runs the relevant UDS requests over the DoIP session, emitting
uds_transactionevents with negative-response decoding plus per-requeststatus servicesreports which UDS services the ECU supports;security-seedrequires an odd--level;dump-didsreads a bounded DID range- all
doipcommands honour the active-transmit safety model and support--dry-runrequest plans; bounds/validation errors (DOIP_INVALID_VALUE,DOIP_INVALID_SECURITY_LEVEL,DOIP_INVALID_DID_RANGE) exit 1 and DoIP transport/protocol errors exit 2 - the
doipcommand group is CLI-only and is not exposed as MCP tools (active network egress to an arbitrary host)
j1587 decode
Decode a J1708 capture file into J1587 PID parameters.
canarchy j1587 decode --file <path> [--offset N] [--max-frames N] [--seconds N] [--json|--jsonl|--text]
canarchy j1587 decode --file tests/fixtures/j1708_sample.j1708 --json
Notes:
- each line of the capture file must read
(timestamp) j1708 <hex>, where<hex>is the full raw message (source MID, PID-framed parameters, and a trailing checksum byte) - emits one
j1587_parameterevent per parameter, withmid,pid,raw,name,value,units,checksum_valid, andtimestamp; PIDs are resolved against the bundledresources/j1587/pids.jsoncatalog (override viaCANARCHY_J1587_PID_OVERRIDESor~/.canarchy/j1587_pids.json) - an all-ones raw value (the J1587 "data not available" sentinel) resolves
valuetonullwhile keepingname/units datareportsmode: "passive",file,message_count,parameter_count, andchecksum_failures--offset/--max-frames/--secondsapply to the message stream the same way they do forj1939 decode- a missing
--filereturnsJ1587_SOURCE_UNAVAILABLE; a line that does not match the expected format, has an odd number of hex digits, or fails J1708 framing returnsJ1587_SOURCE_INVALID(exit code 1)
j1587 pids
Inspect the built-in J1587 PID catalog.
canarchy j1587 pids [--json|--jsonl|--text]
Notes:
- this is a reference command and does not require a capture file
- output includes each PID's name, data length, resolution, offset, units, and byte order
j2497 decode
Decode a J2497 (PLC4TRUCKS trailer power-line) capture file into frames.
canarchy j2497 decode --file <path> [--offset N] [--max-frames N] [--seconds N] [--json|--jsonl|--text]
canarchy j2497 decode --file tests/fixtures/j2497_sample.j2497 --json
Notes:
- each line of the capture file must read
(timestamp) j2497 <hex>, where<hex>is the full raw frame (source MID, message data, and a trailing checksum byte) - emits one
j2497_messageevent per frame, withmid,name,data,checksum_valid, andtimestamp; MIDs are resolved against the bundledresources/j2497/mids.jsoncatalog (override viaCANARCHY_J2497_MID_OVERRIDESor~/.canarchy/j2497_mids.json) - J2497 reuses the J1708/J1587 frame format; the
databytes follow the J1587 PID framing rules, so feed the same byte format toj1587 decodefor PID-level resolution datareportsmode: "passive",file,frame_count, andchecksum_failures--offset/--max-frames/--secondsapply to the frame stream the same way they do forj1939 decode- live J2497 / power-line access requires a power-line carrier modem and external hardware and is not provided; this command is decode-only over captured frames
- a missing
--filereturnsJ2497_SOURCE_UNAVAILABLE; a line that does not match the expected format, has an odd number of hex digits, or is too short to be a frame returnsJ2497_SOURCE_INVALID(exit code 1)
j2497 mids
Inspect the built-in J2497/J1587 MID catalog.
canarchy j2497 mids [--json|--jsonl|--text]
Notes:
- this is a reference command and does not require a capture file
- output includes each MID's ECU name (trailer ABS controllers and related units)
re counters
Rank likely counter fields from recorded CAN traffic.
canarchy re counters (<file> | --file <file>) [--top <n>] [--json|--jsonl|--text]
Notes:
- this command is passive and file-backed
- the current implementation inspects nibble- and byte-sized candidate fields on recorded arbitration IDs
- candidates are ranked by monotonicity evidence and explicit rollover detection
- J1939 transport-protocol IDs (TP.CM / TP.DT / ETP.CM / ETP.DT) are excluded — their sequence numbers are protocol plumbing, not application counters — and reported in metadata as
excluded_transport_ids - J1939 candidates carry
pgn,pgn_label,source_address, andsource_address_name; every candidate carriesarbitration_id_hex --topcaps the returnedcandidatesarray (default 20;0for all);candidate_countreports the full total andreturned_countthe number returned
re signals
Rank likely signal fields from recorded CAN traffic.
canarchy re signals (<file> | --file <file>) [--top <n>] [--json|--jsonl|--text]
Notes:
- this command is passive and file-backed
- the current implementation inspects nibble-aligned 4-bit fields, byte-aligned 8-bit fields, and word-aligned 16-bit fields
- candidates are ranked by change-rate preference, observed range, and value diversity
- J1939 transport-protocol IDs (TP.CM / TP.DT / ETP.CM / ETP.DT) are excluded from signal inference and reported under
excluded_transport_ids - J1939 candidates carry
pgn,pgn_label,source_address, andsource_address_name; every candidate carriesarbitration_id_hex - arbitration IDs with fewer than 5 frames are omitted from the candidate list and reported in
low_sample_ids --topcaps the returnedcandidatesarray (default 20;0for all);candidate_countreports the full total andreturned_countthe number returned
re correlate
Correlate candidate bit fields against a timestamped reference series.
canarchy re correlate (<file> | --file <file>) --reference <ref.json|ref.jsonl> [--json|--jsonl|--text]
Notes:
- this command is passive and file-backed
- reference files may be JSON arrays, named JSON objects with
nameandsamples, or JSONL sample streams - each reference sample must include numeric
timestampandvaluefields - candidates report
pearson_r,spearman_r,sample_count, andlag_ms, and are ranked by absolute Pearson correlation
re anomalies
Flag inter-frame-timing outliers and unexpected/dropped arbitration IDs.
canarchy re anomalies (<file> | --file <file>) [--baseline <ref>] [--dbc <ref>] [--z-threshold <z>] \
[--cv-max <cv>] [--min-samples <n>] [--entropy-drop <r>] [--rate-drop <r>] [--top <n>] \
[--offset <n>] [--max-frames <n>] [--seconds <s>] [--json|--jsonl|--text]
Notes:
- this command is passive and file-backed; it honors the standard
--offset,--max-frames, and--secondswindow flags - with
--baseline, per-ID timing statistics and the expected ID set are learned from the reference capture and the input is scored against them; without it, each ID is scored against its own statistics (self-consistency), ID-presence anomalies are not emitted, and a warning nudges the operator toward supplying a baseline - anomalies carry
arbitration_id,kind(timing/unknown-id/dropped-id/rate-drop/rate-spike/entropy-collapse),score,z_score,z_score_capped,sample_count,timestamp, and arationale, ranked by score; J1939 candidates additionally carrypgn,pgn_label,source_address, andsource_address_name - against a
--baseline, IDs present in both captures are additionally checked for two attack classes that pure timing analysis misses: arate-drop/rate-spikewhen an ID's time-normalised frame rate falls to--rate-dropof (default 0.5; suppression) or rises to its reciprocal above (injection) the baseline rate, and anentropy-collapsewhen an ID's mean per-byte payload entropy falls to--entropy-dropof (default 0.5) a baseline that itself carried meaningful entropy (plateau / frozen-value attacks) --rate-dropand--entropy-dropmust each be strictly between 0 and 1 (an out-of-range ratio would make the corresponding check fire on unchanged IDs or never fire at all); out-of-range values are rejected withINVALID_RATE_DROP/INVALID_ENTROPY_DROP- only IDs judged cyclic are timing-checked, so event-based and event-periodic messages are not falsely flagged. Classification is authoritative from the database when
--dbcis supplied (a message'scycle_time/ send type decides cyclic vs event); otherwise a robust coefficient of variation (scaled median-absolute-deviation over the median inter-frame gap) is compared against--cv-max(default 0.5) - timing statistics use the median and MAD rather than mean and standard deviation, so a minority of outlier gaps cannot inflate the spread and mask themselves
- a cyclic-looking ID needs at least
--min-samplesinter-frame gaps before its timing is scored (default 10 without a baseline, 3 with one); sparser IDs are listed underlow_rate_idswith classification sourcelow-sampleinstead of being ranked, and reported z-scores are capped at ±100σ --topcaps the rankedcandidatesarray (default 20;0for all) for agent-friendly output;candidate_countalways reports the full total andreturned_countthe number returned- the payload also reports
mode,timing_source(dbc/observed),min_samples,entropy_drop,rate_drop,cyclic_ids,event_ids(timing skipped),low_rate_ids, and a per-IDclassificationslist
re corpus
Cross-capture corpus analysis: per-ID coverage matrix, cycle-time drift, and signal stability across multiple captures.
canarchy re corpus (<file> ... | --file <file> ...) [--corpus-glob <pattern>] \
[--offset <n>] [--max-frames <n>] [--seconds <s>] [--json|--jsonl|--text]
Notes:
- this command is passive and file-backed; accepts two or more captures positionally, via repeatable
--file, or expanded from--corpus-glob - reports per-ID
coverage(frame counts per capture, presence),cycle_time_drift(cross-capture mean-gap stddev and drift ratio), andsignal_stability(per-byte coefficient of variation), plus asummaryof unique/stable/drifting/new IDs - J1939 ids are annotated with
pgn,pgn_label, andsource_address_name; every row carriesarbitration_id_hex --offset,--max-frames, and--secondsbound each capture independently
re entropy
Rank arbitration IDs and byte positions by Shannon entropy over recorded CAN traffic.
canarchy re entropy (<file> | --file <file>) [--top <n>] [--json|--jsonl|--text]
Notes:
- this command is passive and file-backed
- JSON output includes one candidate per arbitration ID plus a per-byte entropy breakdown inside each candidate
- IDs with fewer than 10 observed frames are retained and marked with
low_sample: true - J1939 transport-protocol IDs are retained but labeled with
j1939_transport: trueand a rationale note, so TP framing is not mistaken for an application signal - J1939 candidates carry
pgn,pgn_label,source_address, andsource_address_name; every candidate carriesarbitration_id_hex --topcaps the returnedcandidatesarray (default 20;0for all);candidate_countreports the full total andreturned_countthe number returned
re match-dbc
Rank candidate DBC files against a capture using provider-backed catalog metadata.
canarchy re match-dbc (<capture> | --file <capture>) [--provider <name>] [--limit <n>] [--json|--jsonl|--text]
Notes:
- this command is passive and file-backed
- candidates are scored by frequency-weighted arbitration-ID coverage against the capture
- the default provider is
opendbc
re shortlist-dbc
Rank candidate DBC files against a capture after pre-filtering by vehicle make.
canarchy re shortlist-dbc (<capture> | --file <capture>) --make <brand> [--provider <name>] [--limit <n>] [--json|--jsonl|--text]
Notes:
- this command is passive and file-backed
--makenarrows provider-catalog candidates before scoring them against the capture- the default provider is
opendbc
re suggest
Propose names for ranked signal candidates.
canarchy re suggest (<file> | --file <file>) [--reference-dbc <ref>] [--limit <n>] \
[--llm <provider> [--llm-model <model>] [--yes]] [--json|--jsonl|--text]
Notes:
- passive and file-backed: reuses
re signalsto rank candidates, then attachessuggestions(each with asourceofdbc/spn/pgn/heuristic/llmand aconfidence), reporting the top assuggested_name/suggested_source - heuristics combine reference-DBC overlap (
--reference-dbc, a path or provider ref), bit-range overlap with the bundled J1939 SPN catalog, the PGN name as a coarse fallback, and a plain-English template from the candidate's change behaviour — all fully offline --llm <provider>(off by default; onlyanthropicis supported) enriches names via an external LLM. It requires explicit confirmation (--yes, or aYESreply, orCANARCHY_LLM_NONINTERACTIVE=1), sends only candidate metadata — never payload bytes — and recordsexternal_enrichmentplus anEXTERNAL_SERVICE_CALLEDwarning. Declining returnsLLM_CONFIRMATION_DECLINED; an unknown provider returnsLLM_PROVIDER_UNSUPPORTED; a missing key returnsLLM_PROVIDER_UNAVAILABLE- the
re_suggestMCP tool exposes the heuristic path only; the--llmenrichment is CLI-only
config show
Inspect the effective transport configuration and the source of each setting.
canarchy config show [--json|--jsonl|--text]
The payload includes both interface (the python-can backend type) and default_interface (the optional CAN channel fallback for commands that omit their interface argument).
doctor
Run local environment health checks and return the canonical envelope.
Each check has a name, status (ok, warn, or fail), detail, and
an optional hint for non-ok results.
canarchy doctor [--json|--jsonl|--text]
Covered checks:
python_version— Python is at least 3.12.python_can—python-canis importable in the active environment.transport_backend— the effective transport backend resolves to a known backend.python_can_interface_dependency— when the effective python-can interface is a known vendor backend such aspcan,vector, orkvaser, the corresponding python-can interface module is importable. This is an offline import check only; it does not open hardware.config_file—~/.canarchy/config.tomlparses cleanly when present.cache_dirs— DBC, dataset, and skills caches are writable.opendbc_cache— opendbc DBC cache is populated; warns if it needsdbc cache refresh.mcp_server— the MCP stdio server is constructable.version_consistency— the installed package version matchessrc/canarchy/__init__.py.
The command also runs against the MCP server as the doctor tool. No
network or live bus access is required.
completion
Emit a shell completion script for the given shell. The script is written to stdout — not wrapped in the canonical envelope, because the output is meant to be sourced.
canarchy completion {bash,zsh,fish}
Install snippets:
- bash —
eval "$(canarchy completion bash)"in~/.bashrc, or copy the output into~/.bash_completion.d/canarchy. - zsh —
eval "$(canarchy completion zsh)"in~/.zshrc, or save the output to a directory on$fpathsuch as~/.zsh/completions/_canarchyand runcompinit. - fish —
canarchy completion fish | sourcefrom~/.config/fish/config.fish, or save to~/.config/fish/completions/canarchy.fish.
Supplying an unsupported shell name returns the standard
INVALID_ARGUMENTS structured error.
Global flags
The following flags are accepted before any subcommand (place them
between canarchy and the subcommand name):
--log-level {debug,info,warn,error}— stderr log verbosity; defaults towarn. Log records never contaminate machine-readable stdout (--json,--jsonl,--text).--quiet— suppress every level belowERROR. Useful in pipelines where only structured errors should reach stderr.
fuzz
Active-transmit fuzzing, gated by the controls in
docs/design/active-transmit-safety.md.
Three subcommands, all built on the pure-function mutation engine in
src/canarchy/fuzzing.py. Every emitted event carries a stable
run_id (UUID) so post-mortem analysis can match output to the
invocation that produced it.
--dry-run is the safe planning path: events are emitted as JSONL
with payload.frame.dry_run = true, no transport is opened, and the
--ack-active confirmation prompt is skipped. Without --dry-run,
the existing active-transmit safety gate (--ack-active plus optional
config-driven prompt) applies before any frame is transmitted via
LocalTransport.send.
canarchy fuzz payload <interface> --id <hex> --strategy {bitflip,random,boundary}
[--data <hex>] [--dlc <n>] [--max <n>]
[--rate <hz>] [--seed <int>] [--extended]
[--repair-crc] [--crc-algorithm <name>] [--crc-address <id>]
[--dry-run] [--run-id <uuid>] [--ack-active]
canarchy fuzz replay --file <capture> --strategy {timing,payload-bitflip}
[--interface <iface>] [--max <n>] [--rate <hz>] [--seed <int>]
[--repair-crc] [--crc-algorithm <name>] [--crc-address <id>]
[--dry-run] [--run-id <uuid>] [--ack-active]
canarchy fuzz arbitration-id <interface> --range <start>:<end> [--step <n>]
[--data <hex>] [--rate <hz>] [--extended]
[--repair-crc] [--crc-algorithm <name>] [--crc-address <id>]
[--dry-run] [--run-id <uuid>] [--ack-active]
--repair-crc recomputes the final payload byte after mutation. --crc-algorithm
accepts stellantis, sae-j1850, or fca-giorgio; if omitted, fuzz repair uses
stellantis. --crc-address supplies the arbitration ID used by algorithms that
include the message address; when omitted, each generated frame's arbitration ID is used.
Strategies and the engine they map to are documented in the
active-transmit safety design. The
following follow-up controls from that spec are tracked separately and
will land in subsequent PRs: configurable rate-cap ceiling
([safety.rate_cap] in ~/.canarchy/config.toml), TOML target
allowlist (--targets), explicit KILL_SWITCH_TRIGGERED alert on
SIGINT, MCP ack_active=true enforcement (#312).
fuzz guided
Response-feedback coverage-guided fuzzing against an ECU target.
canarchy fuzz guided <interface> --id <arb-id> [--signals nrc,pos,dm1,timing,silence]
[--corpus <dir>] [--seed-data <hex>] [--max-iterations <n>]
[--max-seconds <s>] [--max-corpus <n>] [--rate <hz>] [--seed <int>]
[--extended] [--ack-active] [--dry-run] [--json|--jsonl|--text]
Notes:
- active-transmit: each iteration sends a mutated payload (via the
canarchy.fuzzinghavoc/splice mutators) on--idand observes the target's response. Novelty is scored from observed responses — UDS NRCs, UDS positive responses, DM1 fault emergence, response-timing buckets, and silence — selectable via--signals(default all) - inputs that elicit new behaviour become corpus seeds whose lineage is prioritised for further mutation;
--corpus <dir>persists the corpus (raw seed files plus alineage.jsonmanifest) and reloads it to resume campaigns;--max-corpuscaps retained seeds (lowest-scoring pruned first) - the campaign is bounded by
--max-iterationsand/or--max-seconds; the envelope reportsiterations,new_behaviour_count,corpus_size,unique_markers,stop_reason, and afindingslist - honours the active-transmit safety model (
--ack-active,--ratepacing);--dry-runplans the campaign (planned mutations,mode: dry_run) without opening the transport. Structured errors:FUZZ_GUIDED_INVALID_SIGNALS,FUZZ_GUIDED_INVALID_ID(exit 1),FUZZ_GUIDED_TRANSPORT_FAILED(exit 2) - the
fuzz_guidedMCP tool is gated like other active tools (mandatoryack_active=true,dry_rundefaulting to true)
fuzz identify
Narrow a fuzz log to the culprit frame by replaying bisected windows and recording effect/no-effect observations.
canarchy fuzz identify <log> [--interface can0] [--observations FILE] [--observe effect|no-effect ...]
[--rate 100] [--max-window N] [--ack-active] [--dry-run] [--json|--jsonl|--text]
Notes:
<log>is a candump capture or a JSONL fuzz log / replay plan (one CAN-frame object per line, with top-level orpayload-nestedarbitration_id+data)- the workflow bisects the log: each round replays the lower half of the current candidate range, and the operator records whether the effect reproduced. Mark observations non-interactively with
--observe effect|no-effect(repeatable) and/or a JSON--observationsfile (["no-effect", "effect", ...]) - one round per invocation: with an
--interfaceand without--dry-runit replays the next window live (behind the active-transmit safety model), then reports the candidate range / next window so you record an observation and re-invoke. With a full observation sequence supplied up front it resolves the culprit with no transmission - JSON output includes
next_window/replayed_window,observations,candidate_lo/candidate_hi/candidate_frames,resolved/culprit,confidence,rationale, and provenance (source,frame_count,planned_rounds) --max-windowrefuses to replay a window larger than N frames (FUZZ_IDENTIFY_WINDOW_TOO_LARGE); invalid logs/observations returnFUZZ_IDENTIFY_LOG_UNAVAILABLE/FUZZ_IDENTIFY_INVALID_LOG/FUZZ_IDENTIFY_INVALID_OBSERVATION(exit 1)fuzz identifyis a CLI-only operator workflow and is not exposed as an MCP tool
mcp serve
Start the MCP server over stdio.
canarchy mcp serve
Notes:
- this command does not accept output flags
- the current MCP tool surface is a curated non-interactive subset of the CLI, not every implemented command
mcp install
Write the canarchy MCP server block into a client configuration file.
canarchy mcp install --client {claude-desktop,claude-code} [--config-path PATH] \
[--command COMMAND] [--dry-run] [--ack] [--json|--jsonl|--text]
Flags:
--client {claude-desktop,claude-code}— required; selects the target client.claude-desktopresolves the per-platform config path (macOS / Windows / Linux);claude-codewrites a project-scoped.mcp.jsonin the current directory.--config-path PATH— override the auto-detected config path.--command COMMAND— the command the client runs for the server (defaultcanarchy; use an absolute venv path whencanarchyis not onPATH).--dry-run— print the would-write config without touching disk.--ack— skip theYESconfirmation prompt and write immediately.
Behavior:
- merges the
mcpServers.canarchyentry without disturbing other servers - treats an identical existing entry as a no-op (
action: unchanged) - refuses to overwrite a different existing
canarchyentry actionin the envelope data is one ofcreate,update,unchanged, orplanned(dry-run)- this command is CLI-only and is not exposed as an MCP tool (writing a client config is a user action)
Structured error codes: MCP_INSTALL_CONFLICT, MCP_INSTALL_INVALID_CONFIG, MCP_INSTALL_DIR_MISSING, MCP_INSTALL_READ_FAILED, MCP_INSTALL_WRITE_FAILED, MCP_INSTALL_DECLINED.
Output Modes
All commands support:
--json--jsonl--text
--text is the default when no output mode is specified. --table remains accepted as a compatibility alias for --text, but new examples and automation should use --text.
Current behavior:
--jsonemits one structured JSON object--jsonlemits one JSON object per line- event-producing commands emit each event as its own JSON line; command warnings that are not already events are emitted as
alertevent lines - event-less successful commands emit a single result object line
- failed commands emit a single error result object line
--textemits a human-readable summary view, with protocol-aware pretty-printing for J1939 monitor and decode workflows
J1939 --text output includes:
- PGN
- source address
- destination address when present, otherwise broadcast
- priority
- CAN identifier
- payload bytes
JSON Result Shape
Successful --json output uses this shape:
{
"ok": true,
"command": "capture",
"data": {},
"warnings": [],
"errors": []
}
Error --json output and event-less/error --jsonl output use this shape:
{
"ok": false,
"command": "decode",
"data": {},
"warnings": [],
"errors": [
{
"code": "DBC_LOAD_FAILED",
"message": "Failed to parse DBC file.",
"hint": "Validate the DBC syntax and line endings."
}
]
}
Event Types In Structured Output
Implemented commands currently emit these event types:
framedecoded_messagesignalj1939_pgnj1587_parameterj2497_messageuds_transactionxcp_transactionxcp_measurementreplay_eventalert
Exit Codes
0success1user, input, or usage error2backend or transport error3decode, schema, or DBC error4partial success
Representative failures:
INVALID_ARGUMENTS=> exit code1INVALID_RATE=> exit code1TRANSPORT_UNAVAILABLE=> exit code2CAPTURE_SOURCE_UNAVAILABLE=> exit code2DBC_LOAD_FAILED=> exit code3DBC_SIGNAL_INVALID=> exit code3
Examples
Transport Capture
canarchy capture can0 --json
Transport Stats
canarchy stats --file tests/fixtures/sample.candump --json
Capture Metadata
canarchy capture-info --file tests/fixtures/sample.candump --json
Deterministic Replay
canarchy replay --file tests/fixtures/sample.candump --rate 0.5 --json
J1939 Monitor
canarchy j1939 monitor --json
J1939 PGN Filter
canarchy j1939 monitor --pgn 65262 --json
DBC Decode
canarchy decode --file tests/fixtures/sample.candump --dbc tests/fixtures/sample.dbc --json
DBC Provider Search
canarchy dbc search toyota --provider opendbc --json
DBC Provider Decode
canarchy decode --file tests/fixtures/sample.candump --dbc opendbc:toyota_tnga_k_pt_generated --json
Reverse-Engineering DBC Match
canarchy re match-dbc tests/fixtures/sample.candump --provider opendbc --limit 5 --json
DBC Encode
canarchy encode --dbc tests/fixtures/sample.dbc EngineStatus1 CoolantTemp=55 OilTemp=65 Load=40 LampState=1 --json
UDS Scan
canarchy uds scan can0 --json
Notes:
- the result reports
protocol_decoderasbuilt-inby default - when the optional Scapy extra is installed, UDS transaction payloads may include summary-level request/response enrichment without changing the command surface
UDS Trace
canarchy uds trace can0 --json
Notes:
- the result reports
protocol_decoderasbuilt-inby default - negative responses may include
negative_response_codeandnegative_response_name
Dataset Analysis (CANdid)
The CANdid dataset (VehicleSec 2025) provides candump-format CAN logs ready for direct analysis:
# Summarize a CANdid capture
canarchy stats --file 2_driving_CAN.log --json
canarchy capture-info --file 2_driving_CAN.log --json
# Filter for specific IDs
canarchy filter 'id==0x123' --file 2_steering_CAN.log --json
# Reverse-engineering helpers
canarchy re entropy --file 2_driving_CAN.log
canarchy re counters --file 2_driving_CAN.log
# Inspect the catalog entry
canarchy datasets inspect catalog:candid --json
Session Save
canarchy session save lab-a --interface can0 --dbc tests/fixtures/sample.dbc --capture tests/fixtures/sample.candump --json
Shell One-Shot Command
canarchy shell --command "capture can0 --text"
Current Gaps
Planned capabilities that are intentionally not exposed in the CLI yet:
- active fuzzing workflows for replay mutation, payload mutation, and arbitration-ID probing
These deeper capabilities are also not implemented yet even where the command surface exists:
- deeper live transport integration beyond the current
python-cantransport path