MCP URI 与工具参考
本页是 Kabegame 本地 MCP 服务器的完整接口参考,面向插件作者与 MCP Host 集成方。如果你只想知道怎么在 Claude Desktop / Cursor 里用上这个服务,先看 MCP 服务;如果你要走 stdio 通道,见 安装 MCP Bundle。
端点与连接
| 项 | 值 |
|---|---|
| URL | http://127.0.0.1:7490/mcp |
| 端口 | 默认 7490,可在设置中修改 |
| 绑定 | 默认 127.0.0.1;可允许局域网访问并改绑 0.0.0.0(无鉴权) |
| Transport | StreamableHTTP(rmcp 3.0,LocalSessionManager) |
| 启动时机 | 默认关闭;在「设置 → 高级 → Web 服务器」开启后启动(仅桌面) |
| 平台 | Windows / macOS / Linux(仅桌面),Android 不暴露 MCP |
Web 服务器只接受 curl、脚本、MCP Host 等非网页客户端。所有带 Origin 或
Sec-Fetch-* 浏览器特征头的请求都会返回 403,且响应不包含任何 Access-Control-* 头;因此不能从
网页的 fetch、EventSource、图片标签、表单或地址栏访问这些端点。
设置页提供两个可点击复制的地址:
- 服务器地址(
http://<主机>:<端口>):粘贴到「Kabegame 服务器」插件的「服务器地址」,让另一个 Kabegame 的爬虫从这里复制图片。开启局域网访问时自动显示本机局域网 IP;探测不到时仍显示127.0.0.1,需手动替换。 - MCP 地址(
http://127.0.0.1:<端口>/mcp):给本机的 MCP 客户端使用。局域网内的 MCP 客户端可把主机换成局域网 IP。
MCP、JSON-RPC 与事件订阅共用同一端口。
JSON-RPC 与事件订阅
应用 Web 服务器同时提供 web 版同款接口:
| 端点 | 用途 |
|---|---|
POST /rpc | JSON-RPC 2.0;默认只读,写方法需在 URL 添加 ?super=1 |
GET /events | SSE 事件流;连接后先收到 connected |
GET /file?path=... | 读取图库中已登记的本地文件 |
GET /thumbnail?path=... | 读取图库缩略图 |
GET /compatible?path=... | 读取兼容格式 |
GET /download/<path> | 以下载响应读取图库文件 |
GET /__ping | 返回 ok 的存活探测 |
桌面服务不提供 /proxy。下面是只读 RPC 调用示例:
curl -X POST http://127.0.0.1:7490/rpc \ -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"get_albums"}'?super=1 只是允许调用写方法的客户端声明,并不是密码或鉴权机制。非 super 响应还会清洗插件配置中的
httpHeaders。事件订阅可用 curl -N http://127.0.0.1:7490/events 调试。
Server instructions
连接后,服务器会在 MCP 握手的 instructions 字段里返回一份 cheat sheet:包含 URI 速查、字段清单、plugin:// 瘦身提示,以及「不支持删除」的说明。Host 侧可以把它直接作为系统提示的一部分。
发现流程与 PathQL 路径文法
Kabegame 的图片资源是一棵懒加载树:list_resources 只列出少量预置入口,不会展开完整画廊。模型应使用 list_pathql_entry 每次枚举一层,读取当前节点和子节点的 note,而不是猜测路径段、插件 id 或图片 id。
标准的三步发现循环是:
- 调用
list_pathql_entry({ "path": "images://gallery" }),从返回的 22 个维度及其note中选择入口。 - 对选中的
child.path继续调用list_pathql_entry,例如枚举images://gallery/plugin下已安装的插件。大型子节点列表用offset/limit翻页。 - 原样复制返回的、已 percent-encode 的
child.path;集合叶子补上/_kb_desc/_kb_x100x/1等显式分页后交给resources/read。不要再次编码,也不要对分页节点调用发现工具。
例如,插件维度的完整路径可以从 images://gallery → images://gallery/plugin → 返回的插件 child 逐层得到,最后读取:
images://gallery/plugin/<pluginId>/_kb_desc/_kb_x100x/1画廊维度速查
list_pathql_entry("images://gallery") 当前返回 22 个可枚举维度:
| 类别 | 路径段 |
|---|---|
| 常用集合 | all、wallpaper-order、no-album |
| 过滤维度 | name、plugin、task、surf、media-type、date、album、size、aspect |
| 路径控制 | hide、search、sort |
| 精确查询 | by_id、by_path、by_compatible_path、by_thumbnail_path、by_url、by_hash、bigger_crawler_time |
list_pathql_entry("images://gallery/sort") 返回 7 个排序键:by-id、by-time、by-size、by-name、by-aspect、by-set-time、by-album-order。
组合规则
- 每个路径段都会继续收窄前一个节点,沿路径累积的过滤条件按 AND 组合;路径大小写敏感。
_kb_fc用于在已有过滤之后再组合一个维度,例如images://gallery/plugin/patreon/_kb_fc/media-type/image/_kb_desc/_kb_x100x/1。aspect可列举应用内置的五个桶,也可直接写任意宽高比区间段:-3x4(≤ 3:4)、3x4-4x3、4x3-16x9、16x9-(大于 16:9)、unknown(尺寸缺失)。比值为正整数<宽>x<高>,区间左开右闭,例如images://gallery/aspect/16x9-7x3/_kb_x100x/1。sort是all的兄弟节点,不是子节点。正确写法是gallery/sort/<key>/...,不要写成gallery/all/sort/...。/_kb_desc反转当前排序方向;默认画廊顺序为crawledAt升序,因此/_kb_desc表示最新在前。_kb_fc、_kb_desc与_kb_x<N>x由_kb_全局前缀表提供,不是 provider 的可枚举 child, 因此list_pathql_entry看不到这些段;请按节点note显式追加。hide是排除隐藏图片的前缀。gallery/hide/all/...有效,gallery/all/hide/...无效。- 对未列出的后续语法,继续发现当前节点并读取
note,不要自行发明路径。
五类 URI scheme 一览
| Scheme | 路径形态 | Entry / List | 支持 ?without= | 返回 | MIME | since 版本 |
|---|---|---|---|---|---|---|
images:// | id_{id} / id_{id}/metadata / gallery/... / x{N}x/{page} | 两者 | — | ImageInfo / metadata JSON / Vec<ImageInfo> | application/json | — |
albums:// | all / id_{id} | 两者 | — | Vec<Album> 或 Album | application/json | — |
tasks:// | all / id_{id} | 两者 | — | Vec<TaskInfo> 或 TaskInfo | application/json | — |
surf_records:// | all / id_{id} | 两者 | — | Vec<SurfRecord> 或 SurfRecord | application/json | — |
plugin:// | “ / {id} / {id}/icon / {id}/description_template / {id}/doc / {id}/changelog / {id}/asset/{path} | 两者 + 子资源 | — | 瘦身的 Plugin / 二进制 / 文本 | 多种 | — |
images://
图片与 metadata
| 形态 | 返回 | MIME | since 版本 |
|---|---|---|---|
images://id_{id} | 完整 ImageInfo(含 metadataId) | application/json | — |
images://id_{id}/metadata | 爬取时 metadata(tags、作者、URL 等,可能数十 KB) | application/json | — |
图片缺失返回 resource_not_found;metadata 行缺失返回 metadata_not_found。
画廊路径示例
| 路径 | 含义 |
|---|---|
images://gallery/all/_kb_desc/_kb_x100x/1 | 所有图片第 1 页,最新在前,每页 100 张 |
images://gallery/album/{albumId}/_kb_x100x/1 | 指定画册第 1 页 |
images://gallery/album/{albumId}/_kb_desc/_kb_x100x/1 | 指定画册第 1 页,最新在前 |
images://gallery/date/2024y/03m/_kb_desc/_kb_x100x/1 | 2024-03 爬取图片第 1 页,最新在前 |
images://gallery/media-type/image/_kb_x100x/1 | 仅图片媒体类型,第 1 页 |
images://gallery/wallpaper-order/_kb_x100x/1 | 壁纸历史第 1 页 |
images://x100x/1 | 原始 images 表第 1 页 |
images://gallery/... 直接返回 Vec<ImageInfo>;不再返回旧 provider:// 的 Dir / Image 混合 entries 结构,也不支持 ?without=。
ImageInfo 字段(camelCase)
id、url、localPath、pluginId、taskId、surfRecordId、crawledAt(unix 秒)、metadataId、pluginVersion、thumbnailPath、favorite、isHidden、localExists、hash、width、height、displayName、type、lastSetWallpaperAt、size(字节)、albumOrder、compatiblePath、postUrl。
type 是入库前经 normalize_stored_media_type 归一化的存储格式 key,例如 image/jpg、video/mp4;只有历史空值才回落为 image。序列化 key 是 type,不是 mediaType。
albums://
| 形态 | 返回 | since 版本 |
|---|---|---|
albums://all | Vec<Album>(全部画册) | — |
albums://id_{id} | 单个 Album,缺失返回 resource_not_found | — |
tasks://
| 形态 | 返回 | since 版本 |
|---|---|---|
tasks://all | Vec<TaskInfo>(全部任务) | — |
tasks://id_{id} | 单个 TaskInfo,缺失返回 resource_not_found | — |
surf_records://
| 形态 | 返回 | since 版本 |
|---|---|---|
surf_records://all | Vec<SurfRecord>(全部记录) | — |
surf_records://id_{id} | 单个 SurfRecord,缺失返回 resource_not_found | — |
plugin://
| 形态 | 返回 | MIME | since 版本 |
|---|---|---|---|
plugin:// | Vec<Plugin>,瘦身 | application/json | — |
plugin://{id} | 单个瘦身 Plugin | application/json | — |
plugin://{id}/icon | Base64 图标 PNG | image/png | — |
plugin://{id}/description_template | EJS 描述模板 | text/plain | — |
plugin://{id}/doc | 默认语言的 doc.md | text/markdown | — |
plugin://{id}/changelog | 默认语言的 CHANGELOG.md | text/markdown | — |
plugin://{id}/asset/{path} | kbAssets 声明的单个插件资源 | 按扩展推断(见下) | — |
asset 的 MIME 推断:.png → image/png,.jpg / .jpeg → image/jpeg,.webp → image/webp,.svg → image/svg+xml,.gif → image/gif,其它回落到 application/octet-stream。路径是 kbAssets 中归一化后的插件根相对路径,文档与更新日志共用这些资源。
「瘦身」指剥离了 assets、iconPngBase64、descriptionTemplate 三个重字段;这些内容要通过上面的子路径单独拉取。
通用分页规则
- 页码从 1 开始。
page 0是非法值,一律视为错误。 - 画廊页大小段匹配
_kb_x([1-9][0-9]*)x,接受任意N ≥ 1,例如_kb_x25x、_kb_x100x、_kb_x1200x; 「只写页号默认 100」的简写已取消。原始images://表仍使用x<N>x/<page>。 - 第 N 页从
(N - 1) * page_size处开始。 - 不是
id_*单图、且末两段未匹配画廊_kb_x<N>x/<数字>(或原始根x<N>x/<数字>)的images://集合会先执行 COUNT;总数超过 500 时返回pagination_required。
预置资源(list_resources)
服务器预先声明六条可列举的资源,方便 Host 在 UI 里直接展示:
| URI | 名称 | 说明 |
|---|---|---|
images://gallery/all/_kb_desc/_kb_x100x/1 | Gallery images (first page) | 画廊最新 100 条 |
images://x100x/1 | Raw image rows | 原始 images 表第 1 页 |
albums://all | All albums | Vec<Album> |
tasks://all | All tasks | Vec<TaskInfo> |
surf_records://all | All surf records | Vec<SurfRecord> |
plugin:// | All plugins (trimmed) | 瘦身列表 |
资源模板(list_resource_templates)
共十六条模板,供 Host 动态拼接:
images://id_{imageId}、images://id_{imageId}/metadataimages://gallery/plugin/{pluginId}/_kb_desc/_kb_x100x/{page}images://gallery/album/{albumId}/_kb_desc/_kb_x100x/{page}images://gallery/date/{year}y/{month}m/{day}d/_kb_desc/_kb_x100x/{page}images://gallery/search/display-name/{query}/all/_kb_desc/_kb_x100x/{page}images://gallery/by_id/{imageId}albums://id_{albumId}、tasks://id_{taskId}、surf_records://id_{surfRecordId}plugin://{pluginId}、plugin://{pluginId}/doc、plugin://{pluginId}/changelog、plugin://{pluginId}/icon、plugin://{pluginId}/description_template、plugin://{pluginId}/asset/{assetPath}
新增的 5 条 gallery 模板都复用 images.read.gallery capability id。
能力开关(资源/工具过滤)
「设置 → MCP」可以按「大类 → 读/写 → 具体资源/工具」勾选要暴露的 MCP 能力。大类包括 images、albums、tasks、surf_records、plugin;能力 id 形如 images.read.gallery、albums.write.create_album。
被禁用的能力会在协议层过滤:
list_resources不再列出被禁用的预置资源。list_resource_templates不再列出被禁用的资源模板。list_tools不再列出被禁用的工具。read_resource读取被禁用资源时返回resource_disabled。call_tool调用被禁用工具时返回tool_disabled。
当 URI 能精确映射 capability id 时,按该 id 判定。若 read_capability_id 返回 None,现在只有在同 scheme 下仍有至少一个 read capability 开启时才放行:因此关闭全部 images read 后,images:// 裸根也会返回 resource_disabled;fail-images:// 等未注册 scheme 会直接拒绝。list_pathql_entry 复用同一判定,没有新增 capability。
读工具 list_pathql_entry
Rust MCP 服务器共暴露 5 个工具:1 个只读发现工具和 4 个写工具。list_pathql_entry 每次列出 PathQL 懒树的一层;不含 :// 的 path 会提升为 images://。
输入 schema:
{ "type": "object", "properties": { "path": { "type": "string", "description": "PathQL URI. Paths without :// are promoted to images://." }, "include_counts": { "type": "boolean", "default": false }, "offset": { "type": "integer", "minimum": 0, "default": 0 }, "limit": { "type": "integer", "minimum": 0, "maximum": 200, "default": 100 } }, "required": ["path"]}limit > 200 不会被截断,而是返回 limit_exceeded。include_counts 只有在本次返回窗口不超过 50 个 child 时才生效,以避免对每个子节点扇出昂贵的 COUNT;实际是否执行会反映在 countsIncluded。
返回结构:
| 字段 | 含义 |
|---|---|
path | 规范化后的 PathQL URI |
total | 当前路径的 COUNT;COUNT 失败时为 null |
note | 当前 provider 的可读说明 |
children[] | 当前分页窗口内的子节点 |
childCount | 当前节点的全部直属 child 数量 |
offset / limit | 实际窗口参数 |
hasMore | 是否还有后续 child |
countsIncluded | 是否为本窗口执行了逐 child COUNT |
hint | 节点无 child 或请求到空窗口时出现的提示 |
每个 child 包含 name、path、note、meta、total。其中 path 已 percent-encode,可以直接交给 resources/read 或再次传给 list_pathql_entry,不要重新编码;total 只在 countsIncluded = true 且该 child COUNT 成功时有值。
鉴权直接复用 is_uri_capability_enabled:例如 images://gallery/... 受 images.read.gallery 控制;发现工具本身不新增 capability。常见错误包括:
| 错误码 | 条件 |
|---|---|
limit_exceeded | limit > 200,data 含 limit / maxLimit |
resource_disabled | 目标路径对应的 read capability 已关闭,或该 scheme 没有任何 read capability 开启 |
resource_not_found | PathQL 路径、provider 或 schema 不存在 |
invalid_params | 输入无法按 schema / 参数类型解析 |
internal_error | 其它 PathQL 或后台任务错误 |
写工具(Rust MCP 服务器)
Rust 端通过 HTTP transport 暴露四个写入工具。Stdio Bundle 会透传这四个非删除写工具,并额外提供资源读取包装,详见下一节。
set_album_images_order
为画册设置手动显示顺序。每次调用最多 100 张;更大的画册需要多次调用。
输入 schema:
{ "album_id": "string", "image_orders": [ { "image_id": "string", "order": 0 } ]}效果:调用 Storage::update_album_images_order,写入 album_images 表的 order 字段。
副作用:手动顺序不会立即出现在画廊中——用户必须在画册里把排序模式切到「加入顺序」才看得到新排列。响应文本会提醒模型这一点。
create_album
创建画册,可选挂在 parent_id 下作为子画册。
输入 schema:
{ "name": "string", "parent_id": "string | null"}效果:调用 Storage::add_album,返回新建的 Album JSON。
add_images_to_album
把图片加入画册。重复图片被静默跳过。可同步指定每张的 order;未指定则自动追加在当前最后一张之后。
输入 schema:
{ "album_id": "string", "image_ids": ["string"], "image_orders": [ { "image_id": "string", "order": 0 } ]}效果:调用 Storage::add_images_to_album,若提供了 image_orders 则再调 update_album_images_order。响应文本形如 "Added X/Y images to album 'id'."。
副作用:画册图片列表变化会通过 album-images-change 事件广播;已打开的画册画廊视图会实时刷新。
rename_image
修改图片的显示名。
输入 schema:
{ "image_id": "string", "display_name": "string"}效果:调用 Storage::update_image_display_name。
副作用:先通过 image-changed 即时更新图片的可见名,再通过 images-change 让已打开的画廊视图对账排序与成员。
MCPB stdio 桥(kabegame-gallery-node)
当 Host 只支持 stdio 时(例如 Claude Desktop),需要 MCPB 桥把调用转发到上面的 HTTP 端点。桥本身是一层带强校验的防御性子集,暴露范围比 Rust 服务器窄。
运行环境
| 项 | 值 |
|---|---|
| 平台 | darwin / win32 / linux |
| Node.js | >= 18.0.0 |
| MCP SDK | @modelcontextprotocol/sdk ^1.18.0 |
user_config
| 键 | 类型 | 默认 | 约束 |
|---|---|---|---|
kabegame_mcp_endpoint | string | http://127.0.0.1:7490/mcp | 仅回环(127.0.0.1 / localhost / ::1) |
request_timeout_ms | number | 12000 | 1000–60000,越界自动 clamp |
debug_logging | boolean | false | — |
桥暴露的工具
所有工具响应都包在 { ok, data } 或 { ok: false, code, message, details } 里。错误码包括:INVALID_ARGUMENT、UPSTREAM_MCP_ERROR、TIMEOUT、UPSTREAM_REQUEST_FAILED、UNKNOWN_TOOL、UNEXPECTED_ERROR。
list_pathql_entry
输入 schema、返回结构和限制与 Rust 服务器的同名工具一致。桥通过 SDK 的 client.callTool 原样转发参数;当上游关闭全部 images read capability 时,桥的能力过滤也不再暴露该工具。
read_gallery_provider
输入 schema:
{ "path": "string" }校验:非空;不能包含 ..;不能以 / 开头;长度 ≤ 512。
转发:resources/read,uri = "images://" + path;如果 path 没有 scheme 且不是 gallery/、vd/、id_ 或 x{N}x/... 开头,会自动映射到 images://gallery/{path}。
read_image
输入 schema:
{ "image_id": "string" }校验:非空,长度 ≤ 256。
转发:resources/read,uri = "images://id_{image_id}"。
read_image_metadata
输入 schema:
{ "image_id": "string" }校验:非空,长度 ≤ 256。
转发:resources/read,uri = "images://id_{image_id}/metadata"。
read_album
省略 album_id 时转发 albums://all;提供 album_id 时转发 albums://id_{album_id}。
read_task
省略 task_id 时转发 tasks://all;提供 task_id 时转发 tasks://id_{task_id}。
read_surf
省略 surf_record_id 时转发 surf_records://all;提供 surf_record_id 时转发 surf_records://id_{surf_record_id}。旧的 host 直查不再支持。
read_plugin
省略 plugin_id 时转发 plugin://;提供 plugin_id 时默认转发 plugin://{plugin_id}。resource 可取 icon、description_template、doc、changelog、asset,其中 asset 需要 key。
set_album_images_order
与 Rust 工具同名同形,但在 schema 层显式声明 maxItems: 100。
输入 schema:
{ "album_id": "string", "image_orders": [ { "image_id": "string", "order": 0 } ]}校验:album_id 非空;image_orders 长度在 1–100 之间;每项需非空 image_id 与整数 order。
桥未暴露的能力
MCPB 暴露 list_pathql_entry、和 HTTP MCP 同名的四个写工具,并额外提供上面的资源读取包装。它仍保持以下限制:
- endpoint 只能指向本机回环地址。
read_gallery_provider只读取images://资源,不支持旧provider://的?without=images结构目录模式。set_album_images_order单次最多 100 张,add_images_to_album单次最多 1000 张。
若 Host 支持 HTTP transport(例如 Cursor),也可以直接连 http://127.0.0.1:7490/mcp,跳过 stdio 桥。
版本兼容性矩阵
| 能力 | 首次出现版本 |
|---|---|
images:// + 复数表 scheme 布局 | — |
list_pathql_entry | — |
set_album_images_order | — |
create_album | — |
add_images_to_album | — |
rename_image | — |
| MCPB stdio 桥 | — |
边界与错误
协议错误速查
| 错误码 | 条件与 data |
|---|---|
pagination_required | 未显式分页的 images 集合超过 500 行;data 含 { uri, total, maxRows, howTo } |
limit_exceeded | list_pathql_entry.limit > 200;data 含 { limit, maxLimit } |
resource_disabled | 精确 read capability 已关闭,或 URI 无精确映射且同 scheme 没有任何 read capability 开启 |
tool_disabled | 对应写工具 capability 已关闭 |
resource_not_found | PathQL 路径或目标资源不存在 |
- 页码 0 非法,永远从第 1 页开始。
- PathQL 页大小为任意
N ≥ 1:画廊语法是/_kb_x<N>x/<page>,原始images://根保持/x<N>x/<page>;这与画廊 UI 的页大小选项无关。 - 分页护栏检查末两段:纯数字搜索词不会被单独当成页号;画廊集合必须在完整搜索路径后追加
/_kb_x<N>x/<page>。 - 鉴权收紧:关闭某个 scheme 的全部 read capability 后,该 scheme 的裸根也会返回
resource_disabled;未注册 scheme 直接拒绝。 - 旧 scheme 不再支持:
provider://、image://、album://、task://、surf://没有兼容别名,会被 capability gate 以resource_disabled拒绝。 - 不要批量拉 plugin 重字段:
plugin://和plugin://{id}返回瘦身对象,图标、描述模板、文档与文档资源要按子路径单独读取。 - metadata 懒加载:图片列表结果只带
metadataId,只有images://id_{id}/metadata会返回完整 metadata。 surf_records://id_{id}以记录 id 为键,不是 host。- 不提供删除工具:MCP 没有 delete-image / delete-album。服务器 instructions 明确建议模型把想删的图片收集到一个「待删除」画册里,由用户最终确认。
set_album_images_order对用户不可见:手动顺序要等用户把画册排序切到「加入顺序」才会显示;响应文本会提醒这一点。set_album_images_order分页:单次最多 100 张,大画册需要多次调用。- Android 无 MCP:服务器仅在桌面启动。
- 无鉴权:MCP 绑定在
127.0.0.1,通过任何方式把7490暴露出去就等于开放读写。 - 端口冲突:MCP 端口默认
7490,可在「设置 → MCP」中修改。手动开启时如果端口被占用,服务开启失败并保持关闭,前端会提示原因;应用启动时如果已保存为开启状态但端口被占用,服务不会启动,并会自动将开关置为关闭。
延伸阅读
- MCP 服务 — Host 接入流程与日常使用。
- 安装 MCP Bundle — 在 Claude Desktop 等 stdio Host 上使用。
- 画廊 — PathQL 画廊路径与应用内浏览视图的对应关系。
- 插件使用 —
plugin://所对应的用户侧视图。