Skip to main content
Glama
ranjit534

ontology-mcp

by ranjit534

Login Query Agent — Ontology MCP & Knowledge Graph

Прототип, который использует граф знаний OWL/SHACL/SKOS + два MCP-сервера для маршрутизации запросов диагностики входа через SQL Server и MongoDB с условной эскалацией в New Relic.


Краткий обзор архитектуры

User prompt (VS Code Copilot)
        │
        ▼  LLM classifies category natively — no tool call
        │
  ontology-mcp  ──► Fuseki KG (SPARQL)
        │              get_diagnosis_plan(category)
        │              returns: capability_id, required_entities,
        │                       validation_sequence, newrelic_tool
        ▼
  data-mcp  ──► SQL Server  (UM_Users, UM_UserPartnermapping,
        │                    UM_UserMobileNumberVerified)
        ├──────► MongoDB     (users collection — 9 projected fields)
        ├──────► SHACL Validator  (shapes read from KG shacl graph, evaluated in sequence order)
        └──────► New Relic   (only when all_shapes_pass=true — 2-step NRQL)

Related MCP server: OntoRamp Graph Query

Обзор сервисов

Сервис

Тип

Кто запускает

Требуется для

Apache Jena Fuseki

Локальный процесс

Вы (вручную)

запросы к графу знаний ontology-mcp

ontology-mcp

Дочерний процесс stdio

VS Code запускает автоматически

Планирование диагностики

data-mcp

Дочерний процесс stdio

VS Code запускает автоматически

Запросы к БД + валидация

SQL Server

Удалённый/LocalDB

Уже запущен

Запросы к данным

MongoDB

Удалённый сервер

Уже запущен

Запросы к данным

New Relic

Облачный сервис

Всегда доступен

Эскалация (все проверки пройдены)

Только Fuseki требует ручного запуска. Оба MCP-сервера автоматически запускаются VS Code.


Предварительные требования

1. Java 11+

java -version

2. Apache Jena Fuseki JAR

JAR-файл исключён из git (54 МБ). Скачайте с jena.apache.org и поместите в:

infra/fuseki/fuseki-server.jar

3. Python 3.12+

python --version

4. Зависимости Python

cd c:\Ontology
python -m pip install -r requirements.txt

5. ODBC Driver for SQL Server

Скачайте ODBC Driver 17 or 18 for SQL Server от Microsoft, если он ещё не установлен.

6. VS Code с GitHub Copilot (режим агента)

VS Code 1.99+ с расширением GitHub Copilot.


Пошаговый локальный запуск

Шаг 1 — Запустите Fuseki

cd c:\Ontology
java -jar infra\fuseki\fuseki-server.jar --config infra\fuseki\config\login-kg.ttl

Держите этот терминал открытым. Проверьте на http://localhost:3030.

Шаг 2 — Загрузите граф знаний

Требуется при первом запуске или после любого изменения схемы/артефактов.

$env:PYTHONIOENCODING = "utf-8"
python scripts/generate/generate.py --schema login --version 1.0.0
python scripts/kg/load_kg.py        --schema login --version 1.0.0
python scripts/kg/promote.py        --schema login --version 1.0.0

Шаг 3 — Настройте секреты

Скопируйте .env.example в .env и заполните свои значения:

SQL_SERVER_HOST=your-server
SQL_SERVER_DATABASE=your-database
SQL_SERVER_TRUSTED_CONNECTION=yes
SQL_SERVER_ENCRYPT=yes
SQL_SERVER_TRUST_CERT=yes

MONGODB_URI=mongodb://your-host:27017
MONGODB_DATABASE=your-database

NEW_RELIC_API_KEY=NRAK-xxxxxxxxxxxxxxxxxxxx
NEW_RELIC_ACCOUNT_ID=your-account-id
NEW_RELIC_REGION=US

APP_ENV=prod

Шаг 4 — Зарегистрируйте оба MCP-сервера

Создайте .vscode/mcp.json в корне рабочей области:

