Skip to main content
Glama
Pawangunjkar

ontology-rag-mcp

by Pawangunjkar

🧠 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.

Python 3.11+ Solr 9.x MCP Protocol License: MIT


πŸ“‹ Table of Contents


Related MCP server: Axon.MCP.Server

🌐 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

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

# 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

  1. Open Settings β†’ MCP (or Ctrl+Shift+P β†’ "MCP")

  2. Look for ontology-rag with a green status indicator

  3. Try: "What REST endpoints does this expose?"

  4. The agent should call find_rest_endpoints and 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:

  1. Extracts the endpoint β€” class-level @RequestMapping prefix + method @GetMapping etc.

  2. Resolves dependencies β€” @Autowired fields, constructor injection, @Qualifier

  3. Traces the call chain β€” Controller β†’ Service(s) β†’ Repository / external call (bounded depth, cycle-safe)

  4. Detects cross-service calls β€” @FeignClient interfaces, RestTemplate/WebClient usage

  5. Persists as Solr fields β€” callsOut, calledBy, flowName, httpMethod, route

  6. 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 CLI ask all 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:

  1. Verify the server is running: curl http://localhost:8765/mcp

  2. Check MCP_PORT matches your mcp.json URL

  3. For stdio mode, ensure ontology-rag is in your PATH

  4. Restart Cursor after config changes

Empty search results

Symptom: rag_search returns 0 hits.

Fixes:

  1. Run ingest first: ontology-rag ingest

  2. Check index stats: ontology-rag ask won't work, but MCP stats tool shows doc counts

  3. Verify RAG_PRODUCT matches the ingested product name

  4. 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.


Built with FastMCP + Apache Solr 9 + sentence-transformers

Turn any Spring Boot repo into a queryable code ontology.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

–Maintainers
–Response time
–Release cycle
–Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    An MCP server that transforms repositories into queryable knowledge by combining static code analysis with git history tracking. It allows users to investigate codebase structure, identify fragile files based on churn, and receive risk assessments through natural language queries.
    7
  • F
    license
    -
    quality
    F
    maintenance
    An MCP server that transforms codebases into intelligent, queryable knowledge bases, enabling AI assistants to perform semantic search, explore architecture, and analyze code relationships.
    165
  • F
    license
    -
    quality
    B
    maintenance
    MCP server that exposes code tracing capabilities including journey flows, HTTP seams, and findings from indexed projects, allowing AI assistants to query software architecture.

View all related MCP servers

Related MCP Connectors

  • An MCP server that gives your AI access to the source code and docs of all public github repos

  • A MCP server built for developers enabling Git based project management with project and personal…

  • A Model Context Protocol (MCP) application for automated GitHub PR analysis and issue management.…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Pawangunjkar/ontology-rag-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server