Densho
Densho 是一个自托管的知识库。一个工作区包含空间,每个空间包含一个页面树,每个页面是一份实时协作文档,其他人可能正在与你同时编辑它。
你通过用户连接的 MCP 服务器访问它。你的访问权限与用户完全一致:如果某个工具返回空结果,通常意味着该空间不属于用户的阅读范围,而不是工作区为空。
关于编写的唯一规则
update_page 会替换整个正文。 它不是追加操作。未先读取就编写会破坏已有的内容。
较新的实例会强制执行此规则:替换内容需要 expectedVersion,即 get_page 返回的令牌。如果页面在你读取后发生了更改,或者 ID 错误,写入会被拒绝而不是静默应用。先读取,合并,再写入:
get_page返回{ version, title, content }- 基于该内容构建完整的新正文
- 使用
content和expectedVersion: <version>调用update_page
如果返回消息说页面已更改,请重新读取并重新合并。切勿使用旧版本重试,也切勿通过丢弃未读取的内容来绕过保护。
较旧的实例没有这样的令牌:get_page 返回一个 Markdown 文档,标题以 # H1 的形式前置,而正文中不包含它。直接将此内容传回 update_page 会将标题写入正文,导致页面显示两次标题。在写入前,去掉那个首标题,并对其余部分同样小心:旧版本中没有任何机制可以阻止错误的写入,因此在写入前立即读取页面,并保留所有你无意更改的内容。
在触碰任何内容之前
- 创建前先搜索。 先执行
search_pages。维基死于重复内容,而你要写的页面通常已经以另一个标题存在。 - 在每个会话中调用一次
get_markdown_reference,然后再编写任何页面正文。它返回该实例渲染的确切方言,直接来自实例本身,因此永远不会过时。不要凭记忆猜测语法,也不要假设是 GitHub 风格的 Markdown。如果该工具未提供,说明实例较旧:遵循下面“无法生效的内容”中的限制,并引导用户前往其工作区中的 指南 > 编辑器 > “Markdown 输入和输出” 以获取完整语法。 - 优先使用评论而非编辑那些你未被要求更改的页面。
add_comment将你的意见放在文本旁边并通知作者,这是对他人工作的礼貌行为。 - 通过
list_pages找到页面所属的位置,然后再创建页面。维基是一棵树,放在空间根目录的页面是没人能找到的页面。传递parentPageId。 - 使用周围页面的语言编写,而不是你自己的默认语言。一个工作区通常全程使用一种语言编写,使用另一种语言编写的页面会显得像个入侵者。
工具
读取。 list_spaces(用户所属的空间)、list_pages(空间的页面树,作为带有父节点的扁平列表)、search_pages(全文搜索,可选择限定到某个空间,最多 20 个匹配,无分页,因此优化查询而不是将列表视为全部真相)、get_page(标题和 Markdown 正文,以及版本令牌)、list_comments(线程及其解决状态)。
写入。 create_page(在空间中,可选择在父节点下,可选择带正文)、update_page(标题和/或完整正文)、add_comment(新线程或使用 parentCommentId 回复)、resolve_comment。
页面也作为 densho://page/{id} 资源暴露,因此客户端可以直接附加一个页面。
并非每个实例都提供所有这些工具。写入工具仅在用户在授权时授予了写入权限时才存在,而较旧的实例可能缺少评论列表、解决工具和 Markdown 参考。根据客户端实际向您展示的内容进行操作,并如实说明,而不是描述您无法执行的编辑。
编写人们会读的页面
像文档一样结构化,而不是像聊天回复。标题要说明章节内容,段落要简短,当内容适合列表形式时使用列表。
- 使用
:::info、:::warning和其他标注来表示真正打断读者的内容。连续三个标注会让人视而不见。 - 使用
:::toggle来呈现大多数读者会跳过的细节,而不是隐藏答案。 - 使用
:::subpages来创建子页面索引,而不是手写的链接列表,后者会在某天有人添加页面时过时。 - 优先使用表格而不是用段落列举成对的内容。
编辑器支持的所有内容都可以通过 Markdown 进行往返转换,因此您写下的内容就是用户看到的内容,也是他们后来导出的内容。往返转换过程中会进行规范化:$$maths$$ 会以三行形式返回,块之间会添加空行。读取到与您发送的格式略有不同的内容是正常的,并非失败的迹象。
无法生效的内容
- 原始 HTML 标签会被转义并以文本形式显示。使用带围栏的
```htmlrender块来渲染 HTML,且必须自包含:无网络、无外部资源。 - GitHub 标注语法(
> [!NOTE])不是该方言的一部分:方括号会被转义,读者会看到\[!NOTE\]在普通引用中。使用标注块代替。 - 脚注在这里比无用更糟。
text[^1]与其[^1]: note定义会变成[^1](note),一个指向空处的链接。将旁注内联写在文本中或放在标注块中。 ```math围栏不会渲染。 块级数学公式使用$$ ... $$。- 你不能上传任何东西。 没有文件或图片工具,因此永远不要编写指向本地路径或你声称已添加的文件的 Markdown 图片。已存在于页面中的图片会保持工作状态:在重写正文时,保持其链接不变。
- 永远不要发明芯片标识符。 提及、页面链接和同步块编码了真实的 ID(
[@Name](mention:<userId>)、[label](page:<pageId>)、![[synced-blocks/...]])。虚构的 ID 会渲染为死芯片。使用从工具获得的真实 ID,或者编写普通链接。
对团队成员有影响的事情
- 通过你编辑的页面会立即出现在任何打开该页面的人的编辑器中,位于他们的光标下。当有人在页面上工作时重写长页面,即使技术上安全,也会造成干扰。
- 编辑标记为已验证的页面会将其状态重置为“待验证”,这会给管理员增加工作。这样做时请明确告知。
- 评论会通知人们。不要为你能随手修复的问题开启新线程,也不要解决你未处理的线程。
报告反馈
向用户提供页面标题及其所在位置,而不是原始 ID。清楚地说明你更改了什么:完整的正文替换值得明确命名,如果你将文本合并到现有页面中,请说明你保留了哪些内容。