Skip to main content

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 and that 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 line. 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 the same endpoint, 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.

bash
docker build -t knossos-mcp:dev .
docker run --rm knossos-mcp:dev doctor --json

Examples

Two calls, both run for real against Knossos-MCP's own source, abridged with '…'.

Scanning the repository:

bash
$ 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:

bash
$ 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

CategoryTools (selection)What it answers
Orientationserver_info, diagnose_runtimeWhich roots are readable, whether the runtimes are healthy
Projects and historyscan_project, list_snapshots, snapshot_diff, quality_gateBuild or refresh the graph, what changed between two scans, whether a change breaches architecture budgets
Finding and reading componentsfind_component, inspect_component, list_usages, architecture_summaryRanked candidates from a partial name, a component's roles and relations, every usage with evidence
Structure and impact analysisimpact_analysis, explain_flow, dependency_cycles, change_impact, test_impact, review_diffWhat depends on a symbol, how A reaches B, circular dependencies, the blast radius of a change, which tests it touches
Maintenanceannotate_component, remove_project, cleanup_stale_scans, maintain_databaseRecording a durable annotation, cleaning up projects, checking database integrity
LanguageExtractionFramework enrichment
PHP 8.3+Declarations, inheritance, calls, construction, types, injectionLaravel, Symfony
TypeScript/JavaScriptCompiler symbol resolution, imports, calls, types, project referencesNext.js, React, Vue, stores, endpoints
Python 3.11+Standard-library AST in an isolated interpreter; manifests, packages, calls, routesFastAPI, Django, Flask, Celery
Rust 1.82+syn parsing; Cargo manifests, cross-file impl blocks, routes. Never invokes cargo or rustcaxum, 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.

impact_analysis and related tools label every conclusion with a confidence: certain, probable, or possible. A relationship the scanner cannot vouch for is dropped instead, 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:

json
{
  "$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 those regions, and check_architecture tests every change against those policies. quality_budgets sets hard thresholds on regressions such as new circular dependencies or boundary violations, and quality_gate enforces them.

Session orientation for Claude Code

The server answers structural questions whenever an agent thinks to ask one. A separate plugin is what makes it think to ask.

Installing it adds two things to a Claude Code session. A SessionStart hook renders a short brief: a one-line verdict on whether the graph still matches the tree, plus the project's boundary rules and recorded notes. Entry points and hubs come too, on a fresh verdict and nothing else.

The second half is a skill that tells the session which questions to bring back to the graph and which to leave alone. A config key, an error message, a TODO stay with grep, because structure is what the graph indexes. A file you are about to edit stays with Read, because Edit matches the exact bytes. And while the verdict reads stale, no structural question is worth asking at all.

Nothing invokes that skill by name. The brief's closing line is what arms it, which is why that line falls outside the brief's character budget: a brief that fits its budget by dropping the pointer leaves the skill unarmed for the rest of the session.

bash
knossos install-agent-plugin           # previews; add --execute to apply

The plugin ships no binary of its own. The hook runs the first knossos it finds in a deliberately short list, KNOSSOS_BIN, then PATH, then three conventional locations, because a long search is a slow session start. When it finds none it exits silently, like every failure path in that hook: one that breaks a session start costs more than the brief was ever worth. A symlink into ~/.local/bin, one of those three, is usually the one step missing.

There is no public marketplace route, on purpose. The descriptor is generated into a directory that stays out of git and is never committed, so claude plugin marketplace add AraneaDev/Knossos-MCP fails with Marketplace file not found. It has to fail there: the clone it would otherwise resolve to has no vendor/, so its own bin/knossos cannot run, and an install that fails silently every time would produce nothing and say nothing about why.