{
  "servers": {
    "ontology-mcp": {
      "type": "stdio",
      "command": "python",
      "args": ["-m", "mcp_server.server"],
      "cwd": "c:\\Ontology",
      "env": {
        "PYTHONPATH": "c:\\Ontology\\src",
        "PYTHONIOENCODING": "utf-8"
      }
    },
    "data-mcp": {
      "type": "stdio",
      "command": "python",
      "args": ["-m", "mcp_server.diagnostic_server"],
      "cwd": "c:\\Ontology",
      "env": {
        "PYTHONPATH": "c:\\Ontology\\src",
        "PYTHONIOENCODING": "utf-8"
      }
    }
  }
}

Перезагрузите VS Code (Ctrl+Shift+PDeveloper: Reload Window).


Полный процесс диагностики

User: "testgdpr1235@gep.com can't reset password"
        │
        │  LLM classifies: category = "password_reset"  (no tool call)
        │
        ▼
① ontology-mcp / get_diagnosis_plan(category="password_reset")
     Reads x_capability_registry from login.yaml (no Fuseki needed for this step)
     Returns: capability_id, required_entities, validation_sequence, newrelic_tool
        │
        ▼  (agent extracts username from user message; asks if missing)
        │
② data-mcp / query_sql_user(username, capability_id)
     SELECT from UM_Users → islocked, isactive, isdeleted, usertype, emailaddress, ...
        │
③ data-mcp / query_sql_mobile_verification(username, capability_id)
     SELECT from UM_UserMobileNumberVerified → ismobilenumberverified
        │
④ data-mcp / query_sql_partner_mappings(username, capability_id)
     SELECT from UM_UserPartnermapping → bpc, partnercode, isactive, contactcode
        │
⑤ data-mcp / query_mongo_user(username, capability_id)
     db.users.find_one({...}, { 9 diagnostic fields }) → MongoDB document
        │
⑥ data-mcp / validate_login_shapes(username, capability_id, validation_sequence)
     Runs only the shapes in validation_sequence (plan-scoped)
     Returns: per-shape PASS/FAIL, all_shapes_pass, advisories (e.g. dr_012)
        │
   ┌────┴──────────────────────────┐
violations found              all_shapes_pass = true
   │                               │
report per shape              ⑦a data-mcp / query_newrelic_login_mfa(username, capability_id)
with mapped rule                   OR
dr_003..dr_008                ⑦b data-mcp / query_newrelic_reset_password(username, capability_id)
                                    → Transaction → Log per traceId (max 7 days)

Выбираются только сущности, перечисленные в required_entities. Шаги ②–⑤ пропускаются для категорий, которым они не нужны (например, account_locked пропускает запросы к партнёру и мобильному).


Справочник инструментов MCP

ontology-mcp — инструменты планирования на основе графа знаний (3 инструмента)

Инструмент

Шаг

Входные данные

Возвращает

get_diagnosis_plan

0 — обязательный первый вызов

category, schema

capability_id, required_entities, validation_sequence, newrelic_tool, required_parameters, datasources, additional_checks

list_capabilities

только запасной вариант

schema

Все 8 категорий с id, description, covers

get_entity_descriptor

по требованию

class_name, schema

Полное сопоставление столбцов/полей из графа дескрипторов KG

get_diagnosis_plan читает реестр возможностей напрямую из login.yaml — вызов Fuseki не требуется. get_entity_descriptor запрашивает граф дескрипторов Fuseki — для этого требуется запущенный Fuseki.

data-mcp — инструменты для работы с реальными данными (7 инструментов)

Все 7 инструментов требуют capability_id от get_diagnosis_plan. Вызов без него возвращает структурированную ошибку.

Инструмент

Шаг

Источник

Возвращает

query_sql_user

1a

UM_Users

userid, username, emailaddress, usertype, authenticationtype, islocked, isactive, isdeleted, issystemuser, mobileno

query_sql_mobile_verification

1b

UM_UserMobileNumberVerified

