mcpField
O
Obsidian MCP Server

Obsidian MCP Server

本地服务
npmjs.com记忆与知识7003 天前更新

关于 Obsidian MCP Server

Obsidian MCP Server 通过 Local REST API 插件连接 Obsidian 库,提供笔记、标签和 frontmatter 操作。它支持按路径限制读写权限,并为 MCP 客户端提供 stdio 和 Streamable HTTP 传输方式。

主要功能

  1. 01以正文、章节或结构化数据读取笔记
  2. 02按文本、JSONLogic 或 Omnisearch 搜索
  3. 03创建、追加、局部修改和替换笔记内容
  4. 04管理标签和 frontmatter 字段
  5. 05提供库、标签和状态资源

适用场景

  1. 01查找符合文本或结构化条件的笔记
  2. 02原位编辑标题章节或 frontmatter 字段
  3. 03将笔记访问限制在配置的库路径内

MCP 相关

该 MCP 服务提供 14 个工具和 3 个资源,用于操作 Obsidian 笔记、标签及状态,并支持 stdio 和 Streamable HTTP 传输。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": [
"-y",
"obsidian-mcp-server"
],
"env": {
"OBSIDIAN_API_KEY": "<OBSIDIAN_API_KEY>",
"OBSIDIAN_BASE_URL": "<OBSIDIAN_BASE_URL>",
"OBSIDIAN_VERIFY_SSL": "<OBSIDIAN_VERIFY_SSL>",
"OBSIDIAN_REQUEST_TIMEOUT_MS": "<OBSIDIAN_REQUEST_TIMEOUT_MS>",
"OBSIDIAN_ENABLE_COMMANDS": "<OBSIDIAN_ENABLE_COMMANDS>",
"OBSIDIAN_READ_PATHS": "<OBSIDIAN_READ_PATHS>",
"OBSIDIAN_WRITE_PATHS": "<OBSIDIAN_WRITE_PATHS>",
"OBSIDIAN_READ_ONLY": "<OBSIDIAN_READ_ONLY>",
"OBSIDIAN_DELETE_ELICITATION": "<OBSIDIAN_DELETE_ELICITATION>",
"OBSIDIAN_OMNISEARCH_URL": "<OBSIDIAN_OMNISEARCH_URL>",
"MCP_LOG_LEVEL": "<MCP_LOG_LEVEL>",
"MCP_TRANSPORT_TYPE": "<MCP_TRANSPORT_TYPE>",
"MCP_HTTP_HOST": "<MCP_HTTP_HOST>",
"MCP_HTTP_PORT": "<MCP_HTTP_PORT>",
"MCP_HTTP_ENDPOINT_PATH": "<MCP_HTTP_ENDPOINT_PATH>",
"MCP_AUTH_MODE": "<MCP_AUTH_MODE>"
}
}
}
}
启动命令npx -y obsidian-mcp-server
需要配置的环境变量
OBSIDIAN_API_KEY密钥Bearer token for the Obsidian Local REST API plugin (Settings → Community Plugins → Local REST API).
OBSIDIAN_BASE_URLBase URL of the Obsidian Local REST API. Default: http://127.0.0.1:27123 (enable "Non-encrypted (HTTP) Server" in plugin settings). Use https://127.0.0.1:27124 for the always-on HTTPS port (self-signed cert; pair with OBSIDIAN_VERIFY_SSL=false).
OBSIDIAN_VERIFY_SSLWhether to verify the TLS certificate on the Obsidian endpoint. Default false because the plugin uses a self-signed cert.
OBSIDIAN_REQUEST_TIMEOUT_MSPer-request timeout in milliseconds.
OBSIDIAN_ENABLE_COMMANDSOpt-in flag for the command-palette pair (obsidian_list_commands + obsidian_execute_command). Off by default — Obsidian commands are opaque and can be destructive.
OBSIDIAN_READ_PATHSOptional comma-separated vault-relative folder allowlist for reads. Prefix-based with implicit recursion; case-insensitive; trailing slashes normalized. Unset = full vault. Write paths are implicitly readable. Example: 'public/,projects/'.
OBSIDIAN_WRITE_PATHSOptional comma-separated vault-relative folder allowlist for writes. Same syntax as OBSIDIAN_READ_PATHS. Unset = full vault, or the read scope when reads are restricted. Example: 'projects/,scratch/'.
OBSIDIAN_READ_ONLYGlobal read-only kill switch. When true, every write is denied regardless of OBSIDIAN_WRITE_PATHS, and the command-palette pair is suppressed (commands can mutate). Useful for shared or public-facing deployments.
OBSIDIAN_DELETE_ELICITATIONOpt-in delete confirmation. When true, obsidian_delete_note asks the user to confirm each delete through an elicitation round (the client must support elicitation), and HTTP startup requires a stateful session unless OBSIDIAN_READ_ONLY=true disables the tool. Off by default — the delete runs on the first call, bounded by OBSIDIAN_WRITE_PATHS and OBSIDIAN_READ_ONLY.
OBSIDIAN_OMNISEARCH_URLOverride URL for the Omnisearch plugin HTTP server. Unset derives from OBSIDIAN_BASE_URL host with port 51361. Required only if the Omnisearch plugin is not on the default port.
MCP_LOG_LEVELSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_TRANSPORT_TYPESelects the HTTP transport.
MCP_HTTP_HOSTThe hostname for the HTTP server.
MCP_HTTP_PORTThe port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHThe endpoint path for the MCP server.
MCP_AUTH_MODE密钥Authentication mode to use: 'none', 'jwt', or 'oauth'.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmobsidian-mcp-server3.7.2

