Agent Guide¶
AGENTS.md¶
Project¶
CANarchy is a CLI-first CAN security research toolkit with optional REPL and TUI front ends.
The implementation language is Python, and the project uses uv for dependency management, virtual environments, and packaging workflows.
The core design rule is simple:
The CLI is the contract. The REPL and TUI are views over the same engine.
The project is focused on:
- CAN and CAN FD workflows
- J1939-first heavy vehicle workflows
- security research and protocol exploration
- automation-friendly use by coding agents
- automation-friendly development by coding agents
- structured outputs suitable for pipelines and machine parsing
Project planning¶
GitHub Issues are the source of truth for project planning and task tracking.
Every change must be associated with an issue¶
This is a hard rule, not a suggestion.
- Before starting any new feature, bug fix, or non-trivial refactor, check whether an open issue already covers it.
- If no issue exists, create one with a clear title, description, and acceptance criteria before writing code.
- Every commit that implements or fixes something must reference the relevant issue number using
closes #N,fixes #N, orrefs #Nin the commit message. - Do not merge or push code changes that have no associated issue.
- Bug fixes discovered incidentally (e.g. while working on a different issue) get their own issue opened first, then fixed.
The only exceptions are:
* typo/whitespace-only changes in docs or comments
* changes to .gitignore or other non-functional config
Branch and pull-request workflow¶
This is a hard rule, not a suggestion.
- Before creating a branch, post a comment on the issue claiming it — for example: "Starting work on this; branch will be
<branch-name>." This prevents two agents or contributors from independently implementing the same issue. - For any non-trivial feature, bug fix, refactor, or documentation change, agents shall create and work from a dedicated branch rather than committing directly on
main. - Branch names should be short, descriptive, and tied to the issue when practical, for example
issue-110-j1939-compare. - When issue-scoped work is complete, agents shall push the branch and open a pull request unless the user explicitly asks for a direct push or direct commit flow.
- Pull requests should be the default handoff for review, CI, and merge discussion.
- Agents shall not merge their own pull requests unless the user explicitly asks them to do so.
- If urgent work must go directly to
main, the user shall explicitly request that exception.
Changelog policy¶
CHANGELOG.md follows the Keep a Changelog format. Every non-trivial change must be recorded in the [Unreleased] section before or alongside the commit that introduces it.
This is a hard rule, not a suggestion.
- Every new feature, bug fix, behaviour change, or significant documentation update must have a corresponding
CHANGELOG.mdentry under[Unreleased]. - Group entries under the standard headings:
Added,Changed,Deprecated,Removed,Fixed,Security, orDocumentation. - Write entries from the operator's perspective — describe what changed and why it matters, not what files were edited.
- Changelog entries must be committed in the same commit or PR as the change they describe. Do not leave the changelog update for a separate follow-up.
- When a release is cut, the
[Unreleased]section is promoted to a versioned heading. Do not manually create versioned headings outside of the release workflow. - The only exceptions are: typo/whitespace-only changes in docs or comments, changes to
.gitignoreor other non-functional config, and MkDocs nav or theme-only changes.
Versioning after release¶
This is a hard rule, not a suggestion.
- After cutting release
X.Y.Z, advancesrc/canarchy/__init__.pyonmaintoX.Y.(Z+1).dev0unless a different next-version target is explicitly planned and documented. - Do not leave
mainon the released version once unreleased work resumes. - Keep release tags on the stable release version only, such as
v0.4.0. - If the next intended release is a minor or major bump instead of the next patch version, document that decision explicitly and set the
.dev0version accordingly.
PR acceptance criteria¶
A PR is not ready to merge until all of the following are true.
This is a hard rule, not a suggestion.
| # | Gate | Notes |
|---|---|---|
| 1 | Issue referenced | Commit message contains closes #N, fixes #N, or refs #N |
| 2 | Tests pass | All existing tests pass; new behaviour has new tests |
| 3 | Changelog updated | [Unreleased] section reflects the change (see Changelog policy) |
| 4 | Design spec current | Any touched docs/design/ spec reflects the implemented behaviour — requirements updated, no stale wording |
| 5 | Test spec current | Any touched docs/tests/ spec reflects the actual test coverage — new TEST-* IDs added, traceability table updated |
| 6 | Agent guide current | If the change affects the command surface, MCP tools, output schema, or any workflow an agent would follow, AGENTS.md and docs/agents.md are updated |
| 7 | No stale documentation left | Verify that no other doc (architecture docs, tutorials, command_spec.md) references old behaviour that the PR changes |
When reviewing your own work before committing or pushing, explicitly check each gate in order. Do not defer documentation updates to a follow-up commit.
Other issue rules¶
- Use GitHub Issues to track planned work rather than ad hoc task lists in docs.
- Claim an issue before starting work. Post a comment on the issue as the very first action — before creating a branch or writing any code — stating that work is beginning and naming the intended branch. This is the coordination signal that prevents duplicate effort by other agents or contributors.
- When starting or completing work that relates to an issue, update the issue with progress or implementation notes.
- Commit and push the relevant code changes before closing an issue so the issue state matches the remote repository state.
- Close an issue when its scope and acceptance criteria have been satisfied.
- When creating a new issue, always include explicit acceptance criteria that define what must be true to close it.
- If code changes only partially satisfy an issue, leave the issue open and note the remaining work.
- If work for an issue is complete locally but has not yet been committed and pushed, explicitly offer to the user to commit and push the changes and then close or update the issue.
- After completing issue-scoped work, summarize what was implemented, recommend the most sensible next steps, and present those next steps as a concise multiple-choice menu the user can select from.
Recommended completion handoff when issue-scoped work is done locally¶
- State that the issue work is complete locally.
- Summarize the shipped changes and verification results.
- Offer to commit, push the branch, and open a pull request if that has not happened yet.
- If the branch and pull request already exist, offer to update or close the issue if still needed.
- Recommend the next 2–4 highest-value follow-up tasks.
- Present the next steps as a multiple-choice menu, for example:
A. commit, push the branch, and open a pull request B. start the next recommended issue C. refine docs or tests around the completed work D. inspect or review the implementation before moving on
Primary goals¶
- Build a stable, scriptable command surface for CAN security research.
- Make common analyst workflows easy from the terminal.
- Support agentic use through deterministic commands, structured output, and explicit error handling.
- Keep protocol logic in the core engine, not in the UI.
- Preserve parity across CLI, REPL, and TUI wherever practical.
Non-goals for the first versions¶
Do not try to do all of these immediately:
- Full OEM-specific protocol coverage
- Deep GUI-first workflows
- Large-scale cloud architecture
- Automatic “AI magic” without clear, inspectable outputs
- Feature parity with every existing CAN tool before the core model is stable
Product shape¶
CANarchy should be implemented as three layers:
1. Core engine¶
Responsible for:
- transport backends
- frame ingest and transmit
- decode/encode pipelines
- protocol state tracking
- replay and mutation
- analysis and reverse engineering helpers
- event generation
2. Command layer¶
Responsible for:
- canonical commands and subcommands
- validation of arguments
- output formatting modes
- exit codes
- scripting compatibility
3. Front ends¶
Responsible for presentation only:
- CLI
- REPL shell
- TUI
Front ends must not contain business logic that cannot also be reached through the CLI.
Front-end rules¶
CLI¶
The CLI is the authoritative interface.
Every important workflow must be reachable as a non-interactive command.
Examples:
canarchy capture can0 --jsonlcanarchy capture --jsonlwhen[transport].default_interfaceorCANARCHY_DEFAULT_INTERFACEis configuredcanarchy capture-info --file capture.log --jsoncanarchy decode --file capture.log --dbc truck.dbc --jsoncanarchy j1939 monitor --pgn 65262 --jsoncanarchy uds scan can0 --jsoncanarchy replay --file drive.log --rate 0.5
Single-interface transport commands may resolve their CAN interface from user config when the command-line value is omitted. The explicit command-line interface always has the highest precedence; use [transport].default_interface in ~/.canarchy/config.toml or CANARCHY_DEFAULT_INTERFACE for the fallback channel. This is separate from [transport].interface, which selects the python-can backend type such as socketcan, udp_multicast, pcan, vector, or kvaser. Use canarchy doctor for offline configured-backend dependency hints; live hardware access still requires operator-run validation against the adapter and bus.
REPL¶
The REPL is a convenience layer for human operators.
The REPL should:
- reuse the same command parser where possible
- preserve context like active bus, loaded decode database, and session artifacts
- expose the same operations as the CLI with minimal drift
TUI¶
The TUI is a state and visualization surface over the same engine.
The TUI should:
- consume the same event stream model used by CLI/REPL
- trigger the same underlying commands/actions
- avoid introducing unique features that cannot be expressed as commands
Initial capability priorities¶
P0¶
- CAN / CAN FD capture
- transmit/send
- replay
- filtering
- stats
- structured export (
json,jsonl) - DBC-backed decode and encode
- J1939 monitor / decode / PGN-first workflows
- clear exit codes and error schema
P1¶
- UDS scan and trace support (CAN/ISO-TP and DoIP —
uds scan|trace doip://host:port?logical_address=0x0E80) - session save/load
- SQLite export
- remote backends
- mutation/fuzzing primitives
- reverse engineering helpers
P2¶
- TUI dashboard
- plugin SDK
- additional output sinks such as MQTT/Kafka/webhooks
- advanced anomaly detection and signal inference
Security research focus¶
CANarchy is intended for defensive research, protocol analysis, lab experimentation, red-team style validation, and tool-assisted reverse engineering.
When implementing features, prefer:
- reproducibility
- evidence capture
- traceability
- safe defaults
- explicit operator intent for active transmission and fuzzing
Suggested safeguards:
- make active transmit/fuzz commands obviously distinct from passive commands
- support dry-run modes where possible
- log enough metadata for lab replay and reporting
Architectural principles¶
1. Structured events over raw text¶
Internally, the system should model events such as:
- frame
- decoded message
- signal value
- J1939 PGN/SPN observation
- UDS request/response transaction
- anomaly
- replay action
- fuzz action
- alert
Prefer typed event objects over free-form strings.
For protocol transactions that can be partially reconstructed from captured traffic, include explicit completeness fields instead of implying that every decoded payload is whole.
Where optional protocol enrichers are present, such as a Scapy-backed diagnostic adapter for UDS, surface them through stable summary-level fields rather than leaking third-party runtime objects into command output.
2. Human output must never break machine output¶
Every command should support explicit output modes:
--json--jsonl--text
Do not mix human decoration into JSON output.
3. Deterministic behavior matters¶
Commands should behave predictably.
Avoid:
- hidden prompts in non-interactive mode
- unstable field names
- ambiguous time formats
- random output ordering unless explicitly requested
4. Stable command grammar¶
Prefer a command layout like:
<domain> <action>- or
<action> <object>only when very obvious
Examples:
j1939 monitorj1939 decodej1939 comparej1939 inventoryskills searchuds scanre signalssession save
5. Protocol semantics are first-class¶
Do not force users to stay at the raw-frame layer when protocol-aware workflows exist.
Examples:
- allow PGN/SPN-first commands for J1939
- allow request/response transaction views for UDS
- allow decode-aware filtering
Coding guidelines¶
General¶
- Favor readability and explicitness over cleverness.
- Keep modules small and focused.
- Add tests for protocol parsing, decode logic, and CLI behavior.
- Prefer pure functions for transforms and protocol analysis.
- Keep transport adapters separate from semantic layers.
Error handling¶
All errors should be actionable.
At minimum, errors should communicate:
- category
- message
- likely cause
- retry or corrective hint when appropriate
Prefer structured errors internally and in JSON output.
Logging¶
- Use structured logging internally.
- Keep logs useful for replay and debugging.
- Avoid noisy logs in default CLI usage.
Configuration¶
- Prefer explicit CLI flags first.
- Add config files only where they reduce repetition without hiding behavior.
- Make the effective configuration inspectable.
Output and exit code conventions¶
Suggested exit codes:
0success1user/input/usage error2backend or transport error3decode/schema/plugin error4partial result / partial success
Suggested JSON result shape:
{
"ok": true,
"command": "j1939 monitor",
"data": {},
"warnings": [],
"errors": []
}
Suggested JSON error shape:
{
"ok": false,
"command": "decode",
"errors": [
{
"code": "DBC_LOAD_FAILED",
"message": "Failed to parse DBC file.",
"hint": "Validate file format and line endings."
}
]
}
Proposed initial command tree¶
canarchy
capture
capture-info
send
replay
filter
stats
decode
encode
skills
provider list
search
fetch
cache list
cache refresh
plugins
list
info
enable
disable
datasets
provider list
search
inspect
fetch
cache list
cache refresh
convert
stream
replay
export
session
save
load
show
j1939
monitor
decode
compare
pgn
spn
tp
dm1
summary
inventory
uds
scan
trace
services
subservices
ecu-reset
tester-present
security-seed
dump-dids
read-memory
auto
re
signals
counters
entropy
correlate
shell
tui
This tree is a starting point, not a lock.
Active-transmit MCP tools (send, generate, gateway, replay, sequence_replay, xcp_scan, fuzz_guided, and fuzz payload|replay|arbitration-id|signal|spn) are behind the active-transmit safety model — mandatory ack_active=true with dry_run defaulting to true. The authoritative CLI-to-MCP coverage matrix (exposed / excluded / deferred) is maintained in docs/design/mcp-server.md, and tests/test_mcp.py enforces that every implemented command is either exposed or a documented exclusion (shell, tui, web serve, cannelloni send, mcp serve, mcp install, completion, datasets stream, dbc generate-c, plugins enable, plugins disable, the active uds workflows uds subservices|ecu-reset|tester-present|security-seed|dump-dids|read-memory|auto, the active xcp info / xcp dump, the active doip command group, and fuzz identify). The uds_scan / uds_trace tools are exposed for CAN interfaces but refuse a doip:// target with DOIP_MCP_EXCLUDED, since DoIP is active TCP egress to an arbitrary host and stays a CLI-only operator action. The active UDS workflows (uds subservices, ecu-reset, tester-present, security-seed, dump-dids, read-memory, auto) transmit invasive diagnostic requests and are CLI-only operator actions behind the active-transmit gate; the reference uds services catalog stays exposed (its active-probe mode only activates when a CLI caller supplies an interface). xcp info (capability queries) and xcp dump (bounded memory upload) connect to a slave and are likewise CLI-only; the broadcast xcp scan stays exposed. The dedicated doip command group (doip discovery|services|ecu-reset|tester-present|security-seed|dump-dids) is also CLI-only — active network egress (UDP discovery + TCP diagnostic sessions) behind the active-transmit gate. fuzz identify is a stateful, multi-round human-in-the-loop replay/narrowing workflow (one bisected window replayed per invocation) and stays CLI-only.
For plugin automation, agents can use MCP plugins_list / plugins_info or CLI canarchy plugins list|info --json to inspect discovered Python entry-point plugins. Plugin toggles are user configuration actions; use CLI canarchy plugins enable|disable <name> only when explicitly requested by the operator.
For dataset automation, agents should prefer MCP dataset tools when available, or explicit CLI JSON output otherwise. datasets_search / datasets search --json and datasets_inspect / datasets inspect --json include stable machine fields: ref, is_replayable, is_index, default_replay_file, download_url_available, and source_type. datasets_fetch distinguishes curated indexes from normal dataset entries with is_index, index_instructions, and download_instructions. Use MCP datasets_replay_plan or CLI datasets replay --dry-run --json for safe replay preflight; use datasets replay --list-files --json to choose a replay file and --file <id-or-name> to select it. Use --max-frames or --max-seconds to bound replay. For catalog:comma-car-segments, use --platform <name> to filter dynamic HuggingFace segment manifests and --limit <n> to bound file listings before selecting a segment. Use datasets stream --max-frames <n> to bound local downloaded dataset-file streaming; --chunk-size controls JSONL provenance chunk metadata and is not a frame limit. comma-rlog streaming requires optional openpilot LogReader support (uv pip install git+https://github.com/commaai/openpilot.git on Python 3.12.x) and otherwise returns COMMA_RLOG_SUPPORT_UNAVAILABLE. Actual dataset frame streaming remains CLI-only. Curated index entries that cannot be replayed return DATASET_INDEX_NOT_REPLAYABLE.
For DBC reconnaissance, agents can use canarchy dbc inspect <dbc> --layout --json or MCP dbc_inspect with layout=true to retrieve cantools-rendered bit-layout diagrams, signal trees, and choice tables as structured message fields.
For stdin pipelines, capture-info --file -, stats --file -, and filter --file - read candump text from stdin. filter --stdin, decode --stdin, and j1939 decode --stdin read JSONL FrameEvents from stdin regardless of output format.
For security workflow examples that combine commands into complete agent tasks, see docs/security-use-cases.md. The primary documented workflows are CAN/J1939 capture triage, dataset-driven IDS experimentation, DBC-assisted signal reconnaissance, protocol-aware incident reporting, and safe replay/regression testing.
J1939 expectations¶
J1939 should be treated as a first-class workflow, not an afterthought.
Priorities:
- PGN-first filtering
- SPN presentation where decode data is available
- source address tracking
- TP/BAM reassembly support
- DM message visibility
- ECU/node activity summaries
The user should not be forced to manually reason from raw 29-bit IDs for common J1939 tasks.
Reverse engineering expectations¶
Reverse engineering features should be evidence-driven and explainable.
Good early features:
- field entropy ranking
- likely counter detection
- likely checksum detection
- correlation against known external series
- changing-bit analysis
- signal boundary suggestions
Do not present guesses as facts. Always expose confidence and rationale where possible.
TUI expectations¶
The TUI should be useful for live analysis, demos, and triage.
Good initial panes:
- bus/interface status
- live traffic table
- decoded signals
- J1939 PGN/SPN activity
- node list
- alerts/events
- command entry area
The TUI should subscribe to the same event model used elsewhere.
Testing expectations¶
At minimum, cover:
- frame parsing and formatting
- J1939 ID decomposition
- DBC-backed decode behavior
- replay timing behavior
- CLI argument validation
- JSON output stability
- error schema behavior
Where possible, use fixtures for:
- representative CAN logs
- representative J1939 traces
- malformed inputs
- edge cases like extended IDs, CAN FD, transport protocol fragmentation
Documentation expectations¶
Documentation should be written for three audiences:
1. Operators¶
Show practical commands and workflows.
2. Developers¶
Explain architecture, module responsibilities, and extension points.
3. Agents¶
Keep command help, output schemas, and command behavior explicit and stable.
Prefer example-heavy docs.
Design and architecture documents¶
CANarchy maintains living specification documents alongside the code. These documents are the authoritative record of how the system is designed to work.
Document types¶
Architecture documents (docs/architecture/)
Describe the overall structure and module responsibilities. Each document should cover:
- the problem the component solves
- its boundaries and responsibilities
- how it interacts with adjacent components
- key design decisions and the reasons for them
- what is intentionally out of scope
Software design specs (docs/design/)
Describe the intended behavior of a specific feature or subsystem before or during implementation. Each spec should include:
- document control metadata including current status and affected command surface
- the goal and user-facing motivation
- explicit requirement IDs in a stable format such as
REQ-<AREA>-NN - the proposed command surface or API shape
- data models and event types involved
- output format definitions (JSON schema or representative examples)
- error cases and expected error codes
- open questions or deferred decisions
Test specs (docs/tests/)
Describe the test strategy and coverage expectations for a component or feature. Each test spec should include:
- document control metadata including the related design spec
- explicit test case IDs in a stable format such as
TEST-<AREA>-NN - what behaviors must be covered
- requirement-to-test traceability mapping back to the design spec requirement IDs
- representative test cases including happy path, edge cases, and failure modes
- fixture requirements
- what is explicitly not tested and why
Spec language standard¶
All design specs and test specs must use the formats defined in docs/spec-template.md.
Design specs shall write requirements using EARS (Easy Approach to Requirements Syntax):
| EARS type | Template |
|---|---|
| Ubiquitous | The system shall … |
| Event-driven | When \<trigger>, the system shall … |
| State-driven | While \<state>, the system shall … |
| Optional feature | Where \<feature> is specified, the system shall … |
| Unwanted behaviour | If \<condition>, the system shall … |
Each requirement row in the table shall include a Type column identifying which EARS pattern applies.
Test specs shall write test cases using Gherkin Given/When/Then syntax inside a fenced gherkin block, followed by a **Fixture:** line naming the required files or environment.
Rules for agents¶
- When implementing a new feature or command, check
docs/design/for an existing spec before writing code. If a spec exists, implement against it. If it conflicts with the code, flag the conflict rather than silently diverging. - When no spec exists for a significant new feature, create one in
docs/design/before or alongside the implementation. Followdocs/spec-template.mdfor the required sections, requirement IDs (REQ-<AREA>-NN), and EARS language. - When adding new protocol logic, transport backends, or output formats, update or create the relevant architecture document in
docs/architecture/. - After implementing a feature, verify the test spec in
docs/tests/matches what was actually tested, includes test IDs (TEST-<AREA>-NN), uses Gherkin Given/When/Then, and traces back to the design-spec requirement IDs. Update it if coverage changed. - Specs are living documents. Update them when the implementation changes rather than letting them drift.
- Do not create specs for trivial changes (single-function fixes, minor output tweaks). Reserve them for features that affect the command surface, data model, or module boundaries.
- Before marking work complete or opening a PR, run through the PR acceptance criteria checklist above. Documentation currency (gates 4–7) is a required part of acceptance, not optional follow-up work.
Preferred development style for agents¶
When proposing code changes or new modules, agents should:
- preserve CLI stability
- avoid leaking UI logic into core modules
- prefer structured outputs over formatted prose
- add tests with new behavior
- document new commands and output fields
- keep protocol-specific logic in well-named modules
- avoid unnecessary dependencies in the core runtime
When uncertain, agents should optimize for:
- CLI reliability
- output stability
- protocol correctness
- architecture clarity
- UI polish
Initial implementation suggestion¶
A reasonable first milestone is:
- core frame/event model
- SocketCAN capture/send/replay
- JSON/JSONL output modes
- DBC decode pipeline
- basic J1939 decomposition and monitor command
- simple session model
- shell scaffolding
Only after the command and event model feel stable should the project invest heavily in TUI and plugin work.
Working summary¶
CANarchy should become:
A CLI-first CAN security research environment with structured outputs, protocol-aware workflows, and shared core logic across CLI, REPL, and TUI.
When making design choices, preserve the following order of importance:
- command clarity
- structured outputs
- protocol correctness
- session reproducibility
- front-end parity
- visual polish
MCP Server Integration¶
CANarchy ships a native Model Context Protocol (MCP) server. Agents that support MCP tool calls can connect directly instead of spawning subprocesses and parsing stdout.
For security workflow examples that combine CLI/MCP calls into complete analyst tasks, see Security Use Cases With Coding Agents.
Starting the Server¶
canarchy mcp serve
The server communicates over stdio using JSON-RPC 2.0 and runs until the client disconnects.
Claude Desktop Configuration¶
The fastest way to wire CANarchy into a client is the canarchy mcp install
helper, which merges the mcpServers.canarchy block for you (see
Install the CANarchy MCP server):
canarchy mcp install --client claude-desktop --dry-run # preview
canarchy mcp install --client claude-desktop # write (prompts; --ack to skip)
canarchy mcp install --client claude-code --ack
It is CLI-only (writing a client config is a user action, so it is not an
MCP tool) and refuses to overwrite a different existing canarchy entry.
To wire it up by hand instead, add the block directly:
{
"mcpServers": {
"canarchy": {
"command": "canarchy",
"args": ["mcp", "serve"]
}
}
}
With uv in a project environment:
{
"mcpServers": {
"canarchy": {
"command": "uv",
"args": ["run", "canarchy", "mcp", "serve"],
"cwd": "/path/to/your/project"
}
}
}
Available Tools¶
The current MCP surface exposes a curated non-interactive subset of the CLI. Spaces in command names become underscores:
For MCP tools that accept a single CAN interface, omit the interface argument only when [transport].default_interface or CANARCHY_DEFAULT_INTERFACE is configured. Explicit MCP interface arguments take precedence over the configured default. [transport].interface is the python-can backend type (socketcan, udp_multicast, pcan, vector, kvaser, etc.) and is not the CAN channel fallback. doctor can report offline configured-backend dependency hints, but it does not open hardware.
Active-transmit MCP tools (send, generate, simulate, gateway, replay, sequence_replay, and fuzz_*) require ack_active=true. Their dry_run argument defaults to true, so agent calls plan without transmitting unless an operator explicitly authorizes live transmission with dry_run=false.
For DBC reconnaissance, dbc_inspect accepts layout=true to include cantools-rendered message bit diagrams, signal trees, and choice tables as structured strings on each message payload.
| MCP tool | CLI equivalent |
|---|---|
capture |
canarchy capture |
send |
canarchy send |
generate |
canarchy generate |
gateway |
canarchy gateway |
replay |
canarchy replay |
sequence_replay |
canarchy sequence replay |
simulate |
canarchy simulate |
filter |
canarchy filter |
stats |
canarchy stats |
capture_info |
canarchy capture-info |
decode |
canarchy decode |
encode |
canarchy encode |
dbc_inspect |
canarchy dbc inspect |
dbc_signals |
canarchy dbc signals |
dbc_convert |
canarchy dbc convert |
dbc_provider_list |
canarchy dbc provider list |
dbc_search |
canarchy dbc search |
dbc_fetch |
canarchy dbc fetch |
dbc_cache_list |
canarchy dbc cache list |
dbc_cache_prune |
canarchy dbc cache prune |
dbc_cache_refresh |
canarchy dbc cache refresh |
datasets_provider_list |
canarchy datasets provider list |
datasets_search |
canarchy datasets search |
datasets_inspect |
canarchy datasets inspect |
datasets_fetch |
canarchy datasets fetch |
datasets_cache_list |
canarchy datasets cache list |
datasets_cache_refresh |
canarchy datasets cache refresh |
datasets_replay_plan |
canarchy datasets replay --dry-run |
export |
canarchy export |
session_save |
canarchy session save |
session_load |
canarchy session load |
session_show |
canarchy session show |
j1939_monitor |
canarchy j1939 monitor |
j1939_decode |
canarchy j1939 decode |
j1939_pgn |
canarchy j1939 pgn |
j1939_spn |
canarchy j1939 spn |
j1939_tp |
canarchy j1939 tp sessions |
j1939_dm1 |
canarchy j1939 dm1 |
j1939_summary |
canarchy j1939 summary |
j1939_inventory |
canarchy j1939 inventory |
uds_scan |
canarchy uds scan |
uds_trace |
canarchy uds trace |
uds_services |
canarchy uds services |
xcp_scan |
canarchy xcp scan |
xcp_trace |
canarchy xcp trace |
xcp_read |
canarchy xcp read |
xcp_commands |
canarchy xcp commands |
j1587_decode |
canarchy j1587 decode |
j1587_pids |
canarchy j1587 pids |
j2497_decode |
canarchy j2497 decode |
j2497_mids |
canarchy j2497 mids |
config_show |
canarchy config show |
doctor |
canarchy doctor |
re_anomalies |
canarchy re anomalies |
re_correlate |
canarchy re correlate |
re_counters |
canarchy re counters |
re_entropy |
canarchy re entropy |
re_match_dbc |
canarchy re match-dbc |
re_shortlist_dbc |
canarchy re shortlist-dbc |
j1939_tp_compare |
canarchy j1939 tp compare |
j1939_faults |
canarchy j1939 faults |
j1939_compare |
canarchy j1939 compare |
j1939_map |
canarchy j1939 map |
re_signals |
canarchy re signals |
re_corpus |
canarchy re corpus |
re_suggest |
canarchy re suggest (heuristic path only) |
plot |
canarchy plot |
cannelloni_decode |
canarchy cannelloni decode |
datasets_convert |
canarchy datasets convert |
datasets_replay_files |
canarchy datasets replay --list-files |
skills_provider_list |
canarchy skills provider list |
skills_search |
canarchy skills search |
skills_fetch |
canarchy skills fetch |
skills_cache_list |
canarchy skills cache list |
skills_cache_refresh |
canarchy skills cache refresh |
plugins_list |
canarchy plugins list |
plugins_info |
canarchy plugins info |
| fuzz_payload | canarchy fuzz payload |
| fuzz_replay | canarchy fuzz replay |
| fuzz_arbitration_id | canarchy fuzz arbitration-id |
| fuzz_signal | canarchy fuzz signal |
| fuzz_spn | canarchy fuzz spn |
| fuzz_guided | canarchy fuzz guided |
| compare | canarchy compare |
Current exclusions:
- dataset streaming commands that emit frame records, such as
datasets streamand non-dry-rundatasets replay - interactive or service commands such as
shell,tui,web serve,mcp serve, andmcp install cannelloni send— active UDP egress to an arbitrary host:port; CLI-only operator action (cannelloni decodeis exposed)doip://targets onuds_scan/uds_trace— DoIP routes UDS over active TCP egress to an arbitrary host; the tools stay CAN-interface-only and refuse adoip://interface withDOIP_MCP_EXCLUDED. Run DoIP scans/traces from the CLI as an operator action- the dedicated
doipcommand group (doip discovery,doip services,doip ecu-reset,doip tester-present,doip security-seed,doip dump-dids) — active network egress (UDP vehicle-identification discovery + TCP diagnostic sessions), CLI-only operator actions behind the active-transmit gate completion, which emits a raw shell script rather than a JSON envelopedbc generate-c, which generates C source/header files to disk and is a developer actionplugins enableandplugins disable, which write user plugin configuration- the active UDS workflows
uds subservices,uds ecu-reset,uds tester-present,uds security-seed,uds dump-dids,uds read-memory, anduds auto— they transmit invasive diagnostic requests (ECU reset, seed collection, DID/memory extraction, ranged enumeration, multi-id recon) and stay CLI-only operator actions behind the active-transmit gate. The referenceuds servicescatalog stays exposed; its active-probe mode only activates when a CLI caller supplies an interface - the active
xcp infoandxcp dumpworkflows — they connect to an XCP slave and read its capabilities / a bounded memory range, so they stay CLI-only operator actions behind the active-transmit gate (the broadcastxcp scanstays exposed) fuzz identify, a stateful multi-round human-in-the-loop replay/narrowing workflow (one bisected window replayed per invocation); CLI-only operator action
The authoritative CLI-to-MCP coverage matrix (exposed / excluded / deferred, with rationale) lives in docs/design/mcp-server.md; a test guard (test_every_cli_command_is_exposed_or_documented) fails the build if a new command drifts out of coverage.
For dataset workflows, agents should prefer MCP dataset tools when available. datasets_search and datasets_inspect include stable machine fields: ref, is_replayable, is_index, default_replay_file, download_url_available, and source_type. datasets_fetch distinguishes curated indexes from normal dataset entries with is_index, index_instructions, and download_instructions. Use datasets_replay_plan for safe replay preflight; use CLI datasets replay --list-files --json to choose a replay file and --file <id-or-name> to select it. Use max_frames or max_seconds to bound replay. For catalog:comma-car-segments, pass --platform <name> and --limit <n> when listing files so dynamic HuggingFace manifests remain bounded. Use CLI datasets stream --max-frames <n> to bound local downloaded dataset-file streaming. --chunk-size controls JSONL provenance chunk metadata only; it is not a frame limit. comma-rlog streaming requires optional openpilot LogReader support (uv pip install git+https://github.com/commaai/openpilot.git on Python 3.12.x) and returns COMMA_RLOG_SUPPORT_UNAVAILABLE when unavailable. Actual frame streaming remains CLI-only. Curated index entries that cannot be replayed return DATASET_INDEX_NOT_REPLAYABLE.
Skills Workflow¶
CANarchy skills are phase-1 workflow descriptors, not MCP tools. Agents should discover and fetch skills through the CLI provider workflow, inspect the cached manifest and entry file, then run the referenced CANarchy commands explicitly through either the CLI or the MCP tools that already exist.
Recommended flow:
- Run
canarchy skills search <domain-or-task> --json. - Select a provider-qualified reference such as
github:j1939_compare_triage. - Run
canarchy skills fetch <provider>:<skill> --json. - Read
local_manifest_pathandlocal_entry_pathfrom the fetch result. - Check
compatibility,required_tools,inputs,outputs,skill.tags, andskill.domainsbefore applying the workflow. - Run required CANarchy commands explicitly and record the selected skill reference plus provenance in the final analysis.
Example:
canarchy skills search j1939 --provider github --json
canarchy skills fetch github:j1939_compare_triage --json
canarchy j1939 summary --file baseline.candump --json
canarchy j1939 compare --file baseline.candump --file after-start.candump --json
If MCP is available, agents may use MCP for commands that are already exposed as tools, such as j1939_summary. The skill itself is still selected and fetched through the CLI in phase 1, and compatibility.mcp=false means the agent should not assume MCP invocation is supported for the skill workflow.
Response Format¶
Every tool returns a single JSON text block with the canonical result envelope:
{
"ok": true,
"command": "<command>",
"data": { "events": [...] },
"warnings": [],
"errors": []
}
Failures set "ok": false and populate errors with structured objects (code, message, hint), using the same error codes as the CLI JSON output.
For UDS workflows, uds_transaction events may include payload.complete=false when a multi-frame ISO-TP response was only partially captured or arrived out of order. In that case payload.response_data still contains the partial bytes that were reassembled.
When the optional Scapy extra is installed, UDS results may also report data.protocol_decoder="scapy" and include summary-level request_summary / response_summary enrichment on uds_transaction payloads while preserving the same result envelope and event type.
Example Interactions¶
tool: uds_services {}
→ {"ok": true, "command": "uds services", "data": {"service_count": 26, ...}}
tool: j1939_spn {"spn": 190, "file": "trace.candump"}
→ {"ok": true, "command": "j1939 spn", "data": {"mode": "passive", "observations": [...]}}
tool: j1939_spn {"spn": 190} # no file → built-in reference lookup
→ {"ok": true, "command": "j1939 spn", "data": {"mode": "reference", "name": "Engine Speed", "pgn": 61444, "units": "rpm", ...}}
tool: send {"interface": "vcan0", "frame_id": "0x7DF", "data": "0201F1", "ack_active": true}
→ {"ok": true, "command": "send", "data": {"frame": {...}, "mode": "dry_run"}}
Notes¶
- MCP streaming is not supported in v1 — live-capture tools (
capture, livegatewaywithdry_run=false) return a buffered batch from the active backend. Use CLIdatasets stream --max-frames <n>for bounded local dataset-file JSONL or candump pipelines, anddatasets replay --max-frames <n>or--max-seconds <s>for bounded remote dataset-ref or URL playback to stdout. shell,tui,mcp serve, andmcp installare not exposed as MCP tools.- Error codes are identical to the CLI, so existing JSON-parsing logic transfers without changes.
- Every MCP response is bounded (default 512 kB, configurable via
CANARCHY_MCP_MAX_RESPONSE_BYTES). Oversized list data is trimmed and marked withdata.truncated: trueplus adata.truncationblock recording each trimmed list'stotal_itemsvsreturned_items— check that marker before treating a short list as a complete result, and re-run via the CLI (or bound the input withmax_frames/seconds) when you need the full output. An unexpected in-tool failure returns aTOOL_EXECUTION_ERRORenvelope; the session and the other tools stay usable. encode(andsend --dbc) resolve message names by exact DBC name, case/spacing-insensitive match, or SAE PGN label (EEC1), and signal names by exact name, case/spacing-insensitive match, or SAE SPN name (Engine Speed) — so names displayed by decode tools re-encode directly. Unsupplied signals are defaulted and reported underdata.resolution.filled_signalswith a warning; review them before transmitting.- CLI capture paths: the
re *family andj1939 compareaccept both positional paths and--file <path>flags, so agents shelling out do not need to remember which convention a command uses. Filter expressions accept decimal,0x-prefixed hex, or bare hex IDs/PGNs with whitespace tolerated around operators. - RE tool results (
re_signals,re_counters,re_entropy,re_anomalies,re_corpus) annotate J1939 frames withpgn,pgn_label,source_address, andsource_address_name, and label or exclude J1939 transport-protocol framing (j1939_transport,excluded_transport_ids).re_anomalieswithout abaselinereports sparse ids underlow_rate_idsinstead of ranking them and caps z-scores at ±100σ — prefer supplying a known-goodbaselinecapture. re_suggestproposes signal names for ranked candidates using offline heuristics only (reference-DBC overlap, the J1939 SPN/PGN catalog, and behaviour templates); each suggestion carries asourceandconfidence. The optional external-LLM enrichment (re suggest --llm <provider>) is CLI-only — it is not reachable through the MCP tool — because it sends candidate metadata to an external service and requires explicit operator confirmation. Even on the CLI it sends only candidate metadata (ids, bit ranges, observed ranges, heuristic names), never raw payload bytes, and records anexternal_enrichmentnote plus anEXTERNAL_SERVICE_CALLEDwarning.- Stdin pipelines:
capture-info,stats, andfilter --file -read candump text from stdin.filter --stdin,decode --stdin, andj1939 decode --stdinread JSONL FrameEvents from stdin regardless of output format. This enables pipingdatasets replaycandump output directly into analysis commands without temporary files.