ismobilenumberverified + выполненный SQL

query_sql_partner_mappings

1c

UM_UserPartnermapping

Все строки маппинга, общее количество, количество активных

query_mongo_user

1d

коллекция users

9 спроецированных полей + выполненный запрос

validate_login_shapes

2

SQL + MongoDB

PASS/FAIL по каждой форме, all_shapes_pass, advisories, next_step

query_newrelic_login_mfa

3a

New Relic NerdGraph

Transaction + Log для /Account/Login (dr_010)

query_newrelic_reset_password

3b

New Relic NerdGraph

Transaction + Log для 3 URI сброса пароля (dr_011)


Диагностические категории (8)

Категория

Срабатывает, когда

login_failure

Не удаётся войти / пройти аутентификацию / получить доступ к приложению, сбой SSO, отклонены учётные данные

password_reset

Не получена ссылка для сброса пароля или письмо «забыли пароль»

otp_email

Не получено OTP-письмо при сбросе пароля

sms_otp

SMS с OTP не получено (мобильный номер подтверждён)

account_state

Учётная запись деактивирована / неактивна / приостановлена / отключена

account_locked

Учётная запись заблокирована после нескольких неудачных попыток

partner_mapping

Отсутствует / неактивен маппинг партнёра (BPC)

data_sync

Несоответствие полей между SQL и MongoDB


SHACL-формы (8, проверяются в порядке последовательности)

#

Форма

Условие

Правило

1

LoginBlockShape

isLocked=1 OR isActive=0 OR isDeleted=1

dr_003

2

SystemUserShape

isSystemUser=1

dr_005

3

BuyerSSOShape

userType=Buyer AND authenticationType=SSO

dr_006

4

PartnerMappingShape

Нет активной строки маппинга партнёра

dr_004

5

SupplierPartnerMappingShape

Поставщик без активного ненулевого BPC

dr_007

6

EmailVerificationShape

Нет действительного зарегистрированного адреса эл. почты (потоки сброса/OTP)

7

MobileConsistencyShape

Несоответствие isMobileNumberVerified между SQL и MongoDB

dr_002

8

PartnerMappingDataSyncShape

Несоответствие полей маппинга партнёра между SQL и MongoDB

dr_008

Для каждой категории validation_sequence выполняет только соответствующий поднабор этих форм. advisories (например, dr_012 — несоответствие email) возвращаются вместе с формами, но не влияют на all_shapes_pass.


Структура запроса New Relic (2 шага)

Step 1: Transaction table (max 7 days lookback, filtered by APP_ENV)
  /Account/Login            → LoginUserName, traceId, RequiresTwoFactor, TwoFactorDetails
  /Account/RecoverPassword  → traceId, errorMessage, RecoveryUserName, RecoveryEmail
  /Account/PreResetPassword → traceId, errorMessage, PreResetUserName
  /Account/ResetPassword    → LoginUserName, traceId, errorMessage

Step 2: Log table (per traceId from Step 1)
  SELECT * FROM Log WHERE `trace.id` = '{traceId}' SINCE {transaction_timestamp}

Граф знаний — именованные графы

Граф знаний хранит 6 именованных графов для каждой версии + 1 мета-граф:

IRI именованного графа

Содержимое

Кто запрашивает

urn:kg:login:v1.0.0:capabilities

Диагностические сценарии — 8 категорий, требуемые сущности, последовательности валидации

get_diagnosis_plan (Шаг 0)

urn:kg:login:v1.0.0:descriptors

Сопоставления столбцов/полей сущностей

get_entity_descriptor + validate_login_shapes (материализация)

urn:kg:login:v1.0.0:rules

Правила принятия решений (dr_001..dr_012)

validate_login_shapes — сопоставление форма→правило, читаемое во время выполнения

urn:kg:login:v1.0.0:shacl

SHACL-формы узлов + ограничения

validate_login_shapes — формы читаются и выполняются во время выполнения (на основе графа знаний)

