目标与背景
平时向 AI 助手问起某本专业书时,它往往只能告诉我这本书讲什么,却不知道学校图书馆里有没有馆藏、有几个版本、具体放在哪一层的哪个书库。HUEL-LibBridge 就是为了打通这最后一步:把河南财经政法大学图书馆的公开馆藏检索系统(OPAC)封装成本地 MCP 服务,让 AI 助手能在对话里直接帮我查书、看索书号和确认在架状态。
整个查询走的是图书馆网页端公开的免登录接口,不需要绑定校园卡账号密码。首版专注把图书检索和馆藏详情做扎实,研修室与座位预约相关的功能留待后续单独探索。
我的工作
我独立完成了上游 OPAC 接口抓包分析、字段清洗规则设计、本地 MCP 服务端开发与双版本安装文档编写。
在采样真实返回数据时,我遇到了不少老牌教务/图书系统常见的格式细节:比如统计数量有时返回整数、有时又是数字字符串,部分年代久远的书目没有 ISBN 或馆藏地字段,检索结果的标题里还会夹杂着用来标红关键词的 HTML 标签。我在数据规范化层把这些不一致全部清洗干净,防止大模型把缺失字段误判成 0,或者把 <span> 高亮标签当成书名的一部分。
实现内容
检索与详情两步工具设计
服务通过两个职责分明的 MCP 工具配合完成查询:
| 工具名称 | 功能说明 |
|---|---|
search_books | 支持按题名、作者、ISBN、索书号或条码五种方式检索,返回指定页的书目列表与分页信息 |
get_book_detail | 接收搜索结果附带的 detail_ref 引用,查询完整出版信息与每一册实体书的馆藏明细 |
实际对话时,AI 可以先调 search_books 搜《平凡的世界》,对比不同出版社和年份的版本后,再把目标书目的 detail_ref 原样传给 get_book_detail 查看具体哪一册在馆。每次调用只请求明确指定的一页,不在后台擅自改写关键词或全量翻页抓取,翻页和深入查询完全交给上层对话按需决定。
区分书目信息与单册状态
同一本书在馆里通常有多册复本,散落在不同校区或阅览室。因此 get_book_detail 的返回结构严格区分了书目层(作者、出版社、ISBN 等)与单册馆藏层(条码号、索书号、原馆藏地、当前所在架位、借阅属性与当前在架状态)。
对于上游接口返回的原始状态文字(如“在架”“可借”或电子资源无实体馆藏等),服务如实保留各字段语义,不强行捏合成单一的布尔值,也不去猜测上游未提供的应还日期;暂未映射的冷门字段则保留在 extra 字典中备查。
本地运行与双版本文档
项目基于 Python、FastMCP、httpx 与 Pydantic 构建,使用 uv 锁定依赖环境,通过标准输入输出(stdio)与本地 MCP 客户端通信。仓库除了提供给普通读者看的手动配置教程外,还专门写了一份面向编码 Agent 的自动安装与自检指南,方便直接丢给 AI 助手自动完成环境配置。
方案与取舍
代码内部按 MCP 工具入口层 → OPAC 网络请求层 → 数据规范化层 三层解耦。搜索结果里直接携带自包含的详情引用参数,使整个服务完全无状态,不需要在本地挂数据库或维护容易失效的内存会话表。
网络层复用同一个 httpx 客户端连接池,请求串行执行并限制了合理的间隔与超时时间,避免给学校图书馆服务器造成突发压力。遇到上游超时或返回结构异常时直接向客户端抛出明确错误,绝不把网络故障伪装成“馆内查无此书”。
验证与后续计划
首版代码(2026 年 10 月 15 日)已在 macOS 环境下通过公开接口只读采样与真实 stdio 子进程联调,离线单元测试也覆盖了字段缺失、异常响应与参数边界校验(具体采样范围见仓库 docs/validation.md)。
由于图书馆馆藏随时都在动态借还,查询结果仅反映请求当下的公开页面状态;Windows 与 Linux 平台目前已配好安装说明与 CI 检查,后续有机会再补上实机联调。下一步打算另行研究图书馆座位查询与预约系统的认证机制,看能否在安全合规的前提下做成独立的扩展模块。