obsidian-mcp-server 3.2.8 → 3.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/AGENTS.md +19 -12
  2. package/CLAUDE.md +19 -12
  3. package/Dockerfile +11 -7
  4. package/README.md +6 -3
  5. package/changelog/3.2.x/3.2.10.md +47 -0
  6. package/changelog/3.2.x/3.2.9.md +30 -0
  7. package/changelog/template.md +5 -3
  8. package/dist/mcp-server/resources/definitions/index.d.ts +20 -20
  9. package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -1
  10. package/dist/mcp-server/tools/definitions/_shared/regex-safety.d.ts +11 -6
  11. package/dist/mcp-server/tools/definitions/_shared/regex-safety.d.ts.map +1 -1
  12. package/dist/mcp-server/tools/definitions/_shared/regex-safety.js +13 -8
  13. package/dist/mcp-server/tools/definitions/_shared/regex-safety.js.map +1 -1
  14. package/dist/mcp-server/tools/definitions/_shared/schemas.d.ts +3 -3
  15. package/dist/mcp-server/tools/definitions/_shared/schemas.js +2 -2
  16. package/dist/mcp-server/tools/definitions/_shared/schemas.js.map +1 -1
  17. package/dist/mcp-server/tools/definitions/index.d.ts +242 -215
  18. package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
  19. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts +9 -3
  20. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts.map +1 -1
  21. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js +14 -3
  22. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js.map +1 -1
  23. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts +1 -1
  24. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts +6 -6
  25. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts.map +1 -1
  26. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js +3 -2
  27. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js.map +1 -1
  28. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts +6 -1
  29. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts.map +1 -1
  30. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js +15 -1
  31. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js.map +1 -1
  32. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts +2 -2
  33. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts +3 -3
  34. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts +11 -6
  35. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts.map +1 -1
  36. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js +10 -4
  37. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js.map +1 -1
  38. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts +6 -1
  39. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts.map +1 -1
  40. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js +24 -1
  41. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js.map +1 -1
  42. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts +58 -58
  43. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts.map +1 -1
  44. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js +3 -3
  45. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js.map +1 -1
  46. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts +9 -3
  47. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts.map +1 -1
  48. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js +14 -3
  49. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js.map +1 -1
  50. package/dist/services/obsidian/frontmatter-ops.d.ts.map +1 -1
  51. package/dist/services/obsidian/frontmatter-ops.js +24 -21
  52. package/dist/services/obsidian/frontmatter-ops.js.map +1 -1
  53. package/dist/services/obsidian/obsidian-service.d.ts +8 -1
  54. package/dist/services/obsidian/obsidian-service.d.ts.map +1 -1
  55. package/dist/services/obsidian/obsidian-service.js +74 -4
  56. package/dist/services/obsidian/obsidian-service.js.map +1 -1
  57. package/dist/services/obsidian/path-policy.d.ts.map +1 -1
  58. package/manifest.json +1 -1
  59. package/package.json +15 -14
  60. package/server.json +3 -3
package/AGENTS.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Agent Protocol
2
2
 
3
3
  **Server:** obsidian-mcp-server
4
- **Version:** 3.2.8
5
- **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.10.9`
6
- **Engines:** Bun ≥1.3.11, Node ≥24.0.0
7
- **MCP SDK:** `@modelcontextprotocol/sdk` ^1.29.0
4
+ **Version:** 3.2.10
5
+ **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.11.1`
6
+ **Engines:** Bun ≥1.3.0, Node ≥24.0.0
7
+ **MCP SDK:** `@modelcontextprotocol/sdk` ^1.30.0
8
8
  **Zod:** ^4.4.3
9
9
 
10
10
  > **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
@@ -296,7 +296,6 @@ Available skills:
296
296
  | `security-pass` | Audit server for MCP-flavored security gaps: output injection, scope blast radius, input sinks, tenant isolation |
297
297
  | `tool-defs-analysis` | Read-only audit of MCP definition language across the surface — voice, leaks, defaults, recovery hints, output descriptions |
298
298
  | `code-simplifier` | Post-session cleanup against `git diff` — modernize syntax, consolidate duplication, align with the codebase |
299
- | `devcheck` | Lint, format, typecheck, audit |
300
299
  | `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
301
300
  | `git-wrapup` | Land working-tree changes as a versioned commit + annotated tag — version bump, changelog, verify, tag. Local only. |
302
301
  | `release-and-publish` | Ship a release end-to-end across npm, MCP Registry, GitHub Releases (`.mcpb`), and GHCR |
@@ -304,12 +303,14 @@ Available skills:
304
303
  | `orchestrations` | Chain task skills into a gated multi-phase pipeline — build-out, QA-fix, update-ship — when you can spawn sub-agents |
305
304
  | `report-issue-framework` | File a bug or feature request against `@cyanheads/mcp-ts-core` via `gh` CLI |
306
305
  | `report-issue-local` | File a bug or feature request against this server's own repo via `gh` CLI |
306
+ | `techniques` | Catalog of response/data-shaping techniques — overflow handling, payload shaping, retrieval patterns |
307
307
  | `api-auth` | Auth modes, scopes, JWT/OAuth |
308
308
  | `api-canvas` | DataCanvas: register tabular data, run SQL, export, plus the `spillover()` helper for big result sets — Tier 3 opt-in |
309
309
  | `api-config` | AppConfig, parseConfig, env vars |
310
310
  | `api-context` | Context interface, logger, state, progress |
311
311
  | `api-errors` | McpError, JsonRpcErrorCode, error patterns |
312
312
  | `api-linter` | Definition linter rule catalog — invoked by `bun run lint:mcp` and `devcheck` |
313
+ | `api-mirror` | MirrorService: persistent self-refreshing local mirror (embedded SQLite + FTS5) of a bulk upstream dataset — Tier 3 opt-in |
313
314
  | `api-services` | LLM, Speech, Graph services |
314
315
  | `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
315
316
  | `api-testing` | createMockContext, test patterns |
@@ -324,7 +325,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
324
325
 
325
326
  ## Commands
326
327
 
