ontology-mcp
Login Query Agent — 온톨로지 MCP & 지식 그래프
OWL/SHACL/SKOS 지식 그래프와 두 개의 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: OntoRamp Graph Query
서비스 개요
서비스 | 유형 | 시작 주체 | 필요한 용도 |
Apache Jena Fuseki | 로컬 프로세스 | 직접 (수동) | ontology-mcp KG 쿼리 |
| stdio 자식 프로세스 | VS Code가 자동 생성 | 진단 계획 |
| stdio 자식 프로세스 | VS Code가 자동 생성 | DB 쿼리 + 검증 |
SQL Server | 원격/LocalDB | 이미 실행 중 | 데이터 쿼리 |
MongoDB | 원격 서버 | 이미 실행 중 | 데이터 쿼리 |
New Relic | 클라우드 서비스 | 항상 사용 가능 | 에스컬레이션 (모든 셰이프 통과) |
Fuseki만 수동으로 시작하면 됩니다. 두 MCP 서버는 모두 VS Code가 자동으로 생성합니다.
사전 요구 사항
1. Java 11+
java -version2. Apache Jena Fuseki JAR
JAR 파일은 git에서 제외되어 있습니다 (54 MB). jena.apache.org에서 다운로드하여 다음 위치에 배치하세요:
infra/fuseki/fuseki-server.jar3. Python 3.12+
python --version4. Python 의존성
cd c:\Ontology
python -m pip install -r requirements.txt5. SQL Server용 ODBC 드라이버
아직 설치하지 않은 경우 Microsoft에서 SQL Server용 ODBC Driver 17 또는 18을 다운로드하세요.
6. GitHub Copilot (Agent mode)이 포함된 VS Code
GitHub Copilot 확장 기능이 포함된 VS Code 1.99+.
단계별 로컬 시작
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.03단계 — 시크릿 구성
.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=prod4단계 — 두 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 — 지식 그래프 계획 도구 (3개 도구)
도구 | 단계 | 입력 | 반환 |
| 0 — 필수 최초 호출 |
|
|
| 폴백 전용 |
|
|
| 요청 시 |
| KG 디스크립터 그래프의 전체 열/필드 매핑 |
get_diagnosis_plan은 기능 레지스트리를login.yaml에서 직접 읽습니다 — Fuseki 호출이 필요 없습니다.get_entity_descriptor는 Fuseki 디스크립터 그래프를 쿼리합니다 — Fuseki가 실행 중이어야 합니다.
data-mcp — 실시간 데이터 도구 (7개 도구)
7개 도구 모두 get_diagnosis_plan의 capability_id가 필요합니다. 이것 없이 호출하면 구조화된 오류가 반환됩니다.
도구 | 단계 | 소스 | 반환 |
| 1a |
| userid, username, emailaddress, usertype, authenticationtype, islocked, isactive, isdeleted, issystemuser, mobileno |
| 1b |
| ismobilenumberverified + 실행된 SQL |
| 1c |
| 전체 매핑 행, 전체 개수, 활성 개수 |
| 1d |
| 9개 프로젝션 필드 + 실행된 쿼리 |
| 2 | SQL + MongoDB | 셰이프별 PASS/FAIL, |
| 3a | New Relic NerdGraph |
|
| 3b | New Relic NerdGraph | 3개의 리셋 URI에 대한 트랜잭션 + 로그 (dr_011) |
진단 카테고리 (8)
카테고리 | 트리거 조건 |
| 로그인 / 인증 / 앱 접근 불가, SSO 실패, 자격 증명 거부 |
| 리셋 링크 또는 비밀번호 찾기 이메일을 받지 못함 |
| 리셋 중 OTP 이메일을 받지 못함 |
| SMS OTP를 받지 못함 (모바일 인증됨) |
| 계정 비활성화 / 비활성 / 정지 / 사용 중지 |
| 여러 번의 실패한 시도 후 계정 잠김 |
| 파트너 (BPC) 매핑 누락 / 비활성 |
| SQL과 MongoDB 필드 불일치 |
SHACL 셰이프 (8개, 시퀀스 순서로 평가)
# | 셰이프 | 조건 | 규칙 |
1 |
| isLocked=1 OR isActive=0 OR isDeleted=1 | dr_003 |
2 |
| isSystemUser=1 | dr_005 |
3 |
| userType=Buyer AND authenticationType=SSO | dr_006 |
4 |
| 활성 파트너 매핑 행 없음 | dr_004 |
5 |
| 활성 상태의 0이 아닌 BPC가 없는 공급업체 | dr_007 |
6 |
| 유효한 등록 이메일 주소 없음 (리셋/OTP 흐름) | — |
7 |
| SQL과 MongoDB의 isMobileNumberVerified 불일치 | dr_002 |
8 |
| 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}지식 그래프 — 명명된 그래프
KG는 버전당 6개의 명명된 그래프와 1개의 메타 그래프를 저장합니다:
명명된 그래프 IRI | 내용 | 사용처 |
| 진단 플레이북 — 8개 카테고리, 필수 엔티티, 검증 시퀀스 |
|
| 엔티티 열/필드 매핑 |
|
| 결정 규칙 (dr_001..dr_012) |
|
| SHACL 노드 셰이프 + 제약 조건 |
|
| OWL 클래스 + 속성 | 검사용으로 사용 가능 |
| SKOS 개념 체계 + 레이블 | 검사용으로 사용 가능 |
| 활성 버전 포인터 | 모든 Fuseki 쿼리 (그래프 디스커버리) |
Fuseki는 모든 진단의 두 단계에서 쿼리됩니다:
get_diagnosis_plan(0단계) —get_active_graphs(메타 그래프) +get_capability_plan(캐퍼빌리티 그래프) → 전체 진단 플레이북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문제 해결
오류 | 원인 | 수정 |
| Fuseki가 실행 중이 아님 | Fuseki 시작(1단계) |
| 에이전트가 | 대화 다시 시작; |
|
|
|
|
|
|
|
|
|
| 종속성 누락 |
|
| Windows 콘솔 인코딩 |
|
Fuseki 그래프가 비어 있음 | 재시작 후 새 Fuseki 시작 |
|
일일 워크플로
# 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 컬렉션)
ontology/schemas/login/v1.0.0/entities/new_entity.yaml생성login.yaml임포트에- entities/new_entity추가generate + load + promote 실행
진단 범주 추가 또는 변경
login.yaml에서x_capability_registry편집x_shacl_rules(login.yaml)에서 일치하는 셰이프 추가/업데이트 — KG 기반 검증기는shacl그래프에서 이를 읽습니다.sh_in/sh_property/sparql/cross_source셰이프에는 Python 편집이 필요 없습니다generate + load + promote 실행(새 셰이프/규칙이 KG에 들어가도록)
MCP 서버 다시 시작
SHACL 셰이프 추가 또는 변경
셰이프는 코드가 아닌 KG에서 실행됩니다. login.yaml에서 x_shacl_rules를 편집한
다음 regenerate + reload를 수행하세요. kg_shacl_validator.py(일반 엔진)는
완전히 새로운 제약 조건 유형을 도입하지 않는 한 변경할 필요가 없습니다.
새 스키마 버전 추가
ontology/schemas/login/v1.0.0/→v1.1.0/복사v1.1.0/에서 엔터티 파일 편집v1.1.0에 대해 generate + load + promote 실행
두 버전 모두 KG에 공존합니다 — 롤백은 항상 promote.py로 가능합니다.
This server cannot be deployed
Maintenance
Related MCP Connectors
Knowledge graph for AI agents. Query concepts, walk edges, get advisories.
Knowledge graph ingestion, entity search, ontology analysis, and CoSync scoring.
LLM Orchestration Observability Agent
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to query and record SOC analyst reasoning via a knowledge graph, allowing access to institutional memory from Splunk.MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to query organizational architecture and governance constraints, returning evidence-grounded answers from documented structures.MIT
- FlicenseNot gradedqualityCmaintenanceLets AI agents query a computerized system inventory as a knowledge graph using Cypher, enabling blast radius, data lineage, regulation checks, and change impact assessments while preventing hallucinated regulatory claims.-
- FlicenseNot gradedqualityCmaintenanceEnables manufacturing traceability queries and analysis through GraphRAG, supporting semantic search, graph traversal, natural language to Cypher, defect chain retrieval, requirement traceability, and product health dashboards.-