工具

12

收录的工具列表 · 更新于 3 周前

参数类型必填说明
formatenum是要返回的投影形式。`content` — 原始 Markdown 正文。`full` — 内容以及解析后的 frontmatter、标签和文件元数据。`document-map` — 标题、块 ID 和 frontmatter 字段名目录(用于发现补丁目标)。`section` — 单个标题、块或 frontmatter 区段(需要 `section`);标题区段包含该标题下的完整子树,嵌套时使用 `Parent::Child` 语法。content | full | document-map | section
targetany是笔记所在的位置。
sectionobject否当 `format` 为 `"section"` 时必需。指定要提取的标题、块或 frontmatter。
section.typeenum是按名称指定标题、按引用指定块,或按键指定 frontmatter 字段。heading | block | frontmatter
section.targetstring是标题名称——完整路径(`"Parent::Child"`)或与唯一一个标题完全匹配的叶级名称——不带开头插入符的块引用(例如 "2d9b4a",而不是 "^2d9b4a"),或 frontmatter 字段名。
includeLinksboolean否当 `format: "full"` 时为 true,会从笔记正文解析指向外部的 wiki 和 Markdown 链接引用。其他格式下会跳过。

详细介绍

obsidian-mcp-server

通过 MCP 读取、写入、搜索和精准编辑 Obsidian 知识库中的笔记、标签和 frontmatter。支持 STDIO 或 Streamable HTTP。

14 个工具 • 3 个资源

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework


概述

通过 Local REST API 插件访问你的 Obsidian 知识库。读取、搜索和写入笔记,在原位置编辑单个标题、区块或 frontmatter 字段,并管理标签;同时内置按文件夹范围限定的读写权限。

工具
工具描述
obsidian_get_note将笔记读取为原始内容、完整结构化形式、文档映射或单个部分
obsidian_list_notes递归列出 vault 路径下的笔记和文件夹,并按扩展名和名称筛选
obsidian_list_tags列出 vault 标签及其使用次数,按使用次数从高到低排序
obsidian_search_notes按文本、JSONLogic 搜索;如果 Omnisearch 插件可访问,也可使用 BM25 排序搜索
obsidian_write_note创建笔记、替换一个部分,或使用 overwrite: true 覆盖整个文件
obsidian_append_to_note向笔记追加内容(如果笔记不存在则创建),或追加到某个标题、块或 frontmatter 字段
obsidian_patch_note针对某个标题、块引用或 frontmatter 字段追加、前置或替换内容
obsidian_replace_in_note在单个笔记内执行字面值或正则搜索替换;默认仅搜索正文
obsidian_manage_frontmatter获取、设置或删除一个 frontmatter 键
obsidian_manage_tags在 frontmatter、行内或两者中添加、移除或列出笔记标签
obsidian_delete_note永久删除笔记;可选择在用户确认后删除(OBSIDIAN_DELETE_ELICITATION)
obsidian_open_in_ui在 Obsidian 应用中打开文件,可选择在新窗格中打开
obsidian_list_commands列出命令面板命令(通过 OBSIDIAN_ENABLE_COMMANDS 选择启用)
obsidian_execute_command按 ID 运行命令面板命令(通过 OBSIDIAN_ENABLE_COMMANDS 选择启用)
资源
资源描述
obsidian://vault/{+path}笔记的内容、frontmatter、标签和文件元数据
obsidian://tags所有 vault 标签及其使用次数,不设上限的快照
obsidian://status插件可访问性、身份验证状态、版本和已注册的 API 扩展

