Skip to main content

AST-native code intelligence for Python — MCP server for Claude Code (12 agent tools) + standalone audit CLI (dead code, import graph, swallowed exceptions, 500+ language LOC via Linguist port).

Project description

symbol

AST-native code intelligence for Python. A CLI for humans, an MCP server for agents.

Point symbol at a directory and ask it questions a human or a coding agent actually has:

  • What frameworks does this project use, where are the entry points, which files are dead, what runs on import, where the TODOs and swallowed exceptions hide?
  • Where is UserService defined, who calls db.commit, what's the body of process_payment — without re-reading 800 lines of file?

Static analysis only — symbol never imports or executes the target code.

Status: v0.1.0, install from GitHub (PyPI release as wyolet-symbol coming soon — the bare symbol name is reserved by PyPI policy; CLI command stays symbol). Python is the proving ground. Go and TypeScript are next on the roadmap.

Install

CLI only

uv tool install wyolet-symbol      # or: pipx install wyolet-symbol

Then symbol audit /path/to/project, symbol loc, symbol map work from any directory.

Claude Code plugin (CLI + MCP server + skill + hooks)

For full agent integration — MCP tools (SearchSymbol, SymbolBody, MultiPatch, …), the symbol skill, and soft-nudge PreToolUse / PostToolUse hooks that steer Claude away from native Grep/Read/Edit on indexed Python files:

# 1. Install the CLI from PyPI
uv tool install wyolet-symbol

# 2. Install the plugin in Claude Code (bundles MCP server registration, skill, hooks)
claude plugin install git+https://github.com/wyolet/symbol@main

Other agent coding tools

The MCP server is plain stdio MCP — it works anywhere MCP works. opencode, Cursor, Continue, and Zed integrations are tracked in #8; help wanted. The Claude-Code-specific glue (skill + hooks) does not port automatically.

Updating / uninstall

uv tool upgrade wyolet-symbol      # or: uv tool uninstall wyolet-symbol
claude plugin update symbol        # or: claude plugin uninstall symbol

Commands

symbol audit <path> — Full codebase audit

Runs all registered checkers: stack detection, entry points, orphan files, side effects, swallowed exceptions, TODOs, unused deps, code structure metrics.

symbol audit /path/to/project
symbol -v audit /path/to/project   # verbose — full detail
symbol /path/to/project            # shortcut — defaults to audit

symbol loc <path> — Lines of code

GitHub Linguist port: 500+ languages, real GitHub colors, multi-strategy detection (modeline, shebang, filename, extension, XML, manpage). Colored bar chart by default.

symbol loc /path/to/project

symbol map <path> — Import graph analysis

Circular imports, hotspots, fragile modules, deep chains, leaf modules, blast radius.

symbol map /path/to/project
symbol map /path/to/project --blast src/models.py      # blast radius
symbol map /path/to/project --min-chain 3              # show shorter chains
symbol map /path/to/project --min-fan-in 3             # lower hotspot threshold

Symbol-level inspection

symbol search UserService              # exact / suffix match on qualified path
symbol search user service --fixed     # all patterns must appear as substrings
symbol search '^get_' --regex          # Python regex
symbol search save --kind method

symbol code services.user.UserService         # body by qualified path
symbol code services.user.UserService.save    # method
symbol code src/services/user.py:120-145      # by explicit line range

symbol outline src/services/user.py    # parent-child tree of one file
symbol callers UserService             # textual tier-1 reference scan

symbol patch <file> — Byte-range edit

Edit by line range without sending an old_string payload. Replace (with content), delete (empty content), or insert (zero-width range).

symbol patch src/foo.py --range 10-20 --content 'new body'    # replace
symbol patch src/foo.py --range 10-20 --content ''            # delete
symbol patch src/foo.py --range 10-10 --content 'import os'   # insert before line 10

symbol patch src/foo.py --range 10-20 --content '...' --dry-run   # preview diff
symbol patch src/foo.py --range 10-20 --content '...' --force     # skip read-cache check
symbol patch src/foo.py --range 10-20 --content '...' --agent     # plain text for LLMs

Exit codes: 0 applied/dry-run, 1 error, 2 needs_read_confirmation.

Plus

symbol analyze <file>, symbol dump <path>, symbol init <path>, symbol update-linguist, symbol undo, symbol refresh [--full].

MCP surface (12 agent tools)

When run as symbol mcp (or installed via the plugin), symbol exposes:

Read Write Safety
SearchSymbol Patch Undo
SymbolBody MultiPatch Refresh
SymbolOutline InsertSymbol
SymbolCallers DeleteSymbol
RenameSymbol
ReplaceSymbol

Undo is transactional and operates on .symbol/transactions/ — no git involvement, no staged changes touched. Refresh is the escape hatch when the index drifts.

Configuration

Two equivalent forms — standalone or in pyproject.toml:

# symbol.toml at project root, or [tool.symbol] in pyproject.toml
[tool.symbol]
exclude = ["alembic/*", "scripts/*"]

