关于 Inkwell
Inkwell 是可自托管的 MCP 服务,为 AI Agent 提供跨会话和项目的持久记忆。它以 Markdown 文件为事实源,通过混合搜索、类型化关系图和双时态版本保留可读历史。
主要功能
- 01Markdown 文件作为事实源
- 02BM25 与本地嵌入混合搜索
- 03类型化关系图与反向链接
- 04条目类型校验
- 05双时态版本记录
- 06stdio、SSE 和 HTTP 传输
适用场景
- 01跨会话检索项目决策
- 02记录故障原因和解决步骤
- 03追踪知识条目的变更历史
MCP 相关
MCP 服务通过 remember、recall、search、list、tags、forget、rebuild 和 doctor 等工具提供知识库操作,并支持 stdio、SSE 和 streamable-http 传输。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
docker run -i --rm -e INKWELL_DATA_PATH -e INKWELL_ENABLE_DASHBOARD docker.io/foreigndmitryi/inkwell-memory:0.14.0INKWELL_DATA_PATHKnowledge base root inside the container; matches the volume mount targetINKWELL_ENABLE_DASHBOARDSet to 0 to skip the web dashboard process and run the MCP server only本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Inkwell — 持久化知识库 MCP 服务
Inkwell 是一个可自托管的 Model Context Protocol 服务,为 AI Agent 提供跨会话、跨项目的持久记忆。它有三点与其他记忆服务不同:纯 Markdown 文件是事实来源(索引只是可随时删除并重建的临时缓存);条目通过带类型的 kb:// 图谱连接,而不是堆成一叠扁平文件;更新采用双时态机制——替换某条事实时,旧版本仍可读取,而不会被覆盖。
Docker Hub: foreigndmitryi/inkwell-memory · 网站: veronchenko.github.io/inkwell-memory
原名为 Engram。 在 0.14.0 版本中更名——有十几个互不相关的项目都叫“Engram”,这个名称已经很难搜索到。本项目与它们以及 Engram 键盘布局都没有关联。更名带来的影响,请参阅变更日志。
目录
概念
Agent 对话结束时,上下文也随之消失。Inkwell 则能留存下来:它是一个知识库,Agent 会在采取行动之前搜索它,并在解决不显而易见的问题之后将信息写入其中。这样,无论下一次会话是在同一项目还是另一个项目中,都能基于已有经验开始,而不必重新推导。
它刻意不存储任何可发现的信息。如果某条事实可以从代码、git 历史、配置文件或现有文档中获取,就不应放进 Inkwell——这类信息可以通过 grep 或重新阅读来获取。适合存入的是对话中容易丢失的知识:某项决策及其排除的替代方案、某个 bug 的根本原因及修复方法、经过摸索才学会的流程,或只说明过一次、但之后一直适用的偏好。
有两点能确保知识库在不断增长时仍然易用:
- 原子性——一条目、一事实。遇到 Markdown 标题、超过 3 个段落或内容超过 512 B/1 KB 时,
remember会发出非阻塞警告,促使用户将包含多项事实的内容拆分为彼此链接的独立条目,而不是塞进一大段搜索难以排出高位的文本。 - 图谱,而非堆叠——条目通过
kb://uuid#type引用相互链接,因此相关事实(一个核心项目、它的功能,以及与其中一项功能相关的诊断信息)可以双向导航,而不是孤立地存放在各行中。
功能
- 混合搜索 — 将 SQLite FTS5(BM25、Porter 词干提取)与本地 Model2Vec 嵌入上的余弦相似度,以及通过倒数排名融合(RRF)结合的、基于标题/标签的 IDF 加权精确匹配通道融合;既能按含义查找条目,也能按字面专有名词查找——对于后者,BM25/嵌入单独使用时可能会被词汇相似的干扰项稀释;完全不依赖云服务
- 带类型的图关系 — 条目之间通过
kb://uuid#type链接;每次recall时都会解析两个方向(出链 + 反向链接),还可选择再跳一层(hops=2),查看两个条目如何通过中间条目关联 - 由架构约束的条目类型 —
hub、decision、diagnostic、feature、procedure、integration、pattern、snippet、preference、idea;在schema.json中声明并以枚举形式提供给客户端,因此无法写入无效类型;可在搜索/列表中筛选 doctor完整性检查 — 根据架构对 Markdown 文件执行统一检查,查找失效和已被取代的链接、未声明类型、缺失的模板字段、超级节点,以及标签/类型冲突part_of结构性归属 — 将详细条目(decision、diagnostic、feature、procedure、integration等)链接到其中心条目;架构会按类型强制执行此规则;可在search/list中筛选,并与kb://反向链接一起分组显示在中心条目的recall摘要中- 双时态版本管理 —
remember(..., supersede=True)会创建新版本,而不是覆盖;旧版本会保留在历史记录中(include_superseded=True),不会丢失 - 重复项检测和链接建议 —
remember会匹配标题近似的条目以避免重复,并返回suggested_links(基于嵌入相似度的匹配项),让相关事实相互交叉引用,而非成为孤立条目 - 原子性防护 — 对结构性反模式(标题、超过 3 个段落、内容过长)发出非阻塞警告,确保知识库在扩展时仍保持每个条目只包含一项事实
- Web 仪表板 — 提供力导向图视图、混合搜索,以及用于管理与 MCP 工具相同知识库的 CRUD 面板(参见仪表板)
- 三种传输方式 — stdio(由 Agent 管理)、SSE、streamable-http;同一服务既可供单个本地 Agent 使用,也可用于共享的多 Agent 部署
- 以 Markdown 为唯一事实来源 — SQLite 索引是可重建的缓存;删除后执行
rebuild即可,数据永远不会丢失
对比
| Inkwell | Mem0 | Zep / Graphiti | LangMem | |
|---|---|---|---|---|
| 事实来源 | 磁盘上的 Markdown 文件 | 向量数据库 / 托管 API | 时序知识图谱 | 向量存储(基于 LangChain) |
| 搜索 | BM25 + 本地 Model2Vec 嵌入(RRF 融合) | 向量相似度 | 图遍历 + 嵌入 | 向量相似度 |
| 关系 | 显式的 kb://uuid#type 链接,由 Agent 编写 | 隐式(通过 LLM 提取事实) | 自动提取的时序图边 | 无内置支持 |
| 时态模型 | 写入时使用双时态 valid_at/supersede | 覆盖事实 | 原生时序图(双时态边) | 无内置支持 |
| 部署 | 可自托管,单个 Docker 镜像,无云服务依赖 | 托管 API 或自托管 + 向量数据库 | 可自托管,需要 Neo4j | 库,无服务 |
| 设计重点 | 刻意保持极简——不主动暴露任何信息,由 Agent 决定哪些内容值得保留 | 从对话中自动提取事实 | 自动提取实体/关系 | 为 LangGraph Agent 提供可组合的记忆原语 |
Inkwell 以自动提取(Mem0、Zep)换取由 Agent 精选、原子化且显式链接的知识库——没有由 LLM 驱动的摄取流水线,不依赖图数据库,磁盘上的 Markdown 也始终便于人阅读和查看差异。
与纯 Markdown Wiki 的对比
我们将 Inkwell 与打包成普通 Markdown wiki 的同一知识库进行了基准测试——每个主题一个文件,按项目和类别(决策、诊断、功能、流程……)分文件夹组织,每个项目都有一个索引页,相关页面之间互相链接,并通过 Read/Grep/Glob/Bash 浏览。内容相同,查找方式不同——在事实覆盖率相当的情况下,Inkwell 的 search/recall 使用情况如下:
| Inkwell | Wiki | 改进 | |
|---|---|---|---|
| 工具调用次数 | 104 | 186 | -44% |
| 总令牌数 | 3.87M | 5.91M | -35% |
| 成本 | $1.31 | $1.62 | -19% |
| 总耗时 | 577s | 760s | -24% |
| 事实率 | 1.000 | 0.964 | +3.7% |
针对 5,070 条条目提出了 32 个问题(单跳、多跳、否定、跨语言、替代)——涵盖 4 个虚构项目中的 70 条精选事实,以及 5,000 条真实文本干扰条目,因此检索必须能在超出 Agent 上下文容量的规模下正常工作:
wiki/
├── Ledgerbird/ )
├── Pipewren/ ) 4 curated projects — 70 real
├── Snipfox/ ) decisions/diagnostics/features/
├── Featherstore/ ) procedures/integrations/snippets
│ ├── README.md <- project index page, links to every entry below
│ ├── decision/
│ │ ├── offline-engine-duckdb-over-spark.md
│ │ ├── online-value-serialization-msgpack.md
│ │ └── ... (2 more)
│ ├── diagnostic/
│ │ ├── redis-memory-doubling-from-ttl-less-deprecated-feature-groups.md
│ │ └── training-serving-skew-from-tz-naive-event-timestamps.md
│ ├── feature/ (4 entries)
│ ├── integration/ (2 entries)
│ ├── procedure/ (1 entry)
│ └── snippet/ (1 entry)
├── _shared/ cross-project patterns & preferences
└── haystack-project-00000.../00199/ 200 distractor projects x 25 pages
│ = 5,000 real-text (Wikipedia) pages
├── README.md <- same index-page shape as a real project
├── decision/ (2 entries)
├── feature/ (3 entries)
├── idea/ (7 entries)
├── pattern/ (4 entries)
├── procedure/ (1 entry)
└── snippet/ (2 entries)
每个类别文件夹都是由单条目文件组成的平铺列表,每个项目文件夹(无论是真实项目还是干扰项目)都有自己的 README.md 索引页,链接到所有条目——两者在结构上完全相同,因此 wiki 测试组无法仅凭结构区分精选事实与干扰项。
已经知道在哪里查找的 Agent,不必一路 grep、重新读取再 grep——在事实覆盖率相当的情况下,效率优势依然成立。检索排序也在持续改进:添加 IDF 加权精确匹配通道(见下文)后,MRR 从 0.851 提升到 0.857,recall@5 从 0.851 提升到 0.869,且所有语言均未出现性能回退。
设计模式
- 倒数排名融合 — 分别计算 BM25 和嵌入排名,再按排名位置而非原始分数合并,从而避免对不可比的相似度指标进行归一化。
- 基于事实来源构建的可重建缓存 — SQLite 索引完全由 Markdown 文件派生(
rebuild会从头重新生成索引);数据库绝不会是事实的唯一副本。 - 双时态版本控制 —
supersede会写入新条目,并通过superseded_by将旧条目指向新条目,而不是直接覆盖,因此仍可查询历史记录(include_superseded)。 - HATEOAS 风格的图遍历 — 每个
recall响应都携带自身的传入和传出kb://链接,因此遍历知识图谱时无需每跳单独查询。 - 共享领域层,双传输方式 — 仪表板的 REST API 和 MCP 工具都会调用相同的
KnowledgeBase/SQLiteBackend方法,因此无论通过哪种接口触发写入,都只有一条代码路径。
架构
Markdown files ---> Search index ---> MCP ---> Agent
(source of truth) (SQLite FTS5 + (server.py) (Claude Code,
Model2Vec, ChatGPT, ...)
rebuildable cache)
<data-path>/entries/ 中的 Markdown 文件是唯一真实数据源。SQLite 索引(search_backend.py)是由这些文件构建的临时缓存——使用 Reciprocal Rank Fusion 融合 BM25 与 Model2Vec 嵌入,并包含 kb:// 关系图——始终可以通过 rebuild 重新生成。server.py 将该索引作为 MCP 工具(remember/recall/search/...)提供给 Agent;仪表板则是在同一层提供的另一种入口,通过 REST 而非 MCP 直接访问相同的 KnowledgeBase/索引,因此无论由 Agent 调用还是在浏览器中手动编辑,remember/delete 的行为都相同。
src/server.py— MCP 工具定义(remember、recall、search、list、tags、forget、rebuild、doctor),单个进程,支持 stdio/SSE/streamable-http 传输src/database.py—KnowledgeBase:Markdown + YAML frontmatter 增删改查、UUID 分配、重复项检测、双时态替代逻辑src/schema.json+src/schema.py— 以数据形式定义条目分类体系及各类型的规则,以及将其转换为 MCP 客户端据以校验的entry_type枚举的加载器src/doctor.py— 由架构驱动的完整性检查,同时供doctor工具、rebuild的警告和remember的一致性检查使用src/search_backend.py—SQLiteBackend:通过 Reciprocal Rank Fusion 融合 BM25(FTS5)与 Model2Vec 余弦相似度,并支持kb://关系提取/图遍历;嵌入在写入时按需计算,并以 BLOB 列存储src/dashboard/— 第二个可选进程(app.pyFastAPI REST +/api/graph、static/index.html原生 JavaScript 画布图、__main__.py独立的 uvicorn 入口点),复用相同的KnowledgeBaseplugins/inkwell-hooks/— 可同时安装到 Claude Code 和 Codex 的独立插件(.claude-plugin/plugin.json、SessionStart/Stop/SessionEnd+PreToolUse的先搜索再记忆门控,以及仅适用于 Claude Code 的inkwell-project-onboarderAgent);它通过机制强制执行先搜索、后记忆的工作流,而非仅依赖系统提示词;在仓库根目录的.claude-plugin/marketplace.json(Claude Code)和plugins/marketplace.json(Codex)中均以inkwell-hooks列出
在 Docker 中,MCP 服务和仪表板作为两个进程运行在同一个容器内(docker-entrypoint.sh),共享同一个 /knowledge 卷;任一进程退出时,容器都会退出。
快速开始
stdio
由你的 Agent 管理服务。推荐用于 Claude Code、ChatGPT Desktop、Cursor。
claude mcp add --transport stdio inkwell -- \
docker run -i --rm -v ./knowledge:/knowledge foreigndmitryi/inkwell-memory
SSE
在网络上运行的持久服务。可让多个 Agent 共享知识。
docker run -d --name inkwell \
-p 8192 \
-v ./knowledge:/knowledge \
foreigndmitryi/inkwell-memory --transport sse
docker port inkwell 8192 # host port Docker assigned
claude mcp add --transport sse inkwell http://your-host:<port>/sse
-p 8192(省略主机端口)会让 Docker 选择一个空闲的临时主机端口,而不是在固定端口(例如 8192)已被其他容器占用时失败——使用 docker port 查看实际分配的端口。如果需要固定主机端口,请改用 -p 8192:8192。
HTTP
无状态,可进行负载均衡。
docker run -d --name inkwell \
-p 8192 \
-v ./knowledge:/knowledge \
foreigndmitryi/inkwell-memory --transport streamable-http
docker port inkwell 8192 # host port Docker assigned
claude mcp add --transport http inkwell http://your-host:<port>/mcp
多租户
一个服务,多个团队,每个团队的数据文件夹和 API 密钥彼此隔离。设置 INKWELL_MULTI_TENANT=1(需要 INKWELL_PUBLIC_URL 和 INKWELL_ADMIN_API_KEY,并使用网络传输——绝不能使用 stdio);随后 src/app.py 会在一个进程中提供 MCP、管理界面和仪表板。使用 inkwell add-team <name> 创建团队(通过 docker exec 运行,参见 src/cli.py)并获取其 API 密钥,然后将每个团队的 Agent 指向 /mcp,并将该密钥作为 bearer token:
claude mcp add --transport http inkwell https://your-host/mcp \
--header "Authorization: Bearer <TEAM_API_KEY>"
也可以使用原始 mcpServers 配置(适用于 Claude Desktop 和其他客户端):
{
"mcpServers": {
"inkwell": {
"type": "http",
"url": "https://your-host/mcp",
"headers": {
"Authorization": "Bearer <TEAM_API_KEY>"
}
}
}
}
TeamTokenVerifier(src/server.py)会在每次请求时对令牌进行哈希处理,并在 admin.db 中查找——不进行缓存,因此密钥撤销后会立即失效。
搜索
混合搜索:将 SQLite FTS5(Porter 词干提取、BM25)与基于本地 Model2Vec 嵌入向量(minishlab/potion-multilingual-128M,不依赖云端)的余弦相似度,通过 Reciprocal Rank Fusion 融合。因此,即使查询与某个条目没有任何字面词汇重合,也仍可按含义找到该条目。如果无法加载嵌入模型,则回退到仅关键词搜索。索引仍是单个 SQLite 文件,可使用标准 SQL 工具查询。
工具
| 工具 | 描述 | 关键参数 |
|---|---|---|
remember | 创建或更新条目(通过 upsert 检测重复,或通过 supersede 创建新版本)。必须提供 entry_type;根据架构的 membership 规则,part_of(中心条目的 UUID)对不同类型可能是必需、可选或不允许的。返回 size、非阻塞的原子性 warnings(Markdown 标题、超过 3 个段落、超过 512 B / 1 KB),以及 suggested_links——值得通过 kb:// 链接交叉引用的近似重复或相关条目(基于嵌入向量相似度)。 | title、content、tags、entry_type、entry_id、force、resource、supersede、part_of |
recall | 读取条目及其图关系(出链和反向链接)。返回 size 和 last_modified。高连接度类型(中心条目)会返回 in_digest:按链接类型分组的反向链接,以及按 part_of 分组的成员,而不是任意截断的列表。 | entry_id、relations_limit |
search | 混合关键词与语义搜索,可按标签、精确的 entry_type 和/或 part_of 筛选 | query、tags、limit、include_superseded、entry_type、part_of |
list | 按标题排序浏览条目,可按标签、精确的 entry_type 和/或 part_of 筛选 | tags、limit、include_superseded、entry_type、part_of |
tags | 列出所有标签及其条目数量 | — |
forget | 删除条目(文件和索引)。如果仍有其他条目链接到它,则会发出警告。 | entry_id |
rebuild | 根据 Markdown 文件重建搜索索引;也会运行 doctor | — |
doctor | 根据 schema.json 检查每个条目:悬空/已废弃的 kb:// 目标、未声明的类型、缺少必需的 frontmatter 和模板正文字段、超级节点、标签/类型冲突 | — |
条目架构
条目分类及各类型的规则定义在 schema.json 中,而不是 Python 代码中:类型必须包含哪些 frontmatter 字段、应包含哪些模板正文字段、搜索是否可以根据使用情况提升其排名,以及 recall 是否会汇总其反向链接。entry_type 会根据该架构构建为枚举并提供给 MCP 客户端,因此未声明的类型会在调用到达服务之前被拒绝。
解析顺序为先找到者优先:先查找 <data-path>/schema.json,再查找随软件包提供的 src/schema.json。用户文件会直接替换随软件包提供的文件——两者绝不会合并,因此请复制默认文件并进行编辑。架构在启动时只读取一次,因此编辑后必须重启服务。手动编写的条目仍可包含未声明的类型;doctor 会报告这些条目。
仪表板
一个 Web UI,可视化浏览并手动编辑 MCP 工具所用的同一知识库——无需重复实现协议,每项操作都通过 KnowledgeBase 执行。
- 力导向图展示所有条目及其
kb://关系——点击节点可查看详情,点击图例标签可按类型筛选(匹配项保持高亮,其他项变暗) - 混合搜索使用与
searchMCP 工具相同的 BM25 + 语义索引,并支持按标签和entry_type筛选 - CRUD 面板可创建、编辑、替代或删除条目,无需手动处理 Markdown 文件——字段旁会显示出向和入向图关系
- 深色、紧凑、无多余装饰的界面——这是维护工具,而非面向消费者的应用(参见
PRODUCT.md/DESIGN.md)
默认禁用(容器仅运行 MCP 服务)。如需启用,请在同一容器中将其作为第二个进程运行:
docker run -d --name inkwell \
-e INKWELL_ENABLE_DASHBOARD=1 \
-p 8192 -p 8193 \
-v ./knowledge:/knowledge \
foreigndmitryi/inkwell-memory --transport sse
docker port inkwell 8193 # dashboard host port
或者在本地单独运行:python -m dashboard(有关 INKWELL_DASHBOARD_HOST/INKWELL_DASHBOARD_PORT,请参阅配置)。
图关系
在 Markdown 内容中使用 kb://uuid#type URL 链接条目:
This service runs on [Saturn](kb://a1b2c3d4-...#runs-on)
and depends on [PostgreSQL](kb://f9e8d7c6-...#depends-on).
recall 会返回两个方向的关系,以及大小元数据:
{
"id": "a1b2c3d4-...",
"title": "My API Service",
"content": "...",
"tags": ["..."],
"size": 1024,
"last_modified": "2026-03-14",
"relations": {
"out": [{"type": "runs-on", "id": "e5f6...", "title": "Saturn"}],
"in": [{"type": "depends-on", "id": "b7c8...", "title": "Frontend App"}]
}
}
如同面向知识的 HATEOAS——每个响应都带有用于浏览图的链接。
使用示例
存储知识
向 Agent 提问:
“记住我们的 API 运行在 8080 端口,并依赖 PostgreSQL 15。”
Inkwell 会创建一个带有唯一 UUID 的 Markdown 文件,将其编入索引并确认。之后,Agent 可以在任何未来会话中回忆起这一事实。
搜索
“我们了解哪些有关 PostgreSQL 的信息?”
Inkwell 会根据内容、标题和标签搜索所有条目,并按相关性对结果排序。
浏览图
“哪些内容依赖 PostgreSQL?”
如果条目通过 kb://uuid#depends-on 链接到 PostgreSQL 文章,Inkwell 会返回所有反向链接——展示每个依赖它的服务,无需 Agent 逐一搜索。
在多个 Agent 之间共享知识
使用 SSE 或 HTTP 传输启动 Inkwell。多个 Agent——甚至来自不同提供商(Claude、ChatGPT、Copilot)的 Agent——都可以连接到同一服务。一个 Agent 记住的内容,其他 Agent 都能回忆起来。
Agent A: "Remember that the deploy key rotates every 90 days."
Agent B: "When does the deploy key expire?"
→ Agent B finds the answer immediately.
提示你的 Agent
将以下内容添加到系统提示词或项目说明中,让 Agent 将 Inkwell 当作一种本能,而不是事后才想起的工具:
Inkwell is your persistent memory. Using it is mandatory, not optional.
Inkwell stores ZERO discoverable information. If you can derive it from
code, git history, configuration files, or existing documentation, it
does not belong in Inkwell. Inkwell captures decisions and their context,
diagnostics and their root causes, procedures learned the hard way —
the kind of knowledge that is lost when a conversation ends.
Before working on any topic: search Inkwell first. Always. Even if you think you know.
Before answering a question about infrastructure or architecture: search first.
Before proposing a solution: check if a past decision exists in Inkwell.
After resolving a diagnostic: remember the root cause and the fix.
After executing a procedure: remember the steps.
After making an architecture decision: remember the choice and the rationale.
After discovering something about the infrastructure: remember it.
系统提示词很容易在会话中途被忘记。plugins/inkwell-hooks/ 提供了一个独立插件(包含 SessionStart、Stop、SessionEnd、PreToolUse 处理程序,以及仅适用于 Claude Code 的 inkwell-project-onboarder Agent),会以机制化方式提示 Agent 在开始工作前搜索 Inkwell,并在结束前提醒它将重要更改 remember,而不是依赖 Agent 在无人提示时想起本节内容。该插件同时适用于 Claude Code 和 Codex——通过 /plugin marketplace add <this-repo>,然后运行 /plugin install inkwell-hooks@inkwell-memory 安装(Claude Code);或通过 codex plugin marketplace add <this-repo>/plugins,然后运行 codex plugin add inkwell-hooks@inkwell-memory 安装(Codex)。有关各个钩子的作用及完整安装流程,请参阅 plugins/inkwell-hooks/README.md。
禁用 Claude Code 内置的自动记忆
Claude Code 自带自动记忆功能(将 MEMORY.md 存放在 ~/.claude/projects/<project>/memory/ 下,并在每次会话中加载)。同时运行该功能和 Inkwell,意味着两个系统会写入重叠的笔记,并争夺 Agent 的注意力,弊大于利。可在 settings.json 中将其关闭:
{
"autoMemoryEnabled": false
}
也可以通过环境变量关闭(其优先级高于设置项和 /memory 开关):CLAUDE_CODE_DISABLE_AUTO_MEMORY=1。详情请参阅 Claude Code 的记忆文档。
配置
所有选项都有对应的 INKWELL_* 环境变量作为备用值。CLI 参数优先。
| 选项 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
--data-path | INKWELL_DATA_PATH | /knowledge | 知识数据的根路径 |
--transport | INKWELL_TRANSPORT | stdio | MCP 传输方式 |
--host | INKWELL_HOST | 0.0.0.0 | 监听地址(SSE/HTTP) |
--port | INKWELL_PORT | 8192 | 监听端口(SSE/HTTP) |
--embedding-model | INKWELL_EMBEDDING_MODEL | minishlab/potion-multilingual-128M | 用于语义搜索的 Model2Vec 模型 |
| — | INKWELL_ENABLE_DASHBOARD | 未设置(关闭) | 设为真值(1/true/yes)时,会启动一个独立进程,在 MCP 服务旁运行仪表盘 |
--host(仪表盘) | INKWELL_DASHBOARD_HOST | 0.0.0.0 | 仪表盘监听地址 |
--port(仪表盘) | INKWELL_DASHBOARD_PORT | 8193 | 仪表盘监听端口(使用大于或等于此值的第一个空闲端口) |
| — | INKWELL_QUERY_LOG | 未设置(关闭) | 文件路径;设置后,search/recall 会将每次调用的 JSONL 跟踪记录追加到文件中,用于检索质量分析 |
存储格式
条目是带有 YAML frontmatter 的 Markdown 文件,存放在 <data-path>/entries/ 中:
---
id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
title: Entry Title
tags: [infrastructure, postgresql]
type: decision
resource: /path/to/relevant/file
---
Markdown content here...
每次 remember 调用都必须提供 type(独立字段,不属于 tags),用于对条目分类(hub、decision、diagnostic、procedure、preference、snippet 等),并可通过 search/list 筛选。resource 为可选项:条目所描述的规范文件或文件夹路径。在这些字段出现之前写入的旧条目仍可正常读取。
搜索索引是可重建的缓存,位于 <data-path>/index/inkwell.db。删除它并运行 rebuild 即可,不会丢失任何数据。rebuild 还会报告现有条目中的架构符合性警告(缺少 type、resource 格式错误)。
开发
# Build
docker build -t inkwell .
# Test (separate Dockerfile — pytest/tests/ never ship in the production image)
docker build -f tests/Dockerfile -t inkwell-test .
docker run --rm inkwell-test
# Run locally (SSE)
docker run -d --name inkwell -p 8192 -v ./knowledge:/knowledge inkwell --transport sse
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。