古籍空间可视化 MCP Server(fastmcp 2.x v0.2.0)
dhcckb-ancient-map 是一个 stdio 模式的 MCP Server(Python ≥ 3.10,依赖 fastmcp>=2.0,<3.0),接收古籍文本的结构化抽取结果(地点、空间关系、人物轨迹),通过三级级联地名解析自动补全坐标,生成自包含的交互式 HTML 可视化地图。
支持 Cherry Studio、Claude Desktop 等 MCP 客户端导入使用。
修订说明(v0.1.1 → v0.2.0)
本次修订目标:从 mcp SDK 底层 API(@server.list_tools() / @server.call_tool())迁移到 fastmcp 2.x 高层框架,使用 @mcp.tool() 装饰器注册工具,Pydantic 模型定义输入 Schema。
核心变更
| 变更项 | 说明 |
|---|---|
| fastmcp 2.x 迁移 | 从 mcp>=0.9.0 迁移到 fastmcp>=2.0,<3.0,使用 FastMCP 实例和 @mcp.tool() 装饰器 |
| Pydantic 模型 | Location、Relation、Agent、NaturalFeature、VisualizationData 等 Pydantic 模型定义工具输入 Schema |
| 简化传输层 | fastmcp 内置 stdio 传输管理、信号处理和异常捕获,移除手动 asyncio loop / transport 监听等 boilerplate |
| 工具注册 | 5 个 tool 直接从函数签名 + Pydantic 模型自动生成 JSON Schema |
| 向后兼容 | 工具名称、输入 JSON 结构和输出格式与 v0.1.1 完全兼容 |
v0.1.1 遗产特性(全部保留)
| 特性 | 说明 |
|---|---|
| 全局异常捕获 | fastmcp 内置 + tool handler 统一 try-catch 保护 |
| health_check 工具 | 返回 server 状态、运行时间、已注册 tool 列表和数量 |
| diagnostics 工具 | 返回 Python 版本、平台信息、内存使用、依赖版本号、脱敏环境变量 |
| structured JSON 日志 | 统一 JSON 行格式输出到 stderr |
| [MCP:READY] 信号 | 初始化完成后向 stderr 写入 READY 信号行 |
验收标准
- ✅ Server 启动后
list-tools调用 100% 成功(连续 10 次无错误) - ✅ 5 个 tool 通过
@mcp.tool()正确注册,fastmcp 自动生成 JSON Schema - ✅ 任一 tool 实现抛出异常时,Server 进程不退出,返回结构化错误响应
- ✅
health_checktool 可供宿主在调用链前探测 Server 就绪状态 - ✅ 日志输出包含启动阶段、tools 注册、请求追踪等关键信息
功能概览
| 工具 | 说明 |
|---|---|
extract_and_visualize |
接收完整结构化 JSON → 数据验证 → 坐标补全 → 生成 HTML |
generate_map |
接收已验证数据(坐标齐全)→ 跳过解析直接渲染 HTML |
query_place |
单独查询地名坐标,返回解析来源和年代范围 |
health_check |
🆕 健康检查:返回 server 状态、运行时间、已注册 tool 列表和数量 |
diagnostics |
🆕 诊断信息:返回 Python 版本、内存使用、依赖版本、脱敏环境变量 |
安装
uvx dhcckb-ancient-map
或在 MCP 客户端配置中添加:
{
"mcpServers": {
"dhcckb-ancient-map": {
"type": "stdio",
"command": "uvx",
"args": ["dhcckb-ancient-map"]
}
}
}
输入数据格式
{
"locations": [
{
"id": "loc1",
"name": "长安",
"type": "concrete",
"coordinates": [108.94, 34.26],
"year": -208,
"description": "西汉都城"
},
{
"id": "loc2",
"name": "洛阳",
"type": "concrete",
"year": 200,
"description": "东汉都城"
}
],
"relations": [
{
"from": "loc1",
"to": "loc2",
"type": "path",
"trigger": "自长安至洛阳",
"description": "东西交通"
}
],
"agents": [
{
"name": "司马迁",
"color": "#d63031",
"trajectory": ["loc1", "loc2"]
}
],
"natural_features": [
{
"feature_type": "mountain",
"coordinates": [110.08, 34.49],
"hint": "华山"
}
],
"mode": "auto",
"title": "《史记》空间关系图",
"source_text": "太史公自叙……"
}
字段说明
- locations:
type为concrete时coordinates可选(不提供则自动调用 API 查询),abstract时无坐标仅有拓扑关系。 - relations:
from/to引用locations的id,type支持path/contain/direction/adjacent/distance。 - agents:
trajectory是locations.id的有序序列。 - natural_features: 山脉、河流、森林等自然地理要素,作为背景装饰层渲染。
- mode:
auto(自动选择)/gis(GIS 地图)/topo(拓扑图)/mixed(混合叠加)。
三级级联地名解析
- 内置坐标表(
data/ancient_places.json,63 个核心地名,人工校验)—— 命中则跳过 API - CHGIS TGAZ API(
http://tgaz.fudan.edu.cn/tgaz/placename,免认证,覆盖前 222 年~1911 年)—— 带yr年份过滤 - GeoNames API(
http://api.geonames.org/searchJSON)—— 中文地名自动转拼音搜索,补充山川河流
渲染特性
- 三段式页面布局:原典文本区 → 地名列表区 → 交互式地图区
- 古风配色:宣纸暖色背景(
#f5f0e8)、传统色系标注 - 标签防重叠:8 个候选方向碰撞检测,选冲突最少方向放置,偏移时画引线
- SVG 缩放平移:鼠标滚轮以光标为中心缩放、拖拽平移、双击重置
- 自然地理装饰:山脉(山形 SVG path)、河流(波浪线)、森林(树形符号),opacity=0.5 在关系线/轨迹下层渲染
- 动态缩放策略:坐标范围小时按比例加 padding(range×0.5),范围大时加固定 padding
- 力导向布局:存在 abstract 地点时自动切换拓扑图(纯 JS 实现,无 D3.js 依赖)
- 自包含 HTML:所有 CSS/JS 内嵌,无外部 CDN 依赖,离线可用,适合长期存档
已知限制
CHGIS API
- 城市内部小地名不准:坊、里、曲、巷等小地名 API 解析普遍不准(实测《李娃传》长安坊名全部错误),需手动赋坐标。
- 朝代歧义:同名地名存在朝代歧义,必须传
yr参数做时间过滤。 - 山川类地名支持有限:自然地名(山、河、湖)CHGIS 覆盖不完整,需用 GeoNames 补充。
GeoNames API
- 拼音匹配不精确:依赖中文→拼音转换,部分地名匹配不精确,可能返回错误结果。
- 古代地名覆盖不足:GeoNames 主要收录现代地名,古代地名查询效果有限。
坐标解析
- 三级级联均无法解析的地名,坐标将设为
[0, 0],需手动补充。 - 建议优先在
data/ancient_places.json中补充常用地名坐标。
项目结构
dhcckb-ancient-map/
├── src/dhcckb_ancient_map/
│ ├── __init__.py
│ ├── server.py # MCP Server 入口,注册 5 个 Tool(加固版)
│ ├── extractor.py # 数据验证与增强
│ ├── geo_resolver.py # 三级级联地名解析
│ ├── renderer.py # HTML 渲染引擎
│ └── logger.py # 🆕 结构化 JSON 日志模块
├── data/
│ └── ancient_places.json # 63 个核心地名坐标表
├── tests/
│ └── test_server.py # 🆕 集成测试(启动→list-tools→各 tool 调用)
├── pyproject.toml
├── mcp-manifest.json
└── README.md
集成测试
# 运行集成测试(需要 uv 和 Python ≥ 3.10)
cd tests
python test_server.py
测试覆盖:
- Server 启动并检测 [MCP:READY] 信号
list-tools返回 5 个 toolhealth_check返回 healthy 状态diagnostics返回运行时信息query_place参数校验extract_and_visualize/generate_map数据校验
日志格式
所有日志以单行 JSON 格式输出到 stderr:
{"timestamp": "2026-07-28T12:00:00.000Z", "level": "INFO", "logger": "dhcckb-ancient-map", "message": "server_ready", "extra": {"tools_count": 5}}
[MCP:READY] 信号行:
{"timestamp": "2026-07-28T12:00:00.000Z", "level": "INFO", "logger": "dhcckb-ancient-map", "message": "[MCP:READY] Server is ready to accept connections", "extra": {"tools_count": 5, "uptime_ms": 123}}
许可
MIT License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
dhcckb_ancient_map-0.3.1.tar.gz
(45.5 kB
view details)
File details
Details for the file dhcckb_ancient_map-0.3.1.tar.gz.
File metadata
- Download URL: dhcckb_ancient_map-0.3.1.tar.gz
- Upload date:
- Size: 45.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
Bun/1.3.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92a0d53231e31ceb45d457b73b92a5ee3233f067fe907fa6c0536ae66c116f76
|
|
| MD5 |
31a5889fd6fd419826642e080cdf2e1f
|
|
| BLAKE2b-256 |
3deef92853eba0cd37c68dea535e6a0c916b82ca40db6f29a302ec0c1da5bc74
|