Phase 2 - Breaking Changes (v2.0.0): - Added typed result interfaces (FileMetadata, DirectoryMetadata, VaultInfo, SearchResult, SearchMatch) - Unified parameter naming: list_notes now uses 'path' parameter (removed 'folder') - Enhanced tool responses with structured JSON for all tools - list_notes: Returns array of FileMetadata/DirectoryMetadata with full metadata - search_notes: Returns SearchResult with line numbers, snippets, and match ranges - get_vault_info: Returns VaultInfo with comprehensive statistics - Updated all tool descriptions to document structured responses - Version bumped to 2.0.0 (breaking changes) Phase 2.1 - Post-Testing Fixes: - Fixed root listing to exclude vault root folder itself (handles path '', '/', and isRoot()) - Fixed alphabetical sorting to be case-insensitive for stable ordering - Improved directory metadata with better timestamp detection and error handling - Fixed parent folder validation order (check if file before checking existence) - Updated documentation with root path examples and leading slash warnings - Added comprehensive test suite for sorting and root listing behavior - Fixed test mocks to use proper TFile/TFolder instances Tests: All 64 tests passing Build: Successful, no errors
20 KiB
Changelog
All notable changes to the Obsidian MCP Server plugin will be documented in this file.
[2.0.0] - 2025-10-16
🔧 Phase 2.1: Post-Testing Fixes
Based on testing feedback, the following improvements were made to the Phase 2 implementation:
Fixed
Root Listing Semantics (src/tools/vault-tools.ts)
- Clarified root path handling:
undefined,""(empty string), or"."all represent the vault root - Root listing now correctly returns direct children only (excludes vault root itself)
- Added explicit check to skip vault root folder (path === '')
- Improved code clarity with explicit
isRootPathcheck
Alphabetical Sorting
- Fixed sorting to be case-insensitive for stable, consistent ordering
- Directories are sorted alphabetically (case-insensitive), then files alphabetically (case-insensitive)
- Ensures predictable order for names like "CTP Lancaster" and "Construction Game"
Directory Metadata
- Added logic to populate
modifiedtimestamp from filesystem if available - Falls back to
0when filesystem metadata is not available (which is typical for directories) - Added documentation explaining when
modifiedmay be0 - Note: Obsidian's TFolder API doesn't include
statproperty, so directories will typically showmodified: 0
Documentation (src/tools/index.ts)
- Updated
list_notesdescription to document root path options (""or".") - Added explicit warning that leading slashes (e.g.,
"/"or"/folder") are invalid - Clarified that sorting is case-insensitive within each group
- Added note that only direct children are returned (non-recursive)
Technical Details
Root Path Handling:
// All of these list the vault root:
list_notes() // undefined
list_notes({ path: "" }) // empty string
list_notes({ path: "." }) // dot
Invalid Paths:
// These will error:
list_notes({ path: "/" }) // leading slash
list_notes({ path: "/folder" }) // leading slash
🔄 Phase 2: API Unification & Typed Results (BREAKING CHANGES)
This release introduces structured, typed responses for all tools and unifies parameter naming. Note: This is a breaking change as backwards compatibility is not maintained.
Added
Typed Result Interfaces (src/types/mcp-types.ts)
FileMetadata- Structured file information (kind, name, path, extension, size, modified, created)DirectoryMetadata- Structured directory information (kind, name, path, childrenCount, modified)VaultInfo- Structured vault information (name, path, totalFiles, totalFolders, markdownFiles, totalSize)SearchMatch- Detailed search match information (path, line, column, snippet, matchRanges)SearchResult- Comprehensive search results (query, matches, totalMatches, filesSearched, filesWithMatches)ItemKind- Type union for "file" | "directory"
Enhanced Tool Responses
- All tools now return structured JSON instead of plain text
- Consistent response format across all operations
- Machine-readable data for better integration
Changed
list_notes Tool (BREAKING)
- Parameter:
folder→path(breaking change -folderparameter removed) - Response: Now returns array of
FileMetadataandDirectoryMetadataobjects - Behavior: Lists direct children only (non-recursive)
- Includes both files AND directories (not just markdown files)
- Sorted: directories first, then files, alphabetically
- Each item includes detailed metadata (size, dates, child count)
search_notes Tool (BREAKING)
- Response: Now returns structured
SearchResultobject - Includes line numbers, column positions, and context snippets
- Provides match ranges for highlighting
- Tracks files searched and files with matches
- Filename matches indicated with line: 0
get_vault_info Tool (BREAKING)
- Response: Now returns structured
VaultInfoobject - Added:
totalFolderscount - Added:
totalSizein bytes - Renamed:
rootPath→path
Tool Descriptions
- Updated all tool descriptions to reflect structured JSON responses
- Clarified return value formats
- Removed deprecated
folderparameter
Implementation Details
src/tools/vault-tools.ts
searchNotes()- Complete rewrite with line-by-line search and snippet extractiongetVaultInfo()- Added folder counting and size calculationlistNotes()- Rewritten to return structured metadata for files and directories- Added
createFileMetadata()helper method - Added
createDirectoryMetadata()helper method
src/tools/index.ts
- Updated tool schemas to use
pathparameter only - Updated tool descriptions to document structured responses
- Modified
callTool()to passpathparameter
Migration Guide
Before (v1.x):
// list_notes returned plain text
"Found 3 notes:\nfile1.md\nfile2.md\nfile3.md"
// search_notes returned plain text
"Found 2 notes:\npath/to/note1.md\npath/to/note2.md"
// get_vault_info returned simple object
{ "name": "MyVault", "totalFiles": 100, "markdownFiles": 80, "rootPath": "/path" }
After (v2.x):
// list_notes returns structured array
[
{ "kind": "directory", "name": "folder1", "path": "folder1", "childrenCount": 5, "modified": 0 },
{ "kind": "file", "name": "note.md", "path": "note.md", "extension": "md", "size": 1024, "modified": 1697472000000, "created": 1697472000000 }
]
// search_notes returns detailed matches
{
"query": "TODO",
"matches": [
{ "path": "note.md", "line": 5, "column": 10, "snippet": "...context around TODO item...", "matchRanges": [{ "start": 15, "end": 19 }] }
],
"totalMatches": 1,
"filesSearched": 100,
"filesWithMatches": 1
}
// get_vault_info returns comprehensive info
{ "name": "MyVault", "path": "/path", "totalFiles": 100, "totalFolders": 20, "markdownFiles": 80, "totalSize": 5242880 }
Benefits
- Machine-readable: Structured JSON for easy parsing and integration
- Detailed metadata: Rich information for each file and directory
- Search precision: Line numbers, columns, and snippets for exact match location
- Consistency: Unified response format across all tools
- Type safety: Well-defined TypeScript interfaces
[1.2.0] - 2025-10-16
📁 Enhanced Parent Folder Detection (Phase 1.5)
Improved create_note tool with explicit parent folder validation and optional automatic folder creation.
Added
Parent Folder Validation (src/tools/note-tools.ts)
- Explicit parent folder detection before file creation (fail-fast)
- New
createParentsparameter for automatic folder creation - Recursive parent folder creation for deeply nested paths
- Validates parent is a folder (not a file)
- Clear error messages with actionable guidance
Tool Schema Updates (src/tools/index.ts)
- Added
createParentsboolean parameter tocreate_notetool - Default:
false(safe behavior - requires parent folders to exist) - Optional:
true(convenience - auto-creates missing parent folders) - Updated tool description with usage examples
Enhanced Error Messages (src/utils/error-messages.ts)
parentFolderNotFound()now suggests usingcreateParents: true- Provides example usage with auto-creation
- Computes grandparent path for better
list_notes()suggestions - Clear troubleshooting steps for missing parent folders
Comprehensive Test Suite (tests/parent-folder-detection.test.ts)
- 15 test cases covering all scenarios
- Tests explicit parent folder detection
- Tests recursive folder creation
- Tests error handling and edge cases
- Validates error message content
Changed
createNote()signature: added optionalcreateParentsparameter- Parent folder validation now happens before file creation attempt
- Error messages include
createParentsusage examples
Benefits
- Fail-fast behavior: Errors detected before attempting file creation
- Flexibility: Optional auto-creation with
createParents: true - Robustness: Handles deeply nested paths and all edge cases
- Backward compatible: Existing code continues to work (default:
false)
🔐 Enhanced Authentication & Security (Phase 1.5)
This update significantly improves authentication security and user experience with automatic key generation and enhanced UI.
Added
Automatic API Key Generation (src/utils/auth-utils.ts)
generateApiKey()- Cryptographically secure random key generation (32 characters)validateApiKey()- API key validation with strength requirements- Uses
crypto.getRandomValues()for secure randomness - Alphanumeric + special characters (
-,_) for URL-safe keys
Enhanced Settings UI (src/settings.ts)
- Auto-generate API key when authentication is enabled
- Copy to clipboard button for API key
- Regenerate key button with instant refresh
- Static, selectable API key display (full width)
- MCP client configuration snippet generator
- Dynamically includes/excludes Authorization header based on auth status
- Correct
mcpServersformat withserverUrlfield - Copy configuration button for one-click copying
- Partially selectable text for easy copying
- Restart warnings when authentication settings change
- Selectable connection information URLs
Security Improvements (src/server/middleware.ts)
- Defensive authentication check: rejects requests if auth enabled but no key set
- Improved error messages for authentication failures
- Fail-secure design: blocks access when misconfigured
Server Validation (src/main.ts)
- Prevents server start if authentication enabled without API key
- Clear error message guiding users to fix configuration
- Validation runs before server initialization
Changed
- API key field changed from user-editable to auto-generated display
- Configuration snippet now shows for both authenticated and non-authenticated setups
- Connection information URLs are now selectable
Security
- Fixed vulnerability where enabling authentication without API key allowed unrestricted access
- Three-layer defense: UI validation, server start validation, and middleware enforcement
- API keys are now always cryptographically secure (no weak user-chosen keys)
[1.1.0] - 2025-10-16
🎯 Phase 1.1: Path Normalization & Error Handling
This release focuses on robustness, cross-platform compatibility, and significantly improved error messages.
Added
Path Utilities (src/utils/path-utils.ts)
PathUtils.normalizePath()- Cross-platform path normalization (Windows/macOS/Linux)PathUtils.isValidVaultPath()- Path validation with security checksPathUtils.resolveFile()/resolveFolder()- Type-safe path resolutionPathUtils.fileExists()/folderExists()- Existence checkingPathUtils.getPathType()- Determine if path is file or folderPathUtils.ensureMarkdownExtension()- Auto-add .md extensionPathUtils.getParentPath()/getBasename()- Path manipulationPathUtils.joinPath()- Safe path joining- Handles backslashes, drive letters, trailing slashes automatically
- Prevents directory traversal attacks (
..paths)
Enhanced Error Messages (src/utils/error-messages.ts)
- Context-aware error messages with troubleshooting tips
- Dynamic
list_notes()suggestions based on path context - Operation-specific guidance (read, create, update, delete)
- Clear examples of correct path formats
- Platform-specific notes (case sensitivity on macOS/Linux)
ErrorMessages.fileNotFound()- File not found with discovery tipsErrorMessages.folderNotFound()- Folder not found with navigation tipsErrorMessages.invalidPath()- Invalid path with format examplesErrorMessages.pathAlreadyExists()- Conflict resolution guidanceErrorMessages.parentFolderNotFound()- Parent folder missing with verification stepsErrorMessages.cannotDeleteFolder()- Folder deletion attempt with alternativesErrorMessages.notAFile()/notAFolder()- Type mismatch errorsErrorMessages.operationFailed()- Generic operation failures
Testing Infrastructure
- Jest testing framework configured
- 43 unit tests for PathUtils (all passing)
- Mock Obsidian API for testing (
tests/__mocks__/obsidian.ts) - Test coverage for cross-platform path handling
- Integration tests with mock App/Vault
npm test/npm run test:watch/npm run test:coveragescripts
Documentation
docs/TOOL_SELECTION_GUIDE.md- Comprehensive 400+ line guide- Decision table for tool selection
- Path format guidelines (correct vs incorrect)
- Common scenarios with step-by-step examples
- Troubleshooting decision tree
- Best practices checklist
- Quick reference card
docs/ERROR_MESSAGE_IMPROVEMENTS.md- Error message enhancement documentationdocs/TOOL_DESCRIPTION_IMPROVEMENTS.md- AI agent tool description improvementstests/README.md- Testing setup and guidelinesPHASE_1.1_IMPLEMENTATION.md- Complete implementation summary
Changed
All Tool Implementations Enhanced
readNote()- Path validation, better error messages, folder detectioncreateNote()- Path normalization, conflict detection, parent folder validationupdateNote()- Enhanced validation, clearer error messagesdeleteNote()- Folder detection with specific error messagelistNotes()- Path validation, folder verification, better errors
Tool Descriptions for AI Agents
- All 7 MCP tool descriptions significantly enhanced
- Critical constraints stated upfront (e.g., "only files, NOT folders")
- Workflow guidance (e.g., "use list_notes() first if unsure")
- Path requirements clearly documented in every parameter
- Multiple concrete examples per tool
- Failure modes explicitly stated
- Self-documenting for AI agents without external docs
Error Message Consistency
- All errors now include vault-relative path reminders
- Case sensitivity noted for macOS/Linux
- Context-specific
list_notes()commands - Operation-appropriate tool suggestions
- Consistent formatting across all tools
Fixed
- Cross-platform paths - Windows backslashes now handled correctly
- Path validation - Prevents invalid characters and directory traversal
- Delete folder error - Now clearly states "cannot delete folders" instead of confusing message
- Parent folder detection - Clear message when parent folder missing during create
- Error message contradictions - All error headers and bodies now consistent
Technical Details
New Dependencies
- jest: ^29.x (dev)
- @types/jest: ^29.x (dev)
- ts-jest: ^29.x (dev)
Test Coverage
- 43 unit tests passing
- PathUtils: 100% coverage
- Cross-platform scenarios tested
- Mock Obsidian API for isolated testing
Build
- All TypeScript compilation successful
- No breaking changes to existing APIs
- Backward compatible with v1.0.0
Developer Experience
- Centralized path handling logic
- Type-safe path operations
- Comprehensive test suite
- Clear error messages reduce support burden
- Self-documenting code
[1.0.0] - 2025-10-16
🎉 Initial Release
Added
Core Features
- MCP (Model Context Protocol) server implementation
- HTTP transport with Express.js
- JSON-RPC 2.0 message handling
- Protocol version 2024-11-05 support
MCP Tools
read_note- Read note content from vaultcreate_note- Create new notesupdate_note- Update existing notesdelete_note- Delete notessearch_notes- Search notes by content or filenamelist_notes- List all notes or notes in specific folderget_vault_info- Get vault metadata and statistics
Server Features
- Configurable HTTP server (default port: 3000)
- Localhost-only binding (127.0.0.1)
- Health check endpoint (
/health) - MCP endpoint (
/mcp) - Auto-start option
Security
- Origin header validation (DNS rebinding protection)
- Optional Bearer token authentication
- CORS configuration with allowed origins
- Request validation and error handling
User Interface
- Settings panel with full configuration
- Status bar indicator showing server state
- Ribbon icon for quick server toggle
- Start/Stop/Restart commands
- Real-time server status display
- Connection information display
Documentation
- Comprehensive README with examples
- Quick Start Guide
- Implementation Summary
- Test client script
- Example MCP requests
- Security considerations
Developer Tools
- TypeScript implementation
- esbuild bundler
- Test client for validation
- Health check endpoint
Technical Details
Dependencies
- express: ^4.18.2
- cors: ^2.8.5
- obsidian: latest
Build
- TypeScript 4.7.4
- esbuild 0.17.3
- Output: 828KB bundled
Compatibility
- Obsidian minimum version: 0.15.0
- Desktop only (requires Node.js HTTP server)
- Protocol: MCP 2024-11-05
Known Limitations
- Desktop only (not available on mobile)
- Single vault per server instance
- No WebSocket support (HTTP only)
- No SSL/TLS (localhost only)
Future Roadmap
See ROADMAP.md for detailed implementation plans.
Phase 1: Foundation (P0-P1)
- Path Normalization - Consistent path handling across platforms
- Error Message Improvements - Clear, actionable error messages with troubleshooting tips
- Enhanced Authentication - Secure API key management, multiple keys with labels, expiration, rate limiting, audit logging, and permission scopes
- API Unification - Standardize parameter naming and return structured, typed results
- Discovery Endpoints - Add
statandexiststools for exploring vault structure
Phase 2: Enhanced Operations (P1-P2)
- Write Operations & Concurrency - ETag-based version control, partial updates (frontmatter, sections)
- Conflict Resolution - Create notes with conflict strategies (error, overwrite, rename)
- File Rename/Move - Rename or move files with automatic wikilink updates
- Enhanced List Operations - Filtering, recursion control, pagination, frontmatter summaries
- Advanced Search - Regex search, snippet extraction, glob filtering
Phase 3: Advanced Features (P2-P3)
- Frontmatter Parsing - Read and update frontmatter without modifying content
- Linking & Backlinks - Wikilink validation, resolution, and backlink queries
- Waypoint Support - Tools for working with Waypoint plugin markers
- Excalidraw Support - Specialized tool for reading Excalidraw drawings
Future Considerations
- Resources API - Expose notes as MCP resources
- Prompts API - Templated prompts for common operations
- Batch Operations - Multiple operations in single request
- WebSocket Transport - Real-time updates and notifications
- Graph API - Enhanced graph visualization and traversal
- Tag & Canvas APIs - Query tags and manipulate canvas files
- Dataview Integration - Query vault using Dataview syntax
- Performance Enhancements - Indexing, caching, streaming for large vaults
Version History
| Version | Date | Notes |
|---|---|---|
| 1.1.0 | 2025-10-16 | Phase 1.1: Path normalization, enhanced error messages, testing infrastructure |
| 1.0.0 | 2025-10-16 | Initial release |
Upgrade Guide
From 1.0.0 to 1.1.0
This is a backward-compatible update. Simply update the plugin:
- Backup your settings (optional, but recommended)
- Update the plugin files
- Restart Obsidian or reload the plugin
What's New:
- Better error messages with troubleshooting tips
- Improved cross-platform path handling
- Enhanced tool descriptions for AI agents
- No configuration changes required
Breaking Changes: None - fully backward compatible
From Development to 1.0.0
If you were using a development version:
- Backup your settings
- Disable the plugin
- Delete the old plugin folder
- Install version 1.0.0
- Re-enable and reconfigure
Breaking Changes
None (initial release)
Support
For issues, questions, or contributions:
- Check the README.md for documentation
- Review QUICKSTART.md for setup help
- Check existing issues before creating new ones
- Include version number in bug reports
Credits
- MCP Protocol: https://modelcontextprotocol.io
- Obsidian API: https://github.com/obsidianmd/obsidian-api
- Built with TypeScript, Express.js, and ❤️