Skip to main content
Glama

move_note

Relocate or rename a note within an Obsidian vault by specifying its current and new paths, enabling organized content management and restructuring.

Instructions

Move or rename a note to a new location in the Obsidian vault

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
destinationPathYesNew path where the note should be moved
sourcePathYesCurrent path to the note within the vault

Implementation Reference

  • Input schema definition for the 'move_note' tool, specifying required parameters sourcePath and destinationPath.
    name: 'move_note', description: 'Move or rename a note to a new location in the Obsidian vault', inputSchema: { type: 'object', properties: { sourcePath: { type: 'string', description: 'Current path to the note within the vault', }, destinationPath: { type: 'string', description: 'New path where the note should be moved', }, }, required: ['sourcePath', 'destinationPath'], }, },
  • src/index.ts:1399-1400 (registration)
    Registration of the move_note tool handler in the CallToolRequestSchema switch statement.
    return await this.handleMoveNote(request.params.arguments); case 'manage_folder':
  • Direct MCP tool handler that validates input arguments and delegates to the moveNote implementation, returning success message.
    private async handleMoveNote(args: any) { if (!args?.sourcePath || !args?.destinationPath) { throw new Error('Source path and destination path are required'); } await this.moveNote(args.sourcePath, args.destinationPath); return { content: [ { type: 'text', text: `Note moved successfully from ${args.sourcePath} to ${args.destinationPath}`, }, ], }; }
  • Core implementation of note moving logic. Tries Obsidian API sequence (read source, POST to dest, DELETE source), falls back to filesystem rename with directory creation and empty dir cleanup.
    private async moveNote(sourcePath: string, destinationPath: string): Promise<void> { try { // First try using the Obsidian API - using standard file operations // Most Obsidian Local REST API implementations don't support direct move operations // So we'll read the source file and create it at the destination, then delete the source // Read source file content via API const sourceResponse = await this.api.get(`/vault/${encodeURIComponent(sourcePath)}`); const content = sourceResponse.data.content || ''; // Create destination file via API await this.api.post(`/vault/${encodeURIComponent(destinationPath)}`, { content }); // Delete source file via API await this.api.delete(`/vault/${encodeURIComponent(sourcePath)}`); } catch (error) { // Fallback to file system operations const sourceFullPath = path.join(VAULT_PATH, sourcePath); const destFullPath = path.join(VAULT_PATH, destinationPath); // Validate source file exists if (!fs.existsSync(sourceFullPath)) { throw new Error(`Source note not found: ${sourcePath}`); } // Check if destination already exists if (fs.existsSync(destFullPath)) { throw new Error(`Destination already exists: ${destinationPath}`); } // Create destination directory if it doesn't exist const destDir = path.dirname(destFullPath); if (!fs.existsSync(destDir)) { fs.mkdirSync(destDir, { recursive: true }); } // Use filesystem rename (works for all file types including PDF) try { fs.renameSync(sourceFullPath, destFullPath); } catch (renameError) { throw new Error(`Failed to move file: ${renameError}`); } // Clean up empty source directory if needed const sourceDir = path.dirname(sourceFullPath); if (sourceDir !== VAULT_PATH) { try { const items = fs.readdirSync(sourceDir); if (items.length === 0) { fs.rmdirSync(sourceDir); } } catch (error) { // Ignore errors when cleaning up empty directories } } }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/newtype-01/obsidian-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server