Skip to main content

Sensez CLI and MCP server for structural maintainability checks

Project description

Why can't coding agents detect code smells? Because they don't have a noze.

Coding agents are very good at producing code. They are also very good at producing the same helper three times, gently ignoring your architecture notes, and using dict[str, Any] when you ask for type safety. You ask it to complete a task like "a staff software engineer", you ask it to follow SOLID principles and use strong type safety. It happily agrees, and starts working on the task. The vibes are immaculate. You come back a few minutes later to a slopocalypse that looks nothing like what your AGENTS.md says and you spend hours trying to understand where to start.

Sensez is a suite of Rust CLIs with an MCP server for maintenance before tech debt accumulates. It runs beside your linter and type-checker and looks for cross-file problems they usually do not own: duplication, dead code, import cycles, boundary violations, and design smells. It is designed to give your coding agent the noze to detect code smells, the bonez to respect architectural boundaries, and the spine to do it fast.

Supported language profiles currently include Python, JavaScript, TypeScript, and Rust (for dogfooding primarily).

Performance Snapshot

xychart-beta
  title "pylint benchmark seconds"
  x-axis ["sensez", "vulture", "repowise", "symilar"]
  y-axis "seconds" 0 --> 20
  bar [0.27, 1.29, 17.26, 20]

sensez scans all structural pillars in one pass (0.27s). vulture checks Python dead code (1.29s). repowise uses a custom ranking mechanism, including dead code (17.26s). symilar checks line-based duplication (234.12s; chart capped at 20s).

JS/TS

xychart-beta
  title "zod benchmark seconds"
  x-axis ["sensez", "fallow", "repowise"]
  y-axis "seconds" 0 --> 6
  bar [0.16, 0.48, 5.75]

sensez scans all structural pillars in one pass (0.16s). fallow checks JS/TS structural dead-code and dependency findings (0.48s). repowise checks repo intelligence signals, including dead code (5.75s).

sensez tries to lower dead code noise and allows for configuration of what gets reported to the agent based on filter levels. It also includes a few more Python and TS/JS opinionated smells, apart from overall structural consistency metrics.

Quick Start

Python

# Run a one-off scan with uv
uvx --from sensez sense noze .

# Add as a dev dependency
uv add --dev sensez
# Or install using pip
pip install sensez

JS/TS

# Add as a dev dependency
npm install --save-dev sensez
# Generate a sensez.toml starter config
sense init . --yes

# Run a one-off scan with npx
npx sense noze .

sense noze . is the default scan, but you can also use the verbose method: sense noze sniff .

The Problem

Coding agents drift. Not due to bad intentions, but because their loop is leaky.

  1. Context rots. You told the agent to respect boundaries, follow SOLID, and think like a staff engineer. Six turns later, the context has been summarized twice and the agent is confidently rewriting the same csv file parser your colleague wrote two weeks ago.

  2. CI is too late. CI is great at saying "absolutely not." It is much worse at saying "hm, this duplication is small but suspicious." Non-blocking warnings have a natural habitat: ignored forever.

  3. Slow checks do not fit the turn. If a check takes minutes, it should not run every agent turn. If it does not run every turn, the slop has time to ferment.

[Agent Proposes Turn Finish] ──> [ 👃 Sensez MCP Sniff ] ──> [ Catches Import Cycle / Duplication ]
                                   │
                                   └──> (Immediate Agent Feedback: "Loose typing violation on line 40 of code.py. Replace loose collections with dataclass/model.")

Sensez provides short, structured feedback directly to the agent while the edit is still fresh. Less archaeology, more "fix it before it becomes load-bearing."

noze

noze takes care of the gorgonzola coding agents love so much:

Area Output key What it catches
Duplication duplication Structural clones, including local rename copies.
Dead code dead_code Unreferenced symbols with confidence tiers.
Cycles cycles Import loops and load-order tangles.
Boundaries boundaries Imports crossing configured architecture rules.
Smells smells Design pressure inside functions, classes, modules, and the graph.

Some smell examples:

Smell Why noze flags it
tuple_packing Positional tuples hide meaning. tuple[int, str, int] is not a data model.
loose_typing Any and vague containers erase the contract callers need.
boolean_blindness do_thing(True, False) is a guessing game with arguments.
implicit_schema Repeated string-key access usually means a real shape is hiding in a dict.
mutated_parameter You pass a parameter and the function you sent it to returns it all chewed up. Disgusting.
feature_envy A method that mostly uses another object's data may belong somewhere else.
message_chain Long a.b.c.d chains couple callers to deep object plumbing.
god_module One module has become the place everything depends on.

noze is not a formatter, linter, or type-checker. Keep using Ruff, ty, mypy, ESLint, TypeScript, rustc, and Clippy. noze sits next to them and watches the repo-level shape.

MCP

MCP is the default integration path for agents. Use it when Sensez should run repeatedly during a coding session instead of shelling out for one-off scans.

sense mcp serve

The MCP tools are themed but explicit:

Tool Use
noze_sniff Scan the repo for smells and structure issues.
noze_gate End-of-turn diff gate for agent hooks.
noze_explain Explain a finding category.
brainz_report Summarize local usage and resolution metrics.
brainz_triage Record user-approved debt or false-positive verdicts.
eyez_search_docs Search docstrings/comments when eyez is enabled.

You can also use the smell noze CLI standalone in GitHub actions.