327
- **Runtime:** Scripts use `tsx`both `bun run <cmd>` and `npm run <cmd>` work. `bun` is preferred (faster startup, native TS).
328
+ **Runtime:** Scripts use Bun's native TypeScript execution — `bun run <cmd>` is the standard invocation. `npm run <cmd>` also works (npm delegates to bun).
328
329
 
329
330
  | Command | Purpose |
330
331
  |:--------|:--------|
@@ -340,7 +341,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
340
341
  | `bun run lint:mcp` | Validate MCP definitions against the linter rules |
341
342
  | `bun run lint:packaging` | Validate env var alignment between `manifest.json` and `server.json` |
342
343
  | `bun run bundle` | Build, pack, and clean a `.mcpb` for one-click Claude Desktop install |
343
- | `bun run test` | Run Vitest tests |
344
+ | `bun run test` | Run tests (Vitest use `bun run test`, not `bun test`) |
344
345
  | `bun run start:stdio` | Production mode (stdio) — requires `bun run build` first |
345
346
  | `bun run start:http` | Production mode (HTTP) — requires `bun run build` first |
346
347
  | `bun run changelog:build` | Regenerate `CHANGELOG.md` rollup from `changelog/<minor>.x/*.md` |
@@ -350,7 +351,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
350
351
 
351
352
  ## Bundling
352
353
 
