obsidian-mcp-server 3.1.5 → 3.1.7
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.
- package/CLAUDE.md +5 -3
- package/Dockerfile +2 -2
- package/README.md +3 -2
- package/changelog/3.1.x/3.1.6.md +23 -0
- package/changelog/3.1.x/3.1.7.md +41 -0
- package/changelog/template.md +67 -25
- package/dist/mcp-server/tools/definitions/index.d.ts +38 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts +6 -0
- package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js +52 -18
- package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts +2 -0
- package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js +18 -6
- package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts +4 -0
- package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js +23 -3
- package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts +4 -0
- package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js +19 -0
- package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts +2 -0
- package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js +21 -4
- package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts +2 -0
- package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js +18 -1
- package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts +2 -0
- package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js +35 -10
- package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js.map +1 -1
- package/dist/services/obsidian/obsidian-service.d.ts +18 -10
- package/dist/services/obsidian/obsidian-service.d.ts.map +1 -1
- package/dist/services/obsidian/obsidian-service.js +52 -14
- package/dist/services/obsidian/obsidian-service.js.map +1 -1
- package/package.json +5 -5
- package/server.json +3 -3
package/CLAUDE.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** obsidian-mcp-server
|
|
4
|
-
**Version:** 3.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
4
|
+
**Version:** 3.1.7
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.8.20`
|
|
6
|
+
**Engines:** Bun ≥1.3.11, Node ≥24.0.0
|
|
6
7
|
|
|
7
8
|
> **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.
|
|
8
9
|
|
|
@@ -304,8 +305,9 @@ Available skills:
|
|
|
304
305
|
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
305
306
|
| `api-linter` | MCP definition linter rule reference (`bun run lint:mcp` failures) |
|
|
306
307
|
| `api-services` | LLM, Speech, Graph services |
|
|
308
|
+
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
307
309
|
| `api-testing` | createMockContext, test patterns |
|
|
308
|
-
| `api-utils` | Formatting, parsing, security, pagination, scheduling |
|
|
310
|
+
| `api-utils` | Formatting, parsing, security, pagination, scheduling, telemetry helpers |
|
|
309
311
|
| `api-workers` | Cloudflare Workers runtime |
|
|
310
312
|
|
|
311
313
|
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
package/Dockerfile
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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 AS build
|
|
7
|
+
FROM oven/bun:1.3 AS build
|
|
8
8
|
|
|
9
9
|
WORKDIR /usr/src/app
|
|
10
10
|
|
|
@@ -28,7 +28,7 @@ RUN bun run build
|
|
|
28
28
|
# application. It uses a slim base image and only includes production
|
|
29
29
|
# dependencies and build artifacts.
|
|
30
30
|
# ==============================================================================
|
|
31
|
-
FROM oven/bun:1-slim AS production
|
|
31
|
+
FROM oven/bun:1.3-slim AS production
|
|
32
32
|
|
|
33
33
|
WORKDIR /usr/src/app
|
|
34
34
|
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](https://www.npmjs.com/package/obsidian-mcp-server) [](https://www.npmjs.com/package/obsidian-mcp-server) [](./CHANGELOG.md) [](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [](https://modelcontextprotocol.io/)
|
|
11
11
|
|
|
12
12
|
[](./LICENSE) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
13
13
|
|
|
@@ -231,7 +231,7 @@ MCP_TRANSPORT_TYPE=http OBSIDIAN_API_KEY=... bun run start:http
|
|
|
231
231
|
|
|
232
232
|
### Prerequisites
|
|
233
233
|
|
|
234
|
-
- [Bun v1.3.11](https://bun.sh/) or higher (or Node.js
|
|
234
|
+
- [Bun v1.3.11](https://bun.sh/) or higher (or Node.js v24+).
|
|
235
235
|
- The [Obsidian Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) plugin installed and enabled in your vault. Generate an API key in **Settings → Community Plugins → Local REST API** and copy it into `OBSIDIAN_API_KEY`.
|
|
236
236
|
- 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).
|
|
237
237
|
|
|
@@ -281,6 +281,7 @@ MCP_TRANSPORT_TYPE=http OBSIDIAN_API_KEY=... bun run start:http
|
|
|
281
281
|
| `MCP_PUBLIC_URL` | Public origin override for TLS-terminating reverse-proxy deployments (landing page, Server Card, RFC 9728 metadata). | unset |
|
|
282
282
|
| `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
|
|
283
283
|
| `MCP_AUTH_SECRET_KEY` | **Required when `MCP_AUTH_MODE=jwt`.** ≥32-char shared secret used to verify incoming JWTs. | — |
|
|
284
|
+
| `MCP_AUTH_DISABLE_SCOPE_CHECKS` | When `true`, bypasses per-tool scope enforcement after the auth-context presence check. Token signature, audience, issuer, and expiry validation remain intact. Use only when a custom claim can't be injected and combine with `OBSIDIAN_READ_PATHS` / `OBSIDIAN_WRITE_PATHS` / `OBSIDIAN_READ_ONLY` for access control. A `WARNING` is logged at startup whenever the bypass is active. | `false` |
|
|
284
285
|
| `MCP_LOG_LEVEL` | Log level (RFC 5424). | `info` |
|
|
285
286
|
| `LOGS_DIR` | Directory for log files (Node.js only). | `<project-root>/logs` |
|
|
286
287
|
| `OTEL_ENABLED` | Enable OpenTelemetry. | `false` |
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Pick up `mcp_tool_scopes` claim + `MCP_AUTH_DISABLE_SCOPE_CHECKS` bypass from `@cyanheads/mcp-ts-core` 0.8.20 — resolves [#47](https://github.com/cyanheads/obsidian-mcp-server/issues/47) for OIDC providers that can't override `scope`."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 3.1.6 — 2026-05-09
|
|
8
|
+
|
|
9
|
+
Maintenance release. Picks up the framework-side fix for [#47](https://github.com/cyanheads/obsidian-mcp-server/issues/47) — operators behind Authentik / Keycloak < 26.5 / Zitadel can now inject per-tool scopes via the `mcp_tool_scopes` custom claim, or set `MCP_AUTH_DISABLE_SCOPE_CHECKS=true` and rely on `OBSIDIAN_READ_PATHS` / `OBSIDIAN_WRITE_PATHS` / `OBSIDIAN_READ_ONLY` for access control. No source changes in this server.
|
|
10
|
+
|
|
11
|
+
## Changed
|
|
12
|
+
|
|
13
|
+
- **`@cyanheads/mcp-ts-core` `^0.8.18` → `^0.8.20`.** Two upstream releases roll up:
|
|
14
|
+
- `0.8.19` — engines bumped to Bun ≥1.3.0 / Node ≥24.0.0; Docker base `oven/bun:1` → `oven/bun:1.3`; new `api-telemetry` skill (v1.0); changelog frontmatter `security: bool` field; `init` template substitutions resolve `{{MCP_SDK_VERSION}}` and `{{ZOD_VERSION}}` from the framework `package.json`.
|
|
15
|
+
- `0.8.20` — `mcp_tool_scopes` JWT claim parsed alongside `scp` and `scope` (granted scopes are the union); `MCP_AUTH_DISABLE_SCOPE_CHECKS` env var bypasses both `withRequiredScopes` and `checkScopes` after the auth-context presence check (signature/audience/issuer/expiry validation intact); `authFactory` logs `WARNING` at startup whenever the bypass is active under non-`none` mode. ([cyanheads/mcp-ts-core#128](https://github.com/cyanheads/mcp-ts-core/issues/128))
|
|
16
|
+
- **`engines.node` `>=22.0.0` → `>=24.0.0`** (mirroring the framework). README prerequisites line updated.
|
|
17
|
+
- **Docker base image `oven/bun:1` → `oven/bun:1.3`** for build and production stages — pins to the matching minor of the framework's published image.
|
|
18
|
+
- **`@types/node` `^25.6.0` → `^25.6.2`.**
|
|
19
|
+
- **README** — env-var table gains `MCP_AUTH_DISABLE_SCOPE_CHECKS` row covering the bypass semantics, the path-policy combination, and the startup `WARNING`.
|
|
20
|
+
- **`.env.example`** — new comment block under the auth section documents the `mcp_tool_scopes` claim union, the OIDC `authorization_code` restriction, and the bypass-flag fallback.
|
|
21
|
+
- **`CLAUDE.md`** — header version updated; skills table picks up the new `api-telemetry` row and the refreshed `api-utils` description (now scoped to the helper API; OTel catalog moved to `api-telemetry`).
|
|
22
|
+
- **Phase A skill bumps** (synced from framework): `api-telemetry` (new, v1.0), `api-auth` 1.0 → 1.1 (claims mapping table + OIDC operator setup + bypass docs), `api-config` 1.3 → 1.4 (env-var row), `api-utils` 2.1 → 2.2 (telemetry section now points to `api-telemetry`), `maintenance` 2.0 → 2.1 (Phase C resyncs pristine reference files), `report-issue-framework` 1.5 → 1.6, `report-issue-local` 1.4 → 1.5 (terser issue-writing guidance), `security-pass` 1.3 → 1.4 (Axis 2 bypass-in-production check), `setup` 1.6 → 1.7 (`bunx` examples, `release-and-publish` in progression), `tool-defs-analysis` 1.0 → 1.1 (env var names allowed in recovery hints).
|
|
23
|
+
- **Phase C reference-file sync:** `scripts/build-changelog.ts` parses the new `security` frontmatter field; `changelog/template.md` documents it.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Every mutating tool now reports `previousSizeInBytes` + `currentSizeInBytes`; `obsidian_append_to_note` gains the `created` upsert flag. Resolves [#48](https://github.com/cyanheads/obsidian-mcp-server/issues/48)."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 3.1.7 — 2026-05-10
|
|
8
|
+
|
|
9
|
+
`obsidian_append_to_note` is silently an upsert primitive — POST against a non-existent path creates the file and writes the body as its full content. This release rolls the response-transparency pattern from `obsidian_write_note` onto every mutating tool: each one now reports byte-size before and after the operation, and the upsert tools flag whether the write created the file. Agents get unambiguous evidence to spot typo paths, accidental whole-file clobbers, and concurrent-writer drift from the response alone.
|
|
10
|
+
|
|
11
|
+
## Added
|
|
12
|
+
|
|
13
|
+
- **`obsidian_append_to_note`** — `created: boolean` on the output. `true` flags the upsert branch where the agent's content became the entire file at a possibly unintended path; `format()` renders the same hint as `obsidian_write_note` when set. Always `false` for section appends (PATCH requires the file to exist).
|
|
14
|
+
- **Every mutating tool** — `previousSizeInBytes` + `currentSizeInBytes` on the output. Server reports raw before/after; agent computes deltas and decides what discrepancies mean (auto-newline injection, concurrent writers, accidental shrinkage). No server-side integrity verdict.
|
|
15
|
+
- **`ObsidianService.tryGetSize(ctx, target)`** — HEAD `/vault/{path}`, parses `Content-Length`, returns `null` on 404. Path-policy gated, retry-bypassed.
|
|
16
|
+
- **`ObsidianService.getSize(ctx, target)`** — same as `tryGetSize` but throws `note_missing` on 404. Used for post-write verification reads.
|
|
17
|
+
|
|
18
|
+
## Changed
|
|
19
|
+
|
|
20
|
+
- **`obsidian_delete_note`** — elicitation prompt now includes the byte size of the file being deleted (`Permanently delete '<path>' (<N> bytes)?`).
|
|
21
|
+
- **`obsidian_write_note`** overwrite check migrated from `noteExists` to `tryGetSize !== null`. Net wash on round trips, gain the `previousSizeInBytes` data for free on the same HEAD.
|
|
22
|
+
- **`obsidian_append_to_note` description** — front-loads the create-if-missing behavior of the no-section branch (matches the wording pattern `obsidian_write_note` uses for `overwrite`).
|
|
23
|
+
- **Source-of-truth rule for note byte sizes** documented on `tryGetSize`: prefer HEAD `Content-Length` or `Buffer.byteLength(deliveredContent)`, never `note.stat.size` from the JSON envelope (shares the upstream `getAbstractFileByPath` cache path with the rest of the envelope, so it can't act as an independent cross-check — see [coddingtonbear/obsidian-local-rest-api#237](https://github.com/coddingtonbear/obsidian-local-rest-api/issues/237)).
|
|
24
|
+
- **`@biomejs/biome` `^2.4.14` → `^2.4.15`** (devDependency).
|
|
25
|
+
|
|
26
|
+
## Removed
|
|
27
|
+
|
|
28
|
+
- **`ObsidianService.noteExists`** — sole caller (`obsidian_write_note` overwrite guard) migrated to `tryGetSize`.
|
|
29
|
+
|
|
30
|
+
## Per-tool source for `currentSizeInBytes`
|
|
31
|
+
|
|
32
|
+
| Tool | Source | Extra round trips |
|
|
33
|
+
|:---|:---|:---|
|
|
34
|
+
| `obsidian_write_note` | Post-write HEAD (whole-file) / pre+post HEAD (section) | +1 / +2 |
|
|
35
|
+
| `obsidian_append_to_note` | Post-write HEAD (whole-file) / pre+post HEAD (section) | +1 / +2 |
|
|
36
|
+
| `obsidian_patch_note` | Pre+post HEAD | +2 |
|
|
37
|
+
| `obsidian_delete_note` | Always 0 (file gone); pre-DELETE HEAD also feeds the elicit prompt | +1 |
|
|
38
|
+
| `obsidian_replace_in_note` | `Buffer.byteLength` from existing GET; post-write HEAD only when matches found | 0 / +1 |
|
|
39
|
+
| `obsidian_manage_frontmatter` (`set`) | `Buffer.byteLength(noteAfter.content)` from existing post-PATCH GET | +1 (pre-PATCH HEAD) |
|
|
40
|
+
| `obsidian_manage_frontmatter` (`delete`) | `Buffer.byteLength` from existing GET; post-write HEAD only when content changed | 0 / +1 |
|
|
41
|
+
| `obsidian_manage_tags` (`add` / `remove`) | `Buffer.byteLength` from existing pre/post GETs | 0 |
|
package/changelog/template.md
CHANGED
|
@@ -1,41 +1,71 @@
|
|
|
1
1
|
---
|
|
2
|
-
# FORMAT REFERENCE —
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
#
|
|
10
|
-
#
|
|
2
|
+
# FORMAT REFERENCE — do not edit. Copy this file to
|
|
3
|
+
# `changelog/<major.minor>.x/<version>.md` (e.g. `changelog/0.8.x/0.8.6.md`)
|
|
4
|
+
# to author a new release. Set that file's H1 to `# <version> — YYYY-MM-DD`
|
|
5
|
+
# with a concrete date.
|
|
6
|
+
|
|
7
|
+
# Required. One-line GitHub Release-style headline. ~250 character soft cap.
|
|
8
|
+
# Default short and scannable. Don't pad, don't stitch unrelated changes with
|
|
9
|
+
# semicolons — pick the headline. Quotes required: unquoted YAML treats `: `
|
|
10
|
+
# inside the value as a key separator and fails GitHub's strict parser.
|
|
11
11
|
summary: ""
|
|
12
12
|
|
|
13
|
-
# Set
|
|
14
|
-
# changes, config renames,
|
|
15
|
-
# Flagged as
|
|
13
|
+
# Set `true` when consumers must change code to upgrade: API removals,
|
|
14
|
+
# signature changes, config renames, behavior changes that break existing
|
|
15
|
+
# usage. Flagged as `Breaking` in the rollup.
|
|
16
16
|
breaking: false
|
|
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.
|
|
21
|
+
security: false
|
|
17
22
|
---
|
|
18
23
|
|
|
19
24
|
# <version> — YYYY-MM-DD
|
|
20
25
|
|
|
21
26
|
<!--
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
AUTHORING GUIDE — applies to the new per-version file you create from this
|
|
28
|
+
template.
|
|
29
|
+
|
|
30
|
+
Audience: someone scanning release notes to decide what affects them. Lead
|
|
31
|
+
each bullet with the symbol or concept name in **bold** so they can skip
|
|
32
|
+
what's irrelevant and zoom in on what's not.
|
|
33
|
+
|
|
34
|
+
Tone: terse, fact-dense, not verbose. Default to one sentence per bullet —
|
|
35
|
+
name the symbol, state what changed, stop. Use a second sentence only when
|
|
36
|
+
it carries weight. If a bullet feels long, it is.
|
|
37
|
+
|
|
38
|
+
Cut: mechanism walkthroughs (those belong in JSDoc, AGENTS.md, or the
|
|
39
|
+
relevant skill), ceremonial framings ("This release introduces…",
|
|
40
|
+
backwards-compat paragraphs), file-by-file test enumerations, internal
|
|
41
|
+
implementation notes. Prefer code/symbol names over English re-explanations.
|
|
42
|
+
|
|
43
|
+
Narrative intro: skip by default. Add one short sentence only when the
|
|
44
|
+
release theme genuinely needs framing the bullets can't carry.
|
|
45
|
+
|
|
46
|
+
Sections: Keep a Changelog order — Added, Changed, Deprecated, Removed,
|
|
47
|
+
Fixed, Security. Include only sections with entries; delete the rest
|
|
48
|
+
(including the commented-out scaffolding below). Don't ship empty headers.
|
|
25
49
|
|
|
26
|
-
|
|
50
|
+
Include: every distinct fact a reader needs to adopt or audit the release —
|
|
51
|
+
new exports, signatures, lint rule IDs, env vars, breaking changes, version
|
|
52
|
+
bumps on shipped skills. Nothing more.
|
|
27
53
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
54
|
+
Links: link issues, PRs, docs, or skills where they help a reader jump to
|
|
55
|
+
context. Once per item per entry — don't re-link the same issue in summary,
|
|
56
|
+
narrative, and bullet. Skip links for inline symbol names; code spans speak
|
|
57
|
+
for themselves.
|
|
31
58
|
|
|
32
|
-
|
|
33
|
-
|
|
59
|
+
Issue/PR URLs: use full URLs. GitHub's bare `#NN` auto-link only resolves
|
|
60
|
+
inside its own UI, not in npm reads or local editors.
|
|
34
61
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
62
|
+
[#38](https://github.com/cyanheads/mcp-ts-core/issues/38) ← issue
|
|
63
|
+
[#42](https://github.com/cyanheads/mcp-ts-core/pull/42) ← PR
|
|
64
|
+
|
|
65
|
+
Verify numbers exist before linking (`gh issue view NN`, `gh pr view NN`).
|
|
66
|
+
Never speculate on a future number — `#42` for an upcoming PR silently
|
|
67
|
+
resolves to whatever real item already owns 42, and timeline previews pull
|
|
68
|
+
in that unrelated item's metadata.
|
|
39
69
|
-->
|
|
40
70
|
|
|
41
71
|
## Added
|
|
@@ -46,6 +76,18 @@ breaking: false
|
|
|
46
76
|
|
|
47
77
|
-
|
|
48
78
|
|
|
79
|
+
<!-- ## Deprecated
|
|
80
|
+
|
|
81
|
+
- -->
|
|
82
|
+
|
|
83
|
+
<!-- ## Removed
|
|
84
|
+
|
|
85
|
+
- -->
|
|
86
|
+
|
|
49
87
|
## Fixed
|
|
50
88
|
|
|
51
89
|
-
|
|
90
|
+
|
|
91
|
+
<!-- ## Security
|
|
92
|
+
|
|
93
|
+
- -->
|
|
@@ -284,6 +284,9 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
284
284
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
285
285
|
path: import("zod").ZodString;
|
|
286
286
|
sectionTargeted: import("zod").ZodBoolean;
|
|
287
|
+
created: import("zod").ZodBoolean;
|
|
288
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
289
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
287
290
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
288
291
|
readonly reason: "path_forbidden";
|
|
289
292
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
@@ -334,6 +337,8 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
334
337
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
335
338
|
path: import("zod").ZodString;
|
|
336
339
|
deleted: import("zod").ZodBoolean;
|
|
340
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
341
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
337
342
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
338
343
|
readonly reason: "path_forbidden";
|
|
339
344
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
@@ -400,11 +405,15 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
400
405
|
path: import("zod").ZodString;
|
|
401
406
|
key: import("zod").ZodString;
|
|
402
407
|
frontmatter: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
|
|
408
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
409
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
403
410
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
404
411
|
operation: import("zod").ZodLiteral<"delete">;
|
|
405
412
|
path: import("zod").ZodString;
|
|
406
413
|
key: import("zod").ZodString;
|
|
407
414
|
frontmatter: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
|
|
415
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
416
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
408
417
|
}, import("zod/v4/core").$strip>], "operation">;
|
|
409
418
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
410
419
|
readonly reason: "path_forbidden";
|
|
@@ -479,12 +488,16 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
479
488
|
applied: import("zod").ZodArray<import("zod").ZodString>;
|
|
480
489
|
skipped: import("zod").ZodArray<import("zod").ZodString>;
|
|
481
490
|
tags: import("zod").ZodArray<import("zod").ZodString>;
|
|
491
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
492
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
482
493
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
483
494
|
operation: import("zod").ZodLiteral<"remove">;
|
|
484
495
|
path: import("zod").ZodString;
|
|
485
496
|
applied: import("zod").ZodArray<import("zod").ZodString>;
|
|
486
497
|
skipped: import("zod").ZodArray<import("zod").ZodString>;
|
|
487
498
|
tags: import("zod").ZodArray<import("zod").ZodString>;
|
|
499
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
500
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
488
501
|
}, import("zod/v4/core").$strip>], "operation">;
|
|
489
502
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
490
503
|
readonly reason: "path_forbidden";
|
|
@@ -571,6 +584,8 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
571
584
|
append: "append";
|
|
572
585
|
prepend: "prepend";
|
|
573
586
|
}>;
|
|
587
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
588
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
574
589
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
575
590
|
readonly reason: "path_forbidden";
|
|
576
591
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
@@ -634,6 +649,8 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
634
649
|
search: import("zod").ZodString;
|
|
635
650
|
count: import("zod").ZodNumber;
|
|
636
651
|
}, import("zod/v4/core").$strip>>;
|
|
652
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
653
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
637
654
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
638
655
|
readonly reason: "path_forbidden";
|
|
639
656
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
@@ -699,6 +716,8 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
699
716
|
path: import("zod").ZodString;
|
|
700
717
|
sectionTargeted: import("zod").ZodBoolean;
|
|
701
718
|
created: import("zod").ZodBoolean;
|
|
719
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
720
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
702
721
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
703
722
|
readonly reason: "file_exists";
|
|
704
723
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
|
|
@@ -770,6 +789,9 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
770
789
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
771
790
|
path: import("zod").ZodString;
|
|
772
791
|
sectionTargeted: import("zod").ZodBoolean;
|
|
792
|
+
created: import("zod").ZodBoolean;
|
|
793
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
794
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
773
795
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
774
796
|
readonly reason: "path_forbidden";
|
|
775
797
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
@@ -820,6 +842,8 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
820
842
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
821
843
|
path: import("zod").ZodString;
|
|
822
844
|
deleted: import("zod").ZodBoolean;
|
|
845
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
846
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
823
847
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
824
848
|
readonly reason: "path_forbidden";
|
|
825
849
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
@@ -1041,11 +1065,15 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
1041
1065
|
path: import("zod").ZodString;
|
|
1042
1066
|
key: import("zod").ZodString;
|
|
1043
1067
|
frontmatter: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
|
|
1068
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
1069
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
1044
1070
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
1045
1071
|
operation: import("zod").ZodLiteral<"delete">;
|
|
1046
1072
|
path: import("zod").ZodString;
|
|
1047
1073
|
key: import("zod").ZodString;
|
|
1048
1074
|
frontmatter: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
|
|
1075
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
1076
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
1049
1077
|
}, import("zod/v4/core").$strip>], "operation">;
|
|
1050
1078
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
1051
1079
|
readonly reason: "path_forbidden";
|
|
@@ -1120,12 +1148,16 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
1120
1148
|
applied: import("zod").ZodArray<import("zod").ZodString>;
|
|
1121
1149
|
skipped: import("zod").ZodArray<import("zod").ZodString>;
|
|
1122
1150
|
tags: import("zod").ZodArray<import("zod").ZodString>;
|
|
1151
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
1152
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
1123
1153
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
1124
1154
|
operation: import("zod").ZodLiteral<"remove">;
|
|
1125
1155
|
path: import("zod").ZodString;
|
|
1126
1156
|
applied: import("zod").ZodArray<import("zod").ZodString>;
|
|
1127
1157
|
skipped: import("zod").ZodArray<import("zod").ZodString>;
|
|
1128
1158
|
tags: import("zod").ZodArray<import("zod").ZodString>;
|
|
1159
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
1160
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
1129
1161
|
}, import("zod/v4/core").$strip>], "operation">;
|
|
1130
1162
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
1131
1163
|
readonly reason: "path_forbidden";
|
|
@@ -1230,6 +1262,8 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
1230
1262
|
append: "append";
|
|
1231
1263
|
prepend: "prepend";
|
|
1232
1264
|
}>;
|
|
1265
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
1266
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
1233
1267
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
1234
1268
|
readonly reason: "path_forbidden";
|
|
1235
1269
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
@@ -1293,6 +1327,8 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
1293
1327
|
search: import("zod").ZodString;
|
|
1294
1328
|
count: import("zod").ZodNumber;
|
|
1295
1329
|
}, import("zod/v4/core").$strip>>;
|
|
1330
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
1331
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
1296
1332
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
1297
1333
|
readonly reason: "path_forbidden";
|
|
1298
1334
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
@@ -1425,6 +1461,8 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
1425
1461
|
path: import("zod").ZodString;
|
|
1426
1462
|
sectionTargeted: import("zod").ZodBoolean;
|
|
1427
1463
|
created: import("zod").ZodBoolean;
|
|
1464
|
+
previousSizeInBytes: import("zod").ZodNumber;
|
|
1465
|
+
currentSizeInBytes: import("zod").ZodNumber;
|
|
1428
1466
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
1429
1467
|
readonly reason: "file_exists";
|
|
1430
1468
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiBH,gFAAgF;AAChF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAM/B,CAAC;AAEF,kFAAkF;AAClF,eAAO,MAAM,oBAAoB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiBH,gFAAgF;AAChF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAM/B,CAAC;AAEF,kFAAkF;AAClF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAQhC,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAAoD,CAAC;AAErF,mHAAmH;AACnH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;+CAAiD,CAAC"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview obsidian_append_to_note — append content to the end of a note,
|
|
3
3
|
* or to the end of a heading/block/frontmatter section via PATCH-with-append.
|
|
4
|
+
* Whole-file appends are silently upserts (POST creates the file when the path
|
|
5
|
+
* does not exist), so the response surface flags `created` and `previousSize`
|
|
6
|
+
* for agent self-correction.
|
|
4
7
|
* @module mcp-server/tools/definitions/obsidian-append-to-note.tool
|
|
5
8
|
*/
|
|
6
9
|
import { z } from '@cyanheads/mcp-ts-core';
|
|
@@ -39,6 +42,9 @@ export declare const obsidianAppendToNote: import("@cyanheads/mcp-ts-core").Tool
|
|
|
39
42
|
}, z.core.$strip>, z.ZodObject<{
|
|
40
43
|
path: z.ZodString;
|
|
41
44
|
sectionTargeted: z.ZodBoolean;
|
|
45
|
+
created: z.ZodBoolean;
|
|
46
|
+
previousSizeInBytes: z.ZodNumber;
|
|
47
|
+
currentSizeInBytes: z.ZodNumber;
|
|
42
48
|
}, z.core.$strip>, readonly [{
|
|
43
49
|
readonly reason: "path_forbidden";
|
|
44
50
|
readonly code: JsonRpcErrorCode.Forbidden;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obsidian-append-to-note.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-append-to-note.tool.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"obsidian-append-to-note.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-append-to-note.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4I/B,CAAC"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview obsidian_append_to_note — append content to the end of a note,
|
|
3
3
|
* or to the end of a heading/block/frontmatter section via PATCH-with-append.
|
|
4
|
+
* Whole-file appends are silently upserts (POST creates the file when the path
|
|
5
|
+
* does not exist), so the response surface flags `created` and `previousSize`
|
|
6
|
+
* for agent self-correction.
|
|
4
7
|
* @module mcp-server/tools/definitions/obsidian-append-to-note.tool
|
|
5
8
|
*/
|
|
6
9
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
@@ -8,7 +11,7 @@ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
|
8
11
|
import { getObsidianService } from '../../../services/obsidian/obsidian-service.js';
|
|
9
12
|
import { ContentTypeSchema, SectionSchema, TargetSchema } from './_shared/schemas.js';
|
|
10
13
|
export const obsidianAppendToNote = tool('obsidian_append_to_note', {
|
|
11
|
-
description: 'Append content to a note. Without `section
|
|
14
|
+
description: 'Append content to a note. **Without `section`: appends to the end of the file, or creates the file if it does not exist (your content becomes the full file).** With `section`: appends to the end of that heading/block/frontmatter; nested headings need `Parent::Child` syntax — use `obsidian_get_note` with `format: "document-map"` to discover available targets. For block-reference targets, content is concatenated adjacent to the block line without inserting a separator — include a leading newline in `content` if you want one. Set `createTargetIfMissing` to bring the target section into existence rather than failing when it does not exist.',
|
|
12
15
|
annotations: { destructiveHint: true },
|
|
13
16
|
input: z.object({
|
|
14
17
|
target: TargetSchema.describe('Where the note lives.'),
|
|
@@ -24,7 +27,16 @@ export const obsidianAppendToNote = tool('obsidian_append_to_note', {
|
|
|
24
27
|
path: z.string().describe('Resolved vault-relative path of the note.'),
|
|
25
28
|
sectionTargeted: z
|
|
26
29
|
.boolean()
|
|
27
|
-
.describe('True when the append went to a section; false for whole-file appends.'),
|
|
30
|
+
.describe('True when the append went to a heading/block/frontmatter section (PATCH); false for whole-file appends (POST).'),
|
|
31
|
+
created: z
|
|
32
|
+
.boolean()
|
|
33
|
+
.describe('True when the whole-file append created a new file. Always false for section appends — PATCH requires the file to exist. Best-effort under concurrent writers, racy between the existence check and the write.'),
|
|
34
|
+
previousSizeInBytes: z
|
|
35
|
+
.number()
|
|
36
|
+
.describe('Byte size of the note before the append. Zero when `created` is true.'),
|
|
37
|
+
currentSizeInBytes: z
|
|
38
|
+
.number()
|
|
39
|
+
.describe('Byte size of the note after the append, read from the upstream after the operation completed. Compare against `previousSizeInBytes` and your own content length to detect unexpected upstream behavior (e.g. auto-newline injection, concurrent writers).'),
|
|
28
40
|
}),
|
|
29
41
|
auth: ['tool:obsidian_append_to_note:write'],
|
|
30
42
|
errors: [
|
|
@@ -67,9 +79,16 @@ export const obsidianAppendToNote = tool('obsidian_append_to_note', {
|
|
|
67
79
|
],
|
|
68
80
|
async handler(input, ctx) {
|
|
69
81
|
const svc = getObsidianService();
|
|
70
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Resolve once and pin the rest of the flow to a path target so the
|
|
84
|
+
* presence probe and the write itself act on the same concrete file —
|
|
85
|
+
* avoids re-resolving `active` / `periodic` targets across calls.
|
|
86
|
+
*/
|
|
87
|
+
const path = await svc.resolvePath(ctx, input.target);
|
|
88
|
+
const pathTarget = { type: 'path', path };
|
|
71
89
|
if (input.section) {
|
|
72
|
-
await svc.
|
|
90
|
+
const previousSizeInBytes = await svc.getSize(ctx, pathTarget);
|
|
91
|
+
await svc.patchNote(ctx, pathTarget, input.content, {
|
|
73
92
|
operation: 'append',
|
|
74
93
|
targetType: input.section.type,
|
|
75
94
|
target: input.section.target,
|
|
@@ -77,21 +96,36 @@ export const obsidianAppendToNote = tool('obsidian_append_to_note', {
|
|
|
77
96
|
createTargetIfMissing: input.createTargetIfMissing,
|
|
78
97
|
contentType: input.contentType,
|
|
79
98
|
});
|
|
80
|
-
const
|
|
81
|
-
return {
|
|
99
|
+
const currentSizeInBytes = await svc.getSize(ctx, pathTarget);
|
|
100
|
+
return {
|
|
101
|
+
path,
|
|
102
|
+
sectionTargeted: true,
|
|
103
|
+
created: false,
|
|
104
|
+
previousSizeInBytes,
|
|
105
|
+
currentSizeInBytes,
|
|
106
|
+
};
|
|
82
107
|
}
|
|
83
|
-
await svc.
|
|
84
|
-
|
|
85
|
-
|
|
108
|
+
const previousSizeInBytes = await svc.tryGetSize(ctx, pathTarget);
|
|
109
|
+
await svc.appendToNote(ctx, pathTarget, input.content, input.contentType);
|
|
110
|
+
const currentSizeInBytes = await svc.getSize(ctx, pathTarget);
|
|
111
|
+
return {
|
|
112
|
+
path,
|
|
113
|
+
sectionTargeted: false,
|
|
114
|
+
created: previousSizeInBytes === null,
|
|
115
|
+
previousSizeInBytes: previousSizeInBytes ?? 0,
|
|
116
|
+
currentSizeInBytes,
|
|
117
|
+
};
|
|
118
|
+
},
|
|
119
|
+
format: (result) => {
|
|
120
|
+
const action = result.created ? 'Created' : 'Appended to';
|
|
121
|
+
const lines = [`**${action} ${result.path}**`];
|
|
122
|
+
if (result.created) {
|
|
123
|
+
lines.push('*Note:* this file did not exist before — your content is now the entire file. If you expected to add to existing content, double-check the path.');
|
|
124
|
+
}
|
|
125
|
+
lines.push(`*Size:* ${result.previousSizeInBytes} → ${result.currentSizeInBytes} bytes`);
|
|
126
|
+
lines.push(`*Created:* ${result.created}`);
|
|
127
|
+
lines.push(`*Section targeted:* ${result.sectionTargeted}`);
|
|
128
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
86
129
|
},
|
|
87
|
-
format: (result) => [
|
|
88
|
-
{
|
|
89
|
-
type: 'text',
|
|
90
|
-
text: [
|
|
91
|
-
`**Appended to ${result.path}**`,
|
|
92
|
-
`*Section targeted:* ${result.sectionTargeted}`,
|
|
93
|
-
].join('\n'),
|
|
94
|
-
},
|
|
95
|
-
],
|
|
96
130
|
});
|
|
97
131
|
//# sourceMappingURL=obsidian-append-to-note.tool.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obsidian-append-to-note.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-append-to-note.tool.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"obsidian-append-to-note.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-append-to-note.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEtF,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC,yBAAyB,EAAE;IAClE,WAAW,EACT,qoBAAqoB;IACvoB,WAAW,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;IACtC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACtD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0DAA0D,CAAC;QACxF,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACxC,kGAAkG,CACnG;QACD,WAAW,EAAE,iBAAiB;QAC9B,qBAAqB,EAAE,CAAC;aACrB,OAAO,EAAE;aACT,OAAO,CAAC,KAAK,CAAC;aACd,QAAQ,CACP,qIAAqI,CACtI;KACJ,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;QACtE,eAAe,EAAE,CAAC;aACf,OAAO,EAAE;aACT,QAAQ,CACP,gHAAgH,CACjH;QACH,OAAO,EAAE,CAAC;aACP,OAAO,EAAE;aACT,QAAQ,CACP,gNAAgN,CACjN;QACH,mBAAmB,EAAE,CAAC;aACnB,MAAM,EAAE;aACR,QAAQ,CAAC,uEAAuE,CAAC;QACpF,kBAAkB,EAAE,CAAC;aAClB,MAAM,EAAE;aACR,QAAQ,CACP,2PAA2P,CAC5P;KACJ,CAAC;IACF,IAAI,EAAE,CAAC,oCAAoC,CAAC;IAC5C,MAAM,EAAE;QACN;YACE,MAAM,EAAE,gBAAgB;YACxB,IAAI,EAAE,gBAAgB,CAAC,SAAS;YAChC,IAAI,EAAE,gGAAgG;YACtG,QAAQ,EACN,uFAAuF;SAC1F;QACD;YACE,MAAM,EAAE,cAAc;YACtB,IAAI,EAAE,gBAAgB,CAAC,QAAQ;YAC/B,IAAI,EAAE,6GAA6G;YACnH,QAAQ,EACN,oIAAoI;SACvI;QACD;YACE,MAAM,EAAE,gBAAgB;YACxB,IAAI,EAAE,gBAAgB,CAAC,QAAQ;YAC/B,IAAI,EAAE,gEAAgE;YACtE,QAAQ,EACN,oFAAoF;SACvF;QACD;YACE,MAAM,EAAE,oBAAoB;YAC5B,IAAI,EAAE,gBAAgB,CAAC,QAAQ;YAC/B,IAAI,EAAE,6DAA6D;YACnE,QAAQ,EAAE,iEAAiE;SAC5E;QACD;YACE,MAAM,EAAE,mBAAmB;YAC3B,IAAI,EAAE,gBAAgB,CAAC,eAAe;YACtC,IAAI,EAAE,6GAA6G;YACnH,QAAQ,EACN,0GAA0G;SAC7G;QACD;YACE,MAAM,EAAE,wBAAwB;YAChC,IAAI,EAAE,gBAAgB,CAAC,eAAe;YACtC,IAAI,EAAE,kGAAkG;YACxG,QAAQ,EACN,gJAAgJ;SACnJ;KACF;IAED,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACtB,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;QAEjC;;;;WAIG;QACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;QAEnD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,mBAAmB,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAC/D,MAAM,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,CAAC,OAAO,EAAE;gBAClD,SAAS,EAAE,QAAQ;gBACnB,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI;gBAC9B,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM;gBAC5B,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;gBACpE,qBAAqB,EAAE,KAAK,CAAC,qBAAqB;gBAClD,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC,CAAC;YACH,MAAM,kBAAkB,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAC9D,OAAO;gBACL,IAAI;gBACJ,eAAe,EAAE,IAAI;gBACrB,OAAO,EAAE,KAAK;gBACd,mBAAmB;gBACnB,kBAAkB;aACnB,CAAC;QACJ,CAAC;QAED,MAAM,mBAAmB,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAClE,MAAM,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QAC1E,MAAM,kBAAkB,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC9D,OAAO;YACL,IAAI;YACJ,eAAe,EAAE,KAAK;YACtB,OAAO,EAAE,mBAAmB,KAAK,IAAI;YACrC,mBAAmB,EAAE,mBAAmB,IAAI,CAAC;YAC7C,kBAAkB;SACnB,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;QACjB,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;QAC1D,MAAM,KAAK,GAAG,CAAC,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;QAC/C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CACR,kJAAkJ,CACnJ,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,mBAAmB,MAAM,MAAM,CAAC,kBAAkB,QAAQ,CAAC,CAAC;QACzF,KAAK,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC;QAC5D,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -26,6 +26,8 @@ export declare const obsidianDeleteNote: import("@cyanheads/mcp-ts-core").ToolDe
|
|
|
26
26
|
}, z.core.$strip>, z.ZodObject<{
|
|
27
27
|
path: z.ZodString;
|
|
28
28
|
deleted: z.ZodBoolean;
|
|
29
|
+
previousSizeInBytes: z.ZodNumber;
|
|
30
|
+
currentSizeInBytes: z.ZodNumber;
|
|
29
31
|
}, z.core.$strip>, readonly [{
|
|
30
32
|
readonly reason: "path_forbidden";
|
|
31
33
|
readonly code: JsonRpcErrorCode.Forbidden;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obsidian-delete-note.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-delete-note.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"obsidian-delete-note.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-delete-note.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqG7B,CAAC"}
|