笔记和标签数据也可通过工具(obsidian_get_note、obsidian_list_tags)访问;obsidian://status 没有对应的工具。

功能参考

obsidian_get_note 工具
  • target 可以是 vault path、active 文件,或 periodic 笔记(从 daily 到 yearly,date 可选);format 可以是 content、full、document-map 或 section;full 需使用 includeLinks: true 才会包含 vault 内部的出站链接
  • result.format 用于区分载荷;如果 section 读取结果匹配多个标题,则返回第一个匹配项,并在 candidates 中列出所有完整路径
  • 如果 path 没有完全匹配项,但其文件夹中有一个不区分大小写的匹配项,则读取该文件:result.path 是实际名称,requestedPath 是传入的路径,notice 会同时列出两者

obsidian_list_notes 工具
  • 从 path(默认为 vault 根目录)开始遍历,深度为 1–20(默认为 2),并按 extension 和 nameRegex(≤256 个字符)筛选;不符合 nameRegex 的文件夹不会被遍历
  • 返回 entries[](file / directory)、totals 和 appliedFilters;遍历在 1,000 个条目处停止,并附带 excluded.reason: "entry_cap";因深度限制而停止遍历的文件夹会带有 truncated: true
  • 设置 OBSIDIAN_READ_PATHS 后,列表中只包含可读取的条目以及通向作用范围的文件夹;这些文件夹会被遍历,并作为 path 接受

obsidian_list_tags 工具
  • 使用 nameRegex(≤256 个字符)和 minCount 缩小范围,然后按次数对标签排序,并限制数量为 limit(默认为 200,最大为 10000);层级父标签也会计数(work/tasks 会计入 work)
  • 如果有标签因数量上限而未显示,响应会包含 truncated、shown 和 cap
  • 设置 OBSIDIAN_READ_PATHS 后,只列出来自可读取笔记的标签;count 是包含该标签或其嵌套标签的可读取笔记数

obsidian_search_notes 工具
  • mode: "text" 要求 query 中按空白拆分的每个词元都作为不区分大小写的子串出现在文件名或正文中(引号按字面处理);结果由 contextLength(默认值为 100)、pathPrefix 和 maxMatchesPerHit(默认值为 10)控制;mode: "jsonlogic" 则基于 path、content、frontmatter.<key>、tags 和 stat 评估 logic 树(在提供这些字段的插件版本中还包括 links、backlinks 和 unresolvedLinks),其中 glob / regexp 接收 [PATTERN, VALUE]
  • result.mode 用于区分负载;每种模式都会报告 totalCount,并通过 nextCursor 分页;被 maxMatchesPerHit 截断的文本命中会带有 truncated 和 totalMatches
  • 仅当启动时 Omnisearch 插件已响应,才会提供 mode: "omnisearch"(BM25 排名、带引号的短语、-exclusion、path: / ext: 过滤器);其上游 50 条命中上限会将 truncated 设为 true

