obsidian-mcp-pro 3.0.0 → 4.0.1
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/README.md +85 -42
- package/build/config.d.ts.map +1 -1
- package/build/config.js +79 -9
- package/build/config.js.map +1 -1
- package/build/http-server.d.ts +4 -2
- package/build/http-server.d.ts.map +1 -1
- package/build/http-server.js +59 -22
- package/build/http-server.js.map +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +24 -27
- package/build/index.js.map +1 -1
- package/build/install.d.ts.map +1 -1
- package/build/install.js +12 -1
- package/build/install.js.map +1 -1
- package/build/lib/bases.d.ts +11 -4
- package/build/lib/bases.d.ts.map +1 -1
- package/build/lib/bases.js +59 -25
- package/build/lib/bases.js.map +1 -1
- package/build/lib/confirmation.d.ts +21 -0
- package/build/lib/confirmation.d.ts.map +1 -0
- package/build/lib/confirmation.js +37 -0
- package/build/lib/confirmation.js.map +1 -0
- package/build/lib/embedding-providers.d.ts.map +1 -1
- package/build/lib/embedding-providers.js +50 -29
- package/build/lib/embedding-providers.js.map +1 -1
- package/build/lib/embedding-store.d.ts +4 -0
- package/build/lib/embedding-store.d.ts.map +1 -1
- package/build/lib/embedding-store.js +74 -21
- package/build/lib/embedding-store.js.map +1 -1
- package/build/lib/errors.d.ts +13 -5
- package/build/lib/errors.d.ts.map +1 -1
- package/build/lib/errors.js +53 -19
- package/build/lib/errors.js.map +1 -1
- package/build/lib/fs-ops.d.ts +1 -0
- package/build/lib/fs-ops.d.ts.map +1 -1
- package/build/lib/fs-ops.js +12 -6
- package/build/lib/fs-ops.js.map +1 -1
- package/build/lib/index-cache.d.ts +4 -7
- package/build/lib/index-cache.d.ts.map +1 -1
- package/build/lib/index-cache.js +39 -205
- package/build/lib/index-cache.js.map +1 -1
- package/build/lib/link-rewriter.d.ts.map +1 -1
- package/build/lib/link-rewriter.js +28 -8
- package/build/lib/link-rewriter.js.map +1 -1
- package/build/lib/logger.d.ts.map +1 -1
- package/build/lib/logger.js +66 -27
- package/build/lib/logger.js.map +1 -1
- package/build/lib/markdown.d.ts +17 -5
- package/build/lib/markdown.d.ts.map +1 -1
- package/build/lib/markdown.js +146 -27
- package/build/lib/markdown.js.map +1 -1
- package/build/lib/permissions.d.ts.map +1 -1
- package/build/lib/permissions.js +19 -8
- package/build/lib/permissions.js.map +1 -1
- package/build/lib/tag-rewriter.d.ts.map +1 -1
- package/build/lib/tag-rewriter.js +12 -43
- package/build/lib/tag-rewriter.js.map +1 -1
- package/build/lib/tool-output.d.ts +9 -0
- package/build/lib/tool-output.d.ts.map +1 -1
- package/build/lib/tool-output.js +35 -0
- package/build/lib/tool-output.js.map +1 -1
- package/build/lib/vault.d.ts +30 -1
- package/build/lib/vault.d.ts.map +1 -1
- package/build/lib/vault.js +455 -87
- package/build/lib/vault.js.map +1 -1
- package/build/lib/yaml.d.ts +2 -0
- package/build/lib/yaml.d.ts.map +1 -0
- package/build/lib/yaml.js +66 -0
- package/build/lib/yaml.js.map +1 -0
- package/build/tools/attachments.d.ts.map +1 -1
- package/build/tools/attachments.js +127 -24
- package/build/tools/attachments.js.map +1 -1
- package/build/tools/bases.d.ts.map +1 -1
- package/build/tools/bases.js +40 -15
- package/build/tools/bases.js.map +1 -1
- package/build/tools/canvas.d.ts.map +1 -1
- package/build/tools/canvas.js +88 -23
- package/build/tools/canvas.js.map +1 -1
- package/build/tools/links.d.ts.map +1 -1
- package/build/tools/links.js +112 -118
- package/build/tools/links.js.map +1 -1
- package/build/tools/read.d.ts.map +1 -1
- package/build/tools/read.js +139 -65
- package/build/tools/read.js.map +1 -1
- package/build/tools/sections.d.ts.map +1 -1
- package/build/tools/sections.js +358 -26
- package/build/tools/sections.js.map +1 -1
- package/build/tools/semantic.d.ts.map +1 -1
- package/build/tools/semantic.js +180 -23
- package/build/tools/semantic.js.map +1 -1
- package/build/tools/tags.d.ts.map +1 -1
- package/build/tools/tags.js +68 -11
- package/build/tools/tags.js.map +1 -1
- package/build/tools/write.d.ts.map +1 -1
- package/build/tools/write.js +48 -13
- package/build/tools/write.js.map +1 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -86,7 +86,7 @@ Give AI assistants deep, structured access to your Obsidian knowledge base. Read
|
|
|
86
86
|
### Bases (Obsidian 1.10+)
|
|
87
87
|
- `list_bases` enumerates `.base` files
|
|
88
88
|
- `read_base` returns the parsed YAML (filters, properties, views)
|
|
89
|
-
- `query_base` runs the filter DSL against the vault and returns matching notes; supports `taggedWith()`, `file.hasTag()`, `file.inFolder()`, comparison operators, and `and`/`or`/`not` combinators
|
|
89
|
+
- `query_base` runs the filter DSL against the vault and returns matching notes; supports `taggedWith()`, `file.hasTag()`, `file.inFolder()`, comparison operators, and `and`/`or`/`not` combinators. Unsupported filters warn and fail closed instead of broadening results.
|
|
90
90
|
|
|
91
91
|
### Attachments
|
|
92
92
|
- `list_attachments` enumerates every non-md/canvas/base file with a per-extension count summary
|
|
@@ -95,8 +95,10 @@ Give AI assistants deep, structured access to your Obsidian knowledge base. Read
|
|
|
95
95
|
|
|
96
96
|
### Semantic Search (optional, Ollama or OpenAI)
|
|
97
97
|
- `index_vault` chunks each note (heading-aware), embeds via the configured provider, persists vectors to `<vault>/.obsidian/cache/`, and incrementally re-embeds only changed notes
|
|
98
|
+
- Because indexing sends readable note chunks to the configured embedding provider, `index_vault` requires `confirm: "send-vault-text-to-embedding-provider"` on each call
|
|
98
99
|
- `search_semantic` ranks notes by cosine similarity against an embedded query
|
|
99
100
|
- `find_similar_notes` reuses an existing note's embeddings, with source-topic anchoring, to surface neighbors without a live API call
|
|
101
|
+
- Stored snippets are returned only while the current note content hash still matches the indexed text; stale chunks are pruned on search
|
|
100
102
|
|
|
101
103
|
### MCP Resources
|
|
102
104
|
- `obsidian://note/{path}` reads any note by its vault-relative path
|
|
@@ -114,9 +116,9 @@ The server exposes five starter prompts that clients (Claude Desktop, Cursor) su
|
|
|
114
116
|
|
|
115
117
|
### Operational features
|
|
116
118
|
- **Folder-scoped permissions**: `OBSIDIAN_READ_PATHS` / `OBSIDIAN_WRITE_PATHS` allowlists gate every tool at the path-resolution choke point
|
|
117
|
-
- **
|
|
119
|
+
- **In-memory mtime cache** speeds repeated vault scans within a running process without persisting note bodies to disk
|
|
118
120
|
- **Progress notifications** (`notifications/progress`) on `rename_tag`, `find_unused_attachments`, and `index_vault` when the client subscribes via `_meta.progressToken`
|
|
119
|
-
- **
|
|
121
|
+
- **Hard bulk-write latches** require `confirmPath` for default `move_note` reference rewrites, `confirmTag` for non-dry-run `rename_tag`, and `confirm=true` for permanent deletion; clients with elicitation support also get typed prompts
|
|
120
122
|
|
|
121
123
|
---
|
|
122
124
|
|
|
@@ -178,22 +180,22 @@ claude mcp add obsidian-mcp-pro -- npx -y obsidian-mcp-pro
|
|
|
178
180
|
### HTTP Transport (Remote Clients, Cursor, ChatGPT, Web)
|
|
179
181
|
|
|
180
182
|
```bash
|
|
181
|
-
npx -y obsidian-mcp-pro --transport=http --port=3333
|
|
183
|
+
MCP_HTTP_TOKEN=your-secret npx -y obsidian-mcp-pro --transport=http --port=3333
|
|
182
184
|
```
|
|
183
185
|
|
|
184
|
-
Endpoint: `http://127.0.0.1:3333/mcp` (Streamable HTTP).
|
|
186
|
+
Endpoint: `http://127.0.0.1:3333/mcp` (Streamable HTTP). HTTP transport requires a bearer token:
|
|
185
187
|
|
|
186
188
|
```bash
|
|
187
|
-
npx -y obsidian-mcp-pro --transport=http
|
|
188
|
-
# or: MCP_HTTP_TOKEN=your-secret npx -y obsidian-mcp-pro --transport=http
|
|
189
|
+
MCP_HTTP_TOKEN=your-secret npx -y obsidian-mcp-pro --transport=http
|
|
189
190
|
```
|
|
190
191
|
|
|
191
192
|
The HTTP server binds to `127.0.0.1` by default with DNS rebinding protection enabled.
|
|
193
|
+
Startup always requires `MCP_HTTP_TOKEN`, including loopback-only local servers. The old `--token` flag was removed because command-line secrets can be exposed through OS process listings.
|
|
192
194
|
|
|
193
195
|
> [!WARNING]
|
|
194
|
-
> **Never bind `--host=0.0.0.0` directly to the public internet.** Doing so exposes your entire Obsidian vault to anyone who can reach the port.
|
|
196
|
+
> **Never bind `--host=0.0.0.0` directly to the public internet.** Doing so exposes your entire Obsidian vault to anyone who can reach the port. The server refuses HTTP startup without a bearer token, but if you need remote access:
|
|
195
197
|
> - Put the server behind a reverse proxy (nginx, Caddy, Cloudflare Tunnel) that terminates TLS, **and**
|
|
196
|
-
> -
|
|
198
|
+
> - Set `MCP_HTTP_TOKEN`, **and**
|
|
197
199
|
> - Restrict `--allow-origin` to the specific origins you trust, **and**
|
|
198
200
|
> - Set `--rate-limit` to cap request volume per IP.
|
|
199
201
|
>
|
|
@@ -203,23 +205,23 @@ Additional hardening flags:
|
|
|
203
205
|
|
|
204
206
|
| Flag | Purpose |
|
|
205
207
|
|------|---------|
|
|
206
|
-
| `--allow-origin=<csv>` | Restrict CORS to an allowlist (e.g. `https://claude.ai,https://chat.openai.com`). Default is
|
|
208
|
+
| `--allow-origin=<csv>` | Restrict CORS to an allowlist (e.g. `https://claude.ai,https://chat.openai.com`). Default is localhost-only; `*` requires bearer auth. |
|
|
207
209
|
| `--rate-limit=<n>` | Cap requests per minute per client IP. `/health` and `/version` are exempt. Default is unlimited. |
|
|
208
210
|
|
|
209
211
|
Operational endpoints (no auth required):
|
|
210
212
|
|
|
211
213
|
| Endpoint | Returns |
|
|
212
214
|
|----------|---------|
|
|
213
|
-
| `GET /health` | `{ status: "ok",
|
|
215
|
+
| `GET /health` | `{ status: "ok", version: <string> }` — liveness for monitoring. |
|
|
214
216
|
| `GET /version` | `{ version: <string> }` — package version, for rollout auditing. |
|
|
215
217
|
|
|
216
|
-
Structured logging is controlled by `LOG_LEVEL` (`debug`/`info`/`warn`/`error`/`silent`, default `info`) and `LOG_FORMAT` (`text`/`json`, default `text`). All logs go to stderr so the stdio transport on stdout is never polluted.
|
|
218
|
+
Structured logging is controlled by `LOG_LEVEL` (`debug`/`info`/`warn`/`error`/`silent`, default `info`) and `LOG_FORMAT` (`text`/`json`, default `text`). All logs go to stderr so the stdio transport on stdout is never polluted, with absolute paths, vault-relative path fields, secret-bearing URLs, and control characters redacted before write.
|
|
217
219
|
|
|
218
220
|
---
|
|
219
221
|
|
|
220
222
|
## Usage
|
|
221
223
|
|
|
222
|
-
Once installed, the server exposes
|
|
224
|
+
Once installed, the server exposes 41 tools, 5 prompts, and 3 resources to whichever MCP client you configured. Below is a transcript of a Claude Desktop conversation showing what day-to-day use looks like.
|
|
223
225
|
|
|
224
226
|
> **You:** Find notes tagged `#project` I touched this week, then summarize the status of each and append today's date under a "Last reviewed" heading in each one.
|
|
225
227
|
|
|
@@ -276,6 +278,26 @@ The server locates your vault using the following priority:
|
|
|
276
278
|
|
|
277
279
|
Auto-detection works on **macOS**, **Windows**, and **Linux** by reading the platform-specific Obsidian configuration directory.
|
|
278
280
|
|
|
281
|
+
### Environment Variables
|
|
282
|
+
|
|
283
|
+
Every setting is optional unless noted. The sections below explain the grouped ones in depth.
|
|
284
|
+
|
|
285
|
+
| Variable | Purpose | Default |
|
|
286
|
+
|----------|---------|---------|
|
|
287
|
+
| `OBSIDIAN_VAULT_PATH` | Absolute path to the vault (highest-priority vault selector). | auto-detect |
|
|
288
|
+
| `OBSIDIAN_VAULT_NAME` | Select a vault by folder name when several exist. | first valid vault |
|
|
289
|
+
| `OBSIDIAN_READ_PATHS` | Comma/colon list of folders read tools may access (see [Folder-Scoped Permissions](#folder-scoped-permissions)). | unrestricted |
|
|
290
|
+
| `OBSIDIAN_WRITE_PATHS` | Same shape, for mutating tools. | unrestricted |
|
|
291
|
+
| `OBSIDIAN_CACHE_DISABLED` | Set truthy to disable the in-memory mtime cache (see [Caches](#caches)). | enabled |
|
|
292
|
+
| `OBSIDIAN_EMBEDDING_PROVIDER` | Semantic-search provider, e.g. `openai` (see [Semantic Search Provider](#semantic-search-provider)). | unset (disabled) |
|
|
293
|
+
| `OBSIDIAN_EMBEDDING_MODEL` | Embedding model name for the chosen provider. | provider default |
|
|
294
|
+
| `OBSIDIAN_EMBEDDING_URL` | Override the embedding endpoint base URL. | provider default |
|
|
295
|
+
| `OBSIDIAN_EMBEDDING_API_KEY` | API key for the embedding provider. | falls back to `OPENAI_API_KEY` |
|
|
296
|
+
| `OPENAI_API_KEY` | Used as the embedding key when `OBSIDIAN_EMBEDDING_API_KEY` is unset. | unset |
|
|
297
|
+
| `MCP_HTTP_TOKEN` | Bearer token required by the HTTP transport (see [HTTP Transport](#http-transport-remote-clients-cursor-chatgpt-web)). | unset |
|
|
298
|
+
| `LOG_LEVEL` | Logger verbosity: `debug`, `info`, `warn`, `error`. | `info` |
|
|
299
|
+
| `LOG_FORMAT` | Log output format: `text` or `json`. | `text` |
|
|
300
|
+
|
|
279
301
|
### Daily-Note Filename Format
|
|
280
302
|
|
|
281
303
|
`get_daily_note`, `create_daily_note`, and the `obsidian://daily` resource render the note path using your vault's `.obsidian/daily-notes.json` `format` string. Moment.js-style tokens are supported:
|
|
@@ -303,18 +325,22 @@ Restrict the tools' read/write surface to specific folders without exposing the
|
|
|
303
325
|
| `OBSIDIAN_READ_PATHS` | Comma- or colon-separated list of folders that read tools may access. Unset means unrestricted. Use `.` to mean the vault root. |
|
|
304
326
|
| `OBSIDIAN_WRITE_PATHS` | Same shape, but for mutations (create / append / update / delete / move / surgical edits). |
|
|
305
327
|
|
|
306
|
-
Read and write are independent, so an audit account can be read-only on most of the vault but write-only to a `Drafts/` folder. The startup log line and `--help` advertise the active scope. The allowlist is enforced at a single path-resolution choke point so every tool inherits it.
|
|
328
|
+
Read and write are independent, so an audit account can be read-only on most of the vault but write-only to a `Drafts/` folder. Moving a note requires read access to the source and write access to the destination, because the move carries the source content into its new folder. Surgical edits (`replace_in_note`, `update_section`, `insert_at_section`, and `edit_block`) require read access to the target plus write access because they inspect existing content before writing. In-vault symlinks are checked against their real target before the allowlist decision is finalized. The startup log line and `--help` advertise the active scope. The allowlist is enforced at a single path-resolution choke point so every tool inherits it.
|
|
329
|
+
|
|
330
|
+
### Caches
|
|
307
331
|
|
|
308
|
-
|
|
332
|
+
The note-content mtime cache is in-memory only. It speeds repeated vault-wide scans
|
|
333
|
+
inside the running process, but it does not persist note bodies or absolute paths to
|
|
334
|
+
disk. Any legacy `<vault>/.obsidian/cache/mcp-pro-index-cache.json` snapshot is
|
|
335
|
+
ignored and removed on first cache use.
|
|
309
336
|
|
|
310
|
-
|
|
337
|
+
Semantic embeddings live under `<vault>/.obsidian/cache/`:
|
|
311
338
|
|
|
312
339
|
| File | Purpose |
|
|
313
340
|
|------|---------|
|
|
314
|
-
| `mcp-pro-
|
|
315
|
-
| `mcp-pro-embeddings.json` | Persisted embeddings for semantic search (only present once `index_vault` has run). Vault-relocation safe via an embedded `vaultRoot` check; switching providers / models invalidates entries automatically. |
|
|
341
|
+
| `mcp-pro-embeddings.json` | Persisted embeddings for semantic search (only present once `index_vault` has run). Vault-relocation safe via an embedded `vaultRoot` check; switching providers/models or stale note content invalidates entries automatically. |
|
|
316
342
|
|
|
317
|
-
|
|
343
|
+
The embedding cache is vault-local, excluded from vault scans (`.obsidian/` is pruned), and can be deleted at any time. Persistence can be turned off with `OBSIDIAN_CACHE_DISABLED=1`.
|
|
318
344
|
|
|
319
345
|
### Semantic Search Provider
|
|
320
346
|
|
|
@@ -322,16 +348,24 @@ The semantic-search tools (`index_vault`, `search_semantic`, `find_similar_notes
|
|
|
322
348
|
|
|
323
349
|
| Env var | Default | Notes |
|
|
324
350
|
|---------|---------|-------|
|
|
325
|
-
| `OBSIDIAN_EMBEDDING_PROVIDER` | `ollama` | `ollama`, `openai`, or `none` to disable. |
|
|
326
|
-
| `OBSIDIAN_EMBEDDING_MODEL` | `nomic-embed-text` (Ollama), `text-embedding-3-small` (OpenAI) | Provider-specific model identifier. |
|
|
327
|
-
| `OBSIDIAN_EMBEDDING_URL` | `http://localhost:11434` (Ollama), `https://api.openai.com/v1` (OpenAI) | Base URL. |
|
|
328
|
-
| `OBSIDIAN_EMBEDDING_API_KEY` | `OPENAI_API_KEY` falls back if unset | Required for hosted providers. |
|
|
351
|
+
| `OBSIDIAN_EMBEDDING_PROVIDER` | `ollama` if unset or blank | `ollama`, `openai`, or `none` to disable. |
|
|
352
|
+
| `OBSIDIAN_EMBEDDING_MODEL` | `nomic-embed-text` (Ollama), `text-embedding-3-small` (OpenAI) if unset or blank | Provider-specific model identifier. |
|
|
353
|
+
| `OBSIDIAN_EMBEDDING_URL` | `http://localhost:11434` (Ollama), `https://api.openai.com/v1` (OpenAI) if unset or blank | Base URL without credentials, query strings, or fragments. |
|
|
354
|
+
| `OBSIDIAN_EMBEDDING_API_KEY` | `OPENAI_API_KEY` falls back if unset or blank | Required for hosted providers. |
|
|
329
355
|
|
|
330
356
|
For local Ollama: install [Ollama](https://ollama.com/), then `ollama pull nomic-embed-text`. The semantic tools register even when no provider is configured, so they're discoverable; calls return a configuration hint until set up.
|
|
331
357
|
|
|
358
|
+
`index_vault` sends readable note chunks to that provider. Calls must include:
|
|
359
|
+
|
|
360
|
+
```json
|
|
361
|
+
{ "confirm": "send-vault-text-to-embedding-provider" }
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
This latch is per call so scripted index refreshes have to keep the privacy decision visible.
|
|
365
|
+
|
|
332
366
|
### Observability
|
|
333
367
|
|
|
334
|
-
Logs stream to stderr as either plain text (default) or single-line JSON, controlled by `LOG_LEVEL` (`debug`/`info`/`warn`/`error`/`silent`) and `LOG_FORMAT` (`text`/`json`).
|
|
368
|
+
Logs stream to stderr as either plain text (default) or single-line JSON, controlled by `LOG_LEVEL` (`debug`/`info`/`warn`/`error`/`silent`) and `LOG_FORMAT` (`text`/`json`). Local stderr and MCP-forwarded log payloads both redact absolute paths, vault-relative path fields, secret-bearing URLs, and control characters.
|
|
335
369
|
|
|
336
370
|
The server also declares the MCP [`logging` capability](https://modelcontextprotocol.io/specification), so every log line is forwarded to the connected client as a `notifications/message` frame alongside tool responses. Clients that honor `logging/setLevel` can filter server-side logs at runtime without restarting. Claude Desktop surfaces these in its MCP DevTools pane; most other clients currently ignore them, so this is useful primarily for self-hosters and tooling authors.
|
|
337
371
|
|
|
@@ -339,12 +373,22 @@ The server also declares the MCP [`logging` capability](https://modelcontextprot
|
|
|
339
373
|
|
|
340
374
|
## Security
|
|
341
375
|
|
|
342
|
-
- **Vault boundary** — every tool and resource routes through a single path resolver that rejects `..` traversal, null-byte injection, and symlinks pointing outside the vault (ancestor-realpath check).
|
|
376
|
+
- **Vault boundary** — every tool and resource routes through a single path resolver that rejects `..` traversal, null-byte injection, and symlinks pointing outside the vault (ancestor-realpath check). On Windows it also rejects reserved device names, alternate data stream syntax, and trailing-dot/space filename aliases.
|
|
377
|
+
- **Note/file boundary** — note read and edit surfaces only target `.md` files; attachments, Canvas files, and Bases stay on their dedicated tools with their own caps and parsers.
|
|
378
|
+
- **Full-note cap** — full `.md` note reads and read-modify-write helpers refuse notes over 5 MiB before materializing them; `get_note` line fragments still stream from large notes for targeted inspection.
|
|
343
379
|
- **Excluded directories** — `.obsidian`, `.git`, and `.trash` are pruned at traversal time and at resolution time, so nested occurrences never leak back to clients.
|
|
344
|
-
- **HTTP transport** — binds to `127.0.0.1` by default with DNS rebinding protection (host-header allowlist).
|
|
345
|
-
- **
|
|
380
|
+
- **HTTP transport** — requires a bearer token at startup and binds to `127.0.0.1` by default with DNS rebinding protection (host-header allowlist). `/mcp` requests must send `Authorization: Bearer <secret>`, compared in constant time. Malformed request URL or Host data is rejected before routing.
|
|
381
|
+
- **Attachment safety** — executable extensions are blocked, SVGs are returned as `text/plain`, and active text formats such as HTML/XML/CSS are served with `text/plain` resource metadata.
|
|
382
|
+
- **Canvas link safety** — Canvas link nodes added through the server accept only absolute `http://` and `https://` URLs, preventing local file and application-protocol links from being persisted by tool calls.
|
|
383
|
+
- **Regex edit safety** — `replace_in_note` caps regex pattern/input size and rejects backtracking-prone repeated groups before matching.
|
|
384
|
+
- **Error and log sanitization** — filesystem error messages are stripped of absolute host paths before being returned to MCP clients, local stderr and MCP-forwarded logs redact paths and secret-bearing URLs, ASCII control bytes and Unicode bidi controls are escaped in displayed values, and note-derived duplicate-alias text is not copied into graph warnings. Uncaught HTTP errors respond with a generic `Internal server error` body while server logs keep sanitized diagnostics.
|
|
385
|
+
- **Untrusted vault text boundaries** — tool outputs that include note bodies, read, search result, semantic result, semantic index failure, write rewrite-warning, link-graph, attachment, Base, and Canvas path summaries, attachment extension summaries, search snippets, semantic snippets and heading paths, tag lists, tag search result paths and previews, tag rename skipped-note rows, frontmatter values, Base data, wikilink targets in link-analysis output, SVG attachment text, section headings, Canvas node identities, colors, previews, edge endpoints, and edge labels, or backlink context wrap those vault-authored portions in `[BEGIN UNTRUSTED VAULT CONTENT: ...]` / `[END UNTRUSTED VAULT CONTENT: ...]` markers before they enter an MCP client's model context. Note and daily resources use the same visible boundaries for markdown bodies and carry `_meta["obsidian-mcp-pro/contentTrust"] = "untrusted-vault-content"`.
|
|
386
|
+
- **YAML parser boundaries** — Obsidian properties are parsed only from `---` YAML delimiter lines; non-YAML gray-matter language blocks stay as body text, oversized frontmatter is skipped on reads and refused for metadata updates, and note/Base YAML containing anchors or aliases is not parsed.
|
|
387
|
+
- **Semantic index freshness** — `search_semantic` and `find_similar_notes` re-check current note content hashes before returning stored snippets or source-note embeddings, pruning stale cache entries instead of surfacing old note text.
|
|
388
|
+
- **Semantic indexing confirmation** — `index_vault` refuses to read and embed vault notes unless the call includes `confirm: "send-vault-text-to-embedding-provider"`, making provider-bound note transfer explicit.
|
|
389
|
+
- **Bulk-write confirmations** — `move_note` reference rewrites require `confirmPath` to match the destination path, and non-dry-run `rename_tag` requires `confirmTag` to match the new tag. Clients that support MCP elicitation are also asked to re-type the destination path or new tag before the rewrite runs.
|
|
346
390
|
- **Atomic writes** — every note write (`create_note`, `append`, `prepend`, `update_frontmatter`, canvas mutations) stages content to a sibling temp file then renames onto the target, so a crash or kill mid-write never leaves a truncated file. Combined with per-path locks for the full read-modify-write cycle, concurrent callers can't lose each other's updates. The `install` subcommand uses the same pattern and keeps a backup of the previous config.
|
|
347
|
-
- **Rate limiting + CORS allowlist** — optional `--rate-limit` caps per-IP request volume; `--allow-origin` restricts browser-facing CORS. `/health` and `/version` stay reachable under load for monitoring.
|
|
391
|
+
- **Rate limiting + CORS allowlist** — optional `--rate-limit` caps per-IP request volume; `--allow-origin` restricts browser-facing CORS and refuses `*` unless bearer auth is enabled. `/health` and `/version` stay reachable under load for monitoring.
|
|
348
392
|
- **Request timeout** — HTTP POST requests are capped at 2 minutes of wall-clock time. Long-lived SSE GET streams are exempt so idle clients aren't reaped.
|
|
349
393
|
- **Process supervision** — `uncaughtException` exits cleanly so systemd/Docker/npx supervisors can restart; `unhandledRejection` logs but doesn't kill the process.
|
|
350
394
|
|
|
@@ -373,7 +417,7 @@ Tag extraction is similarly case-tolerant: `tags`, `Tags`, `TAGS`, `tag`, and `T
|
|
|
373
417
|
| `get_note` | Read a note whole, or by `section` / `block` / `lines` | `path`, `section`, `block`, `lines` |
|
|
374
418
|
| `list_notes` | List notes in the vault or a folder | `folder`, `limit` |
|
|
375
419
|
| `get_daily_note` | Get today's (or a specific date's) daily note | `date` |
|
|
376
|
-
| `search_by_frontmatter` | Find notes by frontmatter property values | `property`, `value`, `folder` |
|
|
420
|
+
| `search_by_frontmatter` | Find notes by frontmatter property values with case-insensitive key/value matching | `property`, `value`, `folder` |
|
|
377
421
|
| `get_recent_notes` | Notes sorted by mtime; optional ISO-or-relative `since` filter | `limit`, `since`, `folder` |
|
|
378
422
|
| `get_vault_stats` | Vault counts, bytes, words, tag coverage, most-recent note | `folder` |
|
|
379
423
|
| `resolve_alias` | Translate frontmatter alias (or basename) to note path | `name`, `includeBasename` |
|
|
@@ -387,7 +431,7 @@ Tag extraction is similarly case-tolerant: `tags`, `Tags`, `TAGS`, `tag`, and `T
|
|
|
387
431
|
| `prepend_to_note` | Prepend content after frontmatter | `path`, `content` |
|
|
388
432
|
| `update_frontmatter` | Update frontmatter properties on a note | `path`, `properties` |
|
|
389
433
|
| `create_daily_note` | Create today's daily note from template | `date`, `content`, `templatePath` |
|
|
390
|
-
| `move_note` | Move or rename a note; rewrites references across the vault | `oldPath`, `newPath`, `updateLinks` |
|
|
434
|
+
| `move_note` | Move or rename a note; rewrites references across the vault | `oldPath`, `newPath`, `updateLinks`, `confirmPath` |
|
|
391
435
|
| `delete_note` | Delete a note (trash by default); optional elicitation on permanent | `path`, `permanent`, `removeReferences` |
|
|
392
436
|
|
|
393
437
|
### Section-level edits
|
|
@@ -406,7 +450,7 @@ Tag extraction is similarly case-tolerant: `tags`, `Tags`, `TAGS`, `tag`, and `T
|
|
|
406
450
|
|------|-------------|----------------|
|
|
407
451
|
| `get_tags` | Get all tags and their usage counts | `sortBy` |
|
|
408
452
|
| `search_by_tag` | Find all notes with a specific tag | `tag`, `includeContent` |
|
|
409
|
-
| `rename_tag` | Rewrite inline + frontmatter occurrences vault-wide; hierarchical | `oldName`, `newName`, `hierarchical`, `dryRun` |
|
|
453
|
+
| `rename_tag` | Rewrite inline + frontmatter occurrences vault-wide; hierarchical | `oldName`, `newName`, `hierarchical`, `dryRun`, `confirmTag` |
|
|
410
454
|
|
|
411
455
|
### Links & graph
|
|
412
456
|
|
|
@@ -423,7 +467,7 @@ Tag extraction is similarly case-tolerant: `tags`, `Tags`, `TAGS`, `tag`, and `T
|
|
|
423
467
|
| Tool | Description | Key Parameters |
|
|
424
468
|
|------|-------------|----------------|
|
|
425
469
|
| `list_canvases` | List all `.canvas` files in the vault | (none) |
|
|
426
|
-
| `read_canvas` | Read a `.canvas`
|
|
470
|
+
| `read_canvas` | Read a bounded `.canvas` node/edge summary | `path` |
|
|
427
471
|
| `add_canvas_node` | Add a node to a canvas | `canvasPath`, `type`, `content`, `x`, `y` |
|
|
428
472
|
| `add_canvas_edge` | Add an edge between two canvas nodes | `canvasPath`, `fromNode`, `toNode` |
|
|
429
473
|
|
|
@@ -433,7 +477,7 @@ Tag extraction is similarly case-tolerant: `tags`, `Tags`, `TAGS`, `tag`, and `T
|
|
|
433
477
|
|------|-------------|----------------|
|
|
434
478
|
| `list_bases` | Enumerate `.base` files in the vault | (none) |
|
|
435
479
|
| `read_base` | Parse a Base file (filters, properties, views) | `path` |
|
|
436
|
-
| `query_base` | Run a Base's filter DSL against the vault | `path`, `view`, `limit`, `includeFrontmatter` |
|
|
480
|
+
| `query_base` | Run a Base's filter DSL against the vault; unsupported filters warn and fail closed | `path`, `view`, `limit`, `includeFrontmatter` |
|
|
437
481
|
|
|
438
482
|
### Attachments
|
|
439
483
|
|
|
@@ -447,7 +491,7 @@ Tag extraction is similarly case-tolerant: `tags`, `Tags`, `TAGS`, `tag`, and `T
|
|
|
447
491
|
|
|
448
492
|
| Tool | Description | Key Parameters |
|
|
449
493
|
|------|-------------|----------------|
|
|
450
|
-
| `index_vault` | Build / refresh the embedding index (incremental, progress events) | `force`, `folder` |
|
|
494
|
+
| `index_vault` | Build / refresh the embedding index (incremental, progress events) | `force`, `folder`, `confirm` |
|
|
451
495
|
| `search_semantic` | Cosine search the embedding index for a natural-language query | `query`, `limit`, `folder`, `includeSnippet` |
|
|
452
496
|
| `find_similar_notes` | Surface notes most similar to a source note, anchored to its opening topic (no live API call) | `path`, `limit` |
|
|
453
497
|
|
|
@@ -487,7 +531,7 @@ All tool paths must be **vault-relative** (e.g. `notes/hello.md`), never absolut
|
|
|
487
531
|
|
|
488
532
|
### HTTP Transport Returns `401 Unauthorized`
|
|
489
533
|
|
|
490
|
-
The server was started with
|
|
534
|
+
The server was started with `MCP_HTTP_TOKEN` but the client isn't sending a matching `Authorization: Bearer <secret>` header. Verify the token value and that the header is present — comparison is case-sensitive and constant-time.
|
|
491
535
|
|
|
492
536
|
### HTTP Transport Returns `429 Too Many Requests`
|
|
493
537
|
|
|
@@ -531,7 +575,6 @@ OBSIDIAN_VAULT_PATH=/path/to/vault npm start
|
|
|
531
575
|
```
|
|
532
576
|
|
|
533
577
|
For the company-grade maintenance and R&D operating plan, see [docs/DEVELOPMENT_GOAL.md](./docs/DEVELOPMENT_GOAL.md).
|
|
534
|
-
For token-based npm publishing, see [docs/RELEASE.md](./docs/RELEASE.md).
|
|
535
578
|
|
|
536
579
|
GitHub Actions workflows are manual-only in this repository. Use `npm run verify` as the required local gate before merging or publishing.
|
|
537
580
|
|
|
@@ -556,7 +599,7 @@ src/
|
|
|
556
599
|
chunker.ts # Heading-aware chunking for embeddings
|
|
557
600
|
embedding-providers.ts# Ollama + OpenAI providers
|
|
558
601
|
embedding-store.ts # Persistent vector index, cosine search
|
|
559
|
-
index-cache.ts # mtime-keyed content cache (in-memory
|
|
602
|
+
index-cache.ts # mtime-keyed content cache (in-memory)
|
|
560
603
|
progress.ts # MCP progress-notification helper
|
|
561
604
|
mime.ts # extension -> MIME map for attachments
|
|
562
605
|
dates.ts # Moment-style date format for daily-note filenames
|
|
@@ -597,7 +640,7 @@ src/
|
|
|
597
640
|
npm test
|
|
598
641
|
```
|
|
599
642
|
|
|
600
|
-
|
|
643
|
+
952 tests covering vault operations, atomic writes + concurrent-mutation races, markdown parsing (frontmatter, wikilinks, tags, fenced + indented code blocks, multi-backtick inline code), section / block-id parsing, tag rewriting (inline + frontmatter, hierarchical sub-tags), Bases filter DSL, attachment classification, semantic chunking + cosine ranking + persistent embedding store, moment-token date formatting, canvas round-trip fidelity, HTTP transport (Bearer auth, oversize-body, CORS allowlist with `Vary: Origin`, per-IP rate limiting, `/version`), leveled logger (text + JSON output), folder-permission allowlist, mtime-cache rehydration across simulated restarts, vault-wide link rewriting on `move_note` and `delete_note` (TOCTOU correctness, control-char injection escape), and security regression guards (symlink escape, case-only rename, path-leak sanitization, cross-process exclusive-create). Handler tests exercise every tool through a real MCP client/server pair via `InMemoryTransport`.
|
|
601
644
|
|
|
602
645
|
```bash
|
|
603
646
|
npm run lint # eslint v9 + typescript-eslint v8 (flat config)
|
|
@@ -629,8 +672,8 @@ npm run lint:fix # auto-fix
|
|
|
629
672
|
block (and don't expose subsequent content to wikilink rewriting).
|
|
630
673
|
- **`/health` no longer leaks the live session count when a Bearer
|
|
631
674
|
token is configured.** Status + version stay public for monitoring;
|
|
632
|
-
`sessions` is dropped in authenticated deployments.
|
|
633
|
-
|
|
675
|
+
`sessions` is dropped in authenticated deployments. In 4.0.0 and
|
|
676
|
+
later, HTTP always starts with bearer auth, so the field stays hidden.
|
|
634
677
|
- **`constantTimeEqual` is now fully length-safe** (pads both inputs
|
|
635
678
|
to a fixed width before comparing), and the regex / parser hardening
|
|
636
679
|
list also closed: `resolveWikilink` proximity tie-break for
|
|
@@ -673,11 +716,11 @@ npm run lint:fix # auto-fix
|
|
|
673
716
|
- **Attachments.** `list_attachments`, `find_unused_attachments`, `get_attachment` (returns image / audio / blob bytes inline).
|
|
674
717
|
- **Tag renames vault-wide.** `rename_tag` rewrites both inline `#tag` and frontmatter `tags:` (hierarchical mode rebases nested sub-tags).
|
|
675
718
|
- **Folder-scoped permissions.** `OBSIDIAN_READ_PATHS` / `OBSIDIAN_WRITE_PATHS` allowlists.
|
|
676
|
-
- **
|
|
719
|
+
- **In-memory mtime cache.** Vault-wide scans (`get_tags`, `search_notes`, `search_by_tag`) reuse unchanged note content within the running process without persisting note bodies to disk.
|
|
677
720
|
- **Quick wins.** `get_recent_notes`, `get_vault_stats`, `resolve_alias`.
|
|
678
721
|
- **MCP prompts.** `daily-review`, `weekly-rollup`, `find-stale-notes`, `extract-action-items`, `build-moc`.
|
|
679
722
|
- **Progress notifications** on `rename_tag`, `find_unused_attachments`, `index_vault`.
|
|
680
|
-
- **
|
|
723
|
+
- **Bulk-write confirmation latches** on `delete_note(permanent: true)`, `move_note` reference rewrites, and non-dry-run `rename_tag`, plus elicitation prompts for clients that support them.
|
|
681
724
|
- **eslint** wired up with typescript-eslint flat config; `npm run lint` and `lint:fix`.
|
|
682
725
|
|
|
683
726
|
**v1.7.0** — `delete_note` reference handling:
|
package/build/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAsN/D,wBAAgB,cAAc,IAAI,WAAW,CAsB5C;AAED,wBAAsB,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAwDrF"}
|
package/build/config.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
|
-
import * as fsp from "fs/promises";
|
|
3
2
|
import * as path from "path";
|
|
4
3
|
import * as os from "os";
|
|
5
4
|
import { log } from "./lib/logger.js";
|
|
5
|
+
import { openVaultInternalFileForRead } from "./lib/vault.js";
|
|
6
|
+
const DAILY_NOTES_CONFIG_REL_PATH = ".obsidian/daily-notes.json";
|
|
7
|
+
const MAX_OBSIDIAN_CONFIG_BYTES = 1024 * 1024;
|
|
8
|
+
const MAX_DAILY_NOTES_CONFIG_BYTES = 64 * 1024;
|
|
9
|
+
const MAX_DAILY_NOTES_CONFIG_FIELD_CHARS = 500;
|
|
6
10
|
function getObsidianConfigPath() {
|
|
7
11
|
const platform = os.platform();
|
|
8
12
|
if (platform === "win32") {
|
|
@@ -35,6 +39,33 @@ function isObsidianConfig(value) {
|
|
|
35
39
|
}
|
|
36
40
|
return true;
|
|
37
41
|
}
|
|
42
|
+
function isPlainObject(value) {
|
|
43
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
44
|
+
}
|
|
45
|
+
function boundedDailyConfigString(value) {
|
|
46
|
+
if (typeof value !== "string")
|
|
47
|
+
return undefined;
|
|
48
|
+
if (value.length > MAX_DAILY_NOTES_CONFIG_FIELD_CHARS)
|
|
49
|
+
return undefined;
|
|
50
|
+
if (value.includes("\0"))
|
|
51
|
+
return undefined;
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
function normalizeDailyNoteFolder(folder) {
|
|
55
|
+
if (folder === undefined)
|
|
56
|
+
return undefined;
|
|
57
|
+
const slashed = folder.replace(/\/+$/g, "");
|
|
58
|
+
if (slashed === "")
|
|
59
|
+
return "";
|
|
60
|
+
if (slashed.startsWith("/"))
|
|
61
|
+
return folder;
|
|
62
|
+
const normalized = path.posix.normalize(slashed).replace(/\/+$/g, "");
|
|
63
|
+
if (normalized === ".")
|
|
64
|
+
return "";
|
|
65
|
+
if (normalized === ".." || normalized.startsWith("../"))
|
|
66
|
+
return slashed;
|
|
67
|
+
return normalized;
|
|
68
|
+
}
|
|
38
69
|
function isValidVaultPath(vaultPath) {
|
|
39
70
|
try {
|
|
40
71
|
const obsidianDir = path.join(vaultPath, ".obsidian");
|
|
@@ -54,9 +85,8 @@ function resolveVaultFromEnv() {
|
|
|
54
85
|
}
|
|
55
86
|
const resolved = path.resolve(envPath);
|
|
56
87
|
if (!isValidVaultPath(resolved)) {
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
// make the error useless. This never goes into a tool response.
|
|
88
|
+
// The logger redacts the path before writing to stderr or forwarding to
|
|
89
|
+
// MCP clients, so this stays useful without leaking host layout.
|
|
60
90
|
log.warn("OBSIDIAN_VAULT_PATH is not a valid vault (missing .obsidian dir)", {
|
|
61
91
|
vaultPath: resolved,
|
|
62
92
|
});
|
|
@@ -77,6 +107,25 @@ function resolveVaultFromObsidianConfig() {
|
|
|
77
107
|
log.warn("Obsidian config not found", { configPath });
|
|
78
108
|
return null;
|
|
79
109
|
}
|
|
110
|
+
try {
|
|
111
|
+
const stats = fs.statSync(configPath);
|
|
112
|
+
if (!stats.isFile()) {
|
|
113
|
+
log.warn("Obsidian config path is not a regular file", { configPath });
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
if (stats.size > MAX_OBSIDIAN_CONFIG_BYTES) {
|
|
117
|
+
log.warn("Obsidian config exceeds size cap; ignoring", {
|
|
118
|
+
configPath,
|
|
119
|
+
bytes: stats.size,
|
|
120
|
+
max: MAX_OBSIDIAN_CONFIG_BYTES,
|
|
121
|
+
});
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
log.warn("Failed to inspect Obsidian config", { configPath, err: err });
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
80
129
|
let config;
|
|
81
130
|
try {
|
|
82
131
|
const raw = fs.readFileSync(configPath, "utf-8");
|
|
@@ -160,10 +209,26 @@ export async function getDailyNoteConfig(vaultPath) {
|
|
|
160
209
|
format: "YYYY-MM-DD",
|
|
161
210
|
};
|
|
162
211
|
const resolvedVaultPath = vaultPath ?? getVaultConfig().vaultPath;
|
|
163
|
-
|
|
212
|
+
let dailyNotesConfigPath = "";
|
|
164
213
|
let raw;
|
|
165
214
|
try {
|
|
166
|
-
|
|
215
|
+
const opened = await openVaultInternalFileForRead(resolvedVaultPath, DAILY_NOTES_CONFIG_REL_PATH);
|
|
216
|
+
dailyNotesConfigPath = opened.fullPath;
|
|
217
|
+
const stats = opened.stats;
|
|
218
|
+
if (stats.size > MAX_DAILY_NOTES_CONFIG_BYTES) {
|
|
219
|
+
await opened.handle.close();
|
|
220
|
+
log.warn("Daily notes config exceeds size cap; using defaults", {
|
|
221
|
+
bytes: stats.size,
|
|
222
|
+
max: MAX_DAILY_NOTES_CONFIG_BYTES,
|
|
223
|
+
});
|
|
224
|
+
return defaults;
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
raw = await opened.handle.readFile("utf-8");
|
|
228
|
+
}
|
|
229
|
+
finally {
|
|
230
|
+
await opened.handle.close();
|
|
231
|
+
}
|
|
167
232
|
}
|
|
168
233
|
catch (err) {
|
|
169
234
|
if (err.code === "ENOENT")
|
|
@@ -176,10 +241,15 @@ export async function getDailyNoteConfig(vaultPath) {
|
|
|
176
241
|
}
|
|
177
242
|
try {
|
|
178
243
|
const parsed = JSON.parse(raw);
|
|
244
|
+
if (!isPlainObject(parsed))
|
|
245
|
+
return defaults;
|
|
246
|
+
const folder = normalizeDailyNoteFolder(boundedDailyConfigString(parsed.folder));
|
|
247
|
+
const format = boundedDailyConfigString(parsed.format);
|
|
248
|
+
const template = boundedDailyConfigString(parsed.template);
|
|
179
249
|
return {
|
|
180
|
-
folder:
|
|
181
|
-
format:
|
|
182
|
-
template
|
|
250
|
+
folder: folder ?? defaults.folder,
|
|
251
|
+
format: format ?? defaults.format,
|
|
252
|
+
template,
|
|
183
253
|
};
|
|
184
254
|
}
|
|
185
255
|
catch (err) {
|
package/build/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/build/http-server.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
2
2
|
export interface HttpServerOptions {
|
|
3
3
|
host: string;
|
|
4
4
|
port: number;
|
|
5
|
-
|
|
5
|
+
/** Required for HTTP transport. Use MCP_HTTP_TOKEN in the CLI path. */
|
|
6
|
+
bearerToken: string;
|
|
6
7
|
buildMcpServer: () => McpServer;
|
|
7
8
|
/** Install SIGINT/SIGTERM handlers + exit the process on shutdown. Default
|
|
8
9
|
* `true` for CLI use. Set `false` when embedding (e.g. inside an Obsidian
|
|
@@ -13,7 +14,8 @@ export interface HttpServerOptions {
|
|
|
13
14
|
/** Allowed CORS origins. Defaults to localhost-only patterns
|
|
14
15
|
* (`["http://localhost:*", "http://127.0.0.1:*", "http://[::1]:*"]`).
|
|
15
16
|
* Use an explicit list (e.g. `["https://claude.ai"]`) for browser-facing
|
|
16
|
-
* deployments. Pass `["*"]` to allow all origins
|
|
17
|
+
* deployments. Pass `["*"]` to allow all origins only when Bearer auth is
|
|
18
|
+
* configured.
|
|
17
19
|
* Requests from other origins still succeed (CORS is a browser-only
|
|
18
20
|
* restriction) but the browser will reject the response. */
|
|
19
21
|
allowedOrigins?: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,
|
|
1
|
+
{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,SAAS,CAAC;IAChC;;wEAEoE;IACpE,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;iEAM6D;IAC7D,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAwND,wBAAsB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwVxF"}
|