About archy
archy is an MCP server in the IoT category: agent which helps to create architecture.
Install
uvx archypip install archyThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Tools (13)
archy_checkRun direct-edge layer rules from `archy.yaml`. Pass `contracts=True` to also run the transitive import-linter contracts (Layers, Forbidden, Independence, Protected, AcyclicSiblings; stricter than the direct edges), nested under the `contracts` field (replaces the removed `archy_contracts`; requires `archy[contracts]`, and degrades to `available=false` with an advisory if the extra is absent). Contracts are skipped when no `archy.yaml` is found (you get a `CheckErrorPayload` first). Always returns `coverage`: how many modules and import edges the rules actually reach, so `passed=true` can be told apart from a config that governs almost nothing. `transitive_checked` says whether this run actually evaluated the `forbid` rules transitively; it is false when contracts were never requested, when they produced no verdict, and when any contract could not have failed, since none of the three evaluated the rules. `transitive_unverified_reason` then says which, naming `archy_check(contracts=True)` if it was never requested, the actual failure if it produced no verdict, and how many contracts matched nothing if that is what happened. So a clean pass is never silent about having seen direct edges only. `min_layers_present:` in `archy.yaml` also gates `passed` here, not just the CLI exit code. `required_violations` reports unsatisfied `required:` rules (module X must transitively reach Y, counting the implicit package-`__init__` import), and gates `passed` too; fix by adding the missing import, not by deleting the rule. Within `contracts`, read `verified`, not `all_kept`: a contract whose module expressions match nothing in the graph is `kept` because it could not have failed, `unverifiable` counts those, and each one carries `matched_nothing` and `unmatched_expressions` naming the patterns that matched no module.
Parameters not published.
archy_conventionsReport the project's own house style, derived from its source: `naming` (class-name suffix families grouped by **home module**, so the module you are about to edit shows its own patterns), `surfaces` (mirrored helper sets like `_x_to_text`/`_x_to_json`, plus names defined in several modules - the "wire all of these together" list), `gates` (sites where a **failed finding** exits non-zero, each with its literal exit `code` and controlling lever: `flag:--strict`, `config:<attr>`, `param:<name>`, `hardcoded`), `errors` (the separate user-error exits - bad config, missing file - kept apart so the gate count stays meaningful), `models` (base-class / frozen / tuple-vs-list census), `bases` (kind families grouped by what they derive from *transitively*, counting only bases the project defines, with suffix agreement reported so a family whose name is not the rule says so), `registries` (`NAME = Ctor(...)` families and the distribution of every keyword passed - how a project declares codes or flags when it does not use classes), `export_gaps` (members absent from an `__all__`, or from a `from .x import Y as Y` block, that already lists their siblings) and `doc_gaps` (members the project's own `.rst`/`.md` surface does not name). Call before adding a class, field, or command to a project you do not know. Advisory: never fails, mutates nothing. `min_family` (default 2) raises the reporting floor; `include_tests` censuses test modules too (default false, because test fixtures dilute a real family).
Parameters not published.
archy_cyclesFind import cycles.
Parameters not published.
archy_diffCompare current state against the snapshot; returns added/resolved cycles & violations, per-component score deltas, and a risk-weighted `summary` whose items carry a `prompt` reframing each delta as a judgment question ("new cycle a -> b; intended, or invert an edge?").
Parameters not published.
archy_dsmDesign Structure Matrix view of the import graph. `response_format="summary"` (**default**) returns a compact overview (block structure, counts, back-edges, cross-block coupling) without the full cell list. `response_format="full"` returns the positional matrix (cell `(row=source, col=target)` non-empty when source imports target), refusing matrices over `DEFAULT_MAX_DSM_CELLS` cells with a `DSMTooLargePayload`. `group_by` controls row/col ordering (`community` for block-diagonal cohesion, `layer` for layer-violation forensics, `topological` to localize back-edges). `weight` is `imports` or `calls`. Narrow large projects with `focus=<qualname>` + `focus_depth` or `package=<prefix>`. When `baseline_path` is provided, returns a structured diff (regardless of `response_format`) whose `new_back_edges` field flags cycles the edit just introduced. Visualization-only; see [`docs/research/DSM_EMPIRICS.md`](docs/research/DSM_EMPIRICS.md).
Parameters not published.
archy_duplicatesCluster functions with identical normalized body shape into two tiers: `duplicates` (likely-real, investigate) and `variants` (demoted likely-intentional clusters - same-class / boilerplate / test / vendored / `independent`, each with a `variant_reason`). `co_change=true` (**default**, needs git) adds the `independent` demotion: copies in actively-maintained files that never co-change (deliberately parallel implementations), the principled precision lever that lifts the primary tier above the ~50% syntactic ceiling (§12f). Within the primary tier, `exact=true` marks byte-identical (Type-1) clusters, the highest-confidence subset. `near_miss=true` (opt-in, slower) adds a lower-confidence `near_miss` tier: Type-3 (gapped) clones the exact shape-hash misses, found by token-multiset overlap (§12h). `response_format="summary"` (**default**) returns ranking fields + one sample member per cluster; `"full"` returns member lists. Advisory surfacer, not a score axis: refactorability is a semantic call (see [`docs/research/RESEARCH_METRICS.md`](docs/research/RESEARCH_METRICS.md) §12c/§12f/§12h). `min_nodes` (default 30) skips trivial stubs.
Parameters not published.
archy_graphInspect the dependency graph. With no `focus`, `response_format="summary"` (**default**) returns the top-N overview by fan-in / fan-out / PageRank plus top external deps (replaces the removed `archy_graph_summary`; `top_n` controls N); `response_format="full"` returns the complete node/edge dump matching `archy graph --format json`, refusing graphs larger than `max_nodes` (default 500) with an explicit `GraphTooLargePayload`. Pass `focus=[...]` (replaces the removed `archy_graph_focus`) for a bounded subgraph around one or more modules (qualnames or file paths): `depth` caps hops, `direction` is `in`/`out`/`both`, each edge carries import line numbers, and `response_format`/`max_nodes`/`top_n` do not apply.
Parameters not published.
archy_impactGiven changed file paths, return what they affect. `mode="blast"` (**default**) returns the modules that transitively import them (blast radius), plus `chains`: the shortest import path back to a changed module (with line numbers) explaining why each is impacted. `mode="affected"` (replaces the removed `archy_affected`) is the CI-shaped lookup instead: modules pre-classified into `impacted_tests` and `impacted_modules`, depth-capped (default 5 hops) so a single-line edit doesn't fan out to thousands of nodes; `test_filter` overrides pytest test detection with a recursive glob. `co_change=true` (blast mode, opt-in) adds a `co_changed` list: modules that historically co-change with the edit in git but have no import/call edge to it, so the structural blast radius misses them (`archy coupling` scoped to your edit; source-only, best-effort, the only path that reads git).
Parameters not published.
archy_module_viewEverything known about ONE module, complete and unranked - the **lookup** counterpart to `archy_conventions`'s ranked report. Because the report truncates, a module's absence from it means nothing; every list here is complete for the module named, so absence is the answer to "does `risk` import `hotspots`" or "does anything still reach `layers`". Returns `imports_internal` (relative imports resolved), `imported_by` (counting test importers even when tests are otherwise set aside, because a module imported only by tests is imported), `classes`, `functions`, `exports` (null when the module declares no `__all__` and no explicit re-exports - different from an empty one), `suffix_families`, `gates`, and `status`, which says whether the module was censused or set aside and why, so an empty view is never mistaken for "nothing to report". An unknown module name raises rather than returning an empty view. Advisory: never mutates.
Parameters not published.
archy_scoreCompute the five-metric score (modularity, acyclicity, depth, equality, complexity, geometric mean); optional `record=True` and `strict=True` for the same regression-gate behaviour the CLI offers. Pass `record=True` to record a start-of-session baseline (replaces the removed `archy_record_baseline`). `view="history"` returns the recent score history from `.archy/history.jsonl` (up to `last_n` rows, oldest-first, for comparing deltas over time; replaces the removed `archy_trend`).
Parameters not published.
Show all 13 tools
archy_simulateCounterfactual pre-edit check: given a proposed import-edge delta (`add`/`remove` of `{from, to}` pairs), return the would-be cycles, back-edges, layer/SDP/required-reach violations, per-axis score delta, and blast-radius change, with no file written. Test a refactoring hypothesis before committing to it.
Parameters not published.
archy_snapshotCapture score, cycles, and violations to `.archy/baseline.json`. Call at session start. Also returns an `invariant_brief` (declared layers, forbidden edges, declared `required:` reach rules, acyclic invariant, baseline score, load-bearing modules) to read before the first edit.
Parameters not published.
archy_what_to_refactor_nextRanked refactor-priority list (replaces the removed `archy_hotspots` and `archy_high_risk_modules` via `lens`). `lens="fused"` (**default**) sums the behavioral lens (CC x churn) and the structural lens (edit-risk: central+fragile) into a `priority`, so a module flagged by *both* generally outranks a comparable single-lens one (a dominant single-lens signal can still rank first). `lens="behavioral"` ranks CC x churn hotspots only (needs git); `lens="structural"` ranks the edit-risk composite only (git-free; pass `min_risk=0` for no floor). Each entry names which lenses fired and carries a one-line `rationale`. An empty list plus a `note` is a real answer.
Parameters not published.
Ask AI
Ask AI about archy
Powered by Claude · Grounded in docs
Security checks
6 checks have not been run yet.