353
- `bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips dependency-shipped agent docs (`node_modules/**` `skills/`, `.claude/`, `.agents/`, `SKILL.md`) that root-anchored `.mcpbignore` patterns cannot reach. MCPB is stdio-only — HTTP deployments are unaffected. Delete `manifest.json` and `.mcpbignore` if not shipping MCPB bundles; `lint:packaging` skips cleanly.
354
+ `bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips two classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`skills/`, `.claude/`, `.agents/`, `SKILL.md`) and platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on. MCPB is stdio-only — HTTP deployments are unaffected. Delete `manifest.json` and `.mcpbignore` if not shipping MCPB bundles; `lint:packaging` skips cleanly.
354
355
 
355
356
  **Adding an env var requires both files:** `server.json` (`environmentVariables[]`) and `manifest.json` (`mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match.
356
357
 
@@ -364,16 +365,22 @@ Each per-version file opens with YAML frontmatter:
364
365
 
365
366
  ```markdown
366
367
  ---
367
- summary: One-line headline, ≤350 chars # required — powers the rollup index
368
- breaking: false # optional — true flags breaking changes
369
- security: false # optional — true flags security fixes
368
+ summary: "One-line headline, ≤350 chars" # required — powers the rollup index
369
+ breaking: false # optional — true flags breaking changes
370
+ security: false # optional — true ONLY for a source-code security fix, never a dependency CVE bump
370
371
  ---
371
372
 
372
373
  # 0.1.0 — YYYY-MM-DD
373
374
  ...
374
375
  ```
375
376
 
376
- `breaking: true` renders a `· ⚠️ Breaking` badge — use it when consumers must update code on upgrade (signature changes, removed APIs, config renames). `security: true` renders a `· 🛡️ Security` badge and pairs with a `## Security` body section. When both are set, badges render `· ⚠️ Breaking · 🛡️ Security`.
377
+ `breaking: true` renders a `· ⚠️ Breaking` badge — use it when consumers must update code on upgrade (signature changes, removed APIs, config renames). `security: true` renders a `· 🛡️ Security` badge and pairs with a `## Security` body section — set it only for a security fix in this server's *own source code*, never for a routine dependency or transitive CVE bump (record those under `## Dependencies`). When both are set, badges render `· ⚠️ Breaking · 🛡️ Security`.
378
+
379
+ `agent-notes` is an optional free-form field for maintenance agents processing the release downstream. Content here won't appear in the rendered CHANGELOG — it's consumed by agents running the `maintenance` skill. Use it for adoption instructions that don't fit the human-facing sections: new files to create, fields to populate, one-time migration steps. Omit entirely when there's nothing to say.
380
+
381
+ **Section order** (Keep a Changelog): Added, Changed, Deprecated, Removed, Fixed, Security. Include only sections with entries — don't ship empty headers.
382
+
383
+ **Tag annotations** render as GitHub Release bodies via `--notes-from-tag`. They must be structured markdown — never a flat comma-separated string. Subject omits the version number (GitHub prepends it). See `changelog/template.md` for the full format reference.
377
384
 
378
385
  ---
379
386
 
package/CLAUDE.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Agent Protocol
2
2
 
3
3
  **Server:** obsidian-mcp-server
4
- **Version:** 3.2.8
5
- **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.10.9`
6
- **Engines:** Bun ≥1.3.11, Node ≥24.0.0
7
- **MCP SDK:** `@modelcontextprotocol/sdk` ^1.29.0
4
+ **Version:** 3.2.10
5
+ **Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.11.1`
6
+ **Engines:** Bun ≥1.3.0, Node ≥24.0.0
7
+ **MCP SDK:** `@modelcontextprotocol/sdk` ^1.30.0
8
8
  **Zod:** ^4.4.3
9
9
 
10
10
  > **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
@@ -296,7 +296,6 @@ Available skills:
296
296
  | `security-pass` | Audit server for MCP-flavored security gaps: output injection, scope blast radius, input sinks, tenant isolation |
297
297
  | `tool-defs-analysis` | Read-only audit of MCP definition language across the surface — voice, leaks, defaults, recovery hints, output descriptions |
298
298
  | `code-simplifier` | Post-session cleanup against `git diff` — modernize syntax, consolidate duplication, align with the codebase |
299
- | `devcheck` | Lint, format, typecheck, audit |
300
299
  | `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
301
300
  | `git-wrapup` | Land working-tree changes as a versioned commit + annotated tag — version bump, changelog, verify, tag. Local only. |
302
301
  | `release-and-publish` | Ship a release end-to-end across npm, MCP Registry, GitHub Releases (`.mcpb`), and GHCR |
@@ -304,12 +303,14 @@ Available skills:
304
303
  | `orchestrations` | Chain task skills into a gated multi-phase pipeline — build-out, QA-fix, update-ship — when you can spawn sub-agents |
305
304
  | `report-issue-framework` | File a bug or feature request against `@cyanheads/mcp-ts-core` via `gh` CLI |
306
305
  | `report-issue-local` | File a bug or feature request against this server's own repo via `gh` CLI |
306
+ | `techniques` | Catalog of response/data-shaping techniques — overflow handling, payload shaping, retrieval patterns |
307
307
  | `api-auth` | Auth modes, scopes, JWT/OAuth |
308
308
  | `api-canvas` | DataCanvas: register tabular data, run SQL, export, plus the `spillover()` helper for big result sets — Tier 3 opt-in |
309
309
  | `api-config` | AppConfig, parseConfig, env vars |
310
310
  | `api-context` | Context interface, logger, state, progress |
311
311
  | `api-errors` | McpError, JsonRpcErrorCode, error patterns |
312
312
  | `api-linter` | Definition linter rule catalog — invoked by `bun run lint:mcp` and `devcheck` |
313
+ | `api-mirror` | MirrorService: persistent self-refreshing local mirror (embedded SQLite + FTS5) of a bulk upstream dataset — Tier 3 opt-in |
313
314
  | `api-services` | LLM, Speech, Graph services |
314
315
  | `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
315
316
  | `api-testing` | createMockContext, test patterns |
@@ -324,7 +325,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
324
325
 
325
326
  ## Commands
326
327
 
327
- **Runtime:** Scripts use `tsx`both `bun run <cmd>` and `npm run <cmd>` work. `bun` is preferred (faster startup, native TS).
328
+ **Runtime:** Scripts use Bun's native TypeScript execution — `bun run <cmd>` is the standard invocation. `npm run <cmd>` also works (npm delegates to bun).
328
329
 
329
330
  | Command | Purpose |
330
331
  |:--------|:--------|
@@ -340,7 +341,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
340
341
  | `bun run lint:mcp` | Validate MCP definitions against the linter rules |
341
342
  | `bun run lint:packaging` | Validate env var alignment between `manifest.json` and `server.json` |
342
343
  | `bun run bundle` | Build, pack, and clean a `.mcpb` for one-click Claude Desktop install |
343
- | `bun run test` | Run Vitest tests |
344
+ | `bun run test` | Run tests (Vitest use `bun run test`, not `bun test`) |
344
345
  | `bun run start:stdio` | Production mode (stdio) — requires `bun run build` first |
345
346
  | `bun run start:http` | Production mode (HTTP) — requires `bun run build` first |
346
347
  | `bun run changelog:build` | Regenerate `CHANGELOG.md` rollup from `changelog/<minor>.x/*.md` |
@@ -350,7 +351,7 @@ When you complete a skill's checklist, check the boxes and add a completion time
350
351
 
351
352
  ## Bundling
352
353
 
353
- `bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips dependency-shipped agent docs (`node_modules/**` `skills/`, `.claude/`, `.agents/`, `SKILL.md`) that root-anchored `.mcpbignore` patterns cannot reach. MCPB is stdio-only — HTTP deployments are unaffected. Delete `manifest.json` and `.mcpbignore` if not shipping MCPB bundles; `lint:packaging` skips cleanly.
354
+ `bun run bundle` produces a `.mcpb` extension bundle for one-click install in Claude Desktop. The pack step is followed by `scripts/clean-mcpb.ts`, which prunes dev dependencies (`mcpb clean`) and strips two classes of `node_modules/**` content that root-anchored `.mcpbignore` patterns cannot reach: dependency-shipped agent docs (`skills/`, `.claude/`, `.agents/`, `SKILL.md`) and platform-specific native bindings, which would otherwise lock the bundle to the platform it was packed on. MCPB is stdio-only — HTTP deployments are unaffected. Delete `manifest.json` and `.mcpbignore` if not shipping MCPB bundles; `lint:packaging` skips cleanly.
354
355
 
355
356
  **Adding an env var requires both files:** `server.json` (`environmentVariables[]`) and `manifest.json` (`mcp_config.env` + `user_config`). `lint:packaging` (run by `devcheck`) verifies the env var names match.
356
357
 
@@ -364,16 +365,22 @@ Each per-version file opens with YAML frontmatter:
364
365
 
365
366
  ```markdown
366
367
  ---
367
- summary: One-line headline, ≤350 chars # required — powers the rollup index
368
- breaking: false # optional — true flags breaking changes
369
- security: false # optional — true flags security fixes
368
+ summary: "One-line headline, ≤350 chars" # required — powers the rollup index
369
+ breaking: false # optional — true flags breaking changes
370
+ security: false # optional — true ONLY for a source-code security fix, never a dependency CVE bump
370
371
  ---
371
372
 
372
373
  # 0.1.0 — YYYY-MM-DD
373
374
  ...
374
375
  ```
375
376
 
376
- `breaking: true` renders a `· ⚠️ Breaking` badge — use it when consumers must update code on upgrade (signature changes, removed APIs, config renames). `security: true` renders a `· 🛡️ Security` badge and pairs with a `## Security` body section. When both are set, badges render `· ⚠️ Breaking · 🛡️ Security`.
377
+ `breaking: true` renders a `· ⚠️ Breaking` badge — use it when consumers must update code on upgrade (signature changes, removed APIs, config renames). `security: true` renders a `· 🛡️ Security` badge and pairs with a `## Security` body section — set it only for a security fix in this server's *own source code*, never for a routine dependency or transitive CVE bump (record those under `## Dependencies`). When both are set, badges render `· ⚠️ Breaking · 🛡️ Security`.
378
+
379
+ `agent-notes` is an optional free-form field for maintenance agents processing the release downstream. Content here won't appear in the rendered CHANGELOG — it's consumed by agents running the `maintenance` skill. Use it for adoption instructions that don't fit the human-facing sections: new files to create, fields to populate, one-time migration steps. Omit entirely when there's nothing to say.
380
+
381
+ **Section order** (Keep a Changelog): Added, Changed, Deprecated, Removed, Fixed, Security. Include only sections with entries — don't ship empty headers.
382
+
383
+ **Tag annotations** render as GitHub Release bodies via `--notes-from-tag`. They must be structured markdown — never a flat comma-separated string. Subject omits the version number (GitHub prepends it). See `changelog/template.md` for the full format reference.
377
384
 
378
385
  ---
379
386
 
package/Dockerfile CHANGED
@@ -4,15 +4,17 @@
4
4
  # This stage installs all dependencies (including dev), builds the TypeScript
5
5
  # source code into JavaScript, and prepares the production assets.
6
6
  # ==============================================================================
7
- FROM oven/bun:1.3 AS build
7
+ FROM oven/bun:1.3.14 AS build
8
8
 
9
9
  WORKDIR /usr/src/app
10
10
 
11
11
  # Copy dependency manifests for optimized layer caching
12
12
  COPY package.json bun.lock ./
13
13
 
14
- # Install all dependencies (including dev dependencies for building)
15
- RUN bun install --frozen-lockfile
14
+ # Install all dependencies (including dev dependencies for building).
15
+ # The BuildKit cache mount persists Bun's global package cache across builds.
16
+ RUN --mount=type=cache,target=/root/.bun/install/cache \
17
+ bun install --frozen-lockfile --ignore-scripts
16
18
 
17
19
  # Copy the rest of the source code
18
20
  COPY . .
@@ -28,7 +30,7 @@ RUN bun run build
28
30
  # application. It uses a slim base image and only includes production
29
31
  # dependencies and build artifacts.
30
32
  # ==============================================================================
31
- FROM oven/bun:1.3-slim AS production
33
+ FROM oven/bun:1.3.14-slim AS production
32
34
 
33
35
  WORKDIR /usr/src/app
34
36
 
@@ -47,14 +49,16 @@ COPY package.json bun.lock ./
47
49
 
48
50
  # Install only production dependencies, ignoring any lifecycle scripts (like 'prepare')
49
51
  # that are not needed in the final production image.
50
- RUN bun install --production --frozen-lockfile --ignore-scripts
52
+ RUN --mount=type=cache,target=/root/.bun/install/cache \
53
+ bun install --production --frozen-lockfile --ignore-scripts
51
54
 
52
55
  # Conditionally install OpenTelemetry optional peer dependencies (Tier 3).
53
56
  # These are not bundled by default to keep the base image lean. Enable at build time
54
57
  # with: docker build --build-arg OTEL_ENABLED=true
55
58
  ARG OTEL_ENABLED=true
56
- RUN if [ "$OTEL_ENABLED" = "true" ]; then \
57
- bun add @hono/otel \
59
+ RUN --mount=type=cache,target=/root/.bun/install/cache \
60
+ if [ "$OTEL_ENABLED" = "true" ]; then \
61
+ bun add --omit=dev --ignore-scripts @hono/otel \
58
62
  @opentelemetry/instrumentation-http \
59
63
  @opentelemetry/exporter-metrics-otlp-http \
60
64
  @opentelemetry/exporter-trace-otlp-http \
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  <div align="center">
9
9
 
10
- [![Version](https://img.shields.io/badge/Version-3.2.8-blue.svg?style=flat-square)](./CHANGELOG.md) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![Docker](https://img.shields.io/badge/Docker-ghcr.io-2496ED?style=flat-square&logo=docker&logoColor=white)](https://github.com/users/cyanheads/packages/container/package/obsidian-mcp-server) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![npm](https://img.shields.io/npm/v/obsidian-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/obsidian-mcp-server) [![TypeScript](https://img.shields.io/badge/TypeScript-^6.0.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3.11-blueviolet.svg?style=flat-square)](https://bun.sh/)
10
+ [![Version](https://img.shields.io/badge/Version-3.2.10-blue.svg?style=flat-square)](./CHANGELOG.md) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![Docker](https://img.shields.io/badge/Docker-ghcr.io-2496ED?style=flat-square&logo=docker&logoColor=white)](https://github.com/users/cyanheads/packages/container/package/obsidian-mcp-server) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.30.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![npm](https://img.shields.io/npm/v/obsidian-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/obsidian-mcp-server) [![TypeScript](https://img.shields.io/badge/TypeScript-^7.0.2-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3.0-blueviolet.svg?style=flat-square)](https://bun.sh/)
11
11
 
12
12
  </div>
13
13
 
@@ -98,6 +98,8 @@ Surgical edits at a single document target.
98
98
  - `operation: "replace"` swaps it out
99
99
  - Targets: heading path, block reference ID, or frontmatter field
100
100
 
101
+ Heading targets accept either the full `Parent::Child` path or a bare leaf name. A bare leaf that matches exactly one heading is expanded to its full path before the write, and the response echoes the locator the edit landed on; a leaf matching several headings is rejected with `ambiguous_section`, whose error data lists the candidate paths. The same resolution applies to `obsidian_write_note` and `obsidian_append_to_note` with `section`.
102
+
101
103
  Use `obsidian_get_note` with `format: "document-map"` to discover what targets exist before patching.
102
104
 
103
105
  ---
@@ -252,8 +254,9 @@ MCP_TRANSPORT_TYPE=http OBSIDIAN_API_KEY=... bun run start:http
252
254
 
253
255
  ### Prerequisites
254
256
 
255
- - [Bun v1.3.11](https://bun.sh/) or higher (or Node.js v24+).
256
- - The [Obsidian Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) plugin **v4.0.0 or later** installed and enabled in your vault. Generate an API key in **Settings → Community Plugins → Local REST API** and copy it into `OBSIDIAN_API_KEY`.
257
+ - [Bun v1.3.0](https://bun.sh/) or higher (or Node.js v24+).
258
+ - The [Obsidian Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) plugin, **v4.0.0 through v5.x**, installed and enabled in your vault. Generate an API key in **Settings → Community Plugins → Local REST API** and copy it into `OBSIDIAN_API_KEY`. Plugin v6.0 removes the markdown-patch 1.x wire format this server pins for section-targeted writes and the document map.
259
+ - Periodic-note targets (`target: { "type": "periodic" }`) additionally need plugin **v5.0.1 or earlier** — v5.0.2 removed the built-in `/periodic/` routes. Every other target type is unaffected.
257
260
  - This server defaults to `http://127.0.0.1:27123` for simplicity. Enable **"Non-encrypted (HTTP) Server"** in the plugin settings to use it. To use the always-on HTTPS port instead, set `OBSIDIAN_BASE_URL=https://127.0.0.1:27124`; the plugin's self-signed cert is handled by `OBSIDIAN_VERIFY_SSL=false` (the default).
258
261
 
259
262
  ### Installation
@@ -0,0 +1,47 @@
1
+ ---
2
+ summary: "Markdown-Patch-Version: 1 pinned on every PATCH and document-map fetch, restoring section-targeted writes against Local REST API v5.x (#94); bare heading leaves resolve to a unique full path or reject as ambiguous_section (#75); bunfig.toml gains a 3-day release-age guard and Socket scanner; mcp-ts-core ^0.11.1"
3
+ breaking: false
4
+ security: true
5
+ ---
6
+
7
+ # 3.2.10 — 2026-08-02
8
+
9
+ ## Added
10
+
11
+ - **`ambiguous_section` error** on `obsidian_patch_note`, `obsidian_append_to_note`, and `obsidian_write_note` — a bare heading leaf matching several headings in a note is rejected with a `Conflict`, `error.data.candidates` listing every matching full path.
12
+ - **`sectionTarget` output field** on `obsidian_append_to_note` and `obsidian_write_note`; `obsidian_patch_note`'s `section` output now echoes the resolved locator. All three surface where a bare leaf write actually landed.
13
+
14
+ ## Changed
15
+
16
+ - **`ObsidianService.patchNote`** resolves a heading target against the note's document map before writing: an exact map entry is used as-is, a leaf matching exactly one heading expands to its full `Parent::Child` path, an unmatched leaf passes through untouched so `createTargetIfMissing` still creates it.
17
+ - **README** documents the supported Local REST API plugin range (v4.0.0 through v5.x — v6.0 removes the markdown-patch 1.x format this server pins, tracked in #102) and that periodic-note targets additionally need plugin v5.0.1 or earlier (v5.0.2 removed the `/periodic/` routes).
18
+ - **`.mcpbignore`-unreachable bundle strip** (`scripts/clean-mcpb.ts`, `scripts/lint-packaging.ts` check 8) now also removes platform-specific `@duckdb/node-bindings-*` native binaries, not just dependency-shipped agent docs — an unstripped binding locked a bundle to its build platform and could push it past the 25 MB registry cap (#274).
19
+ - **`scripts/check-dependency-specifiers.ts`** now scans `overrides` for floating specifiers, alongside the existing four `package.json` dependency sections.
20
+ - **`scripts/devcheck.ts`** Outdated check no longer flags a row held at its current version by `bunfig.toml`'s `minimumReleaseAge` guard, or a `peerDependencies` range (a floor, not a version to track).
21
+ - **`.gitignore`** anchors `data/` to the repo root (`/data/`) so a nested `data/` directory elsewhere in the tree isn't inadvertently ignored.
22
+ - **`package.json`** author field normalized to `Casey Hand <casey@caseyjhand.com> (https://caseyjhand.com)`.
23
+
24
+ ### Dependency bumps
25
+
26
+ - `@cyanheads/mcp-ts-core` ^0.10.10 → ^0.11.1
27
+ - `@modelcontextprotocol/sdk` (transitive) ^1.29.0 → ^1.30.0
28
+ - `typescript` ^6.0.3 → ^7.0.2
29
+ - `@biomejs/biome` ^2.5.1 → ^2.5.6
30
+ - `undici` ^8.5.0 → ^8.9.0
31
+ - `js-yaml` ^5.2.0 → ^5.2.2
32
+ - `tsc-alias` ^1.8.17 → ^1.9.1
33
+ - `@types/node` ^26.0.1 → ^26.1.2
34
+ - `vitest` ^4.1.9 → ^4.1.10
35
+ - `ignore` ^7.0.5 → ^7.0.6
36
+ - `@socketsecurity/bun-security-scanner` ^1.1.2 (new dev dependency, backs the Socket scanner below)
37
+ - `bun` packageManager 1.3.11 → 1.3.14; `engines.bun` floor relaxed `>=1.3.11` → `>=1.3.0`
38
+
39
+ ## Fixed
40
+
41
+ - **Section-targeted writes against Local REST API v5.x** ([#94](https://github.com/cyanheads/obsidian-mcp-server/issues/94)) — `ObsidianService` now sends `Markdown-Patch-Version: 1` on every PATCH and on the document-map fetch. Plugin v5.0.0 made format 2.0 the default and rejects header-driven PATCH targeting outright without a pinned version; plugin v4.x only reads headers it knows by name, so the pin is inert there and one unconditional value covers v4.0.0 through v5.x.
42
+ - **Bare heading-leaf writes reach the section a matching read would** ([#75](https://github.com/cyanheads/obsidian-mcp-server/issues/75)) — `obsidian_get_note` with `format: "section"` matches a heading leaf at any depth, but PATCH targeting wanted the full `Parent::Child` chain, so a write built from a read's locator could silently create a new top-level heading via `createTargetIfMissing` instead of touching the existing one. Resolution now runs before the write, not as a retry after failure.
43
+
44
+ ## Security
45
+
46
+ - **`bunfig.toml` supply-chain guard** — `minimumReleaseAge = 259200` (3 days) blocks installing a package version published within the last 3 days, with `@cyanheads/mcp-ts-core` excluded for same-day framework adoption. Versions already in `bun.lock` are unaffected.
47
+ - **Socket scanner** — `[install.security] scanner = "@socketsecurity/bun-security-scanner"` scans every package for malware, typosquats, and known CVEs before install.
@@ -0,0 +1,30 @@
1
+ ---
2
+ summary: "ReDoS guards reject catastrophic-backtracking regex on obsidian_list_notes and obsidian_replace_in_note (#88); obsidian_manage_frontmatter / obsidian_manage_tags edits preserve comments, quoting, and plain dates (#89); tool description polish (#86); mcp-ts-core ^0.10.10"
3
+ breaking: false
4
+ security: true
5
+ ---
6
+
7
+ # 3.2.9 — 2026-06-30
8
+
9
+ ## Changed
10
+
11
+ - **Tool descriptions tightened** ([#86](https://github.com/cyanheads/obsidian-mcp-server/issues/86)) — `obsidian_patch_note` `applyIfContentPreexists` ("idempotent against retries", "Replace operations are never rejected") and `obsidian_search_notes` `query` / `logic` / `pathPrefix` wording (`pathPrefix` now states it filters after matching and does not narrow the search).
12
+ - **`obsidian_get_note` `format()`** ([#86](https://github.com/cyanheads/obsidian-mcp-server/issues/86)) — the section line drops the `(valueText/valueJson)` suffix and labels the rendered body with `**Value:**`.
13
+
14
+ ### Dependency bumps
15
+
16
+ - `@cyanheads/mcp-ts-core` ^0.10.9 → ^0.10.10
17
+ - `js-yaml` ^4.2.0 → ^5.2.0
18
+ - `@types/js-yaml` ^4.0.9 → removed (v5 ships its own types)
19
+ - `yaml` → ^2.9.0 (new — backs the #89 fix)
20
+ - `@biomejs/biome` ^2.5.0 → ^2.5.1
21
+ - `@types/node` ^26.0.0 → ^26.0.1
22
+
23
+ ## Fixed
24
+
25
+ - **Surgical frontmatter edits preserve formatting** ([#89](https://github.com/cyanheads/obsidian-mcp-server/issues/89)) — `obsidian_manage_frontmatter` key deletes and `obsidian_manage_tags` reconciles now parse the block with the `yaml` package's CST-backed `parseDocument` and edit nodes in place, instead of round-tripping through `js-yaml` `load`/`dump`. Comments, quoting, and scalar formatting on untouched keys survive verbatim — a plain `date: 2026-06-29` is no longer rewritten to an ISO timestamp.
26
+
27
+ ## Security
28
+
29
+ - **ReDoS guard on user-supplied regex** ([#88](https://github.com/cyanheads/obsidian-mcp-server/issues/88)) — `obsidian_list_notes` (`nameRegex`, ≤256 chars) and `obsidian_replace_in_note` (`useRegex` search, ≤1024 chars) statically reject patterns that exceed the length cap or contain nested quantifiers (e.g. `(a+)+`) before compiling, throwing a `regex_unsafe` `ValidationError`. The shared `nameRegexSafetyIssue` helper gained a `maxLength` parameter so `obsidian_replace_in_note` rejects before the pattern runs over the note body.
30
+ - **`bun.lock` refreshed** — `bun audit` reports clean.
@@ -15,9 +15,11 @@ summary: ""
15
15
  # usage. Flagged as `Breaking` in the rollup.
16
16
  breaking: false
17
17
 
18
- # Set `true` if this release contains any security fix. Pairs with the
19
- # `## Security` section below. Flagged as `Security` in the rollup so
20
- # users can triage upgrade urgency at a glance.
18
+ # Set `true` ONLY for a security fix in THIS project's own source code — a
19
+ # vulnerability or hardening in code you ship. A dependency or transitive CVE
20
+ # bump is routine maintenance, NOT a security release: record it under
21
+ # `## Dependencies` (with the advisory ID) and leave this `false`. When true,
22
+ # pairs with the `## Security` section below and flags `Security` in the rollup.
21
23
  security: false
22
24
 
23
25
  # Optional free-form notes for maintenance agents processing this release.
@@ -2,25 +2,7 @@
2
2
  * @fileoverview Resource registration barrel for obsidian-mcp-server.
3
3
  * @module mcp-server/resources/definitions/index
4
4
  */