[tool.symbol.severity]
orphans = "warning"        # default: error
side_effects = "info"      # default: warning
unused_deps = "error"      # default: error

[tool.symbol.ignore]
deps = ["greenlet", "psycopg"]
orphans = ["alembic/*", "src/main.py"]
side_effects = ["*.include_router()", "*.add_middleware()"]

See docs/spec-schema.md for the full spec schema.

Global options

-v, --verbose          Show full detail instead of compact output
--format json          Output as JSON (for CI/CD pipelines)
-i, --include PATTERN  Only analyze files matching glob pattern
-e, --exclude PATTERN  Skip files matching glob pattern

Why

Most Python tools find problems inside files (lint, types, dead code). symbol finds problems between files — and exposes the result to agents in tokens, not line ranges:

  • knip does this for JavaScript/TypeScript. Python didn't have an equivalent. symbol fills that gap.
  • GitHub Linguist ported to Python — accurate detection for 500+ languages with real GitHub colors.
  • scc-style LOC with language breakdown and colored bar chart.
  • Import-graph analysis — circular imports, hotspots, blast radius. Things no other Python tool surfaces.
  • Agent-friendly write surface — symbol-level patch / rename / replace with byte-range edits and a transactional undo log, so coding agents don't have to re-read entire files to make safe changes.

First thing you run on an unfamiliar codebase, before reading a single line of code.

Architecture

src/wyolet/symbol/
├── cli.py                  Typer root CLI
├── commands/               Thin command views (audit, loc, map, analyze,
│                           search, code, outline, callers, patch, refresh,
│                           undo, init, + symbol-level ops for MCP)
├── checkers/               @register'd checkers
│   ├── stack.py            tech stack from deps
│   ├── entrypoints.py      __main__ guards, framework hooks
│   ├── orphans.py          unreachable files
│   ├── side_effects.py     bare module-level calls
│   ├── swallowed.py        silenced exceptions
│   ├── todos.py            TODO/FIXME/HACK/XXX
│   ├── unused_deps.py      declared but unimported
│   └── code_structure.py   functions, classes, type coverage
├── shared/                 Core infrastructure
│   ├── context.py          AnalysisContext (root, spec, cache, config)
│   ├── ast_cache.py        parse once, share across checkers
│   ├── registry.py         @register + views()
│   ├── runner.py           dispatches file/project checkers
│   ├── spec.py             spec loader
│   ├── config_resolver.py  spec → packages → project-config layering
│   ├── framework_detector.py
│   ├── pipeline.py         @hook(pipeline, priority)
│   ├── graph.py            import graph primitives
│   ├── symbol_index.py     qualified-path index for MCP read/write tools
│   └── linguist/           GitHub Linguist port (500+ langs)
└── data/
    ├── spec.toml           Global baseline spec
    └── specs/NAME/         Per-package specs (237 packages: django, fastapi,
                            celery, sqlalchemy, langchain, pydantic, ...)

Contributing

The fastest ways to help:

  • Add a package spec for a library we don't cover yet — no Python required, just TOML. See #3 and CONTRIBUTING.md.
  • Run symbol on your real Python project and file false positives. See #6.
  • Benchmark the MCP surface against native Read/Grep/Edit on representative agent tasks. See #7.
  • Wire symbol mcp into opencode / Cursor / Continue / Zed. See #8.

Pinned issues on the repo show what's most useful right now.

License

MIT

Project details


Download files

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

Source Distribution

wyolet_symbol-0.1.2.tar.gz (306.0 kB view details)

Uploaded Source

Built Distribution

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

wyolet_symbol-0.1.2-py3-none-any.whl (298.7 kB view details)

Uploaded Python 3

File details

Details for the file wyolet_symbol-0.1.2.tar.gz.

File metadata

  • Download URL: wyolet_symbol-0.1.2.tar.gz
  • Upload date:
  • Size: 306.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wyolet_symbol-0.1.2.tar.gz
Algorithm Hash digest
SHA256 37430689f61af3f17da207571812789905b426ac1f24ab84655d3bf0dfced485
MD5 be02baf18148e1fcef45ef930f1f7803
BLAKE2b-256 39f5352fb75360c7ac42e1ad054386b0384d6168bec34cdd48a39af8f2674dfb

See more details on using hashes here.

Provenance

The following attestation bundles were made for wyolet_symbol-0.1.2.tar.gz:

Publisher: release.yml on wyolet/symbol

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

File details

Details for the file wyolet_symbol-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: wyolet_symbol-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 298.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wyolet_symbol-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0120d4b9a81574ebf936330ffa5820574ff82380352580f879a34bb53b07cb72
MD5 1ee5b420edbc6c132d9d34e98ec7fc47
BLAKE2b-256 432f13891ec139ea7dae80970f41abda1c63704486aa22eecab96bd63f0bf0ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for wyolet_symbol-0.1.2-py3-none-any.whl:

Publisher: release.yml on wyolet/symbol

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