Skip to main content
Glama
JiteAgar-Code

ontology-mcp

로그인 쿼리 에이전트 — Ontology MCP & Knowledge Graph

OWL/SHACL/SKOS Knowledge Graph + 두 개의 MCP 서버를 사용하여 SQL Server와 MongoDB 전반에 걸쳐 로그인 진단 쿼리를 라우팅하고, 조건부 New Relic 에스컬레이션을 수행하는 POC입니다.


아키텍처 개요

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: openclaw-brain

서비스 개요

서비스

유형

시작 주체

필요 용도

Apache Jena Fuseki

로컬 프로세스

사용자(수동)

ontology-mcp KG 쿼리

ontology-mcp

stdio 자식 프로세스

VS Code 자동 생성

진단 계획 수립

data-mcp

stdio 자식 프로세스

VS Code 자동 생성

DB 쿼리 + 검증

SQL Server

원격/LocalDB

이미 실행 중

데이터 쿼리

MongoDB

원격 서버

이미 실행 중

데이터 쿼리

New Relic

클라우드 서비스

항상 사용 가능

에스컬레이션(모든 셰이프 통과 시)

Fuseki만 수동 시작이 필요합니다. 두 MCP 서버는 VS Code가 자동으로 생성합니다.


사전 요구 사항

1. Java 11+

java -version

2. Apache Jena Fuseki JAR

JAR 파일은 git에서 제외되어 있습니다(54 MB). 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. SQL Server용 ODBC 드라이버

아직 설치되지 않은 경우 Microsoft에서 SQL Server용 ODBC Driver 17 또는 18을 다운로드하세요.

6. GitHub Copilot(에이전트 모드)이 포함된 VS Code

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단계 — Knowledge Graph 로드

최초 실행 시 또는 스키마/아티팩트 변경 후에 필요합니다.

$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+P → Developer: 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 — Knowledge Graph 계획 도구(3개 도구)

도구

단계

입력

반환

get_diagnosis_plan

0 — 필수 첫 호출

category, schema

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

list_capabilities

폴백 전용

schema

id, description, covers가 포함된 전체 8개 카테고리

get_entity_descriptor

온디맨드

class_name, schema

KG descriptors 그래프의 전체 열/필드 매핑

get_diagnosis_plan은 기능 레지스트리를 login.yaml에서 직접 읽습니다 — Fuseki 호출이 필요 없습니다. get_entity_descriptor는 Fuseki descriptors 그래프를 쿼리합니다 — Fuseki 실행이 필요합니다.

data-mcp — 실시간 데이터 도구(7개 도구)

7개 도구 모두 get_diagnosis_plan의 capability_id가 필요합니다. 이 값 없이 호출하면 구조화된 오류가 반환됩니다.

도구

단계

소스

반환

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

/Account/Login에 대한 트랜잭션 + 로그(dr_010)

query_newrelic_reset_password

3b

New Relic NerdGraph

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

활성 0이 아닌 BPC가 없는 공급업체

dr_007

6

EmailVerificationShape

유효한 등록 이메일 주소 없음(리셋/OTP 흐름)

—

7

MobileConsistencyShape

SQL과 MongoDB의 isMobileNumberVerified 불일치

dr_002

8

PartnerMappingDataSyncShape

SQL과 MongoDB의 파트너 매핑 필드 불일치

dr_008

각 카테고리의 validation_sequence는 관련 셰이프 하위 집합만 실행합니다. advisories(예: dr_012 이메일 불일치)는 셰이프와 함께 반환되지만 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}

Knowledge Graph — 명명된 그래프

KG는 버전당 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 — 셰이프를 런타임에 읽고 실행(KG 기반)

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(capabilities 그래프) → 전체 진단 플레이북

  2. validate_login_shapes(2단계) — shacl 그래프(셰이프), descriptors 그래프(구체화를 위한 필드/유형 매핑), rules 그래프(셰이프→규칙)를 읽음 — 검증기는 KG 기반

폴백(각각 경고 로그 기록): Fuseki에 연결할 수 없는 경우 get_diagnosis_plan은 login.yaml에서 x_capability_registry를 읽고, 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 그래프가 비어 있음

재시작 후 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. login.yaml imports에 - entities/new_entity 추가

  3. generate + load + promote 실행

진단 카테고리 추가 또는 변경

  1. login.yaml의 x_capability_registry 편집

  2. x_shacl_rules(login.yaml)에서 일치하는 셰이프 추가/업데이트 — KG 기반 검증기가 shacl 그래프에서 이를 읽음; sh_in/sh_property/sparql/cross_source 셰이프는 Python 편집 불필요

  3. generate + load + promote 실행 (새 셰이프/규칙이 KG에 들어가도록)

  4. MCP 서버 재시작

SHACL 셰이프 추가 또는 변경

셰이프는 코드가 아닌 KG에서 실행됩니다. login.yaml의 x_shacl_rules를 편집한 후 재생성 + 재로드하세요. kg_shacl_validator.py(일반 엔진)는 완전히 새로운 제약 유형을 도입하지 않는 한 변경할 필요가 없습니다.

새 스키마 버전 추가

  1. ontology/schemas/login/v1.0.0/을 v1.1.0/으로 복사

  2. v1.1.0/의 엔티티 파일 편집

  3. v1.1.0에 대해 generate + load + promote 실행

두 버전 모두 KG에 공존합니다 — promote.py를 통한 롤백은 항상 가능합니다.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    An MCP server that ingests semiconductor PDFs into a Neo4j knowledge graph, enabling AI agents to query domain knowledge, verify claims against source text, and record design reasoning.
    35
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    An autonomous MCP server that enables LLMs to intelligently query and analyze MongoDB databases by reverse-engineering schemas, proving relationships, and enforcing security safeguards like PII masking and query limits.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that provides SQL generation, validation, transpilation, and schema introspection across 10 SQL dialects, using a property graph schema and phase-locked reasoning to convert natural language to accurate SQL.
    3
    MIT