5
- export declare const allResourceDefinitions: (import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
6
- status: import("zod").ZodString;
7
- service: import("zod").ZodString;
8
- authenticated: import("zod").ZodBoolean;
9
- versions: import("zod").ZodOptional<import("zod").ZodObject<{
10
- obsidian: import("zod").ZodOptional<import("zod").ZodString>;
11
- self: import("zod").ZodOptional<import("zod").ZodString>;
12
- }, import("zod/v4/core").$strip>>;
13
- manifest: import("zod").ZodOptional<import("zod").ZodObject<{
14
- id: import("zod").ZodString;
15
- name: import("zod").ZodString;
16
- version: import("zod").ZodString;
17
- }, import("zod/v4/core").$strip>>;
18
- }, import("zod/v4/core").$strip>, undefined> | import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
19
- tags: import("zod").ZodArray<import("zod").ZodObject<{
20
- name: import("zod").ZodString;
21
- count: import("zod").ZodNumber;
22
- }, import("zod/v4/core").$strip>>;
23
- }, import("zod/v4/core").$strip>, undefined> | import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{
5
+ export declare const allResourceDefinitions: (import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{
24
6
  path: import("zod").ZodString;
25
7
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
26
8
  path: import("zod").ZodString;
@@ -42,5 +24,23 @@ export declare const allResourceDefinitions: (import("@cyanheads/mcp-ts-core").R
42
24
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
43
25
  readonly when: "The vault path does not resolve to an existing note.";
44
26
  readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
45
- }]>)[];
27
+ }]> | import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
28
+ tags: import("zod").ZodArray<import("zod").ZodObject<{
29
+ name: import("zod").ZodString;
30
+ count: import("zod").ZodNumber;
31
+ }, import("zod/v4/core").$strip>>;
32
+ }, import("zod/v4/core").$strip>, undefined> | import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
33
+ status: import("zod").ZodString;
34
+ service: import("zod").ZodString;
35
+ authenticated: import("zod").ZodBoolean;
36
+ versions: import("zod").ZodOptional<import("zod").ZodObject<{
37
+ obsidian: import("zod").ZodOptional<import("zod").ZodString>;
38
+ self: import("zod").ZodOptional<import("zod").ZodString>;
39
+ }, import("zod/v4/core").$strip>>;
40
+ manifest: import("zod").ZodOptional<import("zod").ZodObject<{
41
+ id: import("zod").ZodString;
42
+ name: import("zod").ZodString;
43
+ version: import("zod").ZodString;
44
+ }, import("zod/v4/core").$strip>>;
45
+ }, import("zod/v4/core").$strip>, undefined>)[];
46
46
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAAoD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+CAAoD,CAAC"}
@@ -2,17 +2,22 @@
2
2
  * @fileoverview Static safety guards for user-supplied `nameRegex` filters.
