ontology-rag-mcp
An MCP server that ingests Spring Boot REST microservices from GitHub, builds a request-flow ontology, and enables natural-language queries about code with flow-aware answers and citations.
README
π§ ontology-rag-mcp
A generic code ontology platform that ingests Spring Boot REST microservice codebases from GitHub, indexes them into Apache Solr, builds a REST request-flow ontology + relationship graph, and serves it through a Model Context Protocol (MCP) server β so any MCP client (Cursor, Claude, etc.) can ask natural-language questions about the code and get accurate, flow-aware answers with citations.
π Table of Contents
- Overview
- Key Features
- Hard Constraints
- Architecture
- Prerequisites
- Quickstart
- Configuring Your AI IDE
- How It Works
- CLI Reference
- Environment Variables
- Complete MCP Tool Reference
- Pluggable Providers
- Sample Queries
- Project Structure
- Tech Choices
- Development & Testing
- Troubleshooting
- Author & Contact
- License
π Overview
ontology-rag-mcp turns a GitHub repository into a queryable knowledge layer β not just semantic search, but an understanding of:
- REST endpoints (
@GetMapping,@PostMapping, etc.) - Request flows behind each endpoint (Controller β Service β Repository)
- Service relationships and cross-service calls (
@FeignClient,RestTemplate,WebClient) - Configuration files, README/docs, and OpenAPI specs linked to the code they describe
How is this different from plain RAG?
| Plain RAG | ontology-rag-mcp |
|---|---|
| Chunks code by text similarity | Builds a request-flow ontology per endpoint |
| Returns similar-looking snippets | Returns ordered call chains with Mermaid diagrams |
| No graph awareness | Persists callsOut / calledBy edges in Solr fields |
| Needs an LLM to answer | Works fully offline with retrieval-only mode |
| Tied to one vector DB | Uses only Solr 9 (BM25 + dense vector kNN) |
The whole point: any MCP client can ask "walk me through what happens when a user places an order" and get the real ControllerβServiceβRepository chain β even when the query names no class or method.
β¨ Key Features
| Feature | Description |
|---|---|
| REST Flow Ontology | Per-endpoint call graph: Controller β Service β Repository β external calls |
| Hybrid Retrieval | Solr BM25 + dense vector kNN fused with Reciprocal Rank Fusion (RRF) |
| Flow-Aware Search | Intent routing + flow-doc seeding for vague "how does X work" questions |
| 10 MCP Tools | Typed DTOs β rag_search, flow_of, find_rest_endpoints, and more |
| Offline Embeddings | BAAI/bge-small-en-v1.5 (384-dim) via sentence-transformers β no paid API |
| Optional LLM | OpenAI-compatible endpoint for narrative summaries (Ollama, Azure, vLLM, etc.) |
| Incremental Indexing | Commit SHA tracking β re-runs only re-index changed files |
| Pluggable Providers | Local defaults + optional GitHub/Jenkins/SSH MCP adapters |
| Docker Compose | docker compose up starts Solr 9 + MCP server in one command |
| Spring Boot First | Parses @RestController, @Service, @Repository, @FeignClient |
π Hard Constraints
These are architectural invariants β the platform is designed around them:
| Constraint | Implementation |
|---|---|
| Retrieval stack | Apache Solr 9.x only (BM25 + dense vector kNN). No Pinecone/Weaviate/Chroma/Neo4j. Graph is in-memory, persisted as Solr fields. |
| Source of code | Git/GitHub only (public repos or private via GITHUB_TOKEN). No Perforce/Bitbucket/NAS. |
| Target codebases | REST Spring Boot microservices (Java, Maven/Gradle). Parser is pluggable for future languages. |
| Embeddings | Local/offline by default (sentence-transformers). No paid embedding API required. |
| LLM | Optional. System fully functions with LLM_ENABLED=false. |
| Configuration | Everything via environment variables. Secrets never committed. |
| Core reproducibility | Any developer can run with just git + docker compose β MCP adapters are optional. |
π Architecture
Local Path (git + docker)
The default path β no external MCP servers required. Fully reproducible from a public GitHub clone.
flowchart TB
subgraph source [Source]
GitHub[GitHub Repo] --> GitClone[GitPython Shallow Clone]
ReposYml[repos.yml] --> GitClone
end
subgraph parse [Parse & Ontology]
GitClone --> JavaParser[javalang Java Parser]
JavaParser --> ClassDocs[class / method / endpoint docs]
JavaParser --> FlowBuilder[Flow Ontology Builder]
FlowBuilder --> FlowDocs[flow docs + Mermaid]
FlowBuilder --> GraphEdges[callsOut / calledBy edges]
end
subgraph solr [Solr 9]
ClassDocs --> RawCol[product-raw collection]
FlowDocs --> RawCol
GraphEdges --> RawCol
RawCol --> Embed[Local Embeddings bge-small-en-v1.5]
Embed --> RAGCol[product-rag collection]
end
subgraph serve [Serving]
RAGCol --> Retrieval[Hybrid Retrieval BM25 + kNN + RRF]
Retrieval --> Intent[Intent Classifier]
Intent --> MCP[FastMCP Server]
MCP --> Client[Cursor / Claude / any MCP client]
end
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AI IDE (MCP Client) β
β Cursor / Claude Desktop / VS Code β
ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ
β HTTP (streamable-http) or stdio
ββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ
β MCP Server (ontology-rag serve) β
β 10 tools Β· FastMCP + Python β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββββββ β
β β Retriever β β Intent β β LLM Client (optional) β β
β β BM25+kNN β β Classifier β β OpenAI-compatible β β
β ββββββββ¬ββββββββ ββββββββββββββββ ββββββββββββββββββββββββββββ β
βββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Apache Solr 9.x β
β βββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
β β {product}-raw βββββΆβ {product}-rag β β
β β (source of truth) β β (+ 384-dim embedding vectors) β β
β βββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Headless Path (GitHub β Jenkins β SSH)
Optional adapters for zero-manual-step deployment. The core platform does not depend on these β they degrade to local defaults when absent.
sequenceDiagram
participant Agent as Cursor Agent
participant Jenkins as Jenkins MCP
participant Platform as ontology-rag-mcp
participant GitHub as GitHub MCP
participant SSH as Linux SSH MCP
participant Target as Target Linux Host
Agent->>Jenkins: trigger ontology-rag-onboard
Note over Jenkins: Params: REPOS, BRANCH, PRODUCT, TARGET_HOST
Jenkins->>Platform: checkout-platform
Platform->>GitHub: fetch source + record commit SHA
GitHub-->>Platform: file tree + metadata
Platform->>Platform: parse + index + build flow ontology
Platform->>Platform: embed into Solr
Jenkins->>SSH: deploy-mcp to TARGET_HOST
SSH->>Target: sync code, create venv, start MCP on free port
SSH->>Target: health-check + tail logs
Jenkins-->>Agent: {"petclinic-ontology": {"url": "http://host:port/mcp"}}
| Stage | What Happens |
|---|---|
checkout-platform |
Clone ontology-rag-mcp, install deps |
fetch-source |
GitHub MCP (or GitPython) fetches repos, records SHA |
parse+index |
Java parser β Solr raw collection |
build-flow-ontology |
Endpoint extraction, call graph, flow docs |
embed |
Local embeddings β Solr serving collection |
deploy-mcp |
SSH MCP starts MCP server on target host |
verify |
Health-check + print mcp.json snippet |
π¦ Prerequisites
For Docker Compose (recommended)
| Requirement | Version | Verify |
|---|---|---|
| Docker | 20.10+ | docker --version |
| Docker Compose | v2+ | docker compose version |
| Git | any | git --version |
For local development
| Requirement | Version | Verify |
|---|---|---|
| Python | 3.11+ | python --version |
| Git | any | git --version |
| Apache Solr 9 | 9.x | via Docker, or curl http://localhost:8983/solr/admin/info/system |
First ingest downloads ~130 MB for the embedding model (
BAAI/bge-small-en-v1.5). Subsequent runs use the cached model.
π Quickstart
Option 1: Docker Compose (Recommended)
# 1. Clone and configure
cd C:\AI_Workspaces\Anti_Workspace\ontology-rag-mcp
copy .env.example .env
# 2. Start Solr + MCP server
docker compose up -d
# 3. Wait for Solr to be healthy (~30s), then ingest the sample repo
docker compose exec app ontology-rag ingest
# 4. One-shot RAG query
docker compose exec app ontology-rag ask "What REST endpoints does this expose?"
# 5. MCP server is already running β check startup logs for mcp.json snippet
docker compose logs app
The default sample repo is spring-projects/spring-petclinic (configured in repos.yml).
Expected ingest output:
=== Ingesting petclinic ===
Cloning https://github.com/spring-projects/spring-petclinic (branch=main)
Indexing 150+ documents into petclinic-raw
Embedding 150+ documents
Ingest complete: {'repos': 1, 'files': 80, 'docs': 150, 'embedded': 150}
Option 2: Local Development
cd C:\AI_Workspaces\Anti_Workspace\ontology-rag-mcp
# Create virtual environment
python -m venv .venv
.venv\Scripts\Activate.ps1
# Install
pip install -e ".[dev]"
# Copy config
copy .env.example .env
# Start Solr separately (or use docker compose up solr -d)
docker compose up solr -d
# Ingest
ontology-rag ingest
# Start MCP server
ontology-rag serve
On startup, the server prints a ready-to-paste mcp.json snippet:
{
"ontology-rag": {
"url": "http://localhost:8765/mcp"
}
}
π Configuring Your AI IDE
ontology-rag-mcp supports two MCP transports:
| Transport | Use Case | Config Style |
|---|---|---|
streamable-http (default) |
Docker / remote deploy | URL-based |
stdio |
Local dev without HTTP | Command-based |
Set MCP_TRANSPORT=streamable-http or MCP_TRANSPORT=stdio in .env.
1. π± Cursor
Streamable HTTP (Docker / deployed server)
Create .cursor/mcp.json in your project (or ~/.cursor/mcp.json globally):
{
"mcpServers": {
"ontology-rag": {
"url": "http://localhost:8765/mcp"
}
}
}
The server prints this snippet on startup when you run
ontology-rag serve.
stdio (local development)
{
"mcpServers": {
"ontology-rag": {
"command": "ontology-rag",
"args": ["serve"],
"env": {
"MCP_TRANSPORT": "stdio",
"SOLR_BASE_URL": "http://localhost:8983/solr",
"RAG_PRODUCT": "petclinic"
}
}
}
}
Verifying in Cursor
- Open Settings β MCP (or
Ctrl+Shift+Pβ "MCP") - Look for
ontology-ragwith a green status indicator - Try: "What REST endpoints does this expose?"
- The agent should call
find_rest_endpointsand return cited routes
2. π€ Claude Desktop
Configuration File Location
| OS | Path |
|---|---|
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
Streamable HTTP
{
"mcpServers": {
"ontology-rag": {
"url": "http://localhost:8765/mcp"
}
}
}
stdio
{
"mcpServers": {
"ontology-rag": {
"command": "ontology-rag",
"args": ["serve"],
"env": {
"MCP_TRANSPORT": "stdio",
"SOLR_BASE_URL": "http://localhost:8983/solr",
"RAG_PRODUCT": "petclinic"
}
}
}
}
Restart Claude Desktop after saving. Look for the tools icon in the chat input.
3. π» VS Code with Continue / Cline
Add to .continue/config.json or Cline MCP settings:
{
"mcpServers": {
"ontology-rag": {
"url": "http://localhost:8765/mcp"
}
}
}
β‘ How It Works
Ingestion Pipeline
repos.yml / CLI --repos
β
βΌ
βββββββββββββββββββββ
β Source Provider β SOURCE_PROVIDER=local β GitPython shallow clone
β β SOURCE_PROVIDER=github β GitHub MCP (falls back to git)
ββββββββββ¬βββββββββββ
β Records commit SHA for incremental re-runs
βΌ
βββββββββββββββββββββ
β File Curation β Skips: target/, build/, .git/, node_modules/,
β β *.class, *.jar, /test/, generated-sources/
ββββββββββ¬βββββββββββ
βΌ
βββββββββββββββββββββ
β Java Parser β javalang β class-level docs (+ optional method chunks)
β (javalang) β Also: application.yml, README, OpenAPI specs
ββββββββββ¬βββββββββββ
βΌ
βββββββββββββββββββββ
β Flow Ontology β Endpoint extraction, call graph, flow docs + Mermaid
β Builder β Cross-service: @FeignClient, RestTemplate, WebClient
ββββββββββ¬βββββββββββ
βΌ
βββββββββββββββββββββ
β Solr Raw Index β {product}-raw β source of truth, no vectors
ββββββββββ¬βββββββββββ
βΌ
βββββββββββββββββββββ
β Embed Pipeline β BAAI/bge-small-en-v1.5 β {product}-rag collection
β β Optional LLM summaries if LLM_ENABLED=true
βββββββββββββββββββββ
Chunk types indexed:
chunkType |
Description |
|---|---|
class |
One doc per Java class (package, annotations, methods, dependencies) |
method |
Per-method chunk (when RAG_METHOD_LEVEL=true) |
endpoint |
REST route: HTTP method, path, controller#method, request/response types |
flow |
Ordered request flow for an endpoint + Mermaid sequence diagram |
config |
application.yml / application.properties |
document |
README, markdown, OpenAPI/Swagger specs |
REST Flow Ontology
For every @RestController method with an HTTP mapping, the platform:
- Extracts the endpoint β class-level
@RequestMappingprefix + method@GetMappingetc. - Resolves dependencies β
@Autowiredfields, constructor injection,@Qualifier - Traces the call chain β Controller β Service(s) β Repository / external call (bounded depth, cycle-safe)
- Detects cross-service calls β
@FeignClientinterfaces,RestTemplate/WebClientusage - Persists as Solr fields β
callsOut,calledBy,flowName,httpMethod,route - Links docs to code β README/OpenAPI chunks inherit flows from mentioned class/endpoint names
Example flow doc for POST /api/orders:
1. [controller] com.example.OrderController#createOrder
2. [service] com.example.OrderService#createOrder
3. [repository] com.example.OrderRepository#save
Plus a Mermaid sequence diagram:
sequenceDiagram
participant Client
participant OrderController as OrderController
participant OrderService as OrderService
participant OrderRepository as OrderRepository
Client->>OrderController: POST /api/orders
OrderController->>OrderService: createOrder
OrderService->>OrderRepository: save
Hybrid Retrieval
User query
β
βΌ
βββββββββββββββββββββββ
β Intent Classifier β regex-based (no LLM): flow / endpoint / class / config / default
ββββββββββ¬βββββββββββββ
βΌ
βββββββββββββββββββββββ βββββββββββββββββββββββ
β Solr BM25 (edismax)β β Solr kNN (384-dim) β
β field boosts per β β cosine similarity β
β intent profile β β β
ββββββββββ¬βββββββββββββ ββββββββββ¬βββββββββββββ
β β
βββββββββββββ¬ββββββββββββββββ
βΌ
βββββββββββββββββββββββββ
β RRF Fusion β
βββββββββββββ¬ββββββββββββ
βΌ
βββββββββββββββββββββββββ
β Quality Levers β
β Β· down-rank gettersβ
β Β· MMR diversity β
β Β· adaptive rerank β
β Β· flow-doc seeding β
β Β· call-graph fusionβ
βββββββββββββ¬ββββββββββββ
βΌ
Shaped results with citations
(file path + line range + FQN)
Flow-doc seeding (important): when intent is flow and no flow/endpoint doc is in the top results, the retriever runs an extra chunkType-restricted kNN and injects the best-matching flow doc β so anchorless questions like "walk me through what happens when a user places an order" surface the real endpoint flow.
Incremental Indexing
Each repo's latest commit SHA is persisted in .ingest-cache/commit_shas.json.
| Scenario | Behavior |
|---|---|
| Re-run with no new commits | SHA unchanged β incremental no-op for changed files |
| Re-run after new commit | Only changed files (added/modified/deleted) are re-indexed |
| Full rebuild | Delete .ingest-cache/ or set REBUILD=full in Jenkins |
π₯ CLI Reference
ontology-rag ingest [--repos URL1,URL2] [--branch main]
ontology-rag serve
ontology-rag ask "your question here"
| Command | Description |
|---|---|
ingest |
Fetch β parse β index β build flow ontology β embed. Reads repos.yml by default. |
serve |
Start MCP server (streamable HTTP or stdio). Prints mcp.json snippet. |
ask |
One-shot hybrid RAG query with citations (demo / debugging). |
Examples:
# Ingest a specific repo
ontology-rag ingest --repos https://github.com/spring-projects/spring-petclinic --branch main
# Ingest multiple repos (microservices)
ontology-rag ingest --repos https://github.com/org/order-service,https://github.com/org/payment-service
# Ask a flow question
ontology-rag ask "Walk me through what happens when a user creates an order"
# Ask about cross-service calls
ontology-rag ask "Which service calls the payment service?"
π Environment Variables
All configuration is via environment variables. Copy .env.example to .env and adjust.
Provider Selection
| Variable | Required | Default | Description |
|---|---|---|---|
SOURCE_PROVIDER |
No | local |
local = GitPython clone. github = GitHub MCP adapter (falls back to local). |
ORCHESTRATOR |
No | local |
local = CLI. jenkins = Jenkins MCP orchestrator. |
DEPLOY_PROVIDER |
No | docker |
docker = docker compose. ssh = Linux SSH MCP deploy. |
Solr
| Variable | Required | Default | Description |
|---|---|---|---|
SOLR_BASE_URL |
No | http://localhost:8983/solr |
Solr base URL (no trailing collection name). |
SOLR_PORT |
No | 8983 |
Host port for Solr container. |
RAG_PRODUCT |
No | petclinic |
Collection prefix. Creates {product}-raw and {product}-rag. |
RAG_COLLECTION |
No | (auto) | Override serving collection name. Defaults to {RAG_PRODUCT}-rag. |
Embeddings
| Variable | Required | Default | Description |
|---|---|---|---|
RAG_EMBED_MODEL |
No | BAAI/bge-small-en-v1.5 |
Local sentence-transformers model. |
RAG_EMBED_DIM |
No | 384 |
Vector dimension (must match model). |
RAG_RERANK_ENABLED |
No | false |
Enable cross-encoder reranking (BAAI/bge-reranker-base). |
RAG_RERANK_MODEL |
No | BAAI/bge-reranker-base |
Reranker model name. |
Retrieval Feature Flags
| Variable | Required | Default | Description |
|---|---|---|---|
RAG_METHOD_LEVEL |
No | false |
Also index per-method chunks (in addition to class-level). |
RAG_FLOW_SEED |
No | true |
Inject flow/endpoint doc for vague flow questions. |
RAG_MMR_ENABLED |
No | true |
Maximal Marginal Relevance diversity (cap chunks per class). |
RAG_SKIP_PATTERNS |
No | target/,build/,... |
Comma-separated file/path patterns to skip during ingest. |
LLM (Optional)
| Variable | Required | Default | Description |
|---|---|---|---|
LLM_ENABLED |
No | false |
Enable LLM for answer synthesis and domain summaries. |
LLM_BASE_URL |
No | http://localhost:11434/v1 |
OpenAI-compatible API base URL. |
LLM_MODEL |
No | llama3 |
Model name for chat completions. |
LLM_API_KEY |
No | β | API key (OpenAI, Azure, etc.). Not needed for Ollama. |
The system fully functions with
LLM_ENABLED=false. Retrieval, MCP tools, and CLIaskall work without an LLM. Enabling an LLM adds narrative summaries on top.
MCP Server
| Variable | Required | Default | Description |
|---|---|---|---|
MCP_HOST |
No | 0.0.0.0 |
Bind address for HTTP transport. |
MCP_PORT |
No | 8765 |
Port for streamable HTTP transport. |
MCP_TRANSPORT |
No | streamable-http |
streamable-http or stdio. |
Ingestion
| Variable | Required | Default | Description |
|---|---|---|---|
INGEST_CACHE_DIR |
No | ./.ingest-cache |
Git clone cache + commit SHA store. |
REPOS_CONFIG |
No | repos.yml |
Path to repos configuration file. |
GITHUB_TOKEN |
No | β | Enables private repo access. Never commit this value. |
SSH Deploy (DEPLOY_PROVIDER=ssh)
| Variable | Required | Default | Description |
|---|---|---|---|
SSH_HOST |
Yes* | β | Target Linux host for remote MCP deploy. |
SSH_USERNAME |
Yes* | β | SSH username. |
SSH_PASSWORD |
No | β | SSH password (or use key). |
SSH_KEY_PATH |
No | β | Path to SSH private key. |
SSH_PORT |
No | 22 |
SSH port. |
Jenkins Orchestrator (ORCHESTRATOR=jenkins)
| Variable | Required | Default | Description |
|---|---|---|---|
JENKINS_URL |
Yes* | β | Jenkins server URL. |
JENKINS_USER |
Yes* | β | Jenkins username. |
JENKINS_TOKEN |
Yes* | β | Jenkins API token. |
JENKINS_JOB_NAME |
No | ontology-rag-onboard |
Pipeline job name. |
π Complete MCP Tool Reference
All tools return typed, clean DTOs β not raw Solr fragments. Every result includes citations (file path, line range, FQN) where available.
π§ rag_search
Hybrid semantic + keyword search with citations and optional LLM synthesis.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query |
str |
Yes | β | Natural-language search query. |
k |
int |
No | 10 |
Number of results to return. |
mode |
str |
No | "hybrid" |
"hybrid" (BM25 + kNN), "keyword" (BM25 only), or "semantic" (kNN only). |
Returns: query, intent, total, hits[] (with citations), context_block, answer (LLM synthesis if enabled, else context).
Examples:
"Explain the OrderService class"
"How is authentication configured?"
"walk me through what happens when a user places an order"
π§ find_rest_endpoints
List REST endpoints with method, route, controller, and flow name.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query |
str |
No | "" |
Free-text search within endpoints. |
http_method |
str |
No | "" |
Filter by HTTP method (e.g., "GET", "POST"). |
path_contains |
str |
No | "" |
Filter routes containing this substring. |
Returns: List of EndpointInfo β http_method, route, controller, method_name, flow_name, module.
Examples:
find_rest_endpoints()
find_rest_endpoints(http_method="POST")
find_rest_endpoints(path_contains="/orders")
π§ flow_of
Return the ordered request flow for an endpoint or class, with a Mermaid sequence diagram.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
endpoint_or_class |
str |
Yes | β | Route (e.g., "/api/orders"), class name, or FQN. |
Returns: FlowResult β name, endpoint, http_method, steps[] (ordered layers), mermaid (diagram string), cross_service[].
Examples:
flow_of("/api/orders")
flow_of("OrderController")
flow_of("POST /api/orders")
π§ callers_of
Inbound call edges β who calls this class or method.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
class_or_method |
str |
Yes | β | Class name, FQN, or ClassName#methodName. |
Returns: List of caller symbol strings.
Example:
callers_of("PaymentService")
callers_of("OrderService#createOrder")
π§ uses_of
Outbound call edges β what this class or method calls.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
class_or_method |
str |
Yes | β | Class name, FQN, or ClassName#methodName. |
Returns: List of callee symbol strings (includes Feign/RestTemplate targets).
Example:
uses_of("OrderController")
uses_of("PaymentService#processPayment")
π§ find_services
List @Service beans with summaries. Optional query filter.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query |
str |
No | "" |
Filter services by name or description. |
Returns: List of service class docs with annotations, dependencies, and summaries.
π§ get_class
Fetch a specific Java class by simple name or fully-qualified name.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name |
str |
Yes | β | Class name (e.g., "OrderService") or FQN. |
Returns: Class doc with methods, annotations, dependencies, callsOut/calledBy edges, and citation.
π§ get_file
Fetch all indexed chunks for a file path.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path |
str |
Yes | β | File path as indexed (e.g., "src/main/java/com/example/OrderController.java"). |
Returns: List of all chunks (class, method, etc.) for that file.
π§ list_services
Inventory of all @Service beans in the indexed codebase.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| (none) | β | β | β | Takes no parameters. |
Returns: List of all service class docs.
π§ stats
Index statistics β doc counts, chunk types, modules.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| (none) | β | β | β | Takes no parameters. |
Returns: product, raw_collection, serving_collection, total_docs, by_chunk_type, modules[].
π Pluggable Providers
The platform core is fully runnable with just git + docker compose. Three concerns are behind clean provider interfaces β each with a built-in default and an optional MCP adapter.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ontology-rag-mcp CORE β
β (always works: git + docker compose + CLI) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββ ββββββββββββββββ βββββββββββββββββββββ β
β β SOURCE β β ORCHESTRATOR β β DEPLOY β β
β β PROVIDER β β β β PROVIDER β β
β βββββββββββββββ€ ββββββββββββββββ€ βββββββββββββββββββββ€ β
β β local (git) β β local (CLI) β β docker (compose) β β
β β github (MCP)β β jenkins (MCP)β β ssh (MCP) β β
β βββββββββββββββ ββββββββββββββββ βββββββββββββββββββββ β
β β optional β optional β optional β
β GitHub MCP Jenkins MCP Linux SSH MCP β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Concern | Env Var | Default | MCP Adapter | Degrades To |
|---|---|---|---|---|
| Source | SOURCE_PROVIDER |
local |
github β GitHub MCP |
GitPython clone |
| Orchestration | ORCHESTRATOR |
local |
jenkins β Jenkins MCP |
CLI commands |
| Deploy | DEPLOY_PROVIDER |
docker |
ssh β Linux SSH MCP |
docker compose |
MCP adapters are first-class optional integrations, not core dependencies. They are used (a) as agents during development/testing and (b) for headless "GitHub URL + target host β live MCP URL" workflows.
Configuring repos (repos.yml)
repos:
- url: https://github.com/spring-projects/spring-petclinic
branch: main
name: petclinic
- url: https://github.com/your-org/order-service
branch: main
name: orders
subpath: order-service # optional: index only this subdirectory
- url: https://github.com/your-org/payment-service
branch: develop
name: payments
π¬ Sample Queries
These queries are from the acceptance criteria. Use them in Cursor chat or via ontology-rag ask.
Endpoint discovery
What REST endpoints does this expose?
Expected: find_rest_endpoints returns a list of routes with HTTP methods, controller classes, and flow names.
Request flow (anchorless)
Walk me through what happens when a user creates an order.
Expected: flow_of or rag_search (with flow-doc seeding) returns the ControllerβServiceβRepository chain and a Mermaid sequence diagram β even though the query names no specific class.
Cross-service relationships
Which service calls the payment service?
Expected: uses_of / callers_of returns Feign/RestTemplate edges between microservices.
Class explanation
Explain the OrderService class.
Expected: get_class returns the class doc, methods, injected dependencies, and collaborator edges.
Configuration
What database is configured in application.yml?
Expected: rag_search with config intent returns the relevant configuration chunk with file citation.
π Project Structure
ontology-rag-mcp/
βββ ontology_core/ # Config, Solr client, embeddings, retrieval, intent, MCP server, CLI
β βββ config.py # Pydantic settings from env vars
β βββ models.py # Shared DTOs (SearchHit, FlowResult, etc.)
β βββ embeddings.py # Local sentence-transformers embedder
β βββ intent.py # Offline regex intent classifier
β βββ retrieval.py # Hybrid BM25 + kNN + RRF + flow-aware fusion
β βββ llm.py # Optional OpenAI-compatible LLM client
β βββ mcp_server.py # FastMCP server + 10 tools
β βββ cli.py # ontology-rag CLI (ingest / serve / ask)
β βββ solr/
β βββ client.py # Solr 9 REST client
β βββ managed-schema.xml # Collection schema
βββ ontology_ingest/ # Source providers, parser, flow ontology, pipeline
β βββ source/
β β βββ base.py # SourceProvider interface + factory
β β βββ local_git.py # GitPython shallow clone (default)
β β βββ github_mcp.py # Optional GitHub MCP adapter
β βββ parser/
β β βββ java_parser.py # javalang Java/Spring parser
β β βββ spring_annotations.py
β βββ ontology/
β β βββ flow_builder.py # REST flow tracing + call graph
β βββ chunker.py # Parsed artifacts β Solr docs
β βββ pipeline.py # End-to-end ingest orchestrator
β βββ embed_pipeline.py # Raw β serving collection with vectors
βββ ontology_deploy/ # Deploy providers + Jenkins orchestrator
β βββ base.py # DeployProvider interface
β βββ docker_provider.py # docker compose (default)
β βββ ssh_provider.py # Optional Linux SSH MCP adapter
β βββ jenkins_orchestrator.py # Optional Jenkins MCP adapter
βββ docker-compose.yml # Solr 9.6 + app
βββ Dockerfile
βββ repos.yml # Default repos to ingest
βββ Jenkinsfile # CI/CD pipeline for headless deploy
βββ .env.example # All env vars documented
βββ pyproject.toml
βββ tests/
β βββ test_java_parser.py
β βββ test_spring_annotations.py
β βββ test_flow_builder.py
β βββ test_intent.py
βββ README.md
π Tech Choices
| Choice | Rationale |
|---|---|
| javalang | Pure Python, zero native bindings. Sufficient for Spring annotation/method/dependency extraction. tree-sitter is more robust for partial parses but adds build complexity β reserved for future pluggable parser interface. |
| Apache Solr 9 | BM25 + dense vector kNN in one stack. Graph stored as document fields (callsOut, calledBy, flowName) β no separate graph DB. |
| sentence-transformers | Offline embeddings with BAAI/bge-small-en-v1.5 (384-dim). No paid API. Graceful zero-vector fallback if model unavailable. |
| FastMCP | Official MCP Python SDK. Supports streamable HTTP and stdio transports. |
| GitPython | Shallow clone for reproducible, MCP-agnostic source fetching. |
| Pydantic | Typed settings, DTOs, and tool return values. |
π§ͺ Development & Testing
# Install with dev dependencies
pip install -e ".[dev]"
# Run unit tests
pytest tests/ -v
# Lint
ruff check .
# Ingest a repo
ontology-rag ingest --repos https://github.com/spring-projects/spring-petclinic
# Start MCP server
ontology-rag serve
# One-shot query
ontology-rag ask "What REST endpoints does this expose?"
Test coverage:
| Test File | Covers |
|---|---|
test_java_parser.py |
Controller/service parsing, HTTP mapping extraction, call detection |
test_spring_annotations.py |
@RequestMapping, @GetMapping, stereotype detection |
test_flow_builder.py |
ControllerβService flow tracing, call graph edges |
test_intent.py |
Query intent classification (flow/endpoint/class/config) |
π§ Troubleshooting
Solr not ready
Symptom: TimeoutError: Solr not ready during ingest.
Fix:
# Check Solr health
curl http://localhost:8983/solr/admin/info/system
# Restart Solr container
docker compose restart solr
# Wait for healthy status
docker compose ps
Embedding model download slow
Symptom: First ingest hangs on "Loading embedding model."
Fix: The first run downloads ~130 MB for BAAI/bge-small-en-v1.5. Subsequent runs use the cached model. Ensure internet access on first run, or pre-download:
python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('BAAI/bge-small-en-v1.5')"
MCP server not connecting in Cursor
Symptom: ontology-rag shows red/disconnected in Cursor MCP settings.
Fixes:
- Verify the server is running:
curl http://localhost:8765/mcp - Check
MCP_PORTmatches yourmcp.jsonURL - For stdio mode, ensure
ontology-ragis in your PATH - Restart Cursor after config changes
Empty search results
Symptom: rag_search returns 0 hits.
Fixes:
- Run ingest first:
ontology-rag ingest - Check index stats:
ontology-rag askwon't work, but MCPstatstool shows doc counts - Verify
RAG_PRODUCTmatches the ingested product name - Check Solr directly:
curl "http://localhost:8983/solr/petclinic-rag/select?q=*:*&rows=0"
No flow results for vague questions
Symptom: "walk me through..." returns class docs instead of flow docs.
Fix: Ensure RAG_FLOW_SEED=true (default). The retriever injects a flow/endpoint doc when intent is flow but no flow doc is in the top results.
Private repo access denied
Symptom: Git clone fails with 401/403.
Fix: Set GITHUB_TOKEN in .env:
GITHUB_TOKEN=ghp_your_token_here
π₯ Author & Contact
This project was created by Pawan Gunjkar.
- Author: Pawan Gunjkar
- Email: pawangunjkar@gamil.com
- Bug Reports: If you find any bugs, issues, or want to request help, please report them at the email above.
π License
MIT License β see LICENSE for details.
<div align="center">
Built with FastMCP + Apache Solr 9 + sentence-transformers
Turn any Spring Boot repo into a queryable code ontology.
</div>
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
Neon Database
MCP server for interacting with Neon Management API and databases
E2B
Using MCP to run code via e2b.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.