news 2026/9/12 2:49:49

Karakeep SDK 使用指南:用 TypeScript 客户端操作自托管书签 API

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Karakeep SDK 使用指南:用 TypeScript 客户端操作自托管书签 API

Karakeep SDK 使用指南:用 TypeScript 客户端操作自托管书签 API

【免费下载链接】hoarderA self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search项目地址: https://gitcode.com/GitHub_Trending/ho/hoarder

导读

Karakeep(原 Hoarder)是一款自托管"收藏一切"应用,支持链接、笔记和图片,并提供基于 AI 的自动标签与全文搜索。@karakeep/sdk是官方 TypeScript SDK,基于openapi-fetch与自动生成的 OpenAPI 类型封装 REST 接口,让你在几行代码内完成书签创建、检索、搜索、列表与标签管理等操作。读完本文,你将掌握 SDK 的安装方式、客户端初始化、典型增删改查与搜索调用,以及其版本策略与类型安全背后的实现原理。

一、SDK 是什么:从源码看它的真实构成

@karakeep/sdk包位于 packages/sdk,其核心入口 src/index.ts 只有短短十几行,却揭示了这个 SDK 的设计哲学——它不是一个臃肿的封装层,而是直接建立在openapi-fetch之上的薄封装:

import createClient from "openapi-fetch"; import type { components, paths } from "./karakeep-api.d.ts"; // @deprecated Use createKarakeepClient instead. export const createHoarderClient = createClient<paths>; export const createKarakeepClient = createClient<paths>; export type KarakeepAPISchemas = components["schemas"];

关键点解读:

  • 两个客户端工厂createKarakeepClient是推荐入口;createHoarderClient是历史遗留的旧名(源码中以@deprecated标注),仅用于向后兼容。
  • 类型即文档pathscomponents来自 src/karakeep-api.d.ts,该文件由openapi-typescript从服务端 OpenAPI 规范自动生成(文件头注释明确标注 "This file was auto-generated by openapi-typescript"),定义了全部端点路径、请求参数与响应 Schema。
  • 零手写请求逻辑:所有 HTTP 调用行为(fetch、请求/响应类型校验、错误处理)全部由openapi-fetch提供,SDK 本身只负责接入类型。

构建配置方面,vite.config.mts 将 SDK 打包为escjs双格式(index.mjs/index.js),并生成类型声明(vite-plugin-dts),同时把openapi-fetch声明为 external 依赖,避免重复打包。这也解释了为什么 SDK 的运行时依赖只有openapi-fetch一个(见 package.json)。

二、安装

SDK 以 npm 包形式发布,使用任意包管理器安装即可:

npm install @karakeep/sdk

提示:从 package.json 可以看到,main指向./src/index.ts(workspace 内直接使用源码),发布时则通过publishConfig指向构建产物./dist/index.js./dist/index.mjs./dist/index.d.ts,因此安装后同时支持 ESM 与 CommonJS 项目。

当前仓库中该包的版本为0.33.0(与 Karakeep 服务器次版本号一致,详见后文"版本策略")。

三、快速上手:创建客户端

SDK 使用 Bearer Token(API Key)进行认证。在 Karakeep 设置中生成 API Key 后,按如下方式初始化:

import { createKarakeepClient } from "@karakeep/sdk"; // Create a client const apiKey = "my-super-secret-key"; const addr = `https://karakeep.mydomain.com`; const client = createKarakeepClient({ baseUrl: `${addr}/api/v1/`, headers: { "Content-Type": "application/json", authorization: `Bearer ${apiKey}`, }, });

参数说明:

  • baseUrl:指向 Karakeep 服务器的 REST API 根路径,固定为https://<你的域名>/api/v1/。注意末尾的斜杠,SDK 会在此基础路径上拼接端点路径。
  • headers.authorization:必须携带Bearer <apiKey>前缀。服务端通过 packages/api/middlewares/auth.ts 校验 token,未认证请求会返回401 Unauthorized
  • Content-Type:声明请求体为 JSON。