obsidian_write_note 工具
  • 接收 target 和 content,并可选接收 section 和 contentType(markdown / json);将整份文件写入已有笔记时,若未设置 overwrite: true,则会失败并返回 file_exists
  • 在不区分大小写的文件系统(macOS、Windows)上,若要写入的整份文件路径与已有笔记仅字母大小写不同,则会失败并返回 case_variant_exists,且不会写入任何内容;当父文件夹的列表中恰好有一个大小写匹配项时,existingPath 会标明该笔记;若存在多个匹配项,或该路径上有 Obsidian 不会索引的文件(点文件),则省略此字段
  • 指定 section 时,只替换对应的标题、块或 frontmatter 字段,并保留标题行;输出会报告 created、sectionTargeted 和解析后的 sectionTarget

obsidian_append_to_note 工具
  • 未指定 section 时,追加到文件末尾或创建文件(created: true);指定 section 时,追加到已有笔记中对应的标题、块或 frontmatter 字段;设置 createTargetIfMissing: true 可创建该部分
  • 若部分追加的内容已存在于目标位置,则会失败并返回 content_preexists;块目标不会添加分隔符,因此如需换行,请以换行符开头设置 content
  • 在不区分大小写的文件系统上,若整份文件的路径与已有笔记仅字母大小写不同,则追加会失败并返回 case_variant_exists;当父文件夹的列表中恰好有一个大小写匹配项时,existingPath 会标明该笔记

obsidian_patch_note 工具
  • 对已有笔记的一个 section 执行 operation: "append" | "prepend" | "replace";patchOptions 接受 createTargetIfMissing、applyIfContentPreexists 和 trimTargetWhitespace(仅适用于插件 v4.x)
  • 返回解析后的 section 和 operation;若目标位置已存在相同内容,则会失败并返回 content_preexists,除非设置了 applyIfContentPreexists: true

obsidian_replace_in_note 工具
  • 按顺序运行 replacements[],每项操作都会针对上一项的输出;每项接受 useRegex(≤1024 个字符)、caseSensitive(默认值为 true)、wholeWord、flexibleWhitespace(仅限字面模式)和 replaceAll(默认值为 true)
  • 返回 totalReplacements 和包含 bodyCount / frontmatterCount 的 perReplacement[]
  • scope: "body"(默认值)会使 frontmatter 保持字节级不变;"frontmatter" 和 "both" 会在之后重新解析 YAML,若解析失败(frontmatter_invalid),则不会写入任何内容

obsidian_manage_frontmatter 工具
  • 对单个 key 执行 operation: "get" | "set" | "delete";set 要求 value 为 JSON 类型
  • get 会返回 exists 和 value(不存在时为 null);set 和 delete 会返回变更后的完整 frontmatter;若 YAML 无法解析,执行 delete 会失败并返回 frontmatter_invalid,且不会写入任何内容

