Agent-facing MCP query layer over najaeda: navigate elaborated SystemVerilog designs without loading source into context.
Project description
naja-scope
Agent-facing query layer over najaeda: an MCP server whose tools let AI agents navigate elaborated SystemVerilog designs — hierarchy, connectivity, drivers, cones, and source back-links — without loading source code into context.
See DESIGN.md for architecture and scope; NAJAEDA_NOTES.md for upstream feature requests and bugs found while building phase 1.
Status: phase 1 (structural spine + source ranges) + phase-2 intent layer
Phase 1 is the core; the phase-2 living-intent layer (get_intent, warm-only) is
productized — a thin, pyslang-free client over naja's in-engine SNL↔slang link
(keep_ast_link, shipped in najaeda 0.7.8). Its eval gate passed and was
re-confirmed on the productized layer (scope+intent ≤ grep turns on cva6-small;
see docs/phase2-plan.md §4). The DESIGN.md §3 workflow works end to end:
resolve("uart_top.u_tx.tx_o") → term descriptor with src range
get_drivers("uart_top.tx_o") → { path: "uart_top.u_tx.tx_o_dff",
model: "naja_dff", pin: "Q",
src: "rtl/uart.sv:93-94" }
get_source("…tx_o_dff") → the always_ff block, ~5 lines
Three calls, well under a thousand tokens, answer plus quotable source.
Install / run
pip install naja-scope # pulls najaeda>=0.7.8 and mcp from PyPI
naja-scope-mcp # stdio MCP server
Register with Claude Code:
claude mcp add naja-scope -- naja-scope-mcp
For development from a checkout, install editable instead:
python3.11 -m venv .venv
.venv/bin/pip install -e .
Tools
Lifecycle: load_systemverilog (files/flist/top), load_verilog,
load_liberty, load_primitives, save_snapshot, load_snapshot,
reset_universe, status.
Navigation: resolve (paths, bit selects, glob, did-you-mean),
find (design-wide glob, paginated), get_hierarchy.
Connectivity: get_drivers, get_loads (equipotential endpoints),
trace_cone (fanin/fanout combinational cone via naja SNLLogicalCone;
stop-at-flops/ports/black-boxes; counts + a cross_hierarchy summary naming the
frontier registers outside the cone root's subtree; lists bounded by
max_frontier).
Source & summaries: get_source (the SV lines that produced an object),
get_module_card (deterministic ports/counts/clock-reset card),
get_stats (per-model rollups).
Intent (phase 2): get_intent — source-level facts the netlist erases in
lowering: enum/typedef state names + encodings (incl. package typedefs whose
members live in another file), packed struct/union fields, and symbolic
parameter expressions (the formula behind a baked-in width). Backed by naja's
in-engine SNL↔slang link (keep_ast_link, najaeda 0.7.8) — a thin, pyslang-free
client that calls naja.intent_* and returns plain dicts; no second
elaboration. It is warm-only (a slang Compilation never serializes):
enable it with load_intent, load_systemverilog(intent=true) /
load_snapshot(intent=true), or the NAJA_SCOPE_INTENT=1 env opt-in; status
reports intent_loaded / intent_loadable. Cold sessions degrade gracefully
("intent layer not loaded; source range available via get_source") and re-bind by
re-elaborating from the snapshot-persisted load spec. No extra Python dependency
(see DESIGN.md "Phase 2" + docs/phase2-plan.md).
Escape hatch: query_python — najaeda is the query language; recurring
patterns observed there get promoted to first-class tools.
Conventions (DESIGN.md §6): object references are hierarchical path strings;
every list is paginated (limit, cursor); responses carry
src: "file:start-end" where known; errors return structured suggestions.
How source ranges work today
Since najaeda 0.7.2 every SNL object exposes its SystemVerilog origin directly
in Python through getSourceLoc() (naja #389/#390). naja-scope walks the raw
designs once and reads those locations straight into a sidecar index keyed by
(model, kind, name) — no Verilog dump, no attribute reparsing. Anonymous
lowered objects (FFs, gates) are first given stable derived names (tx_o_dff
for the FF driving tx_o), which is also what makes them addressable by path.
The index serializes alongside the naja-if snapshot, so source ranges survive a
snapshot reload (fixed in 0.7.4) with no re-elaboration.
Scope
RTL/design questions on synthesizable SystemVerilog. Not a DV/testbench tool (DESIGN.md §2 explains what is lost in lowering and why).
Development
.venv/bin/python -m pytest tests/ -q
The structural/source/snapshot tests are green on najaeda 0.7.4+ (no xfails):
the upstream bugs once tracked — parameter-specialization merging and naja-if
SV-snapshot reload — are both fixed (see NAJAEDA_NOTES.md); the snapshot
round-trip (tests/test_zz_snapshot.py) is a normal passing test.
naja-scope targets najaeda 0.7.8 (on PyPI since 2026-06-28) — the in-engine
SNL↔slang link (keep_ast_link) + curated intent_* API behind get_intent,
the Python NLID value class + NLUniverse.getObject(NLID) that back its
object-identity model (docs/identity-and-addressing.md), and the 0.7.6 gate
combinatorial modeling trace_cone needs. A plain install runs the full suite:
./.venv/bin/python -m pytest -q
For naja-side development you can instead run against a local naja build at
/Users/xtof/WORK/naja3, compiled for Homebrew Python 3.14 (it segfaults under a
3.11 interpreter), via the .venv314 dev venv plus PYTHONPATH:
PYTHONPATH=/Users/xtof/WORK/naja3/build/test/najaeda ./.venv314/bin/python -m pytest -q
The CVA6 cross-hierarchy cone regression (tests/test_zzz_cone_cva6.py) is
slow and skips unless the eval/.cache/cva6-small snapshot is present.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file naja_scope-0.1.0.tar.gz.
File metadata
- Download URL: naja_scope-0.1.0.tar.gz
- Upload date:
- Size: 49.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f45eaefca4a1dff78dd4714e4c5950d1ed9dd94c7db08dfdb9992fb3b9e93426
|
|
| MD5 |
e1c7e304a37171f02510ca60464bdd01
|
|
| BLAKE2b-256 |
096490dd81fdbc838d1014bad6d227fcc249c4ae4ae064556fad06797046409d
|
Provenance
The following attestation bundles were made for naja_scope-0.1.0.tar.gz:
Publisher:
publish.yml on najaeda/naja-scope
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
naja_scope-0.1.0.tar.gz -
Subject digest:
f45eaefca4a1dff78dd4714e4c5950d1ed9dd94c7db08dfdb9992fb3b9e93426 - Sigstore transparency entry: 2012790427
- Sigstore integration time:
-
Permalink:
najaeda/naja-scope@ae6811a05bd98a8574a70895310c945fd77e6db5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/najaeda
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ae6811a05bd98a8574a70895310c945fd77e6db5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file naja_scope-0.1.0-py3-none-any.whl.
File metadata
- Download URL: naja_scope-0.1.0-py3-none-any.whl
- Upload date:
- Size: 43.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d55f514d6edee4bf6ab0196c2ca781be8692626e4691f09e83b07f733c26db86
|
|
| MD5 |
32331ae15669cbb606db5f163b6490b2
|
|
| BLAKE2b-256 |
011aa605a637a5b1738709abd3c506736760d62769232ba2445e93e46025c567
|
Provenance
The following attestation bundles were made for naja_scope-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on najaeda/naja-scope
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
naja_scope-0.1.0-py3-none-any.whl -
Subject digest:
d55f514d6edee4bf6ab0196c2ca781be8692626e4691f09e83b07f733c26db86 - Sigstore transparency entry: 2012790555
- Sigstore integration time:
-
Permalink:
najaeda/naja-scope@ae6811a05bd98a8574a70895310c945fd77e6db5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/najaeda
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ae6811a05bd98a8574a70895310c945fd77e6db5 -
Trigger Event:
push
-
Statement type: