svitovyd
Project map builder and structural query tool for codebases — scans a project (33 file types: Python, Java, JavaScript/TypeScript, C#, Go, Rust, C/C++, SQL, YAML and more) into a plain-text map of what every file defines and which files it refers to, and answers questions about it from the command line, a web UI or an MCP server, without an LLM.
What it does
svitovyd reads the source files of a project and writes .svitovyd/map.txt: for every file, the
identifiers it defines (classes, functions, endpoints, tables, …) with their line numbers, and the
links to other files, each with its kind (import, call, ref, expr).
The map is then used to:
- find — filter the map by file name and content;
- trace / deps — who refers to an identifier, and what it depends on, step by step;
- search — which files a task description is about: its words become the identifiers the code defines, and those lead to the files;
- keywords — the identifiers of the code as a vocabulary, and the ones a text mentions;
- sym — a health report: identifiers defined but never referred to, cohesion of the hotspots, orphan files;
- idiff — what changed in the structure between two snapshots of the map;
- ui — the project as an interactive map in the browser, layer by layer.
AI agents get the same through the MCP server, so they can navigate a large code base without reading it file by file.
Statement of need
Developers and AI coding agents both need to know how a code base is put together before they change it: where a name is defined, who uses it, what a change will touch. In a large project reading the files is slow, and an agent with a small context window cannot hold them at all. Language servers answer such questions, but each works for one language and needs the project to build.
svitovyd builds one map for a whole project in many languages, from the text of the files alone,
with no build, no compiler and no model. The map is a small text file that a person can read, grep
can search, and an agent can load. It is meant for:
- developers who join or maintain a large code base and want to see its structure and the dependencies between its parts;
- AI coding agents, local or remote, that need a cheap way to find the right files and follow references (through the MCP server or the command line);
- researchers in software engineering who need the structure of many projects in one simple format.
Install
pip install svitovyd # CLI + web UI
pip install "svitovyd[mcp]" # + the MCP server (stdio)
pip install "svitovyd[http]" # + MCP over HTTP/SSE (remote agents, LAN)
pip install "svitovyd[gradio]" # + the older Gradio UI (svitovyd ui --gradio)
Python 3.10+. The core needs only Flask and waitress, so it installs anywhere Python runs.
Quick start
cd my-project
svitovyd index . # -> .svitovyd/map.txt
svitovyd index . 3 # depth 3: also variables and parameters
svitovyd find auth # files whose name contains "auth"
svitovyd trace SessionManager # who refers to it
svitovyd deps Cart # what it depends on
svitovyd search "Login fails after the session expires"
svitovyd sym --k 10 # health report
svitovyd ui # http://127.0.0.1:8097/
After a change, compare the structure with the previous map:
cp .svitovyd/map.txt .svitovyd/map.prev.txt
svitovyd index .
svitovyd idiff --prev .svitovyd/map.prev.txt
Commands
| Command | What it does |
|---|---|
svitovyd index [PATH] [DEPTH] |
Scan a folder and build the map (depth 2 = definitions + links, 3 = also variables and parameters) |
svitovyd find QUERY |
Filter map blocks by file name and content (syntax below) |
svitovyd search TEXT|FILE [--top N] [--json] |
The files a task text is about |
svitovyd trace IDENT |
Who refers to an identifier, step by step backwards |
svitovyd deps IDENT |
What an identifier or file depends on, step by step forwards |
svitovyd keywords [index|extract TEXT] |
The identifier vocabulary: build it, extract the identifiers of a text, or list the most referred-to |
svitovyd sym [--k K] |
Asymmetry and cohesion health report |
svitovyd idiff --prev MAP |
Structural diff between two map snapshots |
svitovyd ui [--port 8097] [--host 0.0.0.0] [--root FOLDER] [--map FILE] |
The web UI |
svitovyd serve [--http --port 8766] |
The MCP server (also svitovyd-mcp) |
find syntax
| Token | Meaning |
|---|---|
term |
the file name contains term |
!term |
leave out files whose name contains term |
\term |
keep a file if any of its lines contains term |
\!term |
leave out a file if any of its lines contains term |
-term |
show only the lines that contain term |
-!term |
hide the lines that contain term |
Example
The output below comes from a small demo shop project (modules auth, checkout, billing, catalog).
The map itself is plain text:
auth\src\LoginController.java
defines : LoginController(ln:2)
links → auth\src\SessionManager.java (call:SessionManager)
auth\src\SessionManager.java
defines : SessionManager(ln:2)
links → auth\src\TokenRefresher.java (call:TokenRefresher)
Which files a task is about:
$ svitovyd search "Login fails after the session expires" --top 3
words -> code: Login (1 id / 1 files), session (1 id / 1 files)
1. auth/src/LoginController.java 2.56 LoginController
2. auth/src/SessionManager.java 2.56 SessionManager
Who uses a class, and what a class depends on:
$ svitovyd trace TaxCalculator
trace: TaxCalculator
billing\src\TaxCalculator.java [defines TaxCalculator(ln:2)]
← call:TaxCalculator billing\src\InvoiceService.java
← import,call:TaxCalculator checkout\src\PriceCalculator.java
← call:PriceCalculator checkout\src\Cart.java
$ svitovyd deps Cart
deps: Cart(ln:3)
checkout\src\Cart.java
→ import,expr:Product catalog\src\Product.java
→ expr:DiscountRule checkout\src\DiscountRule.java
→ call:PriceCalculator checkout\src\PriceCalculator.java
→ import,call:TaxCalculator billing\src\TaxCalculator.java
From a task text to files
svitovyd search, the Task page of the web UI and svitovyd.graph.files_for_text() all work
the same way. The task's words become identifiers the code defines:
- a word that is a defined identifier (
SessionManager) means exactly it; - any other word means every defined identifier whose parts contain its parts of 5 or more letters
(
session→SessionManager).
A word weighs log(files / files defining its identifiers), so a word that is rare in the code
says more. Words found in more than 2 % of the files are skipped, and so are common English words.
svitovyd reads only the map: it needs no task history.
Keywords
The keyword vocabulary links the words of a task to the identifiers of the code.
svitovyd keywords index # -> .svitovyd/keyword.txt
svitovyd keywords extract "apply a discount to the cart total" -f
svitovyd keywords extract "tax" -l -o # substring match + the files
svitovyd keywords --k 100 # the most referred-to identifiers
$ svitovyd keywords extract "apply a discount to the cart total" -f
DiscountRule
$ svitovyd keywords extract "tax" -l -o
TaxCalculator -> billing\src\InvoiceService.java, billing\src\TaxCalculator.java, checkout\src\PriceCalculator.java
| Flag | Meaning |
|---|---|
| (none) | exact match: the word is an identifier |
-f / --fuzzy |
the identifier's camelCase / snake_case parts contain the word's parts of 5+ letters |
-l / --like |
the identifier contains the word as a substring |
-o / --origin |
also the files each identifier appears in |
-n / --counts |
the frequency of each identifier |
-s / --sort-count |
sort by frequency |
-a / --alpha |
sort alphabetically (default: the order in the text) |
-c / --csv |
one comma-separated line |
Web UI
svitovyd ui # http://127.0.0.1:8097/
svitovyd ui --root ~/projects # look for maps under this folder
svitovyd ui --map /path/to/map.txt # open this map
svitovyd ui --host 0.0.0.0 # reachable from other devices on the LAN
The UI lists the maps under the folder it was started in and remembers every map opened or built
(~/.svitovyd/maps.json). One map is worked on at a time.
- Map: the project as an interactive map, layer by layer: the top folders first, then the inside of the one you click. Folders are sized by their files and coloured by cohesion. Click a link to see what it is made of, or a file to see what it defines, uses and is used by.
- Task: paste a task and get the files it is about, marked on the map.
- Find: the
findsyntax, with clickable files. - Paths:
traceanddepsas trees, with the link kind of every step. - Keywords: the identifiers of a text that exist in the code, and the most referred-to ones.
- Health: asymmetry, cohesion of the hotspots, orphans, and drift against an earlier map.
- Maps: open a map, build one for a folder, download
map.txt/keyword.txt.
Which link kinds count is chosen once for every page. expr (a word of one file that equals a
name of another) is off by default, because in a large project it is mostly common words. The UI
has 8 colour themes and 6 languages (English, Ukrainian, German, French, Spanish, Portuguese).
MCP server
The MCP server exposes 6 tools to any connected agent:
| Tool | Description |
|---|---|
map_index |
Build or update the project map |
map_find |
Filter map blocks by filename/content |
map_trace |
BFS backwards — who calls this identifier? |
map_deps |
BFS forward — what does this depend on? |
map_sym |
Asymmetry and cohesion health report |
map_idiff |
Structural diff between two map snapshots |
Start the server
Stdio (for local agents — Claude Code, 1bcoder):
svitovyd-mcp
HTTP/SSE (for remote agents — opencode, nanocoder, LAN):
svitovyd-mcp --http --port 8766
# or
svitovyd serve --http --port 8766
With a specific map file:
svitovyd-mcp --http --port 8766 --map-file /path/to/project/.svitovyd/map.txt
Setup per agent
Claude Code
Add to .claude/settings.json in your project or ~/.claude/settings.json globally:
{
"mcpServers": {
"svitovyd": {
"command": "svitovyd-mcp",
"args": []
}
}
}
With a specific map file:
{
"mcpServers": {
"svitovyd": {
"command": "svitovyd-mcp",
"args": ["--map-file", "/path/to/project/.svitovyd/map.txt"]
}
}
}
opencode
Start the HTTP server first:
svitovyd-mcp --http --port 8766
Add to your opencode config (~/.config/opencode/config.json or project-local):
{
"mcp": {
"svitovyd": {
"type": "sse",
"url": "http://localhost:8766/sse"
}
}
}
Or connect interactively if opencode supports it:
/mcp connect svitovyd http://localhost:8766/sse
nanocoder
Start the HTTP server:
svitovyd-mcp --http --port 8766
Add to nanocoder config:
{
"mcpServers": {
"svitovyd": {
"url": "http://localhost:8766/sse"
}
}
}
1bcoder
/mcp connect svitovyd http://localhost:8766/sse
Or add to .1bcoder/mcp.yaml for auto-connect:
servers:
- name: svitovyd
url: http://localhost:8766/sse
Cursor
Add to .cursor/mcp.json in your project:
{
"mcpServers": {
"svitovyd": {
"command": "svitovyd-mcp",
"args": []
}
}
}
Any MCP-compatible client (generic)
Stdio transport — command: svitovyd-mcp
SSE transport — start server then connect to: http://localhost:8766/sse
MCP tools reference
map_index
path directory to scan (default: ".")
depth 2 = definitions + links (default)
3 = also variables and parameters
map_file output path (default: <path>/.svitovyd/map.txt)
map_find
query filter string — token syntax:
term filename contains term
!term exclude if filename contains term
\term include block if any child line contains term
\!term exclude block if any child line contains term
-term show ONLY child lines containing term
-!term hide child lines containing term
map_file map file to query (default: .svitovyd/map.txt)
map_trace
identifier function/class name defined in the codebase
depth max BFS depth (default: 8)
map_file map file to query
map_deps
identifier function/class name OR file path substring
depth max BFS depth (default: 8)
map_file map file to query
map_sym
k top-K hotspots for cohesion score (default: 5)
map_file map file to query
map_idiff
prev_map_file path to previous map snapshot (required)
map_file current map file (default: .svitovyd/map.txt)
Supported languages
.py .js .ts .java .cs .go .rs .cpp .c .h
.rb .php .kt .scala .swift .lua
.html .css .jsx .tsx .vue .svelte
.sql .yaml .yml .toml .json .xml
.tf .hcl .sh .bat .ps1
Python API
from svitovyd import graph as G
from svitovyd.query import keyword_to_files
idx = G.load(".svitovyd/map.txt")
r = G.files_for_text(idx, "Login fails after the session expires")
r["files"][:3] # [{"file", "score", "names": the identifiers it defines that matched}, ...]
r["words"] # every word that counted, with its identifiers and weight
keyword_to_files(".svitovyd/map.txt", "TaxCalculator") # the files an identifier appears in
Tests
git clone https://github.com/szholobetsky/svitovyd
cd svitovyd
pip install -e .
pip install pytest
pytest
Support
The project is on GitHub: github.com/szholobetsky/svitovyd. Questions, bug reports and suggestions go to its issues.
Part of the SIMARGL toolkit
svitovyd is one of ten tools that together form an intellectual development support system:
| Tool | Role |
|---|---|
| simargl | Task-to-code retrieval — given a task description, finds which files and modules are likely affected, using semantic similarity over git history |
| svitovyd | Project map — scans any codebase and produces a structural map of definitions and cross-file dependencies; queried from the CLI, a web UI with a layered map, or an MCP server |
| 1bcoder | AI coding assistant for small local models — surgical context management, agents, parallel inference, proc scripts |
| yasna | Session memory — indexes conversations from all AI agents so you can find what was discussed, when, and where |
| radogast | Context drift monitor — measures how far an AI agent's conversation has drifted from the original task |
| vyrii | Local AI web UI — chat, translate, web research, RAG and file management in the browser (Flask; Gradio optional); powered by Ollama or any OpenAI-compatible backend |
| syryn | Bluetooth identity beacon for headless devices — the device's IP is its Bluetooth name; hostname, mDNS and network interfaces on request |
| alkonost | Browser cockpit for 1bcoder's flows — the deepagent_* spec pipeline (plan tree → specs → task board) and the glossary (build, browse, search), tuned for small local models |
| gamayun | Statistical ontology without an LLM — builds triples of terms, identifiers, files and modules from task history or a folder of documents and code; every triple carries its significance test |
| mokosh | Dataset gathering — commits of a git repository and the tasks of its tracker (Jira, GitHub, GitLab, YouTrack) in one SQLite database that the other tools read |
- simargl finds the code related to a task by vector search over the task history (embeddings).
- svitovyd answers: how is the code structured and what depends on what?
- 1bcoder answers: how do I work with local models efficiently?
- yasna answers: where did I already discuss this?
- radogast answers: is the AI agent still on track toward the goal?
- vyrii answers: how do I access all of this through a browser?
- syryn answers: what is the address of this headless device?
- alkonost answers: how do I turn one task description into a reviewed, working plan — and see the project's glossary — without a big model or a big context window?
- gamayun finds the code related to a task through an ontology of significant links between words, files and modules (no LLM).
- mokosh prepares the initial dataset from version control and the issue tracker.
Together they cover the full development loop: understand the codebase, find relevant history, work with AI locally, remember what was decided, and verify the context stays on target.
The name comes from Slavic mythology. Svitovyd (Світовид) is the four-faced god who sees all directions simultaneously — past, future, war, and harvest. A fitting name for a tool that maps an entire codebase at once.
License
MIT. See LICENSE.
About
(c) 2026 Stanislav Zholobetskyi, Oleh Andriichuk
Institute for Information Recording, National Academy of Sciences of Ukraine, Kyiv
PhD research: «Intelligent Technology for Software Development and Maintenance Support»
Metadata
Release files for svitovyd 0.1.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| svitovyd-0.1.8.tar.gz | 95.7 kB | Without provenance | Details for svitovyd-0.1.8.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| svitovyd-0.1.8-py3-none-any.whl | Python 3 | none | any | Details for svitovyd-0.1.8-py3-none-any.whl |
Total release size: 196.1 kB
Release files / svitovyd-0.1.8.tar.gz
| Download URL | svitovyd-0.1.8.tar.gz |
|---|---|
| Size | 95.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9191f4bd26c4e8d0cc4f4277cf18466bf9c45928c4f3d2e4a25abef6683ceed6
|
|
BLAKE2b-256 checksum How to use checksums |
5ea25f3ea7af9a3062514a27ff23051fbbda21bc55e13eb9325bdcb57043f8a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.9
|
Release files / svitovyd-0.1.8-py3-none-any.whl
| Download URL | svitovyd-0.1.8-py3-none-any.whl |
|---|---|
| Size | 100.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ddbbe6eefca0c0762e38f979c21a1e6d1fd85ef9b6593f7b20a1da243e054a6a
|
|
BLAKE2b-256 checksum How to use checksums |
1bd4f8d79aedf12fafcd11e9b91511d926b10c429cf2dedf3182c00d1cbe23a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.9
|
Security for svitovyd 0.1.8
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.