obsidian_manage_tags 工具
  • operation: "add" | "remove" | "list",并搭配 tags;location: "frontmatter"(默认,即 tags: 数组)、"inline"(正文中的 #tag;add 会追加到文件末尾),或 "both"
  • add / remove 会报告 applied、skipped 和生成的 tags;list 会返回 frontmatter、inline 和 all
  • 内联标签检测遵循 Obsidian 的标签语法:跳过代码、双链、图片、链接目标、HTML 和数学内容,并会读取 %% … %% 注释

obsidian_delete_note 工具
  • 接受 target(路径、当前文件或周期笔记),并首先检查其是否位于写入范围内;文件夹路径会报错 path_is_directory。API 层面不提供撤销功能,只能使用 Obsidian 的本地垃圾箱
  • 路径必须完全匹配,包括字母大小写,即使文件系统不区分大小写也是如此。大小写不同或省略扩展名的路径会在删除任何内容前报错 note_missing,并在 suggestions 中列出相近路径
  • 默认情况下,首次调用即会删除笔记,不需要确认;OBSIDIAN_WRITE_PATHS 和 OBSIDIAN_READ_ONLY 会限制其可访问范围
  • 设置 OBSIDIAN_DELETE_ELICITATION=true 后,首次调用会返回确认请求,其中包含路径和字节大小;只有用户接受后才会删除笔记。拒绝会报错 cancelled,不支持征询确认的客户端无法删除笔记
  • 在此模式下,回答只有与显示提示时存储的单次使用同意记录匹配才有效;该记录绑定调用方、路径以及当时的笔记内容。预先提供或重放的回答,或在笔记更改后给出的回答,都会触发新的确认提示
  • 同意记录存储在服务的存储提供程序中(STORAGE_PROVIDER_TYPE,默认为 in-memory,仅限当前进程)。这适用于 stdio 或单个 HTTP 实例;多个实例共用一个端点时,需要使用共享提供程序(filesystem、supabase 或 cloudflare-d1,不能使用 cloudflare-kv)

obsidian_open_in_ui 工具
  • path、failIfMissing(默认 true)和 newLeaf(在拆分窗格中打开);当 failIfMissing: false 时,会创建不存在的文件,此操作需要写入权限
  • createdIfMissing 会报告执行了哪个分支
  • 如果 path 的大小写不匹配,但存在一个不区分大小写的匹配项,则会打开该文件而不是创建另一个文件,并通过 notice 报告作为 requestedPath 发送的路径

obsidian_list_commands 工具
  • 可选的 nameRegex(≤256 个字符),用于匹配每个命令的显示名称
  • 返回包含 id 和 name 的 commands[],其中 id 可用于 obsidian_execute_command
  • 仅当 OBSIDIAN_ENABLE_COMMANDS=true 且 OBSIDIAN_READ_ONLY 未启用时才会列出

obsidian_execute_command 工具
  • 使用来自 obsidian_list_commands 的 commandId;成功时返回 executed: true,未注册的 ID 会报错 command_unknown
  • 以键盘快捷键的权限运行,因此某些命令具有破坏性(删除文件、关闭库);其启用条件与 obsidian_list_commands 相同

obsidian://vault/{+path} 资源
  • {+path} 会捕获 /vault/ 之后的所有内容,包括斜杠;字面路径和百分号编码路径会解析为同一篇笔记
  • 返回 path、content、frontmatter、tags 和 stat,结构与 format: "full" 的 obsidian_get_note 相同;失败时会报错 path_forbidden、note_missing 或 path_is_directory

obsidian://tags 资源
  • 返回每个标签及其 count,不设上限、不排序,并包含分层标签的父级
  • 设置 OBSIDIAN_READ_PATHS 后,仅包含可读取笔记中的标签,计数方式与 obsidian_list_tags 相同
  • 不提供排序或筛选;obsidian_list_tags 提供按数量排序且有上限的视图

obsidian://status 资源
  • status、service、authenticated、versions、manifest 和 apiExtensions[];即使 API 密钥错误也会响应,并报告 authenticated: false
  • 对于插件 v5.0.2 及更高版本,在使用 periodic 目标前,请检查 apiExtensions 中是否包含 local-rest-api-periodic-notes

功能

基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none / jwt / oauth)、可替换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及带可选 OpenTelemetry 跟踪功能的结构化日志记录。

Obsidian 专属功能:

  • 为 Obsidian Local REST API 插件提供类型化客户端;分节写入会根据插件报告的版本,向 v5.0 及更高版本发送 markdown-patch 2.0,向 v4.x 发送 1.x
  • 标题目标可使用完整的 Parent::Child 路径或不带父级的叶节点名称;若目标不明确,写入会返回 ambiguous_section 及其 candidates,除非恰好只有一个匹配项是顶级标题。对于插件 v5.0 及更高版本,添加到标题下的内容会以空行分隔(列表项会接续相邻列表),且其中的标题必须低于该分节的层级(heading_outside_section)
  • 支持按文件夹限定的读写权限、只读开关,以及选择启用的一对命令面板命令(参见路径策略);服务器级别的 instructions 会在 initialize 时报告当前生效的策略
  • obsidian_get_note 和 obsidian_open_in_ui 会针对大小写不匹配的路径重试实际文件名,并通过 requestedPath 和 notice 说明;路径不存在时会提供 Did you mean 建议;写入和删除则要求路径完全匹配
  • 正则表达式输入长度受限(nameRegex 最多 256 个字符,useRegex 最多 1024 个字符);包含嵌套量词时会以 regex_unsafe 拒绝
  • 没有专用的反向链接工具;obsidian_search_notes 的 jsonlogic 模式可通过 {"regexp": ["\\[\\[Target Note(\\\\?\\||#|\\]\\])", {"var": "content"}]} 查找反向链接,该表达式也能匹配适用于表格的 [[Target Note\|Alias]]

