Naja Scope
Explore elaborated SystemVerilog/Verilog designs (RTL or gate-level netlists) with najaeda: trace fan-in/fan-out, walk module hierarchy and jump to source.
Que pouvez-vous faire avec Naja Scope ?
- Resolve any signal or instance by hierarchical path (with glob and
- Find objects design-wide by pattern.
- Show the hierarchy of any module.
- Get drivers / loads of a net — the real endpoints, across hierarchy;
- Trace logic cones (fan-in / fan-out) and see the register frontier.
- Get source — the exact SystemVerilog lines behind any object.
- Get a module card — ports, counts, clock/reset at a glance.
- Recover design intent — state-machine names, struct fields, parameter
Installation
Les étapes d'installation sont dans la documentation ci-dessous. Documentation
Documentation
Tirée du README du projet sur GitHub, actualisée chaque semaine. Les liens ouvrent GitHub.
Sommaire
naja-scope
Let your AI assistant explore SystemVerilog designs — without pasting source code into the chat.
naja-scope is an MCP server that gives AI agents (Claude, and any MCP-compatible assistant) a precise, structured view of your elaborated SystemVerilog design. Instead of dumping thousands of lines of RTL into the model's context, the agent asks targeted questions — what drives this signal? what's inside this module? where does this net come from? — and gets back small, exact answers with file-and-line references.
Built on the najaeda netlist engine.
On a 17-question CVA6 benchmark, the same Claude Code agent scored 17/17 with naja-scope versus 10/17 with grep/read source tools — in 77 turns instead of 123, processing about 5× less input. How it was measured ↓
pip install naja-scope
claude mcp add naja-scope -- naja-scope-mcp
Why
Large designs don't fit in a chat window. Pasting RTL is slow, expensive, and the model still can't reliably trace connectivity across hierarchy. naja-scope turns your design into something an agent can navigate:
- 🔎 Trace connectivity — find what drives or loads any signal, across module boundaries.
- 🌲 Walk the hierarchy — explore modules, instances, and ports on demand.
- 🎯 Jump to source — every answer comes with
file:lineranges, so the agent can quote the exact RTL that matters. - 🧩 Logic cones — trace fan-in / fan-out combinational cones up to the register boundary.
- 💡 Recover design intent — enum state names, struct/union fields, and parameter formulas that normally vanish when a design is elaborated.
Works on RTL and gate-level netlists alike: load elaborated SystemVerilog, or load a post-synthesis structural Verilog netlist together with its Liberty standard-cell library and navigate the gates the same way (see Gate-level designs). VHDL loading is in beta.
All responses are token-bounded: lists paginate, large results truncate with clear markers. Your context stays small; your answers stay accurate.
Does it actually help?
naja-scope helps most when the answer exists in the elaborated design rather
than in any single source file. In an initial 17-question run on the
cv32a6_imac_sv32 configuration of
CVA6, the same Claude Code agent was
tested with naja-scope and with source-search tools alone.
| Agent setup | Provider and models | Initial automated score | Turns | Input processed | Output tokens |
|---|---|---|---|---|---|
| Agent + naja-scope | Anthropic Claude Code; claude-sonnet-4-6 with claude-haiku-4-5-20251001 helper | 17 / 17 | 77 | 1,058,556 | 19,520 |
| Agent + grep/read source | Anthropic Claude Code; claude-sonnet-4-6 with claude-haiku-4-5-20251001 helper | 10 / 17 | 123 | 5,461,719 | 55,962 |
The difference is clearest on structural questions that source search cannot answer directly:
| CVA6 question | Agent + naja-scope | Agent + grep/read source |
|---|---|---|
Flattened register groups under ex_stage_i | 92, in 4 turns | No answer at the turn limit |
Flattened register groups under commit_stage_i | 0, in 3 turns | No answer at the turn limit |
Elaborated hpdcache_mux variants | 20, in 3 turns | No answer at the turn limit |
Source search remains the right tool for local textual questions. naja-scope adds the elaborated hierarchy, connectivity, lowered primitives, and generated or uniquified structures that are otherwise difficult to reconstruct.
See the benchmark methodology and multi-model runner and historical result record for configuration, scoring, token accounting, and reproducibility details.
Install
pip install naja-scope # pulls najaeda and the MCP runtime from PyPI
naja-scope-mcp # stdio MCP server
Connect it to Claude Code
claude mcp add naja-scope -- naja-scope-mcp
Or add it to any MCP client's config:
{
"mcpServers": {
"naja-scope": {
"command": "naja-scope-mcp"
}
}
}
Then just ask your assistant to load a design and start exploring:
"Load my UART design from
rtl/uart.svwith topuart_top, then show me everything that drivestx_o."
The agent loads the design once and answers follow-up questions instantly — no re-reading source, no giant pastes.
Connect it to ChatGPT
ChatGPT connects to MCP servers over an HTTP endpoint (custom connectors / Developer mode), so run naja-scope as an HTTP server instead of stdio:
naja-scope-mcp --transport streamable-http --host 127.0.0.1 --port 8000
This serves MCP at http://<host>:8000/mcp. Because ChatGPT reaches the server
over the network, expose that URL where ChatGPT can see it — e.g. a public
tunnel for a local run:
# example: a tunnel to your local server (ngrok, cloudflared, …)
ngrok http 8000 # -> https://<something>.ngrok.app → add /mcp
Then in ChatGPT, open Settings → Connectors (enable Developer mode if
needed), add a custom connector, and paste the server URL
(https://<your-host>/mcp). Once connected, ask it to load a design and explore
exactly as above. (ChatGPT's connector UI evolves; the constant is: it needs an
HTTPS MCP URL, which --transport streamable-http provides.)
⚠️ The HTTP server has no built-in auth — only expose it over a trusted tunnel, and prefer short-lived tunnels for local experiments.
Gate-level designs
Already synthesized? Load the structural Verilog netlist together with the Liberty library that defines its standard cells, and navigate the gates the same way as RTL:
"Load the Liberty library
pdk/stdcells.lib, then the gate netlistbuild/top.v, and tell me what cellstopis built from and what drivesdata_out."
Hierarchy, per-cell counts (get_module_card), drivers/loads, and logic cones
all work on the netlist; cones stop at the sequential cells. get_source
shows a cell's or net's line in the netlist. For Yosys output, load with
yosys_source_attributes=True: the (* src = ... *) attributes become
origins that get_source(path, origin=0) reads back in the RTL. A runnable
example lives in examples/ (stdcells.lib + counter2.v +
gate_level.py).
Storage summaries
get_module_card reports direct-child register bits and inferred RAM/ROM
summaries: width, depth, capacity in bits, read/write port counts, and
initialization status. It lists up to 12 memories, with memories_truncated
when more exist; initialized memories include a 64-character init_preview
and init_truncated. Address zero occupies the least-significant word.
get_stats aggregates these counts below the selected instance using
flat_register_bits, flat_memory_instances, flat_rom_instances,
flat_ram_instances, and flat_memory_bits. Register bits count modeled
flip-flop/latch states, including multibit Liberty banks; RAM capacity is
separate. Sequential cells without a state model are counted in
register_bits_unknown_instances (flat_ in statistics), so known bit
counts remain explicit lower bounds when that count is nonzero. Memories
are recognized from native naja primitives; opaque memory macros are not
assigned an inferred capacity.
VHDL (beta)
VHDL loading is available in beta. Call
load_vhdl(file=["pkg.vhd", "child.vhd", "top.vhd"], top="my_entity") to
explore its elaborated hierarchy and connectivity; the files may be listed in
any order. A single path per call also works (load packages first);
package-only files may return top: null until the top file is loaded. The frontend supports a restricted two-state RTL subset,
and supported constructs may change. get_intent/load_intent remain
SystemVerilog-only; VHDL source ranges are not guaranteed.
What you can ask
Once a design is loaded, your assistant can:
- Resolve any signal or instance by hierarchical path (with glob and did-you-mean suggestions).
- Find objects design-wide by pattern.
- Show the hierarchy of any module.
- Get drivers / loads of a net — the real endpoints, across hierarchy;
literal drivers preserve four-state
0/1/X/Zvalues. - Trace logic cones (fan-in / fan-out) and see the register frontier.
- Get source — the exact SystemVerilog lines behind any object.
- Get a module card — ports, counts, clock/reset at a glance.
- Recover design intent — state-machine names, struct fields, parameter expressions lost during elaboration.
A runnable end-to-end walkthrough lives in examples/, including
versions that run against CVA6 (a
production RISC-V core, cloned on demand — see
examples/cva6_demo.sh) and
CORE-V-MCU (a full multi-vendor
RISC-V SoC — see examples/core_v_mcu_demo.sh).
The Python escape hatch (off by default)
naja-scope also has a query_python tool that runs Python directly against the
loaded design, for queries the typed tools above cannot express. It is not
registered unless you opt in:
NAJA_SCOPE_ENABLE_PYTHON=1 naja-scope-mcp
It is unsandboxed eval/exec inside the server process — read-only by
convention, not enforced — so anything that can reach the server can run
arbitrary Python as the server's user. That matters most under --transport
streamable-http, where the server listens on a socket. Leave it off unless you
need it and trust every client that can reach the endpoint.
Requirements
- Python 3.10+
- Works anywhere
najaedaruns (Linux, macOS, Windows)
Development
# from a checkout
python3 -m venv .venv
.venv/bin/pip install -e .
.venv/bin/python -m pytest -q
The full test suite runs against a plain pip install of najaeda — no native
build required. The CVA6 cross-hierarchy cone regression
(tests/test_zzz_cone_cva6.py) is slow and skips automatically unless a CVA6
snapshot is present.
CI tests every supported Python version on Linux x86_64, plus native platform
lanes for Linux x86_64/aarch64, macOS x86_64/arm64, and Windows x86_64. The
macOS x86_64 lane builds najaeda from its source distribution because PyPI
does not currently provide an Intel macOS wheel.
Support & contact
- 🐛 Found a bug or have a feature request? Open an issue on GitHub →
- 📫 Get in touch: contact@keplertech.io
License
Apache-2.0. See LICENSE. </content> </invoke>
Optional browser schematic
Requires naja-schematic 0.2.0 or later (the release containing the embeddable viewer API):
pip install "naja-scope[schematic]"
Restart the MCP server after installation. Load a design as usual, then use:
open_schematic(path="top.u_cpu"): returns a local browser URL and focuses the instance. Omitpathfor the top. Anonymous#idinstances are supported.annotate_schematic(items=[{"path": "top.u_cpu", "message": "Check reset", "severity": "warning"}]): replaces the overlay. Usekind="term"with a pin/port path to annotate that terminal; annotations apply to the whole port, not individual bus bits. Passitems=[]to clear. At most 200 annotations, each with at most 2000 message characters.get_schematic_selection(): returns the last clicked instance as a regular naja-scope path, usable with source, hierarchy and module-card queries.
The viewer shares the existing raw naja universe; it does not elaborate again. The server binds to loopback and returns a token-bearing URL. Open that URL on the machine running the MCP server; it is not a remote or embedded MCP UI. Treat the URL as access to the loaded design. Design loads/resets refresh open viewers and clear selection, focus and annotations. The browser server stops with naja-scope. Existing tools remain usable without the schematic extra.
Questions fréquentes
Qu'est-ce que Naja Scope ?
Explore elaborated SystemVerilog/Verilog designs (RTL or gate-level netlists) with najaeda: trace fan-in/fan-out, walk module hierarchy and jump to source.
Comment installer Naja Scope ?
Suivez les étapes d'installation de sa documentation, affichée sur cette page et dans son dépôt.
Naja Scope est-il open source ?
Oui. Son code est sur GitHub sous licence Apache-2.0.
Qui maintient Naja Scope ?
Il est publié par najaeda. AI.tn le référence sans le maintenir ni le recommander.
Issu des listes communautaires awesome-mcp-servers et du dépôt GitHub du projet. Être listé n'est pas une recommandation : vérifiez le code et les permissions d'un serveur avant de lui donner accès à vos données.