2025-06-27 16:00:05 +00:00
{
"name" : "obsidian-mcp-plugin" ,
2026-07-13 23:48:38 +00:00
"version" : "0.11.42" ,
2026-07-05 18:15:41 +00:00
"description" : "Read, write, search, and traverse your vault from Claude Desktop and any AI assistant — via a built-in MCP server, no external server to run." ,
2025-06-27 16:00:05 +00:00
"main" : "main.js" ,
"scripts" : {
"dev" : "node esbuild.config.mjs" ,
chore(worker): remove dormant worker-offload path (ADR-105, closes #197)
The worker-thread pool ratified/extended by ADR-104 has never executed a
single request since introduction (v0.5.8b, 22742bd): ConnectionPool's
action-level workerOps gate (tool.vault.search, …) never matched the
operation-level method strings the pool emits (tool.vault, tool.edit, …),
so processWithWorker was unreachable. Independently, the worker built to
dist/workers/workers/semantic-worker.js while WorkerManager loaded
dist/workers/semantic-worker.js — load would have failed anyway.
Verified dead against current main; no CPU-starvation field reports.
Fixing forward was rejected: it would ship an untested concurrency path
that widens the #139 parallel-edit race via a new TOCTOU window for an
unproven perf need (see #197 analysis).
- delete src/workers/semantic-worker.ts, src/utils/worker-manager.ts,
build-worker.js; drop build:worker + the build-worker.js build step
- strip worker wiring from ConnectionPool (retained as a main-thread
bounded queue — the only behaviour that ever ran) and the dead
prepareWorkerContext/workerScript from mcp-server.ts
- ADR-105 records the removal as a partial reversal of ADR-104; ADR-104
stays Accepted (SSE-route deconfliction half, shipped #196, still
governs) with a banner pointing to ADR-105
Behaviour-preserving by construction: the deleted path never ran.
make check green (build + lint 0 errors + 225/225 tests).
2026-05-19 03:26:14 +00:00
"build" : "node sync-version.mjs && tsc -noEmit -skipLibCheck && node esbuild.config.mjs production" ,
2025-06-27 17:15:53 +00:00
"sync-version" : "node sync-version.mjs" ,
"version" : "node sync-version.mjs && git add manifest.json" ,
2026-01-22 00:03:09 +00:00
"test" : "node --no-warnings node_modules/.bin/jest" ,
fix: .mcpignore semantics, TLS 1.3 startup, rename extension (#250, #252, #253)
Bundles the three reported bugs plus an unreported under-blocking bug found
while writing the tests for #250, and adds the coverage tooling that would
have caught all four.
#250 — .mcpignore negation was inverted
The parser stripped the leading '!' before Minimatch saw it, so .negate was
always false and the branch reading it was dead code. '!folder/*' compiled
into a positive exclusion: negation did not merely fail, it inverted.
Under-blocking (found while testing the above, not reported)
Patterns were handed to Minimatch raw, so two gitignore rules were never
implemented: a slash-less pattern matches at any depth ('*.secret' must hide
'a/b/creds.secret'), and a directory match covers its contents ('private/'
must hide 'private/notes.md'). No consumer of isExcluded() checks ancestors —
every caller passes a full file path — so nothing compensated downstream. The
plugin's own shipped .mcpignore template promises both behaviours, so a user
following it believed private files were hidden while they were being served
to the model. Patterns are now translated into the globs that implement
gitignore semantics, and negation is interpreted here rather than by Minimatch.
#252 — min TLS 1.3 crashed the server
secureProtocol mapped 1.3 to 'TLSv1_3_method', which OpenSSL never shipped, so
context creation threw "Unknown method: TLSv1_3_method". Switched to minVersion,
which also fixes a second latent bug: secureProtocol PINS one version, so
"minimum TLS 1.2" was silently refusing TLS 1.3 clients. The setting now
behaves as the floor it is labelled.
#253 — rename dropped the extension
'newName' was concatenated onto the source directory verbatim, so renaming
'note.md' to 'renamed' produced an extension-less file that drops out of
markdown views. The source extension is now carried over when newName omits
one, before the overwrite guard so it checks the right path.
Coverage + test contract
All four bugs shipped through code paths with zero coverage. Adds `make
coverage` / `coverage-map` / `coverage-gate`, a ratcheting coverageThreshold
(security boundary held to a far higher floor than global, since a hole there
leaks vault content), and tests/test-contract.test.ts enforcing that a green
run means something: no .only, no .skip, every file asserts, no tautologies.
The contract immediately caught an `expect(true).toBe(true)` placeholder in the
path-validator suite, now replaced with real assertions.
BREAKING (.mcpignore, both intended):
- The double-'!' workaround for #250 now correctly parses as a double negation
(net exclude) and will stop working.
- A bare '*' now excludes at every depth, per gitignore, rather than top-level
only. This is what makes the '*' + '!keep/**' whitelist idiom work.
2026-07-13 22:46:50 +00:00
"test:coverage" : "node --no-warnings node_modules/.bin/jest --coverage" ,
2026-01-17 01:43:39 +00:00
"lint" : "eslint ." ,
"lint:fix" : "eslint . --fix"
2025-06-27 16:00:05 +00:00
} ,
"keywords" : [
"obsidian" ,
"plugin" ,
"mcp" ,
"rest-api" ,
"ai" ,
"semantic"
] ,
2026-05-15 16:45:43 +00:00
"author" : "Aaron Bockelie" ,
2025-06-27 16:00:05 +00:00
"license" : "MIT" ,
2026-05-15 18:08:53 +00:00
"overrides" : {
2026-05-16 19:08:46 +00:00
"yaml" : "$yaml"
2026-05-15 18:08:53 +00:00
} ,
2025-06-27 16:00:05 +00:00
"devDependencies" : {
chore(deps): upgrade dev toolchain — eslint 10, typescript 6, and grouped bumps
Incorporates the open dependabot dev-dependency PRs as one coherent, tightly
verified upgrade rather than five separate rebase/CI cycles, since they interact
across the build/lint toolchain:
- eslint 9.39.2 → 10.5.0 and @eslint/js 9.39.2 → 10.0.1 (#235 + #236 — these are
coupled: @eslint/js@10 peer-requires eslint@10, so #236 could only ever resolve
alongside #235; neither lands alone)
- typescript 5.9.3 → 6.0.3 (#237)
- typescript-eslint / @typescript-eslint/utils 8.60.1 → 8.62.0, esbuild
0.28.0 → 0.28.1, globals 17.6.0 → 17.7.0, obsidian 1.13.0 → 1.13.1 (#246,
which also subsumes the standalone esbuild bump in #233)
- actions/checkout v6 → v7 across all workflows (#240)
TypeScript 6 turns two tsconfig deprecations into errors. Fixed by modernizing
the config, not suppressing — Obsidian's community-plugin source review forbids
`ignoreDeprecations`-style escape hatches and rewards tight configs:
- dropped `baseUrl: "."` (TS5101) — unused; every local import is relative
- `moduleResolution: "node"` → `"bundler"` (TS5107) — the correct modern value
for an esbuild-bundled project with extensionless imports (node16/nodenext
would force `.js` extensions and break every relative import)
Also ran `npm audit fix` (security fixes are hold-exempt) clearing two dev/test
transitive advisories (@babel/core file-read, js-yaml merge-key DoS) that were
pre-existing on main via the jest/istanbul chain — `npm audit` now reports 0.
Verified tight: `npm run build && npm run lint && npm test` all green, 352/352
tests pass, no rule suppressions added.
2026-07-04 02:13:32 +00:00
"@eslint/js" : "^10.0.1" ,
2026-01-21 23:59:53 +00:00
"@types/jest" : "^30.0.0" ,
feat: Add .mcpignore file-based path exclusion system
Implements comprehensive privacy/security controls with .gitignore-style patterns.
## New Features
- **MCPIgnoreManager**: Handles gitignore-style pattern matching using minimatch library
- **File-based configuration**: Stores exclusion patterns in .obsidian/plugins/obsidian-mcp-plugin/.mcpignore
- **Universal integration**: Filters all vault operations (list, get, search, create)
- **Complete invisibility**: Excluded files/folders appear to not exist
- **Rich settings UI**: File management buttons, pattern examples, status display
## Technical Implementation
- **Pattern syntax**: Full .gitignore compatibility including negation (\!pattern)
- **Performance optimized**: Pattern caching and efficient filtering
- **Security focused**: Access denied errors for excluded paths
- **Auto-reload**: Detects .mcpignore file changes
- **Template generation**: Creates helpful default patterns with examples
## UI Features
- **Toggle control**: Enable/disable exclusions in security settings
- **File management**: Open, create template, reload patterns buttons
- **Live status**: Shows pattern count and last modified timestamp
- **Pattern examples**: Inline help with common use cases
- **Documentation links**: References to gitignore syntax guide
## Use Cases
- **Privacy protection**: Hide personal/sensitive files (journal/, *.secret)
- **Work separation**: Exclude confidential directories (work/internal/)
- **System files**: Hide .obsidian workspace and temp files
- **Backup exclusion**: Skip *.backup, temp/, drafts/ from MCP access
- **Whitelist exceptions**: Use \!pattern for selective inclusion
Pattern examples:
- private/ - exclude directory
- *.secret - exclude by extension
- temp/** - exclude nested paths
- \!public.md - whitelist exception
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 15:25:46 +00:00
"@types/minimatch" : "^5.1.2" ,
2026-06-09 16:06:05 +00:00
"@types/node" : "^25.9.2" ,
chore(deps): upgrade dev toolchain — eslint 10, typescript 6, and grouped bumps
Incorporates the open dependabot dev-dependency PRs as one coherent, tightly
verified upgrade rather than five separate rebase/CI cycles, since they interact
across the build/lint toolchain:
- eslint 9.39.2 → 10.5.0 and @eslint/js 9.39.2 → 10.0.1 (#235 + #236 — these are
coupled: @eslint/js@10 peer-requires eslint@10, so #236 could only ever resolve
alongside #235; neither lands alone)
- typescript 5.9.3 → 6.0.3 (#237)
- typescript-eslint / @typescript-eslint/utils 8.60.1 → 8.62.0, esbuild
0.28.0 → 0.28.1, globals 17.6.0 → 17.7.0, obsidian 1.13.0 → 1.13.1 (#246,
which also subsumes the standalone esbuild bump in #233)
- actions/checkout v6 → v7 across all workflows (#240)
TypeScript 6 turns two tsconfig deprecations into errors. Fixed by modernizing
the config, not suppressing — Obsidian's community-plugin source review forbids
`ignoreDeprecations`-style escape hatches and rewards tight configs:
- dropped `baseUrl: "."` (TS5101) — unused; every local import is relative
- `moduleResolution: "node"` → `"bundler"` (TS5107) — the correct modern value
for an esbuild-bundled project with extensionless imports (node16/nodenext
would force `.js` extensions and break every relative import)
Also ran `npm audit fix` (security fixes are hold-exempt) clearing two dev/test
transitive advisories (@babel/core file-read, js-yaml merge-key DoS) that were
pre-existing on main via the jest/istanbul chain — `npm audit` now reports 0.
Verified tight: `npm run build && npm run lint && npm test` all green, 352/352
tests pass, no rule suppressions added.
2026-07-04 02:13:32 +00:00
"@typescript-eslint/utils" : "^8.62.0" ,
"esbuild" : "^0.28.1" ,
"eslint" : "^10.5.0" ,
2026-05-15 20:00:44 +00:00
"eslint-plugin-obsidianmd" : "^0.3.0" ,
chore(deps): upgrade dev toolchain — eslint 10, typescript 6, and grouped bumps
Incorporates the open dependabot dev-dependency PRs as one coherent, tightly
verified upgrade rather than five separate rebase/CI cycles, since they interact
across the build/lint toolchain:
- eslint 9.39.2 → 10.5.0 and @eslint/js 9.39.2 → 10.0.1 (#235 + #236 — these are
coupled: @eslint/js@10 peer-requires eslint@10, so #236 could only ever resolve
alongside #235; neither lands alone)
- typescript 5.9.3 → 6.0.3 (#237)
- typescript-eslint / @typescript-eslint/utils 8.60.1 → 8.62.0, esbuild
0.28.0 → 0.28.1, globals 17.6.0 → 17.7.0, obsidian 1.13.0 → 1.13.1 (#246,
which also subsumes the standalone esbuild bump in #233)
- actions/checkout v6 → v7 across all workflows (#240)
TypeScript 6 turns two tsconfig deprecations into errors. Fixed by modernizing
the config, not suppressing — Obsidian's community-plugin source review forbids
`ignoreDeprecations`-style escape hatches and rewards tight configs:
- dropped `baseUrl: "."` (TS5101) — unused; every local import is relative
- `moduleResolution: "node"` → `"bundler"` (TS5107) — the correct modern value
for an esbuild-bundled project with extensionless imports (node16/nodenext
would force `.js` extensions and break every relative import)
Also ran `npm audit fix` (security fixes are hold-exempt) clearing two dev/test
transitive advisories (@babel/core file-read, js-yaml merge-key DoS) that were
pre-existing on main via the jest/istanbul chain — `npm audit` now reports 0.
Verified tight: `npm run build && npm run lint && npm test` all green, 352/352
tests pass, no rule suppressions added.
2026-07-04 02:13:32 +00:00
"globals" : "^17.7.0" ,
2026-06-09 16:06:05 +00:00
"jest" : "^30.4.2" ,
"jiti" : "^2.7.0" ,
chore(deps): upgrade dev toolchain — eslint 10, typescript 6, and grouped bumps
Incorporates the open dependabot dev-dependency PRs as one coherent, tightly
verified upgrade rather than five separate rebase/CI cycles, since they interact
across the build/lint toolchain:
- eslint 9.39.2 → 10.5.0 and @eslint/js 9.39.2 → 10.0.1 (#235 + #236 — these are
coupled: @eslint/js@10 peer-requires eslint@10, so #236 could only ever resolve
alongside #235; neither lands alone)
- typescript 5.9.3 → 6.0.3 (#237)
- typescript-eslint / @typescript-eslint/utils 8.60.1 → 8.62.0, esbuild
0.28.0 → 0.28.1, globals 17.6.0 → 17.7.0, obsidian 1.13.0 → 1.13.1 (#246,
which also subsumes the standalone esbuild bump in #233)
- actions/checkout v6 → v7 across all workflows (#240)
TypeScript 6 turns two tsconfig deprecations into errors. Fixed by modernizing
the config, not suppressing — Obsidian's community-plugin source review forbids
`ignoreDeprecations`-style escape hatches and rewards tight configs:
- dropped `baseUrl: "."` (TS5101) — unused; every local import is relative
- `moduleResolution: "node"` → `"bundler"` (TS5107) — the correct modern value
for an esbuild-bundled project with extensionless imports (node16/nodenext
would force `.js` extensions and break every relative import)
Also ran `npm audit fix` (security fixes are hold-exempt) clearing two dev/test
transitive advisories (@babel/core file-read, js-yaml merge-key DoS) that were
pre-existing on main via the jest/istanbul chain — `npm audit` now reports 0.
Verified tight: `npm run build && npm run lint && npm test` all green, 352/352
tests pass, no rule suppressions added.
2026-07-04 02:13:32 +00:00
"obsidian" : "^1.13.1" ,
2026-06-09 16:06:05 +00:00
"ts-jest" : "^29.4.11" ,
2026-01-21 23:50:11 +00:00
"tslib" : "^2.8.1" ,
chore(deps): upgrade dev toolchain — eslint 10, typescript 6, and grouped bumps
Incorporates the open dependabot dev-dependency PRs as one coherent, tightly
verified upgrade rather than five separate rebase/CI cycles, since they interact
across the build/lint toolchain:
- eslint 9.39.2 → 10.5.0 and @eslint/js 9.39.2 → 10.0.1 (#235 + #236 — these are
coupled: @eslint/js@10 peer-requires eslint@10, so #236 could only ever resolve
alongside #235; neither lands alone)
- typescript 5.9.3 → 6.0.3 (#237)
- typescript-eslint / @typescript-eslint/utils 8.60.1 → 8.62.0, esbuild
0.28.0 → 0.28.1, globals 17.6.0 → 17.7.0, obsidian 1.13.0 → 1.13.1 (#246,
which also subsumes the standalone esbuild bump in #233)
- actions/checkout v6 → v7 across all workflows (#240)
TypeScript 6 turns two tsconfig deprecations into errors. Fixed by modernizing
the config, not suppressing — Obsidian's community-plugin source review forbids
`ignoreDeprecations`-style escape hatches and rewards tight configs:
- dropped `baseUrl: "."` (TS5101) — unused; every local import is relative
- `moduleResolution: "node"` → `"bundler"` (TS5107) — the correct modern value
for an esbuild-bundled project with extensionless imports (node16/nodenext
would force `.js` extensions and break every relative import)
Also ran `npm audit fix` (security fixes are hold-exempt) clearing two dev/test
transitive advisories (@babel/core file-read, js-yaml merge-key DoS) that were
pre-existing on main via the jest/istanbul chain — `npm audit` now reports 0.
Verified tight: `npm run build && npm run lint && npm test` all green, 352/352
tests pass, no rule suppressions added.
2026-07-04 02:13:32 +00:00
"typescript" : "^6.0.3" ,
"typescript-eslint" : "^8.62.0"
2025-06-27 16:00:05 +00:00
} ,
"dependencies" : {
2026-05-15 18:00:34 +00:00
"@modelcontextprotocol/sdk" : "^1.29.0" ,
2025-06-27 16:59:25 +00:00
"@types/cors" : "^2.8.19" ,
2026-01-21 23:56:54 +00:00
"@types/express" : "^5.0.6" ,
2025-12-15 05:04:57 +00:00
"@types/node-forge" : "^1.3.14" ,
feat: Complete semantic MCP integration with direct Obsidian API
🎉 MAJOR RELEASE: Full semantic MCP server integration with direct plugin API access
✨ Semantic Tools Integrated (5 tools):
- **vault**: File operations (list, read, create, update, delete, search, fragments)
- **edit**: Smart editing (window, append, patch, at_line, from_buffer)
- **view**: Content viewing (file, window, active, open_in_obsidian)
- **workflow**: AI workflow guidance and suggestions
- **system**: System operations (info, commands, fetch_web)
🔧 Architecture Achievements:
- Replaced HTTP-based ObsidianAPI with direct app.vault/app.workspace calls
- Preserved exact ObsidianAPI interface - semantic router unchanged
- Integrated fragment retrieval system for large files
- Added content buffer manager for edit recovery
- Ported workflow configuration and state management
🚀 Performance & Capabilities:
- Direct vault access - no HTTP overhead
- Rich Obsidian API integration (search, commands, workspace)
- Advanced search with fallback implementation
- Image processing with Sharp integration
- Fetch tool using native fetch API
📦 MCP Resources:
- Added vault-info resource (obsidian://vault-info)
- Real-time vault metadata and file counts
- Active file tracking and plugin status
🛠️ Technical Implementation:
- Removed axios dependencies - browser-compatible
- Fixed all TypeScript type issues
- Maintained proven MCP server patterns from obsidian-semantic-mcp
- Updated to v0.3.0 with automatic version sync
This completes the core architectural vision: semantic MCP operations with
direct Obsidian plugin API integration for maximum performance and capabilities.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-27 17:33:59 +00:00
"@types/turndown" : "^5.0.5" ,
2026-02-23 09:43:57 +00:00
"cors" : "^2.8.6" ,
2026-01-21 23:56:54 +00:00
"express" : "^5.2.1" ,
feat(bases): replace new Function with expression-eval (ADR-201)
PR2 of 2 for #180 (ADR-201). Closes the arbitrary-code-execution vector
reachable through a synced/shared `.base` file.
- Drop `new Function('context', 'with(context){return ${expr}}')` (and its
no-implied-eval eslint-disable) from expression-evaluator.ts.
- Parse with expression-eval@5.0.1 (jsep grammar: no eval/Function/new, no
global scope; member denylist built in). Pinned exact; jsep 0.3.5 is its
audited transitive parser. Both >7d old; npm audit 0 vulns.
- Defense-in-depth AST pre-walk (assertNoForbiddenAccess): rejects
constructor/__proto__/prototype member access (Identifier AND computed
["constructor"] forms) and ThisExpression, independent of the library's
internal list — ADR-201's explicit, tested no-globals property lives in
our code, not a transitive dep.
- createEvalContext and all helpers untouched → behavioural parity.
Differential corpus (tests/bases-expression-evaluator.test.ts, from PR1):
57 EVAL_CASES still green = expression-eval == old new Function for every
realistic Bases construct; the formerly-executing escapes (2/42/99 under
new Function) now fail closed; SECURITY set never reaches a function, the
real global, or a value.
No behavioural change for legitimate `.base` expressions. Breaking only by
design: the RCE vectors, `this`, and prototype-chain access are now
refused. Clears the Obsidian "Dynamic Code Execution" finding.
209/209 tests; build + lint clean. Refs #180, ADR-201
2026-05-17 03:57:43 +00:00
"expression-eval" : "5.0.1" ,
2026-05-15 18:00:34 +00:00
"minimatch" : "^10.2.5" ,
"node-forge" : "^1.4.0" ,
"turndown" : "^7.2.4" ,
2026-06-02 03:25:15 +00:00
"yaml" : "2.9.0" ,
2026-05-15 18:00:34 +00:00
"zod" : "^4.4.3"
2025-06-27 16:00:05 +00:00
}
2025-06-27 16:13:46 +00:00
}