便于 Agent 使用的输出:

  • 提供恢复指引的错误:每种声明的失败都包含 reason、JSON-RPC 代码以及针对该情况编写的 recovery.hint
  • 大小变化量:每个变更类工具都会返回 previousSizeInBytes / currentSizeInBytes,调用方无需后续读取即可发现意外覆盖
  • 将歧义作为数据呈现:共享标题名称会返回 candidates,标签操作会报告 applied 与 skipped
  • 使用判别式输出约定:obsidian_get_note 使用 format,obsidian_search_notes 使用 mode,obsidian_manage_frontmatter 和 obsidian_manage_tags 使用 operation

开始使用

将其添加到 Claude Code:

claude mcp add obsidian-mcp-server -e OBSIDIAN_API_KEY=your-api-key -- npx -y obsidian-mcp-server

对于其他客户端,将以下内容添加到 MCP 配置文件:

{
  "mcpServers": {
    "obsidian-mcp-server": {
      "command": "npx",
      "args": ["-y", "obsidian-mcp-server"],
      "env": { "OBSIDIAN_API_KEY": "your-api-key" }
    }
  }
}

按照先决条件中的说明设置插件后,在 Obsidian 的 设置 → 社区插件 → Local REST API 中生成密钥。Docker 或从源码构建的相关说明,请参阅运行服务。

前置条件
  • 在你的库中启用 Obsidian Local REST API 插件,版本为 v4.0.0 或更高。其 API 密钥为 OBSIDIAN_API_KEY。
  • 服务默认使用 http://127.0.0.1:27123,因此请在插件设置中启用 "Non-encrypted (HTTP) Server",或设置 OBSIDIAN_BASE_URL=https://127.0.0.1:27124,以使用始终开启的 HTTPS 端口(当 OBSIDIAN_VERIFY_SSL=false(默认值)时,系统会接受其自签名证书)。
  • 周期笔记目标在插件 v5.0.1 及更早版本中可原生使用。从 v5.0.2 起,需要安装 periodic-notes API extension;未安装时会报错 periodic_unsupported。
  • 在插件 v4.x 中,向使用 CRLF(Windows)换行符的笔记写入标题段落时,内容会落在行中间:插件的 markdown-patch 1.x 引擎会将其放错位置,且服务无法修正。插件 v5.0 及更高版本可处理使用 CRLF 换行符的笔记。
  • 插件 v6.0 移除了 markdown-patch 1.x,但以下两种表格行写入(contentType: "json")仍会使用它:标题下方的行,以及通过表格下方独立一行的块 ID 定位的行。在 v6.0 中,请通过表格最后一行上的 ID 定位表格。
  • 使用 OBSIDIAN_DELETE_ELICITATION=true 时,需使用支持 elicitation 并能呈现其表单的 MCP 客户端,才能使用 obsidian_delete_note。其他所有工具以及默认删除功能均无需此条件。

配置

