callgraph MCP sunucusu
Commit 14 Kas 2026Yapay zeka ajanlarının tüm dosyaları okumasına gerek kalmadan kod yapısını ve etkilerini anlamalarına yardımcı olmak için AST tabanlı bir kod haritası ve kategorize edilmiş bir çağrı grafiği sunar.
Ayrıca bilinen adı GeRiY/callgraph
- Yıldızlar
- 13
- Araçlar
- —
- İndirmeler, 30 gün
- —
- En son sürüm
- 0.9.5
- Son commit
- 14 Kas 2026
- Lisans
- MIT
callgraph MCP nedir?
callgraph bir MCP sunucusudur. Yapay zeka ajanlarının tüm dosyaları okumasına gerek kalmadan kod yapısını ve etkilerini anlamalarına yardımcı olmak için AST tabanlı bir kod haritası ve kategorize edilmiş bir çağrı grafiği sunar.
Özet, projenin README dosyasından oluşturuldu
callgraph MCP sunucusu hakkında
Yapay zeka kodlama ajanlarını kullanan geliştiriciler, callgraph kullanarak modellerine kod tabanlarının token verimliliği yüksek bir haritasını sunabilirler. Bir ajanı mantığı anlaması için tüm dosyaları okumaya zorlamak yerine, bu araç sınıfların, metodların, özelliklerin ve sabitlerin yapılandırılmış özetlerini sağlamak için Abstract Syntax Tree ayrıştırmasını kullanır. Claude Code içine entegre edilebilen veya yüksek seviyeli mimari bağlam sağlamak için terminal üzerinden kullanılabilen yerel bir Rust binary'si olarak çalışır.
Sunucu, çağrı grafiklerini framework_use veya orm_relation ve external_call gibi belirli türlere ayırarak ajanların sadece isimleri değil, kodun arkasındaki niyeti anlamasını sağlar. PHP, Rust, TypeScript, Swift, Python, Go ve hatta CSS dahil olmak üzere geniş bir dil yelpazesini destekler. Kullanıcılar, önbelleğe alınmış bir indeks kullanarak proje genelindeki çağırıcıları takip edebilir ve böylece belirli bir metod değiştirildiğinde nelerin bozulabileceğini kolayca görebilirler.
Kurulum, binary'nin yüklenmesini ve bir proje yolunun kaydedilmesini içerir. .gitignore kurallarına uyar ve belirli dizinleri veya uzantıları atlamak için .callgraphignore dosyası ile daha fazla özelleştirilebilir. Araç, farklı ajan iş akışlarına uyması için mermaid, json ve summary gibi çeşitli çıktı formatları sunar.
Neler yapabilirsiniz
- 1Kod etkisini analiz edinBir metodun çağırıcılarını takip ederek, belirli bir metodun değiştirilmesiyle projenin hangi kısımlarının etkileneceğini belirleyin.
- 2Nokta atışı kod okumaları yapınBir yapay zeka görüşmesi sırasında token tasarrufu sağlamak için yalnızca belirli bir metoda ait kaynak kodu getirin.
- 3Proje yapısını haritalandırınBir dosyanın sabitlerini, özelliklerini ve kategorize edilmiş metod çağrılarını içeren üst düzey bir taslağını oluşturun.
Projenin README dosyasından alınmıştır. Her kullanım durumu, oradaki bir alıntı ile kontrol edilir.
Yapılandırma
CALLGRAPH_LANG
| Ad | Açıklama | Sunucu |
|---|---|---|
| CALLGRAPH_LANG | — |
Otomatik kontroller
Çalıştırıldı 13 Kas 2026Tam rapor →Henüz doğrulanmadı. Bir sunucunun 80 puana, ciddi bir bulgu olmamasına ve kontrol edebilmemiz için yeterli veriye ihtiyacı vardır. Kontroller nasıl çalışır · Daha fazla puan için nelerin düzeltileceği
- Kaynak deposu bağlantılı ve erişilebilirGeçti
- Açık kaynak lisansı (OSI)Geçti
- Son bir yıl içinde commit veya sürüm mevcutGeçti
- Paket adı popüler bir pakete yakın değilKontrol edilmedi
- Uzak uç nokta HTTPS kullanıyorKontrol edilmedi
- Yıkıcı araçlar etiketlenmişKontrol edilmedi
- Modele yönelik gizli talimat yokGeçti
- Pakette veya bağımlılıklarında kritik uyarı yokKontrol edilmedi
An agent that needs to understand one method usually reads the whole file, then greps, then reads a few more files. callgraph answers those questions from the AST instead, in a few dozen lines: what is in this file, which method lives on which lines, what it calls (sorted by category), who calls it, and what breaks if it changes.
It ships as a single native Rust binary plus a thin Claude Code skill, and it works just as well from any terminal or script.
$ callgraph.sh --project shop app/Models/Order.php
FILE /srv/shop/app/Models/Order.php NS:App\Models
class Order extends Illuminate\Database\Eloquent\Model L7-23
constants (1):
STATUS_OPEN = 'open'
properties (1):
mixed $fillable
saveTranslations() L13-20
external_call create, info
global_helper logger
internal_helper translations
translations() L22-22
orm_relation hasMany
$ callgraph.sh --project shop app --grep saveTranslations --depth 2
== level 1 — directly calls: /saveTranslations/
/srv/shop/app/Models/Order.php Caller::run() L25-25
== level 2 — calls the previous level
(no more callers)
Highlights
- Reads the AST, not the text. Classes / components, methods with exact line ranges, properties, constants,
imports, docblocks, string literals and
if/match/switchbranches. - Categorized call graph. Every call is classified:
native_php,orm_relation,model_use,global_helper,internal_helper,external_call,framework_use, Vuecomposable_useand more, so the agent sees intent, not just names. Calls whose target is decided at runtime ($this->$method(),obj[key](),getattr(obj, name)()) are markeddynamic_callinstead of silently missing. - "Who calls this?" and impact analysis.
--grep <pattern> --depth Nwalks callers of callers across the whole project using a cached, incremental project index. - Surgical reads.
file::method --bodyprints just that method, line-numbered;--lines 30-60prints any range. - Framework views. Laravel / Yii aware:
routes,middleware,validation,jobs,events,providers,magic,di,views. - Many output formats.
outline,api,flow,summary,hotspots,coverage,stats,mermaid,dot,json,jsonl. - Fast and dependency-free. One static binary (no PHP, Node or jq needed), parallel parsing, mtime-based JSONL cache.
- English or Hungarian output, switchable with one command.
Supported languages
Per-language guides with examples: PHP · Rust · TypeScript / JavaScript / Vue · Swift / SwiftUI.
| Language | Extensions | What you get |
|---|---|---|
| PHP | .php |
classes, traits, enums, methods, properties, constants, calls with type tracking, framework detection (Laravel, Yii) |
| Rust | .rs |
modules, structs, enums, traits, impl blocks, functions with visibility / async, fields, consts, use trees, path / method / macro calls, if / match flow, framework detection from Cargo.toml (axum, actix-web, tokio, serde, …) |
| JavaScript / TypeScript | .js .mjs .cjs .jsx .ts .tsx |
modules, functions, classes, imports with alias resolution (jsconfig / tsconfig) |
| Vue | .vue |
props, emits, setup, template components and event handlers, computed, watch, lifecycle hooks, Options API |
| Swift / SwiftUI | .swift |
classes, structs, enums, protocols, actors, extensions; View types as components; func / init / computed properties (body); property wrappers (@State, @Binding, @Published, …); SwiftUI views and modifiers as their own call categories |
| Python | .py .pyi |
classes (bases, decorators), functions / methods (async, @staticmethod, @classmethod, @property) with signatures, constants, __all__, docstrings, imports, calls (native_python, internal_helper, static_call, …), Django / Flask / FastAPI detection |
| Go | .go |
packages, structs (fields as properties, embedded types), interfaces, type aliases, functions and methods with receivers and signatures (several return values, generics), const / var, imports (alias, blank, dot), calls (native_go, internal_helper, …), go / defer, exported (capitalised) = public; vendor / testdata skipped, _test.go ranked as tests |
| CSS / SCSS | .css .scss |
rule blocks and at-rules (@media, @layer, Tailwind v4 @theme / @utility / @source …), mixins, functions, variables, @use / @import |
| JSON / Markdown | .json .md |
key paths with their short values (package.json::scripts --body prints one key); heading sections by level, and links |
| HTML | .html .htm |
<title> and <h1>–<h6> heading sections by level; visible text and title / alt / placeholder / aria-label / value attributes for --strings (<script> / <style> skipped); links |
Which files are processed
Only files with the extensions above, in upper or lower case (B.PHP counts as PHP); everything else is ignored.
Also skipped, even with a supported extension: generated files (package-lock.json, *.min.js, *.min.css) and
files with binary content. Minified or bundled JavaScript / CSS is recognised by its content too (very long lines,
e.g. a Vite app-CBW7lKWe.js) and skipped. Each file is read once, even if a symlink points to it. Folders like
vendor/ and node_modules/ are skipped, and so is everything your .gitignore files exclude, with the same rules as
git: /public/build, public/build/, build/, **/assets, *.log, !keep.js, and the .gitignore of every
subfolder relative to that folder.
To exclude more in a project, put a .callgraphignore file in its root (or in any subfolder). Commit it, and the whole
team gets the same results. A line that is just an extension (md, .md or *.md) skips that extension (the
nearest .callgraphignore applies, as before); any other line is a .gitignore-style path pattern, relative to the
folder of the file:
# callgraph: skip these extensions in this project
md
json
*.vue
# and these paths (same syntax as .gitignore)
public/build/
/storage/
legacy/**/*.php
A protect <pattern> line (e.g. protect migrations/) is the opposite of an exclusion: the matching files stay in
the map and fully queryable, but are marked 🔒 in the output (outline, --body, --lines, locate): protected, read
them, don't edit them. Same pattern rules; a line that is just protect stays an extension rule.
To map files your .gitignore excludes, add --no-gitignore to any command (or set CALLGRAPH_GITIGNORE=0 for the
MCP server and the hook); .callgraphignore and the built-in skipped folders still apply. Note: a bare word such as
build in .callgraphignore is an extension rule; write build/ or /build for a folder.
When not to use it
- You need the exact text of a known line range: use
--linesor a targeted read. - Non-code files (plain text, data dumps): the outline adds little.
- Macro- or reflection-heavy code: dynamic calls that can't be resolved statically are marked
dynamic_callin the outline (PHP, JS / TS / Vue, Python), are not callers for--grep/--depth, and show up as name-only matches (?) with--guessonly where the name is known. - Files with a syntax error (mid-edit, merge conflict) are flagged with
⚠ syntax error at L<n>and a closing⚠line: the code before and after the broken part is still mapped (JS / TS / Vue, Rust: from the next top-level function, class or item on), the broken part itself is missing — read such a file directly. The exit code stays 0; for CI, add--strict(or setCALLGRAPH_STRICT=1):show,locateandprofilethen exit with code 3 when a file they read has a syntax error, with the same output.
--signatures (or CALLGRAPH_SIGNATURES=1) prints the signature (params, return type) on the outline method lines.
Quick start
# 1. install (macOS / Linux, see below for Windows)
p="$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m)" && t="$(mktemp -d)" \
&& curl -fsSL -o "$t/cg.zip" "https://update.callgraph.eu/v1/download/latest/callgraph-$p.zip?k=install" \
&& mkdir -p ~/.claude/skills && unzip -qo "$t/cg.zip" -d ~/.claude/skills \
&& bash ~/.claude/skills/callgraph/install.sh && rm -rf "$t"
# 2. register a project once
bash ~/.claude/skills/callgraph/projects.sh add shop /absolute/path/to/shop
# 3. ask questions
CG=~/.claude/skills/callgraph/callgraph.sh
bash $CG --project shop app/Models/Order.php # outline
bash $CG --project shop app/Models/Order.php::save --body # one method's source
bash $CG --project shop app --grep 'Order::cancel' --depth 3 # impact analysis
Restart Claude Code afterwards so it picks up the skill (SKILL.md).
Installation
Prebuilt packages (skill files + the binary for your platform + install guide) are attached to every GitHub Release:
| Platform | Package |
|---|---|
| macOS, Apple Silicon (M1–M4) | callgraph-darwin-arm64.zip |
| macOS, Intel | callgraph-darwin-x86_64.zip |
| Linux x86_64 (static musl) | callgraph-linux-x86_64.zip |
| Linux ARM64 (static musl) | callgraph-linux-aarch64.zip |
| Windows x86_64 (Git Bash) | callgraph-windows-x86_64.zip |
All five binaries in one archive: callgraph-<version>.tar.gz on the same release page.
macOS / Linux: use the one-liner from Quick start. It installs into ~/.claude/skills/callgraph/
and runs install.sh. Updating is the same command; your projects.json, errors.jsonl, feedback.jsonl and
language setting are kept.
Windows / manual: unzip the package, copy the callgraph/ folder under ~/.claude/skills/
(Windows: %USERPROFILE%\.claude\skills\) and run bash install.sh there (Git Bash). On macOS install.sh also
clears the download quarantine flag. Step-by-step guide (Hungarian): skill/TELEPITES.md.
From source: see Development.
The only runtime requirement is bash.
Updating
bash ~/.claude/skills/callgraph/callgraph.sh update --check # is there a newer release? (changes nothing)
bash ~/.claude/skills/callgraph/callgraph.sh update # download and install it
The update downloads your platform's zip from the latest GitHub Release and overwrites the skill files and bin/;
projects.json, errors.jsonl, feedback.jsonl and the language setting are kept. --force reinstalls the current
version; callgraph --version shows the installed one.
Every release ships a SHA256SUMS file; the update verifies the downloaded zip against it and installs nothing on a
mismatch. Releases without it (v0.1.0) are refused unless you pass --insecure-skip-checksum. With --from <zip> the
zip is checked against --sha256 <hex> or a SHA256SUMS next to it (otherwise a one-line warning).
callgraph.sh also checks for a new release in the background at most once a day (without slowing queries down) and,
if there is one, ends its output with a one-line ℹ callgraph X is available notice; CALLGRAPH_UPDATE_CHECK=0
turns this off (it is also off when CI is set).
Dev builds (develop branch): update --dev installs the newest build of the develop branch (the rolling dev
pre-release, version X.Y.Z-dev.<commit>, verified against its SHA256SUMS like a release); update --check --dev
only tells you whether there is a newer one. Dev builds are for trying out unreleased changes and may be unstable. A
plain update takes you back to the latest stable release; the background check and the MCP --auto-update stay on
stable releases (on a dev build they only speak up for a newer stable version).
Usage
All commands go through callgraph.sh (or the binary directly: callgraph show …). --project <alias> makes paths
relative to a registered project root; --project <dir> (an existing folder, absolute or relative) works without
registering; without it, the current directory is the root.
| Task | Command |
|---|---|
| Where do I start with this task? | callgraph.sh locate <term>... [--all] |
| Outline of a file / directory | callgraph.sh <file|dir> |
| One method only | callgraph.sh <file>::<method> (several selectors allowed) |
| Method source, line-numbered | callgraph.sh <file>::<method> --body |
| Any line range | callgraph.sh <file> --lines 30-60 |
| Where is it called? | callgraph.sh <dir> --grep <pattern> |
| Impact analysis | callgraph.sh <dir> --grep <pattern> --depth N [--guess] |
| String literal / constant usages | callgraph.sh <dir> --strings <pattern> · --const <pattern> |
| Filter by call category | callgraph.sh <dir> --category model_use,orm_relation |
Where to start: locate
More on the website: callgraph.eu/locate.
Give locate the names and domain terms from the task in one call (function, class and file names, column names,
routes); it answers from the project map, without reading the source, with a short ranked list of files to start
from, each with the reason:
bash ~/.claude/skills/callgraph/callgraph.sh locate RefundController processRefund refund payment_status checkout.vue --project myapp
root: /home/me/myapp
locate: 5 terms · 14 matches in 6 files · start here ↓
1. app/Http/Controllers/RefundController.php ★★★
class RefundController L6-16 ← "RefundController", "refund" (exact class)
store() L14 calls RefundService::processRefund ← "processRefund" (call)
2. app/Services/RefundService.php ★★
processRefund() L6-9 callers: 2 (RefundController::store, RefundJob::handle) ← "processRefund", "refund" (exact method)
…
A match counts more the stronger it is: exact definition, then file name, then a part of a name (refund ~
RefundJob, refunds_table, singular / plural), then a string literal, then a call. A file that matches several
different terms ranks above one that matches a single term many times, and files with an exact definition or file
name always come before files that only match strings (translations, build output). By default 5 files are shown
(--all: every match); terms without a match and terms that are too general are listed at the end. Paths are always
relative to the root: line. Plain text search (an exact message or config value) is still a job for grep; locate
answers "where do I start?".
Special terms:
- A phrase: a quoted argument with spaces (
"Organizer's other events") is one term. It is matched as a whole (case-insensitive) against string literals, such as UI labels and translations, and is never split into words. - A route name:
route::events.showlists the route definition first (->name('events.show')inroutes/*.php), then every place that uses the name:route('events.show', …),to_route(…),redirect()->route(…)in PHP, androute('events.show')in JS / TS / Vue (Ziggy). If nothing matches, it says what was searched. - A CSS custom property:
locate --orange-500searches for the variable (no--separator needed); the known options (--all,--project) stay options.
bash ~/.claude/skills/callgraph/callgraph.sh locate route::events.show "Organizer's other events" --project myapp
Output formats (--format)
| Format | Gives you |
|---|---|
outline (default) |
structure + calls by category |
api |
public contract + docblocks, no implementation |
flow |
if / match / switch branches with line ranges (condition → what it calls) |
summary |
one line per file |
hotspots |
top 20 methods by in/out degree |
coverage |
undocumented public methods |
stats |
category statistics |
mermaid / dot |
diagrams of inheritance and call edges |
json / jsonl |
the raw graph |
routes middleware validation jobs events providers magic di views |
framework views (run on a directory) |
Large results are capped (above 400 lines a directory outline turns into a summary, a single file into a method
index); --full lifts the cap. Full reference: callgraph.sh --help and skill/SKILL.md.
Project profile
More on the website: callgraph.eu/profile.
In an unfamiliar project, start with bash ~/.claude/skills/callgraph/callgraph.sh profile [--project alias]. From
folder and file names (and the framework found in composer.json / package.json / Cargo.toml) it tells you the
architecture (Laravel / Yii layered MVC, DDD / hexagonal, Vue / React frontend, SwiftUI MVVM, Rust web), the layers
with their folders and file counts, the design patterns (Repository, Factory, Strategy, Observer…), the folders
without a clear role, and how the layers call each other. The code graph confirms it: extends Controller,
implements *RepositoryInterface, defineStore, and the direction of the calls between layers. About 15 lines;
--full gives the per-folder details. Every file gets a role with a confidence (high / medium / low), or stays
"unknown" — it never guesses. MCP: the project_profile tool, and a compact profile is sent on connect.
The layers are listed by file count, so the main layer is always on top. A role found in both the backend and the
frontend is shown apart, e.g. controller (php) and controller (js) for PHP controllers next to AngularJS ones, and
the call direction keeps the two apart. Third-party code copied into the project (a subfolder with its own
composer.json, package.json or LICENSE, folders like vendors/, third_party/, extensions/, libs/, or a
copied framework core: CodeIgniter system/, Yii framework/, Kohana system/) and build output (dist/, build/,
*.min/, minified files) do not count: one line says how many files were skipped and where (profile --with-vendor
counts them anyway); your queries still see these files. event, listener, job, mail and notification
layers need proof in the code (an Event / Listener base class, Laravel's Dispatchable or ShouldQueue, a
handle(…) method in a Listeners namespace, extends Mailable / extends Notification) — a folder that is just
named Event is not an event layer. An enum never gets a role from its name (PaymentProvider is not a provider);
an Enums folder is shown as enum. The flow: line only links layers that really call each other; a side branch
follows after ;, e.g. flow: controller → service → model; command → service.
A large subtree the profile should not look at at all (an old copy of the whole app, a bundled legacy tool such as
sn_monitoring/) can be left out with a path line in .callgraphignore (sn_monitoring/); note that it then
disappears from every query too.
Use the layers in queries (all opt-in, the default output does not change):
bash ~/.claude/skills/callgraph/callgraph.sh app --layer service # only the service files (name,name...)
bash ~/.claude/skills/callgraph/callgraph.sh . --layer controller:js # one ecosystem only: php, js, swift, rust
bash ~/.claude/skills/callgraph/callgraph.sh app --format summary --layers # summary grouped by layer
bash ~/.claude/skills/callgraph/callgraph.sh app --grep 'Repo::find' --depth 2 --by-layer # callers grouped by layer
--by-layer puts the layer closest to the called method first (model → repository → service → controller) and
starts each group with a header such as [service] 3 calls, in the short and the long --grep view alike (with
--depth: in every level). The layer switches classify the files exactly like profile (with the same code proof,
read from the project map); without the map (CALLGRAPH_NO_GRAPH=1) a folder that needs proof, such as Event,
gives the next role (app/Services/Event/X.php → service).
Folder names that say nothing (or are not English)? A commit-able .callgraph-layers file in the project root maps
them: service = app/Szolgaltatasok, app/Logic, ignore-role = app/Legacy.
Language
Terminal output and help are in English by default; Hungarian is available:
bash ~/.claude/skills/callgraph/callgraph.sh set-lang hu # save (back: set-lang en)
bash ~/.claude/skills/callgraph/callgraph.sh set-lang # show current language and its source
CALLGRAPH_LANG=hu bash ~/.claude/skills/callgraph/callgraph.sh app/Models/Order.php # one run only
callgraph MCP soruları
Callgraph, tüm dosyaları okumaktan nasıl ayrılır?
Tüm dosyaları okuyup grep kullanmak yerine, metod gövdeleri, satır aralıkları ve kategorize edilmiş çağrılar gibi yapılandırılmış bilgiler sağlamak için Abstract Syntax Tree (AST) kullanır.
Belirli dosya veya klasörlerin işlenmesini engelleyebilir miyim?
Evet, .gitignore tarzı desenler kullanarak belirli uzantıları veya yolları hariç tutmak için proje kök dizininizde bir .callgraphignore dosyası kullanabilirsiniz.
Etki analizi (impact analysis) desteği var mı?
Evet, bir etki analizi gerçekleştirmek için önbelleğe alınmış, artımlı bir proje indeksi kullanarak tüm proje genelinde çağırıcıları (callers) takip edebilir.