brainz

brainz is local-only memory. It records scans, gate blocks, triage decisions, resolved findings, regressions, detector precision, and usage reports.

Everything stays under:

.sensez/local-metrics/

No telemetry. No source upload. Disable it per repo:

[self_improvement]
enabled = false

Configuration

Sensez reads sensez.toml from the project root, or [tool.sensez] from pyproject.toml when sensez.toml is absent.

sense init . --yes

Main knobs:

  • [duplication] for clone thresholds
  • [dead_code] for dynamic entrypoints
  • [smells] for smell toggles and thresholds
  • [[boundaries.forbidden]] for architecture contracts
  • [action] for how strongly agents/gates treat each pillar
  • [accept] for shared accepted findings
  • [self_improvement] for local metrics

Small example:

[duplication]
threshold = 50

[dead_code]
entrypoint_names = ["register", "main", "setup"]

[[boundaries.forbidden]]
from = "app.domain"
to = "app.web"

[smells.rules.long_function]
max_lines = 80
action = "warning"

That boundary rule says: domain code does not import web code. If it does, the import has chosen drama.

eyez

eyez is optional doc/comment search for first-pass orientation:

sense eyez search . "where do we compute prices?"

It is a lead finder, not a complete code search.

Project Anatomy

  • spine: file discovery, parsing, shared IR, and dependency graph.
  • profiles: language adapters for Python, JS/TS, TSX, and Rust.
  • noze: duplication, dead code, cycles, and design smells.
  • bonez: architecture boundary auditing.
  • brainz: local-only metrics and feedback memory.
  • eyez: optional doc/comment search.
  • mcp: JSON-RPC/MCP surface for agent integration.
  • reporter: terminal and JSON output.
  • setup: sense init, starter config, MCP registration, and hook setup.

Privacy

Sensez does not send telemetry or source code anywhere. Local metrics stay under .sensez/local-metrics/. The optional eyez feature downloads an embedding model from HuggingFace the first time it is used; after that, indexing and search are local.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

sensez-0.1.0-py3-none-win_amd64.whl (2.7 MB view details)

Uploaded Python 3Windows x86-64

sensez-0.1.0-py3-none-manylinux_2_39_x86_64.whl (3.1 MB view details)

Uploaded Python 3manylinux: glibc 2.39+ x86-64

sensez-0.1.0-py3-none-manylinux_2_39_aarch64.whl (3.0 MB view details)

Uploaded Python 3manylinux: glibc 2.39+ ARM64

sensez-0.1.0-py3-none-macosx_11_0_arm64.whl (2.8 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

sensez-0.1.0-py3-none-macosx_10_12_x86_64.whl (2.9 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file sensez-0.1.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: sensez-0.1.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 2.7 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sensez-0.1.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 920b4803ed5b2ec48ac6df63659ba052183c3f4d3e15f659013450fddba10e4f
MD5 5f740c5a73bf875d8a576ea6c36d77e8
BLAKE2b-256 489c03e50509adb983582d837b457db0542dcec08ee9aa68cefb9023745b9a4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for sensez-0.1.0-py3-none-win_amd64.whl:

Publisher: release.yml on popov95s/sensez

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sensez-0.1.0-py3-none-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for sensez-0.1.0-py3-none-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 23e6a4f2234a2c8e26b30749fec098ff3154a6595438007bc315938c435b0b58
MD5 36b2cdcf3ebc4ac553baf6f7d75df75b
BLAKE2b-256 f82de4a13c969b0170f2a781dce4bbf13d361751b02029b134209d2f405fd25e

See more details on using hashes here.

Provenance

The following attestation bundles were made for sensez-0.1.0-py3-none-manylinux_2_39_x86_64.whl:

Publisher: release.yml on popov95s/sensez

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sensez-0.1.0-py3-none-manylinux_2_39_aarch64.whl.

File metadata

File hashes

Hashes for sensez-0.1.0-py3-none-manylinux_2_39_aarch64.whl
Algorithm Hash digest
SHA256 b89cae271157d31183d3807b1a9b001b6c6b2e427b5d06e5bc0c7346885817ea
MD5 401f2f25740d8066017313f7ec71ec8d
BLAKE2b-256 760ae1eec95128d052bb17fe02397d4d9f9eea549617ef62f612887f5d58c9f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for sensez-0.1.0-py3-none-manylinux_2_39_aarch64.whl:

Publisher: release.yml on popov95s/sensez

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sensez-0.1.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for sensez-0.1.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d2e5e49e9b8eef6780a0d25a35226abed6754a5c65ad3cae92af6540cb6c0255
MD5 8261c95d28520573fa4450ab4a71e303
BLAKE2b-256 468c499aec608edc1587dbb5f6c7136ac751b7ac2a556fef0f58ffd97c37d891

See more details on using hashes here.

Provenance

The following attestation bundles were made for sensez-0.1.0-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on popov95s/sensez

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sensez-0.1.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for sensez-0.1.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 14eb73433e0100de0815638fb08b0ef8de32549c4b4d23b191215e36cf39c44a
MD5 a1ad6885df826e37b153b2afae370c1c
BLAKE2b-256 33f8d0d36e0166d3e9b251c6d337ee87181f86985bb9490190d8677dd8244b05

See more details on using hashes here.

Provenance

The following attestation bundles were made for sensez-0.1.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: release.yml on popov95s/sensez

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page