Knossos-MCP
The labyrinth mapped once, so nobody has to wander it again.
Knossos (Κνωσός) is the Bronze Age palace at the heart of Minoan Crete, a complex so sprawling that Greek myth remembered it as the Labyrinth, the maze Daedalus built for the Minotaur, which no one could navigate without a thread to follow back out. Ariadne handed Theseus that thread.
What it does
Ask an agent what depends on a class and it reads the source tree again, every session, and tells you what it inferred. Knossos-MCP scans the repository once instead and answers from a graph where every fact carries a file and a source location. What static analysis cannot prove is labelled with its confidence rather than quietly guessed at.
Four languages land in the same graph. A Vue component that calls a PHP endpoint, a Python worker that consumes it, a Rust binary beside them: they reconcile into one set of nodes and relationships, so a question about impact crosses a language boundary the way the code does.
Scanning never installs dependencies, imports a module, or boots an application framework: workers run supervised, resource-capped, and their output only counts once it passes a schema and limit check. Thirty-three MCP tools cover orientation, projects and history, finding and reading components, structure and impact analysis, and maintenance; only server_info has no CLI equivalent. The four write tools preview by default and only apply once you pass execute explicitly.
Quick start
Knossos-MCP is not yet published to Packagist or any container registry, so build the image yourself from source. The recommended distribution is Docker: it pins PHP, Node, Python, Composer, SQLite, the PHP parser, and the TypeScript compiler, so the scanned project needs none of them. The Rust worker is compiled in a builder stage and copied in as a binary, so the runtime image carries no Rust toolchain either.
docker build -t knossos-mcp:dev .
docker run --rm knossos-mcp:dev doctor --jsonExamples
Two calls, both run for real against Knossos-MCP's own source, abridged with '…'.
Scanning the repository:
$ knossos scan . --json
{"summary":"Scanned 411 files into 5851 nodes and 33284 relationships.",
"data":{"files":411,"nodes":5851,"edges":33284,"diagnostics":0,"mode":"full",
"scanner_metadata":{"knossos.php":{"files_scanned":377},
"knossos.typescript":{"files_scanned":17,"programs":1},
"knossos.python":{"files_scanned":7,"parser":"python.ast"},
"knossos.rust":{"files_scanned":10,"parser":"rust.syn"}},
"metrics":{"elapsed_ms":6494.8, …}}}All four workers contribute to that one scan, and it reports zero diagnostics.
Orienting yourself in the resulting graph:
$ knossos architecture-summary project_1b4f41… --json
{"summary":"Knossos-MCP contains 5851 nodes and 33284 relationships.",
"data":{"node_kinds":[{"kind":"method","count":3979},{"kind":"class","count":437},
{"kind":"external_method","count":407},{"kind":"external_function","count":310},
{"kind":"function","count":297}, …],
"languages":[{"kind":"php","count":377},{"kind":"javascript","count":17},
{"kind":"rust","count":10},{"kind":"python","count":7}]}}Capabilities
| Category | Tools (selection) | What it answers |
|---|---|---|
| Orientation | server_info, diagnose_runtime | Which roots are readable, whether the runtimes are healthy |
| Projects and history | scan_project, list_snapshots, snapshot_diff, quality_gate | Build or refresh the graph, what changed between two scans, whether a change breaches architecture budgets |
| Finding and reading components | find_component, inspect_component, list_usages, architecture_summary | Ranked candidates from a partial name, a component's roles and relations, every usage with evidence |
| Structure and impact analysis | impact_analysis, explain_flow, dependency_cycles, change_impact, test_impact, review_diff | What depends on a symbol, how A reaches B, circular dependencies, the blast radius of a change, which tests it touches |
| Maintenance | annotate_component, remove_project, cleanup_stale_scans, maintain_database | Recording a durable annotation, cleaning up projects, checking database integrity |
| Language | Extraction | Framework enrichment |
|---|---|---|
| PHP 8.3+ | Declarations, inheritance, calls, construction, types, injection | Laravel, Symfony |
| TypeScript/JavaScript | Compiler symbol resolution, imports, calls, types, project references | Next.js, React, Vue, stores, endpoints |
| Python 3.11+ | Standard-library AST in an isolated interpreter; manifests, packages, calls, routes | FastAPI, Django, Flask, Celery |
| Rust 1.82+ | syn parsing; Cargo manifests, cross-file impl blocks, routes. Never invokes cargo or rustc | axum, actix, Rocket |
Rust is the one language that is optional on a native install: without cargo there is no Rust worker, and the container always has one.
Mixed repositories reconcile into one graph. impact_analysis and related tools label every conclusion with a confidence: certain, probable, or possible. A relationship the scanner cannot vouch for is dropped rather than guessed, which is a deliberate false negative.
Configuration
Knossos-MCP reads knossos.json (or knossos.jsonc) from the scanned project's root. This is Knossos-MCP's own configuration:
{
"$schema": "./schemas/project-config-v1.schema.json",
"version": 1,
"ignores": ["tests/Fixtures"],
"boundaries": [
{ "name": "core", "path_prefix": "src" },
{ "name": "php-worker", "path_prefix": "workers/php" },
{ "name": "typescript-worker", "path_prefix": "workers/typescript" },
{ "name": "python-worker", "path_prefix": "workers/python" },
{ "name": "tooling", "path_prefix": "tools" },
{ "name": "tests", "path_prefix": "tests" }
],
"policies": [
{
"id": "workers-are-out-of-process",
"from_boundary": "php-worker",
"deny_targets": ["core"]
}
],
"quality_budgets": {
"new_cycles": 0,
"boundary_violations": 0,
"error_diagnostics": 0,
"warning_diagnostics": 0,
"hub_degree_growth": 25,
"unreferenced_candidates": 110
}
}boundaries divides the codebase into named regions; policies forbids specific relationships between them, and check_architecture checks every change against them. quality_budgets sets hard thresholds on regressions such as new circular dependencies or boundary violations, enforced by quality_gate.