此外,SDK 还导出类型KarakeepAPISchemas(即components["schemas"]),可以用于标注你自己的业务类型,例如:

import type { KarakeepAPISchemas } from "@karakeep/sdk"; type Bookmark = KarakeepAPISchemas["Bookmark"];

四、核心操作:创建与搜索书签

初始化客户端后,最典型的两个操作是"创建书签"与"搜索书签",这也是 README 中的官方示例。

4.1 创建一条书签

// Create a bookmark const { data: createdBookmark, response: createResponse, error: createError, } = await client.POST("/bookmarks", { body: { type: "text", title: "Search Test 1", text: "This is a test bookmark for search", }, }); console.log(createResponse.status, createdBookmark, createError);

从生成的 API 类型(karakeep-api.d.ts)看,POST /bookmarks支持三种书签类型,body.type决定内容结构:

类型必填字段说明
linkurl链接书签,若 URL 已存在会返回既有书签(HTTP 200 而非 201)
texttext文本/笔记书签,可选sourceUrl
assetassetTypeassetId图片或 PDF 书签,需先通过上传接口获得assetId

公共可选字段还包括titlenotesummaryarchivedfavouritedcreatedAtcrawlPriority"low"/"normal")、source"api"/"web"/"cli"/"mobile"/"extension"/"singlefile"/"rss"/"import")等。

返回值是三元组:data(成功时的响应体,类型为Bookmark)、response(原始 Response,可用response.status判断 200/201)、error(失败时的错误信息,通常为带codemessageErrorSchema)。

4.2 搜索书签

// Search for bookmarks const { data: searchResults, response: searchResponse, error: searchError, } = await client.GET("/bookmarks/search", { params: { query: { q: "test bookmark", }, }, }); console.log(searchResponse.status, searchResults, searchError);

GET /bookmarks/searchq参数支持全文搜索(覆盖标题、正文、描述与笔记),按相关性排序;Karakeep 的语义搜索与混合排序模式则仅支持相关性排序(详见 karakeep-api.d.ts 中的端点描述)。搜索语法本身可参考仓库文档 search-query-language.md。

五、进阶能力:分页、读取与标签管理

SDK 的类型定义覆盖了 API 的全量能力,这里列举几个高频场景:

5.1 分页列出书签

GET /bookmarks返回PaginatedBookmarks,包含bookmarks数组与nextCursor(为null表示没有下一页)。查询参数支持archivedfavourited过滤、sortOrder"asc"/"desc")、limitcursor游标分页;includeContent设为false可让响应更轻量(仅元数据,见 karakeep-api.d.ts)。

const page1 = await client.GET("/bookmarks", { params: { query: { limit: 50, sortOrder: "desc" } }, }); if (page1.data?.nextCursor) { const page2 = await client.GET("/bookmarks", { params: { query: { cursor: page1.data.nextCursor, limit: 50 } }, }); }

5.2 读取可读化内容

GET /bookmarks/{bookmarkId}/content返回分块(chunked)的 agent 可读内容:contentrange(起始/结束偏移与总字符数)、truncated标志,以及用于续读的nextCursor。链接书签内容来自提取的 HTML,文本与媒体书签则使用存储或提取的文本。对大书签可循环携带nextCursor完整拉取。

5.3 附加与移除标签

POST /bookmarks/{bookmarkId}/tags附加标签、DELETE /bookmarks/{bookmarkId}/tags移除标签,标签既可用id也可用name标识——按名称传入且标签不存在时会自动创建(见 karakeep-api.d.ts)。书签响应中的tags数组还带有attachedBy字段("ai"/"human"),用于区分 AI 自动标签与人工标签。

六、认证与权限:API Key 的作用域模型

SDK 示例使用的是 API Key(Bearer Token),其权限由服务端的作用域(scope)机制控制。从 packages/api/middlewares/apiKeyScopes.ts 的源码可以看到,服务端中间件会校验请求资源(ZApiKeyScopeResource)与操作(ZApiKeyScopeAccess)是否被 API Key 的作用域覆盖,不满足则返回403,错误信息形如API key is missing required scope: <scope>

