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>
This commit is contained in:
2026-04-30 18:20:49 -05:00
parent ec507531ce
commit d27abcfca4

View File

@@ -28,17 +28,18 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
// T029: Create note tool // T029: Create note tool
server.registerTool( server.registerTool(
'obsidian_create_note', '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', type: 'object',
required: ['name'],
properties: { properties: {
name: { name: {
type: 'string', 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: { path: {
type: 'string', 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: { content: {
type: 'string', type: 'string',
@@ -50,7 +51,7 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
}, },
overwrite: { overwrite: {
type: 'boolean', type: 'boolean',
description: 'Overwrite if file exists (optional)', description: 'Replace the file if it already exists (optional)',
}, },
open: { open: {
type: 'boolean', type: 'boolean',
@@ -66,14 +67,15 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
'Create a new note in the Obsidian vault', 'Create a new note in the Obsidian vault',
{ {
type: 'object', type: 'object',
required: ['name'],
properties: { properties: {
name: { name: {
type: 'string', 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: { path: {
type: 'string', 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: { content: {
type: 'string', type: 'string',
@@ -85,7 +87,7 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
}, },
overwrite: { overwrite: {
type: 'boolean', type: 'boolean',
description: 'Overwrite if file exists (optional)', description: 'Replace the file if it already exists (optional)',
}, },
open: { open: {
type: 'boolean', type: 'boolean',
@@ -102,8 +104,6 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
const sanitized = sanitizeParameters(validated) as any; const sanitized = sanitizeParameters(validated) as any;
const cmdArgs: string[] = []; const cmdArgs: string[] = [];
// Add name or path parameter
if (sanitized.name) cmdArgs.push(formatParam('name', sanitized.name as string)); if (sanitized.name) cmdArgs.push(formatParam('name', sanitized.name as string));
if (sanitized.path) cmdArgs.push(formatParam('path', sanitized.path as string)); if (sanitized.path) cmdArgs.push(formatParam('path', sanitized.path as string));
if (sanitized.content) cmdArgs.push(formatParam('content', sanitized.content as string)); if (sanitized.content) cmdArgs.push(formatParam('content', sanitized.content as string));