Skip to main content
Glama
lesskao

SNOMED GraphRAG MCP Server

by lesskao
README.md
# SNOMED GraphRAG MCP Server

基于 Neo4j 与 SNOMED 子集的 GraphRAG MCP 服务,提供 `graph_search_concept`、`graph_get_related` 两个 Tools。

---

## 1. 快速开始

**环境**:Python 3.10+、Neo4j 5.x(Docker Desktop 且 Docker 已运行)、`uv` 或 `pip`、PowerShell 或 CMD。以下在**项目根**执行。

### 1.1 数据与 Neo4j

```powershell
# 生成 concept_minimal、复制 DR
python scripts/gen_concept_minimal.py
copy SNOMED_CSV\DR_118170007_new.csv docker\import\

# 启动 Neo4j
cd docker && docker compose up -d --force-recreate && cd ..

# Neo4j 启动约 10s 后执行 build(PowerShell)
Get-Content docker\import\build_minimal.cypher -Raw | docker exec -i neo4j cypher-shell -u neo4j -p password

# 校验(PowerShell)
$env:NEO4J_PASSWORD="password"
uv run python scripts/check_neo4j.py
```

> CMD 下:`type docker\import\build_minimal.cypher | docker exec -i neo4j cypher-shell -u neo4j -p password`;`set NEO4J_PASSWORD=password` 再执行 `check_neo4j.py`。Neo4j 密码非 `password` 时替换。

### 1.2 安装依赖

```powershell
uv sync
```

或 `pip install "mcp[cli]" neo4j`。

### 1.3 配置 MCP(Cursor / Claude Desktop)

在 MCP 配置中加入(`cwd`、`command` 改成本机项目**绝对路径**):

```json
{
  "mcpServers": {
    "snomed-graph-rag": {
      "command": "D:/ai/gientech/code/rag-neo-mcp-week6/.venv/Scripts/python.exe",
      "args": ["-u", "-m", "mcp_server.main"],
      "cwd": "D:/ai/gientech/code/rag-neo-mcp-week6",
      "env": { "PYTHONUNBUFFERED": "1", "NEO4J_PASSWORD": "password" }
    }
  }
}
```

- Cursor:设置 → MCP,或编辑 `%USERPROFILE%\.cursor\mcp.json`。完整示例见 `mcp_config_example.json`。
- 若出现「No server info found」:确保 `command` 指向 **项目根\\.venv\\Scripts\\python.exe**,`args` 含 `-u`,或改用 `run_mcp.bat` 作 `command`、`args: []`。

### 1.4 重启 Cursor,确认 Docker 中 Neo4j 已启动

---

## 2. 探索更复杂的 RAG 应用场景和范式

相对「文档切片 + 向量检索 + 一次查回」的简单 RAG,本项目从**应用场景**和**检索范式**两方面做更复杂探索,并落实到实现。

### 2.1 应用场景

| 维度 | 简单 RAG | 本项目 |
|------|----------|--------|
| 数据形态 | 扁平文本/切片 | **领域知识图谱**:SNOMED 本体(ObjectConcept、RoleGroup、定义关系) |
| 领域 | 通用文档 | **医学术语**:FSN、sctid、SPECIMEN_SOURCE_IDENTITY 等 |
| 语义结构 | 语义相似 | **显式关系**:`(概念)-[:HAS_ROLE_GROUP]->(RoleGroup)-[关系类型]->(目标概念)` |

**本项目实现**:`build_minimal.cypher` 构建 ObjectConcept、RoleGroup、HAS_ROLE_GROUP、SPECIMEN_SOURCE_IDENTITY;`mcp_server/neo4j_client` + Cypher 查询该图。

### 2.2 检索范式

- **多范式并存**(非单一向量检索):
  - **graph_search_concept**:按 FSN 子串或 sctid 的**关键词/属性检索**(图上的索引查找);
  - **graph_get_related**:按**图结构 + 关系类型**的**图遍历检索**,模式  
    `(c:ObjectConcept)-[:HAS_ROLE_GROUP]->(rg:RoleGroup)-[r]->(c2:ObjectConcept)`,`type(r) IN $types`。
- **图原生检索**:用 Cypher 在 Neo4j 上做模式匹配,关系类型直接参与查询,替代「向量检索 + 过滤」。

### 2.3 工具化 / Agent 范式

- **RAG 即工具**:图检索封装为 MCP 的 `graph_search_concept`、`graph_get_related`,由 Cursor/LLM **按问题选工具、组合调用**,而非固定一条检索流水线。
- **检索与生成解耦**:模型根据自然语言选工具与参数(如 `rel_types`),再基于图返回结果生成回答(Tool-augmented / Agent-RAG)。

---

## 3. MCP 应用

### 3.1 在 Cursor 里用

- 在对话中**用自然语言提问**,例如:「sctid 119299002 有哪些 SPECIMEN_SOURCE_IDENTITY 相关概念?」、「按 FSN 搜 Concept (119299002)」。
- 模型会**自动选** `graph_search_concept` 或 `graph_get_related`,把 Neo4j 查到的结果当上下文再回答。
- 流程:**提问 → Cursor 调用 Tool → MCP 查 Neo4j → 文本结果给模型 → 生成回答**。

### 3.2 两个 Tool

| Tool | 作用 |
|------|------|
| **graph_search_concept** | 按 FSN 子串或 sctid 检索 ObjectConcept;参数 `keyword`、`limit`。 |
| **graph_get_related** | 按 sctid 与关系类型(如 SPECIMEN_SOURCE_IDENTITY)查经 RoleGroup 的相邻概念;参数 `sctid`、`rel_types`(可选)。 |

### 3.3 示例问题

- 「sctid 119299002 有哪些 SPECIMEN_SOURCE_IDENTITY 相关概念?」→ `graph_get_related`
- 「在 SNOMED 图里查和 116154003 有定义关系的概念」→ `graph_get_related`
- 「按 FSN 搜 Concept (119299002)」→ `graph_search_concept`

### 3.4 前端界面(可选)

不通过 Cursor 时,可在浏览器查图:`uv sync --extra web`,然后  
`$env:NEO4J_PASSWORD="password"`;`uv run uvicorn web.app:app --host 127.0.0.1 --port 8000`,打开 http://127.0.0.1:8000。

### 3.5 错误与边界

sctid 不存在、keyword 无匹配、Neo4j 断线时,Tool 返回明确提示,不抛错。

TDQS

B3.1/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have completely distinct purposes: graph_search_concept retrieves concepts by search, and graph_get_related fetches related concepts via relationships. There is no overlap or ambiguity.

Naming Consistency5/5

Both tools follow the consistent 'graph_<verb>_<noun>' pattern with snake_case. 'graph_search_concept' and 'graph_get_related' are parallel and predictable.

Tool Count2/5

With only 2 tools for a complex domain like SNOMED CT, the server is severely under-scoped. Typical SNOMED interactions require many more operations (e.g., detail retrieval, hierarchy browsing, multiple relation types).

Completeness2/5

The tool surface has major gaps: no tool to get full concept details (descriptions, synonyms), no hierarchy navigation, and graph_get_related is limited to a single relation type (SPECIMEN_SOURCE_IDENTITY). Missing core CRUD-like operations for a knowledge graph.

Maintenance

ActivityInactive
ResponsivenessNo issues