Skip to main content

Turn any folder of code into a queryable knowledge graph. Multi-language AST extraction with plugin architecture and MCP server for AI tools.

Project description

GraphFocus

Turn any folder of code into a queryable knowledge graph. Multi-language AST extraction with plugin architecture, designed to feed AI coding tools (Claude Desktop, Trae AI, Cursor, Windsurf) with focused, token-efficient context via MCP.

Why

Most code intelligence tools either parse only one language (so a fullstack Spring Boot + Vue project becomes a black box) or shovel raw files to an LLM until you blow your context window. GraphFocus extracts a deterministic knowledge graph via tree-sitter ASTs across 19 languages, links cross-language references (e.g. @Entity OrderEntity ↔ SQL orders table), and exposes it to AI tools so the model can ask find_callers("validate") instead of grepping the whole repo.

Features

  • 20 extractors — Python, Java, TypeScript / JavaScript / React, Vue, C#, Go, Kotlin, Rust, Swift, Ruby, PHP, Scala, Lua, C, C++, Dart, R, SQL, PL/SQL, plus Markdown / ADR and OpenAPI / Swagger specs.
  • Cross-language linker — Java/C# @Entity/@Table automatically wired to SQL/PL-SQL tables.
  • Plugin architecture — add a language by implementing a single interface.
  • Parallel analyze — fans the per-file work across ProcessPoolExecutor with a live progress bar; SQLite cache reuses unchanged files and prunes deleted ones.
  • MCP server with 10 tools — find_symbol, find_semantic, get_node, get_neighbors, find_callers, find_path, get_context_pack, hot_paths, cross_language_links, list_languages, get_stats. Plug it into any AI IDE (Trae AI, Cursor, Claude Desktop, Windsurf, Continue.dev, Zed, VS Code Cline) with graphfocus install-mcp.
  • Outputsgraph.json, WebGL-rendered graph.html (Sigma.js, 100k+ nodes), GRAPH_REPORT.md, dense AI_SUMMARY.md for LLM context, navigable Obsidian vault, Mermaid diagrams, TF-IDF semantic index.
  • Architecture lint.graphfocus.yml rules (disallow, require, max_outgoing) enforce layering in CI.
  • File watchergraphfocus watch re-analyzes on every save so the IDE always sees fresh data.
  • FastAPI server — REST endpoints for non-Python clients.
  • Optional LLM enrichment — semantic extraction from documents.

Install

Requires: Python 3.11+

# Core + all 19 extractors
pip install graphfocus

# Add the MCP server for AI tools
pip install "graphfocus[ai]"

# Add the FastAPI server
pip install "graphfocus[api]"

# Everything
pip install "graphfocus[all]"

Quick start

# Analyze the current directory; --update enables incremental cache;
# --ai writes the dense LLM summary; --obsidian writes a navigable vault.
graphfocus analyze . --update --ai --obsidian

# Output lands in ./graphfocus-out/:
#   graph.json        ← raw data
#   graph.html        ← interactive D3 visualization
#   GRAPH_REPORT.md   ← human report
#   AI_SUMMARY.md     ← LLM-friendly dense map (paste into a chat)
#   obsidian/         ← one .md per node, with wikilinks
#   .cache.db         ← incremental cache

Query the graph from the CLI

graphfocus find UserService                  # substring search
graphfocus semantic "auth user payment"      # TF-IDF semantic search
graphfocus neighbors userservice_user --depth 2
graphfocus callers validate                  # who calls validate()?
graphfocus languages                         # list active extractors

Other useful commands

Command What it does
graphfocus analyze . --update -j 4 Incremental analyze using 4 parallel workers
graphfocus analyze . --include "src/**" --exclude "**/test_*" Limit the scope with globs
graphfocus watch . Re-analyze automatically whenever a file changes
graphfocus serve-viz Serve graph.html locally so WebGL works
graphfocus serve Start the FastAPI REST server
graphfocus mcp Launch the MCP server (used by AI IDEs)
graphfocus install-mcp Auto-wire the MCP server into installed AI IDEs
graphfocus export-mermaid --root <id> --markdown -o diagram.md Mermaid subgraph
graphfocus init Scaffold .graphfocus.yml for the lint engine
graphfocus lint --fail-on-violation Run architecture rules; non-zero exit on violations

Plug into your AI tool (MCP)

GraphFocus ships an MCP server that exposes the graph to any compatible AI tool. The LLM gains these tools:

Tool What it does
find_symbol Search nodes by label/id, filter by language or kind
get_node Full info on one node + its incoming/outgoing edges
get_neighbors Walk N hops out from a node
find_callers Who calls this function/method
find_path Shortest path between two nodes
list_languages What's in the graph
get_stats Counts by kind and relation
cross_language_links Only edges that cross languages

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "graphfocus": {
      "command": "graphfocus",
      "args": ["mcp"],
      "cwd": "/absolute/path/to/your/project"
    }
  }
}

Trae AI / Cursor / Windsurf / Continue.dev

In the tool's MCP config (.cursor/mcp.json, Trae settings, etc.):

{
  "mcpServers": {
    "graphfocus": {
      "command": "graphfocus",
      "args": ["mcp"]
    }
  }
}

