6 Commits

Author SHA1 Message Date
8bc0094604 chore: bump version to 1.1.6 and update CHANGELOG
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-30 18:24:08 -05:00
d27abcfca4 fix: clarify name vs path semantics in obsidian_create_note (fixes #8)
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>
2026-04-30 18:20:49 -05:00
ec507531ce chore: bump version to 1.1.5 and update CHANGELOG
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-28 12:22:38 -05:00
96b44ac97f fix: preserve < and > in note content so Mermaid arrows and HTML are not stripped (fixes #7)
< and > were in DANGEROUS_CHARS on the assumption they could trigger
shell redirection. However, shell redirection only applies at the
command level — inside double-quoted strings (which is how all values
are passed via formatParam) they are completely inert.

Removing them from DANGEROUS_CHARS and sanitizePath preserves:
- Mermaid diagram connectors: ->>, -->, <|, >>, etc.
- HTML tags in note content
- Any other angle-bracket syntax

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-28 12:21:24 -05:00
fe12e00e03 chore: bump version to 1.1.4 and update CHANGELOG
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-28 12:16:57 -05:00
3922056b25 fix: preserve Markdown code fences by escaping backticks instead of removing them (fixes #6)
Backticks were being stripped entirely by the sanitizer, destroying
Markdown code fences (```) in note content.

The real injection risk is backtick command substitution inside
double-quoted shell strings (e.g. content=`rm -rf /`). The fix is to
escape backticks as \` in formatParam — exactly as we already do for
double quotes — so the shell never interprets them while the content
is preserved intact.

Changes:
- sanitizer.ts: remove ` from DANGEROUS_CHARS and the backtick command
  substitution pattern from COMMAND_INJECTION_PATTERNS (now handled at
  the quoting layer, not the stripping layer)
- cli-helpers.ts: escape backticks as \` in formatParam alongside the
  existing double-quote escaping

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-28 12:15:28 -05:00
6 changed files with 54 additions and 18 deletions

View File

@@ -73,6 +73,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Comprehensive input schema definitions
- Security audit of parameter handling
## [1.1.6] - 2026-04-30
### Fixed
- **`obsidian_create_note` parameter semantics**: Fixed issue #8 where ambiguous `path` description led callers to pass the full file path (including filename) in `path`, causing the CLI to misbehave and the `overwrite` flag to auto-suffix filenames instead of replacing them
- `name` is now clearly documented as the **filename only** (e.g. `"My Note.md"`)
- `path` is now clearly documented as the **folder only** (e.g. `"Projects/Work"`) — never include the filename
- Added `required: ['name']` to the input schema
## [1.1.5] - 2026-04-28
### Fixed
- **Mermaid Arrows and HTML Preserved**: Fixed issue #7 where `<` and `>` were being stripped from note content, breaking Mermaid diagram connectors (`->>`, `-->`, `<|`, `>>`) and HTML tags
- `<` and `>` are only meaningful as shell redirects at the command level — inside double-quoted strings (how all values are passed) they are completely inert
- Removed from `DANGEROUS_CHARS` in both `sanitizeString` and `sanitizePath`
## [1.1.4] - 2026-04-28
### Fixed
- **Markdown Code Fence Preservation**: Fixed issue #6 where backticks were being stripped from note content, destroying Markdown code fences (` ``` `)
- Backticks are now escaped as `` \` `` inside double-quoted CLI parameter strings instead of being removed
- This preserves code fences and inline code in note content while still preventing shell command substitution via backticks
- Affects all tools that pass content: create, append, prepend, etc.
## [1.1.3] - 2026-04-17
### Fixed
@@ -128,6 +151,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Version History
- **1.1.6** - Bug fix release: Clarify `name` vs `path` semantics in `obsidian_create_note` (fixes #8)
- **1.1.5** - Bug fix release: Preserve `<` and `>` in note content for Mermaid/HTML (fixes #7)
- **1.1.4** - Bug fix release: Preserve Markdown code fences (fixes #6)
- **1.1.3** - Bug fix release: Large file chunking for obsidian_read_note; docs clarification for Obsidian must be running (fixes #4, #5)
- **1.1.2** - Bug fix release: Ampersand support in filenames (fixes #2)
- **1.1.1** - Bug fix release: Quote escaping in note content
@@ -137,6 +163,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Search & Discovery (12 tools)
- Task & Property Management (8 tools)
[1.1.6]: https://git.mortons.site/Peter.Morton/obsidian-mcp/releases/tag/v1.1.6
[1.1.5]: https://git.mortons.site/Peter.Morton/obsidian-mcp/releases/tag/v1.1.5
[1.1.4]: https://git.mortons.site/Peter.Morton/obsidian-mcp/releases/tag/v1.1.4
[1.1.3]: https://git.mortons.site/Peter.Morton/obsidian-mcp/releases/tag/v1.1.3
[1.1.2]: https://git.mortons.site/Peter.Morton/obsidian-mcp/releases/tag/v1.1.2
[1.1.1]: https://git.mortons.site/Peter.Morton/obsidian-mcp/releases/tag/v1.1.1

View File

@@ -1,7 +1,7 @@
{
"manifest_version": "0.3",
"name": "obsidian-mcp",
"version": "1.1.3",
"version": "1.1.6",
"display_name": "Obsidian CLI Bundle",
"description": "MCP Bundle for Obsidian CLI - Enable AI assistants to manage Obsidian vaults through conversational interface",
"long_description": "This MCP bundle provides a comprehensive set of tools for AI assistants to interact with and manage Obsidian vaults. It includes capabilities for creating, reading, updating, and deleting notes, managing links and tags, handling tasks, and more. With this bundle, AI assistants can seamlessly integrate with Obsidian to help users organize their knowledge and workflows.",

View File

@@ -1,6 +1,6 @@
{
"name": "obsidian-mcp",
"version": "1.1.3",
"version": "1.1.6",
"description": "MCP Bundle for Obsidian CLI - Enable AI assistants to manage Obsidian vaults through Model Context Protocol",
"type": "module",
"main": "dist/index.js",

View File

@@ -28,17 +28,18 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
// T029: Create note tool
server.registerTool(
'obsidian_create_note',
'Create a new note in the Obsidian vault. Optionally specify path, content, template, and whether to overwrite existing notes or open after creation.',
'Create a new note in the Obsidian vault. "name" is the filename only (e.g. "My Note.md"). "path" is the folder only (e.g. "Projects/Work") — do not include the filename in path. When overwrite is true the existing file is replaced.',
{
type: 'object',
required: ['name'],
properties: {
name: {
type: 'string',
description: 'File name for the new note',
description: 'Filename for the new note (e.g. "My Note.md"). Do not include folder path here.',
},
path: {
type: 'string',
description: 'Full file path (alternative to name)',
description: 'Folder path where the note will be created (e.g. "Projects/Work"). Do not include the filename here. Omit for vault root.',
},
content: {
type: 'string',
@@ -50,7 +51,7 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
},
overwrite: {
type: 'boolean',
description: 'Overwrite if file exists (optional)',
description: 'Replace the file if it already exists (optional)',
},
open: {
type: 'boolean',
@@ -66,14 +67,15 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
'Create a new note in the Obsidian vault',
{
type: 'object',
required: ['name'],
properties: {
name: {
type: 'string',
description: 'File name for the new note',
description: 'Filename for the new note (e.g. "My Note.md"). Do not include folder path here.',
},
path: {
type: 'string',
description: 'Full file path (alternative to name)',
description: 'Folder path where the note will be created (e.g. "Projects/Work"). Do not include the filename here. Omit for vault root.',
},
content: {
type: 'string',
@@ -85,7 +87,7 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
},
overwrite: {
type: 'boolean',
description: 'Overwrite if file exists (optional)',
description: 'Replace the file if it already exists (optional)',
},
open: {
type: 'boolean',
@@ -102,8 +104,6 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
const sanitized = sanitizeParameters(validated) as any;
const cmdArgs: string[] = [];
// Add name or path parameter
if (sanitized.name) cmdArgs.push(formatParam('name', sanitized.name as string));
if (sanitized.path) cmdArgs.push(formatParam('path', sanitized.path as string));
if (sanitized.content) cmdArgs.push(formatParam('content', sanitized.content as string));

View File

@@ -14,9 +14,12 @@ export function formatParam(key: string, value: string | number): string {
// Always quote string values to handle spaces and special characters safely
// Note: Obsidian CLI docs say: "Quote values with spaces: name="My Note""
// Escape any double quotes in the value to prevent shell interpretation issues
// This prevents truncation when content contains quotes like "Bot QM"
const escapedValue = String(value).replace(/"/g, '\\"');
// Escape double quotes and backticks to prevent shell interpretation inside double-quoted strings.
// In bash double-quoted strings: \" prevents quote termination, \` prevents command substitution.
// This preserves Markdown code fences (``` ` ```) while blocking injection via backticks.
const escapedValue = String(value)
.replace(/"/g, '\\"')
.replace(/`/g, '\\`');
return `${key}="${escapedValue}"`;
}

View File

@@ -11,13 +11,16 @@ import { logger } from '../utils/logger.js';
* Note: Brackets [], parentheses (), and braces {} are safe because values are quoted and passed as array args
* They're essential for Obsidian markdown (wikilinks [[link]], tasks - [ ] Task, templates {{...}}, etc.)
* Note: Single & is safe in quoted args (filenames like "Research & Development.md")
* We only block: ; | ` $ < > (command separators, pipes, substitution, redirects)
* Note: Backticks are safe because formatParam escapes them as \` inside double-quoted strings,
* preventing shell command substitution while preserving Markdown code fences (``` ```)
* Note: < and > are safe inside double-quoted strings — shell redirection only applies at the
* command level, not inside quotes. Stripping them breaks Mermaid arrows (->>, -->) and HTML.
* We only block: ; | $ (command separators, pipes, variable substitution)
* Command injection patterns (&&, ||, etc.) are handled separately
*/
const DANGEROUS_CHARS = /[;|`$<>]/g;
const DANGEROUS_CHARS = /[;|$]/g;
const COMMAND_INJECTION_PATTERNS = [
/\$\(/g, // Command substitution $(...)
/`[^`]*`/g, // Command substitution `...`
/\|\|/g, // OR operator
/&&/g, // AND operator
/;/g, // Command separator
@@ -73,7 +76,8 @@ export function sanitizePath(path: string): string {
// Remove dangerous characters but allow path separators
// Note: Brackets, parentheses, braces, and single & are safe in paths (quoted args)
sanitized = sanitized.replace(/[;|`$<>]/g, '');
// Note: < and > are safe inside double-quoted strings (not shell redirects)
sanitized = sanitized.replace(/[;|`$]/g, '');
return sanitized;
}