关于 Audiobookshelf
Audiobookshelf 的 MCP 服务,让 MCP 客户端浏览有声书和播客库、查询收听记录,并管理进度、书签、合集与播放列表。支持只读模式、工具筛选及紧凑媒体结果。
主要功能
- 01浏览、搜索有声书和播客
- 02查看章节、统计与收听记录
- 03同步进度、书签、合集和播放列表
- 04只读模式与工具筛选
- 05媒体结果紧凑呈现,支持完整详情
适用场景
- 01查询拥有或已收听的内容
- 02查找未听完的书或最近播客
- 03更新收听位置和书签
- 04整理合集与播放列表
MCP 相关
作为 MCP 服务向客户端提供 Audiobookshelf 图书馆查询、收听状态读取及写入工具。可限制注册的工具,部分写操作需经 MCP elicitation 确认。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y audiobookshelf-mcpAUDIOBOOKSHELF_URLBase URL of the Audiobookshelf instance, e.g. https://abs.example.comAUDIOBOOKSHELF_API_KEY密钥API key from Settings -> Users -> API Keys (Audiobookshelf 2.26.0 or newer)AUDIOBOOKSHELF_READ_ONLYSet to true to register only the 29 read tools and no write toolsAUDIOBOOKSHELF_INSECURE_TLSSet to true to accept self-signed certificates for this connection onlyAUDIOBOOKSHELF_ALLOW_TOOLSComma-separated tool names or list_* prefixes to register; 'essential' selects a curated preset (default: all tools)AUDIOBOOKSHELF_DENY_TOOLSComma-separated tool names or list_* prefixes to remove from whatever AUDIOBOOKSHELF_ALLOW_TOOLS left本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
audiobookshelf-mcp
这是一个适用于 Audiobookshelf 的 Model Context Protocol(MCP)服务;Audiobookshelf 是一款可自托管的有声书和播客服务。
它让 Claude Code、Claude Desktop 或 Codex 等 MCP 客户端能够浏览你的媒体库,回答有关你拥有和听过哪些内容的问题;除非你关闭此功能,否则还会保持你的收听进度、书签、合集和播放列表为最新状态:共 44 个工具,其中 29 个只读,15 个可写。
44 个工具是上限,而不是起点:设置 AUDIOBOOKSHELF_ALLOW_TOOLS=essential,即可只注册精选的 8 个工具。模型从 8 个工具中选择正确工具的可靠性远高于从 44 个中选择——请参阅选择加载哪些工具。
有何不同
每个响应都是投影,而非原始对象。 展开的媒体库项目包含每个音频文件、曲目和章节的完整 ffprobe 元数据。媒体工具会以精简结构返回结果;当你确实需要原始对象时,可使用 detail="full"。
44 个工具中有 29 个只能读取。 设置 AUDIOBOOKSHELF_READ_ONLY=true 后,只会注册这些工具,因此写入工具不会出现在 tools/list 中,而不是等到调用时才拒绝请求。
六个会移除内容的工具都会先征求用户确认,通过 MCP elicitation 实现——这是模型无法代替用户作答的对话;如果客户端无法显示此对话,则会改用绑定到确切目标的一次性令牌。
要求
- Node.js 22 或更高版本
- Audiobookshelf 2.26.0 或更高版本——更早版本不支持 API 密钥
- Audiobookshelf API 密钥
获取 API 密钥
管理员可在 设置 → 用户 → API 密钥 中管理 API 密钥。每个密钥只代表一位 Audiobookshelf 用户,并继承该用户的权限。因此,为普通账户签发的密钥无法查看该账户无权访问的媒体库,且只有该账户拥有删除权限时才能删除内容。密钥仅在创建时显示一次。
配置
| 变量 | 必填 | 描述 |
|---|---|---|
AUDIOBOOKSHELF_URL | 是 | 实例的基础 URL,例如 https://abs.example.com。不得包含凭据。 |
AUDIOBOOKSHELF_API_KEY | 是 | API 密钥,通过 Authorization: Bearer … 发送 |
AUDIOBOOKSHELF_READ_ONLY | 否 | true 只注册 29 个读取工具 |
AUDIOBOOKSHELF_INSECURE_TLS | 否 | true 接受自签名证书——仅作用于此连接,不影响整个进程 |
AUDIOBOOKSHELF_ALLOW_TOOLS | 否 | 以逗号分隔的工具名称、list_* 前缀,或用于精选预设的 essential |
AUDIOBOOKSHELF_DENY_TOOLS | 否 | 语法相同;从 AUDIOBOOKSHELF_ALLOW_TOOLS 留下的工具中移除 |
ELICITATION | 否 | false 将审批对话框替换为双调用令牌。不带前缀 |
服务器无需配置即可启动:它会完成 MCP 握手并列出工具,但之后每次调用都会失败并显示设置说明。这是有意为之,方便注册表和沙箱检查器对其进行自省。
选择要加载的工具
AUDIOBOOKSHELF_ALLOW_TOOLS 和 AUDIOBOOKSHELF_DENY_TOOLS 接受以逗号分隔的工具名称;末尾的 * 可匹配整个工具族。essential 是一个精选预设,包含八个工具:list_libraries、search_library、list_library_items、get_library_item、get_item_chapters、list_items_in_progress、get_media_progress、set_media_progress。
AUDIOBOOKSHELF_ALLOW_TOOLS=essential
AUDIOBOOKSHELF_ALLOW_TOOLS=search_library,get_library_item,set_media_progress
AUDIOBOOKSHELF_DENY_TOOLS=delete_*
如果某个条目与任何工具都不匹配,启动就会中止并指出该条目,因此拼写错误不会悄悄隐藏工具——否则没人能追查某个工具为何缺失是由环境变量造成的。经过筛选的工具永远不会注册,因此它不会出现在 tools/list 中,也无法通过 tools/call 调用;这与 AUDIOBOOKSHELF_READ_ONLY 下的写入工具完全一样。
如果你同时运行多个此类服务器,mcp-hub 是另一种选择——它的 /hub 端点会用六个元工具替换所有服务器的工具。
安装
Claude Code
claude mcp add audiobookshelf \
-e AUDIOBOOKSHELF_URL=https://abs.example.com \
-e AUDIOBOOKSHELF_API_KEY=… \
-- npx -y audiobookshelf-mcp
Claude Desktop
claude_desktop_config.json:
{
"mcpServers": {
"audiobookshelf": {
"command": "npx",
"args": ["-y", "audiobookshelf-mcp"],
"env": {
"AUDIOBOOKSHELF_URL": "https://abs.example.com",
"AUDIOBOOKSHELF_API_KEY": "…"
}
}
}
}
Codex
~/.codex/config.toml:
[mcp_servers.audiobookshelf]
command = "npx"
args = ["-y", "audiobookshelf-mcp"]
env = { AUDIOBOOKSHELF_URL = "https://abs.example.com", AUDIOBOOKSHELF_API_KEY = "…" }
Docker
支持多架构,并提供 SBOM 和构建来源证明:
docker run -i --rm \
-e AUDIOBOOKSHELF_URL=https://abs.example.com \
-e AUDIOBOOKSHELF_API_KEY=… \
ghcr.io/ni-c/audiobookshelf-mcp
必须使用 -i——协议通过 stdin 和 stdout 运行。无需发布端口。更多客户端配置示例(包括如何避免将密钥暴露在 docker run 命令行中),请参阅客户端指南。
通过 mcp-hub
无法启动本地进程的客户端——ChatGPT connectors、Claude on the web、
Cursor、LibreChat——可通过 mcp-hub 连接到 audiobookshelf-mcp:一个
容器即可通过 Streamable HTTP 为多个 stdio MCP 服务提供服务,并通过单一密码进行 OAuth 2.1 登录,
同时为无法使用 OAuth 的客户端提供长期令牌。它的
/hub 端点会将每个服务置于六个元工具之后,因此一个连接器就能连接所有服务,无需在模型上下文中加入 N×工具架构;它还同时支持两个协议修订版——本服务提出的问题会经由它传递给另一端的人。
它的 /config/mcp.json 使用 Claude Code 的格式,因此可以直接使用你已有的条目:
{
"mcpServers": {
"audiobookshelf": {
"command": "npx",
"args": ["-y", "audiobookshelf-mcp"],
"env": { "AUDIOBOOKSHELF_ALLOW_TOOLS": "essential" },
"denyTools": ["delete_*"]
}
}
}
其中的 allowTools 和 denyTools 是 hub 自己针对每个服务的筛选器,与 env 中的 *_ALLOW_TOOLS 并不相同——两者的区别,以及由此引发的误用,详见客户端指南。
工具
每个工具都声明了 outputSchema,并在文本块之外通过 structuredContent
返回结果,因此客户端无需解析文字说明就能使用结果。
原先会返回一句话——“Collection col_1 deleted.”——的七个工具,现在
也会返回相应字段。
报告媒体库元数据的工具会将 untrusted: true 和
source: "audiobookshelf" 作为字段:从元数据提供方获取的图书简介、
播客 feed 摘要和单集标题都由他人撰写,账户的书签标题和所选标签也一样,
媒体库中时长最长和体积最大的条目标题也同样如此。其他工具则不包含这些字段——
本服务接收到的 ID、被要求存储的位置、实例的版本字符串,以及操作员输入的媒体库名称和文件夹路径。
这些文档被描述为开放对象,并列出本服务构建的顶层键。detail: "full" 会将 API 记录
完整返回,因此同一个工具返回的键远多于其列出的键——而 SDK 会在每个结果发出前
根据其架构进行验证,这正是此处不应使用严格结构的原因。
get_personalized_shelves 返回 {items: [...]},而不是 API 发送的裸数组:对于根节点为数组的架构,
2025 年前后的客户端会将其改写为 {result: …},否则它就会以两种结构返回结果。
阅读
| 工具 | 功能说明 |
|---|---|
list_libraries | 可访问的媒体库及其 ID、名称和媒体类型——入口 |
get_library | 单个媒体库及其文件夹和设置 |
get_library_stats | 项目、作者和类型的数量,以及总时长和大小 |
get_library_filter_data | 媒体库中可用于筛选的值:作者、类型、标签、系列、旁白者、语言、出版商 |
list_library_items | 媒体库中的项目,支持分页、排序和筛选 |
search_library | 在图书、播客、系列、作者、旁白者和标签中进行全文搜索 |
get_personalized_shelves | 主屏幕上的书架:继续收听、最近添加,…… |
list_series / get_series | 系列及其图书数量和总时长 |
list_authors / get_author | 作者,可选择包含其项目 |
list_tags / list_genres | 服务中使用的所有标签 / 类型 |
get_library_item | 单本图书或单个播客及其元数据、标签和你的收听进度 |
get_item_chapters | 图书的章节列表,单独提供是因为列表可能很长 |
get_podcast_episode | 单集及其发布日期、时长和简介 |
list_recent_episodes | 播客媒体库中的最新单集 |
get_me | API 密钥所代表的用户及其权限和媒体库 |
list_items_in_progress | 所有媒体库中已开始但尚未完成的项目 |
get_media_progress | 单个项目的位置、百分比和完成状态 |
get_listening_stats | 总时长、每日和每周各日的收听时长,以及收听最多的项目 |
get_year_stats | 某个日历年的“年度回顾”数据 |
list_listening_sessions | 播放会话及其设备、位置和收听时长 |
list_bookmarks | 所有书签或某个项目的书签 |
list_collections / get_collection | 合集——共享的、有序图书分组 |
list_playlists / get_playlist | 播放列表——按用户私有,包含图书或单集 |
get_server_status | 服务的版本和初始化状态 |
写作
| 工具 | 功能说明 |
|---|---|
set_media_progress | 设置位置、标记为已完成或未完成,或从「继续收听」中隐藏 |
delete_media_progress 👤 | 删除进度记录,即该项目的收听历史 |
create_bookmark / update_bookmark / delete_bookmark 👤 | 书籍中的命名位置 |
create_collection / update_collection / delete_collection 👤 | 合集 |
add_books_to_collection / remove_books_from_collection 👤 | 合集成员 |
create_playlist / update_playlist / delete_playlist 👤 | 播放列表 |
add_items_to_playlist / remove_items_from_playlist 👤 | 播放列表成员 |
👤 通过 MCP elicitation 向用户征求确认;如果客户端无法显示对话框,则回退到两次调用
confirm_token。
响应大小
Audiobookshelf 返回的对象非常大——展开后的媒体库条目包含每个音频文件、曲目和章节的完整 ffprobe 元数据。因此,每个返回媒体内容的工具默认都会返回精简视图,并接受
detail: "full" 来获取原始对象。
设置三道限制,因为一道还不够:
- 响应上限为 5 MB。 读取字节前会检查
content-length,读取分块响应正文时也会统计大小,因此超大响应会被拒绝,而不是继续解析。 - 结果上限为 100 000 字节,在
jsonResult中应用——因此detail: "full"也受此限制。只会移除完整条目,不会截断字符:被截断的文档并不是更小的答案,而是无法解析的内容。结果随后会附带一个truncated块,说明应改为调用什么工具。 - 嵌入成员数量上限。 精简版合集或播放列表最多嵌入前 25 本书或条目,并报告实际数量;
get_collection和get_playlist可返回其中一个的全部成员。
list_library_items 支持正确分页,可使用 limit 和 page。另外七个列表工具——list_libraries、list_authors、list_tags、list_genres、list_collections、list_playlists 和 list_bookmarks——不支持分页,因为它们对应的 Audiobookshelf 路由会一次返回所有内容,且不接受分页参数。library_id 可缩小两个合集相关路由的范围;其余工具则受上述上限约束。
筛选
list_library_items 接受 filter_group 和 filter_value,并据此构造 API 所需的 base64 编码 filter 参数。有效值来自 get_library_filter_data。如果指定了需要值的分组却没有提供值,请求会被拒绝,因为 Audiobookshelf 会静默返回未筛选的媒体库。
filter_group="authors", filter_value="<author id>"
filter_group="progress", filter_value="finished" | "in-progress" | "not-started" | "not-finished"
filter_group="issues" (standalone, no value)
有意不提供的功能
不支持播放。 暂停、跳转和播放属于真实客户端管理的会话状态机。set_media_progress 可用于“标记为已完成”和“跳到第 12 章”;播放则交给你的手机。
不提供管理功能,即使使用管理员密钥也不例外。 没有用于用户管理、服务器设置、备份、清理缓存、浏览文件系统、删除媒体库或条目、重写元数据或上传文件的工具。这些端点在 Audiobookshelf 中确实存在,但这里不会接入,因为如果模型发生混淆或遭到操纵,工具列表可以限制其影响范围。
安全
-
只读模式。
AUDIOBOOKSHELF_READ_ONLY=true会完全不注册写入工具, 而不是在调用时拒绝它们。 -
会征求用户确认,而不只是告知。 八个可能移除内容的工具——三个删除工具、
delete_bookmark、remove_books_from_collection、remove_items_from_playlist,以及在被要求重新排序时会替换成无法还原的顺序的update_collection/update_playlist——会通过 MCP elicitation 弹出真实对话框, 模型无法代替用户作答。模型可以在第一次尝试时就设置一个普通的confirm: true标志, 或者被来自资料库的文本诱导设置该标志。如果客户端无法显示对话框,则会改用一次性令牌,该令牌绑定到确切的目标,并在五分钟后过期。 这种备用方案只能证明使用相同参数调用了两次,仅此而已;提示文本会如实说明这一点, 不会暗示有人已批准。
ELICITATION=false会主动选择这种方案,但绝不会移除保护措施。请参阅 征求用户确认。 -
确认提示绝不引用 API 内容。 合集和播放列表名称由用户提供,且会被模型读取,因此提示中只会显示 ID 和数量。
-
返回的 200 响应不是 JSON 时会报错。 将响应正文作为字符串返回,会让实例前的 SSO 门户或强制门户代理看起来像是空资料库,而不是请求失败。
-
不可信内容会标记出来。 书籍描述来自元数据提供方,播客摘要来自 RSS 源——它们均由第三方编写。所有包含这类内容的结果都会标记为数据,而非指令。
-
读取配置后,API 密钥会从环境中删除,因此子进程和
/proc/<pid>/environ中都不可见。 -
不会跟随重定向(
redirect: 'error'),因此Authorization标头不会被重放到其他主机;每个请求都有 15 秒超时。 -
ID 在进入 URL 路径前会经过验证。
-
上游错误正文会经过清理:HTML 错误页面会被丢弃,其他内容会截断至 2000 个字符。
-
进度更新只会发送列入允许列表的字段。 Audiobookshelf 端点会将请求负载整体应用到进度记录。
-
此服务按设计无法执行的操作:不提供用户管理、服务器设置、备份、清除缓存、浏览文件系统、删除资料库或项目、重写元数据或上传文件的功能。
有一点需要注意,这是 Audiobookshelf 本身的行为:移除播放列表中的_最后一个_条目会删除该播放列表。发生这种情况时,remove_items_from_playlist 会在结果中说明。
文档
完整指南、工具参考和安全说明请见
audiobookshelf-mcp.ni-c.de(源码位于 docs/)。
开发
npm install
npm run lint # oxlint + prettier --check
npm run build # tsc
npm test # vitest
npm run test:coverage # with thresholds
npm run docs:tools # regenerate docs/reference/tools.md from the registered tools
上表由人工整理;完整的 工具参考包含所有参数,由代码生成;如果已提交的副本不是最新版本,CI 会失败。 请参阅 CONTRIBUTING.md,了解如何创建一个可安全写入的一次性 Audiobookshelf 实例——写入工具会使用 API 密钥所属用户的身份更改进度和书签,因此请勿针对你在意的资料库进行开发。
工具定义根据 Audiobookshelf 服务器源码(server/routers/ApiRouter.js 和控制器)整理,而非来自
api.audiobookshelf.org;后者有多处内容已过时——筛选数据端点是 /filterdata,而非 /filter;
进度更新使用 PATCH /api/me/progress/:id,而非 POST /api/me/progress;书签位于 /api/me/item/:id/bookmark 下。
发布
由标签驱动,无需手动发布:
- 将
[Unreleased]条目移入CHANGELOG.md中新建的## [x.y.z] - YYYY-MM-DD部分,并更新package.json中的版本。 npm run lint && npm run build && npm run test:coverage。- 提交,然后创建一个签名的附注标签:
git tag -s vx.y.z -m "vx.y.z"。 git push origin main vx.y.z。
随后,release.yml 会运行测试,通过 Trusted Publishing 将包发布到 npm(无需令牌密钥),根据 CHANGELOG 部分创建 GitHub 发布,并将其发布到
MCP 注册表,名称为
io.github.ni-c/audiobookshelf-mcp。ci.yml 会在同一标签上将多架构镜像推送到 GHCR。
如果注册表步骤失败,请在 main 上修复问题,然后手动触发
Publish to MCP Registry 工作流——不要重新运行标签任务,否则它会检出旧代码树。
贡献
欢迎提交问题、参与讨论和发起拉取请求——请参阅 CONTRIBUTING.md。如需报告漏洞,请使用 私密报告渠道, 不要公开提交问题;相关政策见 SECURITY.md。
许可证
MIT © Willi Thiel
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。