变量描述默认值
OBSIDIAN_API_KEY必需。 Local REST API 插件的 Bearer 令牌。—
OBSIDIAN_BASE_URLLocal REST API 基础 URL;https://127.0.0.1:27124 是始终启用的 HTTPS 端口。末尾的斜杠会被移除。如果没有响应,请求会以 obsidian_unreachable 失败。http://127.0.0.1:27123
OBSIDIAN_VERIFY_SSL验证插件的 TLS 证书。默认关闭,因为插件使用自签名证书;此放宽仅适用于 https: OBSIDIAN_BASE_URL。设为 true 时,不受信任的证书会导致请求以 certificate_rejected 失败。false
OBSIDIAN_REQUEST_TIMEOUT_MS单次请求的超时时间,单位为毫秒。30000
OBSIDIAN_ENABLE_COMMANDS启用 obsidian_list_commands 和 obsidian_execute_command。命令是不透明的,且可能具有破坏性。false
OBSIDIAN_READ_PATHS以逗号分隔的读取文件夹允许列表。参见路径策略。未设置(整个仓库)
OBSIDIAN_WRITE_PATHS以逗号分隔的写入文件夹允许列表。参见路径策略。未设置(使用读取范围;若未设置读取范围,则使用整个仓库)
OBSIDIAN_READ_ONLY拒绝所有写入并禁用命令面板工具对。false
OBSIDIAN_DELETE_ELICITATION删除前,通过征询表单请用户确认每次 obsidian_delete_note 调用。需要能够呈现征询的客户端,以及通过 HTTP 建立的有状态会话(当 OBSIDIAN_READ_ONLY=true 禁用该工具时则不需要)。关闭时,首次调用就会执行删除。false
OBSIDIAN_OMNISEARCH_URLOmnisearch HTTP 服务 URL。未设置时,会根据 OBSIDIAN_BASE_URL 的主机名推导,并使用端口 51361。启动时探测一次;只有在有响应时才会显示 omnisearch 搜索模式。推导得出
MCP_TRANSPORT_TYPE传输方式:stdio 或 http。stdio
MCP_HTTP_PORTHTTP 服务端口。3010
MCP_SESSION_MODEHTTP 会话模式:stateful、stateless 或 auto。当 OBSIDIAN_DELETE_ELICITATION=true 且 OBSIDIAN_READ_ONLY 关闭时,服务需要有状态会话,因为在 2025 年的客户端上确认操作需要会话,因此通过 HTTP 启动时,stateless 会失败。对 stdio 无影响。stateful
MCP_AUTH_MODE身份验证:none、jwt 或 oauth。none
MCP_LOG_LEVEL日志级别(RFC 5424)。info
LOGS_DIR日志文件目录(仅限 Node.js)。<project-root>/logs
OTEL_ENABLED启用 OpenTelemetry。false

完整的可选覆盖项列表请参见 .env.example。

路径策略

三个可选环境变量可限制工具能够访问的保险库路径。未设置时,读写范围覆盖整个保险库。