urn:kg:login:v1.0.0:ontology

Классы и свойства OWL

Доступно для просмотра

urn:kg:login:v1.0.0:skos

Схема концептов SKOS + метки

Доступно для просмотра

urn:kg:login:meta

Указатель активной версии

Каждый запрос Fuseki (обнаружение графа)

Fuseki запрашивается на двух этапах каждой диагностики:

  1. get_diagnosis_plan (Шаг 0) — get_active_graphs (мета-граф) + get_capability_plan (граф возможностей) → полный сценарий диагностики

  2. validate_login_shapes (Шаг 2) — читает граф shacl (формы), граф descriptors (сопоставление полей/типов для материализации) и граф rules (форма→правило) — валидатор управляется графом знаний

Запасные варианты (каждый из них записывает предупреждение в лог): если Fuseki недоступен, get_diagnosis_plan читает x_capability_registry из login.yaml, а validate_login_shapes переключается на программный shacl_validator.py.


Перегенерация артефактов

При изменении любого YAML-файла схемы:

$env:PYTHONIOENCODING = "utf-8"
python scripts/generate/generate.py --schema login --version 1.0.0
python scripts/kg/load_kg.py        --schema login --version 1.0.0
python scripts/kg/promote.py        --schema login --version 1.0.0

Структура проекта

c:\Ontology\
├── src/
│   └── mcp_server/                        # PYTHONPATH=c:\Ontology\src
│       ├── server.py                      # ontology-mcp entrypoint (KG planning tools)
│       ├── diagnostic_server.py           # data-mcp entrypoint (DB/NR tools)
│       ├── tool_meta.py                   # loads config/tool_descriptions.yaml
│       ├── connectors/
│       │   ├── sql_connector.py           # pyodbc — UM_Users, UM_UserPartnermapping, ...
│       │   ├── mongo_connector.py         # pymongo — users collection (projected)
│       │   └── newrelic_connector.py      # NerdGraph GraphQL — 2-step NRQL
│       ├── diagnostics/
│       │   ├── data_fetcher.py            # orchestrates SQL + MongoDB fetch
│       │   ├── kg_shacl_validator.py      # KG-driven SHACL interpreter (PRIMARY)
│       │   └── shacl_validator.py         # programmatic evaluation (Fuseki-down fallback)
│       ├── tools/
│       │   ├── get_diagnosis_plan.py      # ontology-mcp: reads x_capability_registry
│       │   ├── list_capabilities.py       # ontology-mcp: lists all 8 categories
│       │   ├── get_descriptor.py          # ontology-mcp: SPARQL descriptors graph
│       │   ├── fetch_user_data.py         # data-mcp: 4 individual SQL/Mongo queries
│       │   ├── validate_shapes.py         # data-mcp: shape evaluation + advisories
│       │   └── query_newrelic.py          # data-mcp: NR login + reset handlers
│       ├── kg/
│       │   └── sparql_client.py           # Fuseki HTTP client + graph discovery
│       └── registry/
│           └── schema_registry.py         # registry.yaml + load_capability_registry()
│
├── ontology/
│   ├── schemas/
│   │   ├── registry.yaml
│   │   └── login/v1.0.0/
│   │       ├── login.yaml                 # root: x_capability_registry + x_shacl_rules + x_decision_rules
│   │       ├── shared/types.yaml
│   │       ├── shared/enums.yaml          # AuthenticationTypeEnum, UserTypeEnum
│   │       ├── shared/subsets.yaml
│   │       └── entities/
│   │           ├── abstract_user.yaml
│   │           ├── user.yaml              # SQL UM_Users
│   │           ├── partner_mapping.yaml   # SQL UM_UserPartnermapping
│   │           ├── mobile_verification.yaml # SQL UM_UserMobileNumberVerified
│   │           └── user_document.yaml     # MongoDB users collection
│   └── sparql/
│       ├── get_entity_descriptor.sparql
│       └── get_decision_rules.sparql
│
├── artifacts/login/v1.0.0/
│   ├── owl/login.owl.ttl
│   ├── shacl/login.shacl.ttl
│   ├── skos/login.skos.ttl
│   ├── rules/login.rules.ttl
│   ├── descriptors/login.descriptors.json
│   └── jsonld/login.context.jsonld + login.agent_template.json
│
├── scripts/
│   ├── generate/generate.py + gen_*.py + _yaml_loader.py
│   └── kg/load_kg.py + promote.py
│
├── config/
│   └── tool_descriptions.yaml             # single source of truth for all MCP tool descriptions
│
├── infra/fuseki/
│   ├── fuseki-server.jar                  # not committed — download separately
│   ├── config/login-kg.ttl
│   └── data/                              # TDB2 storage — gitignored
│
├── .github/copilot-instructions.md        # Copilot workspace instructions (auto-loaded)
├── CLAUDE.md                              # Claude Code workspace instructions (auto-loaded)
├── .vscode/mcp.json                       # MCP server registration (2 servers)
├── .env / .env.example                    # secrets — .env never committed to git
└── requirements.txt