这意味着:API Key 的权限是细粒度的,如果某个端点调用返回 403,请先检查该 Key 在 Karakeep 设置中是否被授予了相应资源/操作的 scope,而不是简单地认为 Key 无效。认证失败(401)与权限不足(403)在 SDK 的error返回中会以不同状态呈现,建议在业务代码中分别处理。

七、API 文档与版本策略

7.1 API 文档

SDK 的类型定义即 API 契约。仓库的 OpenAPI 规范与文档位于 packages/open-api/karakeep-openapi-spec.json,docs/docs/api 目录下还有按端点组织的 API 参考(如 create-bookmark.api.mdx、search-bookmarks.api.mdx、list-bookmarks.api.mdx 等),包含完整的请求/响应示例,可与 SDK 类型对照阅读。

7.2 版本策略

README 明确了两条版本约定,这也是使用 SDK 时最容易踩坑的地方:

  1. SDK 版本跟随服务器次版本:Karakeep 服务器0.21.0引入的新 API,会从 SDK 的0.21.0版本起可用。因此升级服务器时,也应同步升级 SDK 到相同或更高次版本,以免缺少新端点类型。
  2. 向后兼容承诺:Karakeep 尽力保持 API 向后兼容,因此较旧版本的 SDK 通常仍可配合新版服务器使用(旧版本可能缺少新增端点,但既有端点的调用不会破坏)。

当前仓库中 SDK 版本为0.33.0,与 packages/db 等模块的服务端版本体系保持一致。

八、总结:何时使用 SDK

@karakeep/sdk适合以下场景:

  • 编写脚本或工具批量导入/导出书签、标签、列表与高亮;
  • 在 Node.js 服务中集成 Karakeep,例如将收藏数据同步到内部系统;
  • 构建自定义客户端、CLI 或 Agent 工作流——SDK 暴露的createKarakeepClient让 REST 调用获得完整类型提示,几乎不可能拼错路径或请求体字段。

如果你的场景需要更粗粒度的能力,可以关注仓库中的 packages/cli(命令行工具)与 apps/mcp(MCP 服务器),它们同样基于这套 API;而 SDK 则是把 API 直接嵌入你自己代码的最轻量方式。所有端点的完整类型定义,都可以在 src/karakeep-api.d.ts 中查阅。

【免费下载链接】hoarderA self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search项目地址: https://gitcode.com/GitHub_Trending/ho/hoarder

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 2:49:34

使用Pydantic与JSON Schema高效验证JSONL数据

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 2:48:11

Mosquitto监控与日志管理实战:从$SYS主题到Prometheus告警

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 2:47:33

ESP32蓝牙Beacon测距实战:RSSI校准与滤波工程化实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 2:47:18

MQL5直连CTP柜台:桥接DLL设计、行情订阅与下单实战

简介&#xff1a;基于MQL5语言的MT5客户端直连期货公司CTP柜台程序化交易源码&#xff0c;覆盖行情接入、交易下单、持仓查询、风险控制与数据中心等模块&#xff0c;适合有一定编程基础的期货量化交易者用于搭建或改造自动化交易客户端。压缩包共60个文件&#xff0c;约29.1MB…

作者头像 李华
网站建设 2026/9/12 2:47:15

Apple Silicon Mac 安装 MySQL 完全指南(dmg 与 Homebrew 双教程)

先把话说明白&#xff1a;这是 M 芯片系列教程的第四篇。前面几篇我陆续写了 M1/M2/M3 环境下 Homebrew、Python、Git 这些基础开发的安装折腾过程&#xff0c;这一篇终于轮到数据库了。这个系列默认你手上是一台 Apple Silicon 的 MacBook&#xff0c;也就是 M1、M2、M3 或者 …

作者头像 李华
网站建设 2026/9/12 2:46:08

IntelliJ IDEA社区版:免费轻量Java开发IDE完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华