目标配置
随处读取,仅在 projects/ 和 scratch/ 中写入OBSIDIAN_WRITE_PATHS=projects/,scratch/
仅读取 public/,仅在 public/inbox/ 中写入OBSIDIAN_READ_PATHS=public/、OBSIDIAN_WRITE_PATHS=public/inbox/
禁止在任何位置写入OBSIDIAN_READ_ONLY=true
  • 匹配方式为前缀匹配,递归且不区分大小写;末尾的斜杠会被规范化。写入路径也可读取。
  • OBSIDIAN_READ_ONLY=true 会从 tools/list 中移除所有写入工具和命令面板工具对,包括 obsidian_manage_frontmatter 和 obsidian_manage_tags(因此它们的 get / list 也会一并移除)。obsidian_open_in_ui 仍可打开现有文件,但不会创建文件。
  • 拒绝访问时会返回 path_forbidden,并在 data.activeScope 中回显当前生效的范围和恢复提示。若对 active 或 periodic 目标的访问被拒绝,会指出目标((active file)、daily note for 2026-10-01),而不是它解析到的笔记。obsidian_list_notes 只列出可读条目以及通往范围的文件夹,因此可以从根目录逐级浏览到嵌套范围。
  • 设置 OBSIDIAN_READ_PATHS 后,搜索只会返回可读笔记,JSONLogic 树也不会读取范围之外的笔记:服务会在可读笔记上计算该树,其中 links、backlinks 和 unresolvedLinks 仅包含可读条目。链接指向哪篇笔记仍由 Obsidian 在整个保险库范围内解析,因此在范围外创建或删除笔记时,这三个字段可能会变化;如有需要,请在 content 中匹配链接文本。该计算有上限:嵌套最多 1,000 层;对树构建的值设有每篇笔记的工作预算,对保留的结果设有每次搜索的工作预算;超时为 10 秒。超出任一上限的树会以 logic_too_costly 失败。若可读笔记的数据嵌套过深,无法交给计算器处理(在 Node 下约为 3,500 层),搜索会以 note_too_deep 失败。未设置读取范围时,树会原样传给插件。
  • 设置 OBSIDIAN_READ_PATHS 后,标签列表(obsidian_list_tags、obsidian://tags)仅统计可读笔记,按笔记数量而非出现次数计数。仅设置写入路径或只读模式时,标签列表仍覆盖整个保险库。
  • 服务的 instructions 会说明生效的范围:可读范围为读取路径加写入路径;可写范围为写入路径,或者仅限制读取时的读取范围。启动日志会打印已配置的列表。

运行服务

本地开发

需要 Bun v1.4.0 或更高版本(或 Node.js v24+)。

  • 克隆并安装:

    git clone https://github.com/cyanheads/obsidian-mcp-server.git
    cd obsidian-mcp-server && bun install
    cp .env.example .env   # set OBSIDIAN_API_KEY
    
  • 构建并运行生产版本:

    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:stdio
    # or, listening at http://127.0.0.1:3010/mcp
    bun run start:http
    
  • 运行检查和测试:

    bun run devcheck   # Lint, format, typecheck, security, changelog sync
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec
    
Docker
docker run --rm -e OBSIDIAN_API_KEY=your-key -p 3010:3010 ghcr.io/cyanheads/obsidian-mcp-server:latest

镜像默认使用 0.0.0.0 上的 HTTP 传输、有状态会话,并将日志写入 /var/log/obsidian-mcp-server。在容器内,默认的 OBSIDIAN_BASE_URL(http://127.0.0.1:27123)指向容器自身的回环地址:若要访问主机上的插件,请将其指向 http://host.docker.internal:27123(Docker Desktop),或使用 --network host(Linux)。若要通过 MCP 客户端使用 stdio 运行,请使用 "command": "docker" 和 "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "-e", "OBSIDIAN_API_KEY=your-key", "-e", "OBSIDIAN_BASE_URL=http://host.docker.internal:27123", "ghcr.io/cyanheads/obsidian-mcp-server:latest"]。若要在本地构建,请运行 docker build -t obsidian-mcp-server .;默认会安装 OpenTelemetry 对等依赖,若要省略,请使用 --build-arg OTEL_ENABLED=false 进行构建。

如果其他机器能够访问该端口,请设置 MCP_AUTH_MODE=jwt(并设置 MCP_AUTH_SECRET_KEY)或 oauth。若使用默认值 none,每个调用方都能使用你的 OBSIDIAN_API_KEY 操作你的保险库。

项目结构

目录用途
src/index.tscreateApp() 入口:注册工具和资源,探测 Omnisearch,并应用只读和命令门控。
src/config使用 Zod 解析服务特定的环境变量(OBSIDIAN_*)。
src/services/obsidian本地 REST API 客户端、路径策略、Markdown 补丁格式处理、frontmatter/章节/标签解析、领域类型。
src/mcp-server/tools工具定义(*.tool.ts)以及共享的架构和辅助函数。
src/mcp-server/resources资源定义(*.resource.ts)。
src/mcp-server/prompts提示词定义(未注册)。
tests/针对工具、资源、服务和配置的 Vitest 测试。
docs/本地 REST API OpenAPI 规范和生成的 tree.md。
changelog/各版本的发布说明;CHANGELOG.md 是重新生成的汇总文件。

开发指南

开发指南和架构规则请参阅 CLAUDE.md。简要来说:

  • 处理程序抛出异常,由框架捕获——工具逻辑中不要使用 try/catch
  • 使用 ctx.log 记录请求范围内的日志;所有本地 REST API 调用都必须通过 getObsidianService() 路由
  • 通过 src/mcp-server/*/definitions/index.ts 中的汇总文件注册新工具和资源
  • 封装外部 API 调用:验证原始数据 → 规范化为领域类型 → 返回输出架构;绝不伪造缺失字段

贡献

Bug、功能请求和文档缺漏请提交 issue;关于哪些内容有助于采取行动,请参阅 CONTRIBUTING.md,关于我们的协作方式,请参阅 CODE_OF_CONDUCT.md。安全报告请通过 SECURITY.md 提交,切勿发布到公开 issue。

提交前请运行检查和测试:

bun run devcheck
bun run test

许可证

Apache-2.0 — 详情请参阅 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。