gpkg-mcp
Standalone knowledge graph MCP server for Moleculer/Go microservice projects. Scans a project directory, extracts service metadata (actions, commands, queries, routes, events, dependencies), seeds Neo4j, and exposes everything via a Python MCP server that any LLM client (Claude Desktop, Cursor, the gp-langchain bot) can call.
---
What it does
- Scans TypeScript/JavaScript Moleculer services (layered, CQRS, gateway) and Go services
- Extracts per-action metadata: handler type, params validator,
ctx.calldependencies (regex + variable resolution) - Seeds Neo4j knowledge graph and writes per-service markdown docs
- Serves a FastMCP server over Streamable HTTP or stdio
- Caches scan fingerprints with a
schema_versionso improved extractors always trigger a re-scan
---
Quick start (with sample data)
# One-shot bootstrap: checks prereqs, seeds sample services, starts MCP
./start.sh
The script: checks uv + Neo4j, runs uv sync, seeds sample/ data into Neo4j, then starts the server on http://localhost:8000/mcp.
---
Manual setup
cp .env.sample .env
# edit .env — set GPKG_NEO4J_URI / GPKG_NEO4J_PASSWORD at minimum
uv sync
# Scan a project
uv run gpkg scan ../my-project
# Query the knowledge graph
uv run gpkg query "payment transfer"
# Start the MCP server
uv run gpkg serve
---
Commands
| Command | Description | |---------|-------------| | gpkg scan <dir> | Scan all services under <dir>, seed Neo4j, write markdown KB | | gpkg scan <dir> --use-llm | Enable LLM validation for low-confidence architecture detections | | gpkg scan <dir> --force | Bypass fingerprint cache, rescan everything | | gpkg scan <dir> --concurrency N | Set parallel scan concurrency (default: 5) | | gpkg query "<text>" | Full-text query against the seeded KG | | gpkg query "<text>" --service NAME | Filter results to one service | | gpkg serve | Start MCP server (streamable-http on port 8000) | | gpkg serve --transport stdio | Start for Claude Desktop / Cursor local use |
---
MCP tools
| Tool | Description | |------|-------------| | scan_project(project_dir, use_llm, force) | Scan all services; returns {scanned, seeded, skipped, failed, services} | | scan_service(project_dir, service_path, use_llm) | Scan a single service; returns EnhancedServiceScanResult | | query_knowledge_graph(query, service_name?) | Full-text search; returns {services, actions, relationships} | | get_service(service_name) | Full stored knowledge for one service | | list_services() | All known services with arch type + confidence |
Resource: kb://{service_name} — the generated markdown doc for a service.
---
Configuration
Copy .env.sample to .env:
| Variable | Default | Description | |----------|---------|-------------| | GPKG_NEO4J_URI | bolt://localhost:7687 | Neo4j bolt URI | | GPKG_NEO4J_USER | neo4j | Neo4j username | | GPKG_NEO4J_PASSWORD | _(empty)_ | Neo4j password | | GPKG_KB_DIR | ./knowledge_base | Markdown KB output directory | | GPKG_SCAN_CONCURRENCY | 5 | Parallel scan workers | | GPKG_LLM_ENABLED | false | Enable LLM validation pass | | GPKG_LLM_MODEL | claude-haiku-4-5-20251001 | Model for architecture validation | | GPKG_LLM_CONFIDENCE_THRESHOLD | 0.7 | Only run LLM when confidence is below this | | GPKG_API_KEY | _(empty)_ | Bearer token for MCP server (empty = unauthenticated) | | ANTHROPIC_API_KEY | _(empty)_ | Required when GPKG_LLM_ENABLED=true |
---
Docker
# Build
docker build -t gpkg-mcp .
# Run with a local .env and data volume
docker run --env-file .env -p 8000:8000 -v $(pwd)/knowledge_base:/data/knowledge_base gpkg-mcp
# Scan a project (mount it read-only)
docker run --env-file .env \
-v $(pwd)/knowledge_base:/data/knowledge_base \
-v /path/to/my-project:/project:ro \
gpkg-mcp uv run gpkg scan /project
---
Architecture detection
| Type | Detection signal | |------|-----------------| | layered-moleculer | actions: block with inline handlers in start.ts or *.service.ts | | cqrs-moleculer | CQRSContainer, CommandBus, QueryBus keywords | | gateway-moleculer | integrate-services/ directory with RestRoute() definitions | | golang-moleculer | go-moleculer in go.mod + Publisher pattern | | discrete-golang-moleculer | go-moleculer in go.mod, no Publisher | | external-api-service | No Moleculer; Express / Gin / Echo / Fiber |
Confidence levels: high → medium → low. LLM validation runs when confidence is below GPKG_LLM_CONFIDENCE_THRESHOLD.
---
Cache schema version
knowledge/cache.py has a CACHE_SCHEMA_VERSION constant (currently 4). Bump it whenever an extractor changes — the next scan will ignore all cached fingerprints and re-scan everything.
---
Running tests
uv run pytest
Tests cover: LayeredMoleculerExtractor action/handler/call extraction, cache schema version invalidation, and MCP tool shapes (mocked store, no Neo4j needed).











