The previous implementation prefixed base64 with "BASE64:" in a text
response. This updates the response to use the proper MCP embedded
resource format:
{ type: "resource", resource: { uri, mimeType, blob } }
Changes:
- types.ts: extend ToolOutput content union to allow resource items
- file-operations.ts:
- getMimeType() maps common extensions to MIME types, falling back
to application/octet-stream
- MIME_TYPES table covers PDF, ZIP, images, Office formats, audio/video
- Binary files are now returned as an EmbeddedResource with:
uri: obsidian://<vault>/<path>
mimeType: detected from file extension
blob: base64-encoded raw bytes from the Buffer
- Tool descriptions updated to document the resource response shape
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previously, binary files (ZIP, images, compiled files) were read via
data.toString() which corrupted the bytes through UTF-8 decoding,
making the content unrecoverable on the client side.
Changes:
- executor.ts: add executeCommandBinary / executeObsidianCommandBinary
that collect stdout chunks as raw Buffers instead of strings
- types.ts: add optional stdoutBuffer field to CLIResult
- file-operations.ts:
- obsidian_read_note now uses executeObsidianCommandBinary so the
raw bytes are preserved before any decoding happens
- isBinaryContent() now operates on the raw Buffer (null byte check
+ >10% non-printable byte ratio on first 8KB sample)
- Binary files are returned as "BASE64:<base64string>" so the client
can reliably decode back to the original binary
- Tool descriptions updated to document the BASE64: prefix convention
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When obsidian_read_note read a binary file (ZIP, image, compiled
binary, etc.) the CLI returned raw bytes that were corrupted by text
decoding, producing an unusable response.
Added isBinaryContent() helper that checks for null bytes (definitive
binary marker) and a >10% ratio of non-printable characters in the
first 8KB of content. When binary content is detected the tool returns
a clear error message instead of garbled bytes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The tool descriptions were ambiguous — 'path' was described as a
'full file path (alternative to name)' which led callers to pass the
full path including filename in path, confusing the CLI.
Clarified semantics:
name = filename only (e.g. "My Note.md")
path = folder only (e.g. "Projects/Work") — never include filename
Added required: ['name'] to both input schemas.
Updated tool and handler descriptions accordingly.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add offset and max_chars parameters to obsidian_read_note:
- max_chars (default 50000, max 500000): caps characters returned per call
- offset (default 0): start position for reading, enabling pagination
When content is truncated a trailer message is appended telling the
caller the total size and the exact offset to pass on the next call.
This prevents the 26MB+ responses that caused Claude to reject output
when reading large PDFs stored in an Obsidian vault.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fixed parameter quoting in file operations and search tools to handle
filenames and values containing spaces correctly.
Root Cause:
- Obsidian CLI requires quoting values with spaces: name="My Note"
- Previous implementation used unquoted format: name=My Note
- Shell would split on spaces, breaking multi-word filenames
Solution:
1. Created formatParam() helper in src/utils/cli-helpers.ts
- Always quotes parameter values: param="value"
- Handles spaces and special characters safely
2. Updated file-operations.ts (8 tools):
- All file/path/content/name parameters now quoted
- create, read, append, prepend, delete, move, rename, open
3. Updated search.ts (1 tool):
- query, path, format, limit parameters now quoted
- Fixes searches with multi-word queries
Changes:
- Before: cmdArgs.push(\`file=${name}\`)
- After: cmdArgs.push(formatParam('file', name))
Files changed:
- src/utils/cli-helpers.ts (new): formatParam() and buildCmdArgs() helpers
- src/tools/file-operations.ts: Use formatParam() for all parameters
- src/tools/search.ts: Use formatParam() for all parameters
Impact:
- File operations now work with multi-word filenames
- Search queries with spaces now work correctly
- Content parameters with newlines/special chars handled safely
Known Issue:
- links.ts, tags-aliases.ts, properties.ts still need similar fixes
- These tools have additional structural issues (wrong command names)
- Will be addressed in follow-up commit
Build: 0 errors
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>