3
3
  * JavaScript's RegExp engine has no native execution timeout, so we statically
4
4
  * reject the textbook catastrophic-backtracking shapes before calling
5
- * `new RegExp(...)`. Shared by tools that post-filter upstream listings by
6
- * name (`obsidian_list_tags`, `obsidian_list_commands`).
5
+ * `new RegExp(...)`. Shared by every tool that compiles a user-supplied regex:
6
+ * the name filters on `obsidian_list_tags` / `obsidian_list_commands` /
7
+ * `obsidian_list_notes`, and the `useRegex` search patterns on
8
+ * `obsidian_replace_in_note` (which raises the length cap for note-body input).
7
9
  * @module mcp-server/tools/definitions/_shared/regex-safety
8
10
  */
9
11
  /** Maximum allowed pattern length — bounds compile cost and AST surface. */
10
12
  export declare const NAME_REGEX_MAX_LENGTH = 256;
11
13
  /**
12
14
  * Returns a human-readable reason string when the pattern is unsafe, or
13
- * `undefined` when it passes the static guards. Callers compile with
14
- * `new RegExp(pattern)` after this returns `undefined` and surface the
15
- * returned reason via the tool's `regex_unsafe` error.
15
+ * `undefined` when it passes the static guards. `maxLength` defaults to
16
+ * {@link NAME_REGEX_MAX_LENGTH}; callers running patterns over larger input
17
+ * (e.g. a full note body) may raise it. The nested-quantifier check is applied
18
+ * unchanged regardless of the cap. Callers compile with `new RegExp(pattern)`
19
+ * after this returns `undefined` and surface the returned reason via the
20
+ * tool's `regex_unsafe` error.
16
21
  */