Устранение неполадок

Ошибка

Причина

Исправление

sparql_failed

Fuseki не запущен

Запустите Fuseki (Шаг 1)

capability_id_required

Агент пропустил get_diagnosis_plan

Перезапустите разговор; CLAUDE.md / copilot-instructions.md обеспечивают соблюдение последовательности

schema_not_found

В registry.yaml отсутствует запись схемы

Проверьте ontology/schemas/registry.yaml

registry_load_failed

В login.yaml отсутствует x_capability_registry

Проверьте, что login.yaml содержит этот блок

SQL Server connection error

Неверный хост/учётные данные в .env

Проверьте SQL_SERVER_HOST, TRUSTED_CONNECTION

No module named 'pyodbc'

Отсутствует зависимость

pip install pyodbc

UnicodeEncodeError

Кодировка консоли Windows

Добавьте $env:PYTHONIOENCODING = "utf-8"

Fuseki graphs empty

Чистый запуск Fuseki после перезапуска

Запустите load_kg.py + promote.py


Ежедневный рабочий процесс

# 1. Start Fuseki
java -jar infra\fuseki\fuseki-server.jar --config infra\fuseki\config\login-kg.ttl

# 2. Load KG (only after schema or artifact changes)
$env:PYTHONIOENCODING = "utf-8"
python scripts/kg/load_kg.py --schema login --version 1.0.0
python scripts/kg/promote.py --schema login --version 1.0.0

# 3. Open VS Code — both MCP servers start automatically

Расширение схемы

Добавление новой сущности (новая таблица SQL или коллекция MongoDB)

  1. Создайте ontology/schemas/login/v1.0.0/entities/new_entity.yaml

  2. Добавьте - entities/new_entity в импорты login.yaml

  3. Запустите generate + load + promote

Добавление или изменение диагностической категории

  1. Измените x_capability_registry в login.yaml

  2. Добавьте/обновите соответствующую форму в x_shacl_rules (login.yaml) — валидатор на основе графа знаний читает её из графа shacl; правки в Python не нужны для форм sh_in/sh_property/sparql/cross_source

  3. Запустите generate + load + promote (чтобы новая форма/правило попали в граф знаний)

  4. Перезапустите MCP-серверы

Добавление или изменение SHACL-формы

Формы выполняются из графа знаний, а не из кода. Измените x_shacl_rules в login.yaml, затем выполните regenerate + reload. kg_shacl_validator.py (универсальный движок) не требует изменений, если только вы не вводите совершенно новый тип ограничения.

Добавление новой версии схемы

  1. Скопируйте ontology/schemas/login/v1.0.0/v1.1.0/

  2. Измените файлы сущностей в v1.1.0/

  3. Запустите generate + load + promote для v1.1.0

Обе версии сосуществуют в графе знаний — откат всегда доступен через promote.py.

Related MCP Connectors

Related MCP Servers