Restart the AI tool and ask things like "who calls validateUser?" — the model invokes find_callers and gets back a 200-byte JSON answer instead of grepping the whole codebase.

HTTP transport

For tools that prefer HTTP+SSE over stdio:

graphfocus mcp --http --port 8765

Token efficiency comparison

For a mid-sized Spring Boot project:

Approach Tokens sent to LLM
Raw source files 30–100K
Full graph.json 15–40K
AI_SUMMARY.md + a few Obsidian notes 1–3K
MCP find_callers("X") round-trip 200–800 per question

Supported languages

Language Parser Extracts
Python tree-sitter classes, functions, imports, calls, inheritance
Java tree-sitter classes, interfaces, methods, Spring annotations
TypeScript / JavaScript / React tree-sitter (tsx) classes, interfaces, type aliases, components
Vue regex + delegated TS parser component node, <script> symbols, child component refs in <template>
C# tree-sitter classes, methods, namespaces, attributes
Go tree-sitter structs, interfaces, methods (attached to receiver)
Kotlin tree-sitter classes, data classes, objects, Spring annotations
Rust tree-sitter structs, enums, traits, impl Trait for Type
Swift tree-sitter protocols, structs, classes, methods
Ruby tree-sitter modules, classes, methods, requires
PHP tree-sitter namespaces, interfaces, classes, methods
Scala tree-sitter traits, classes, case classes, objects
Lua tree-sitter functions, module methods (M.foo), requires
C tree-sitter structs, typedefs, functions, includes
C++ tree-sitter namespaces, classes, out-of-class methods
Dart regex classes, mixins, abstract classes, methods
R regex functions, library/source imports
SQL regex (dialect-agnostic) tables, columns, FKs, views, indexes
PL/SQL regex packages, procedures, functions, triggers

Architecture

Input files
   ↓
Detector  →  Registry  →  19 Extractors (per language)
                              ↓
                       Merger (dedup nodes)
                              ↓
                       Cross-language linker
                       (Java @Entity ↔ SQL table)
                              ↓
                Outputs:
                  • graph.json
                  • graph.html (D3 force-directed)
                  • GRAPH_REPORT.md
                  • AI_SUMMARY.md (dense for LLM)
                  • obsidian/  (one .md per node)
                              ↓
                MCP server / FastAPI / Query CLI
                              ↓
                Any AI tool over MCP

Adding a new language

from graphfocus.extractors.base import LanguageExtractor, ExtractionResult

class MyLanguageExtractor(LanguageExtractor):
    @property
    def language_name(self) -> str:
        return "mylanguage"

    @property
    def extensions(self) -> set[str]:
        return {".ml", ".mli"}

    def extract(self, path: Path) -> ExtractionResult:
        # Your extraction logic using tree-sitter or regex
        ...

Register the class in graphfocus/extractors/registry.py and add a test + fixture. See CONVENTIONS.md for details.

Development

make dev      # install with all extras
make test     # run pytest
make lint     # ruff check
make format   # ruff format
make serve    # start the FastAPI server

Release

Publishing to PyPI is automated via GitHub Actions and PyPI Trusted Publishing — no API tokens are stored in this repo.

One-time setup on pypi.org (project owner only):

  1. Log in to https://pypi.org and go to the project (after the first manual upload, or use a pending publisher).
  2. Manage → Publishing → Add a new publisher → fill in:
    • Owner: bamc300
    • Repository name: graphfocus
    • Workflow name: publish.yml
    • Environment name: pypi

Each release:

# 1. bump the version in pyproject.toml
# 2. commit + tag
git commit -am "chore: bump version to 0.2.0"
git tag v0.2.0
git push && git push --tags
# 3. the publish.yml workflow runs automatically and uploads to PyPI

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

graphfocus-0.3.1.tar.gz (184.4 kB view details)

Uploaded Source

Built Distribution

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

graphfocus-0.3.1-py3-none-any.whl (191.9 kB view details)

Uploaded Python 3

File details

Details for the file graphfocus-0.3.1.tar.gz.

File metadata

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

File hashes

Hashes for graphfocus-0.3.1.tar.gz
Algorithm Hash digest
SHA256 0dd75fd99e4eaa8d7f0f84fbe3a0119c7513050539b6ddaddd1b45c1b1cba263
MD5 bacfc35f72ac909a51d6060a298c012a
BLAKE2b-256 f6aa0b52ef5ab7f56795a582b7c046572bc177f95353b60c4fa341c0ecef6afb

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphfocus-0.3.1.tar.gz:

Publisher: publish.yml on bamc300/graphfocus

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

File details

Details for the file graphfocus-0.3.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for graphfocus-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2801405a437c4f9bebf82a17ad44857b891ef74a769140598ddd0e95ae68f61b
MD5 7b1fb0ad6f51f1bae29267d3688b31e5
BLAKE2b-256 fcff41d348b087c517141bb58faa42ebe493b1e9d6a68b791577150df8563c1e

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphfocus-0.3.1-py3-none-any.whl:

Publisher: publish.yml on bamc300/graphfocus

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