17
- export declare function nameRegexSafetyIssue(pattern: string): string | undefined;
22
+ export declare function nameRegexSafetyIssue(pattern: string, maxLength?: number): string | undefined;
18
23
  //# sourceMappingURL=regex-safety.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"regex-safety.d.ts","sourceRoot":"","sources":["../../../../../src/mcp-server/tools/definitions/_shared/regex-safety.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAWzC;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQxE"}
1
+ {"version":3,"file":"regex-safety.d.ts","sourceRoot":"","sources":["../../../../../src/mcp-server/tools/definitions/_shared/regex-safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAWzC;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,SAAwB,GAChC,MAAM,GAAG,SAAS,CAQpB"}
@@ -2,8 +2,10 @@
2
2
  * @fileoverview Static safety guards for user-supplied `nameRegex` filters.
3
3
  * JavaScript's RegExp engine has no native execution timeout, so we statically
4
4
  * reject the textbook catastrophic-backtracking shapes before calling
5
- * `new RegExp(...)`. Shared by tools that post-filter upstream listings by
6
- * name (`obsidian_list_tags`, `obsidian_list_commands`).
5
+ * `new RegExp(...)`. Shared by every tool that compiles a user-supplied regex:
6
+ * the name filters on `obsidian_list_tags` / `obsidian_list_commands` /
7
+ * `obsidian_list_notes`, and the `useRegex` search patterns on
8
+ * `obsidian_replace_in_note` (which raises the length cap for note-body input).
7
9
  * @module mcp-server/tools/definitions/_shared/regex-safety
8
10
  */
9
11
  /** Maximum allowed pattern length — bounds compile cost and AST surface. */
@@ -18,13 +20,16 @@ export const NAME_REGEX_MAX_LENGTH = 256;
18
20
  const NESTED_QUANTIFIER = /[+*}]\)[*+{]/;
19
21
  /**
20
22
  * Returns a human-readable reason string when the pattern is unsafe, or
21
- * `undefined` when it passes the static guards. Callers compile with
22
- * `new RegExp(pattern)` after this returns `undefined` and surface the
23
- * returned reason via the tool's `regex_unsafe` error.
23
+ * `undefined` when it passes the static guards. `maxLength` defaults to
24
+ * {@link NAME_REGEX_MAX_LENGTH}; callers running patterns over larger input
25
+ * (e.g. a full note body) may raise it. The nested-quantifier check is applied
26
+ * unchanged regardless of the cap. Callers compile with `new RegExp(pattern)`
27
+ * after this returns `undefined` and surface the returned reason via the
28
+ * tool's `regex_unsafe` error.
24
29
  */
25
- export function nameRegexSafetyIssue(pattern) {
26
- if (pattern.length > NAME_REGEX_MAX_LENGTH) {
27
- return `pattern exceeds ${NAME_REGEX_MAX_LENGTH}-character limit`;
30
+ export function nameRegexSafetyIssue(pattern, maxLength = NAME_REGEX_MAX_LENGTH) {
31
+ if (pattern.length > maxLength) {
32
+ return `pattern exceeds ${maxLength}-character limit`;
28
33
  }
29
34
  if (NESTED_QUANTIFIER.test(pattern)) {
30
35
  return 'pattern contains nested quantifiers (catastrophic-backtracking risk)';
@@ -1 +1 @@
1
- {"version":3,"file":"regex-safety.js","sourceRoot":"","sources":["../../../../../src/mcp-server/tools/definitions/_shared/regex-safety.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,4EAA4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,IAAI,OAAO,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;QAC3C,OAAO,mBAAmB,qBAAqB,kBAAkB,CAAC;IACpE,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,OAAO,sEAAsE,CAAC;IAChF,CAAC;IACD,OAAO;AACT,CAAC"}
1
+ {"version":3,"file":"regex-safety.js","sourceRoot":"","sources":["../../../../../src/mcp-server/tools/definitions/_shared/regex-safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,4EAA4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEzC;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAe,EACf,SAAS,GAAG,qBAAqB;IAEjC,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QAC/B,OAAO,mBAAmB,SAAS,kBAAkB,CAAC;IACxD,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,OAAO,sEAAsE,CAAC;IAChF,CAAC;IACD,OAAO;AACT,CAAC"}
@@ -15,9 +15,9 @@ export declare const TargetSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
15
15
  type: z.ZodLiteral<"periodic">;
16
16
  period: z.ZodEnum<{
17
17
  daily: "daily";
18
- weekly: "weekly";
19
18
  monthly: "monthly";
20
19
  quarterly: "quarterly";
20
+ weekly: "weekly";
21
21
  yearly: "yearly";
22
22
  }>;
23
23
  date: z.ZodOptional<z.ZodString>;
@@ -25,9 +25,9 @@ export declare const TargetSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
25
25
  /** Sub-document target inside a note. */
26
26
  export declare const SectionSchema: z.ZodObject<{
27
27
  type: z.ZodEnum<{
28
- heading: "heading";
29
28
  block: "block";
30
29
  frontmatter: "frontmatter";
30
+ heading: "heading";
31
31
  }>;
32
32
  target: z.ZodString;
33
33
  }, z.core.$strip>;
@@ -37,8 +37,8 @@ export declare const PatchOptionsSchema: z.ZodOptional<z.ZodObject<{
37
37
  trimTargetWhitespace: z.ZodDefault<z.ZodBoolean>;
38
38
  }, z.core.$strip>>;
39
39
  export declare const ContentTypeSchema: z.ZodDefault<z.ZodEnum<{
40
- markdown: "markdown";
41
40
  json: "json";
41
+ markdown: "markdown";
42
42
  }>>;
43
43
  export type ToolTarget = z.infer<typeof TargetSchema>;
44
44
  export type ToolSection = z.infer<typeof SectionSchema>;
@@ -43,7 +43,7 @@ export const SectionSchema = z.object({
43
43
  target: z
44
44
  .string()
45
45
  .min(1)
46
- .describe('Heading name (use "::" for nested headings), block reference without leading caret (e.g. "2d9b4a", not "^2d9b4a"), or frontmatter field name.'),
46
+ .describe('Heading name — either the full path (`"Parent::Child"`) or a bare leaf name that matches exactly one heading — a block reference without the leading caret (e.g. "2d9b4a", not "^2d9b4a"), or a frontmatter field name.'),
47
47
  });
48
48
  export const PatchOptionsSchema = z
49
49
  .object({
@@ -54,7 +54,7 @@ export const PatchOptionsSchema = z
54
54
  applyIfContentPreexists: z
55
55
  .boolean()
56
56
  .default(false)
57
- .describe('When false (default), the patch is rejected if the supplied content already appears in the target — idempotent against agent retries. Set to true to force-apply even when it would duplicate. Replace operations are unaffected (the plugin exempts them).'),
57
+ .describe('When false (default), the patch is rejected if the supplied content already appears in the target — idempotent against retries. Set to true to force-apply even when it would duplicate. Replace operations are never rejected.'),
58
58
  trimTargetWhitespace: z
59
59
  .boolean()
60
60
  .default(false)
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../../../src/mcp-server/tools/definitions/_shared/schemas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAE3C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IACvD,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QACnE,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CAAC,kEAAkE,CAAC;KAChF,CAAC;SACD,QAAQ,CAAC,4CAA4C,CAAC;IACzD,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;KACnF,CAAC;SACD,QAAQ,CAAC,gEAAgE,CAAC;IAC7E,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QAC1F,MAAM,EAAE,CAAC;aACN,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;aAC3D,QAAQ,CAAC,4BAA4B,CAAC;QACzC,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,KAAK,CAAC,qBAAqB,CAAC;aAC5B,QAAQ,EAAE;aACV,QAAQ,CAAC,mDAAmD,CAAC;KACjE,CAAC;SACD,QAAQ,CAAC,6CAA6C,CAAC;CAC3D,CAAC,CAAC;AAEH,yCAAyC;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;SACzC,QAAQ,CAAC,mEAAmE,CAAC;IAChF,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,+IAA+I,CAChJ;CACJ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,qBAAqB,EAAE,CAAC;SACrB,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,yEAAyE,CAAC;IACtF,uBAAuB,EAAE,CAAC;SACvB,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CACP,6PAA6P,CAC9P;IACH,oBAAoB,EAAE,CAAC;SACpB,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,wEAAwE,CAAC;CACtF,CAAC;KACD,QAAQ,EAAE,CAAC;AAEd,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC;KAC/B,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;KAC1B,OAAO,CAAC,UAAU,CAAC;KACnB,QAAQ,CACP,qPAAqP,CACtP,CAAC"}
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../../../src/mcp-server/tools/definitions/_shared/schemas.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAE3C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IACvD,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QACnE,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CAAC,kEAAkE,CAAC;KAChF,CAAC;SACD,QAAQ,CAAC,4CAA4C,CAAC;IACzD,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;KACnF,CAAC;SACD,QAAQ,CAAC,gEAAgE,CAAC;IAC7E,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QAC1F,MAAM,EAAE,CAAC;aACN,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;aAC3D,QAAQ,CAAC,4BAA4B,CAAC;QACzC,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,KAAK,CAAC,qBAAqB,CAAC;aAC5B,QAAQ,EAAE;aACV,QAAQ,CAAC,mDAAmD,CAAC;KACjE,CAAC;SACD,QAAQ,CAAC,6CAA6C,CAAC;CAC3D,CAAC,CAAC;AAEH,yCAAyC;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;SACzC,QAAQ,CAAC,mEAAmE,CAAC;IAChF,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,yNAAyN,CAC1N;CACJ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,qBAAqB,EAAE,CAAC;SACrB,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,yEAAyE,CAAC;IACtF,uBAAuB,EAAE,CAAC;SACvB,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CACP,iOAAiO,CAClO;IACH,oBAAoB,EAAE,CAAC;SACpB,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,wEAAwE,CAAC;CACtF,CAAC;KACD,QAAQ,EAAE,CAAC;AAEd,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC;KAC/B,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;KAC1B,OAAO,CAAC,UAAU,CAAC;KACnB,QAAQ,CACP,qPAAqP,CACtP,CAAC"}