Files
obsidian-mcp-server/CHANGELOG.md
Bill b681327970 feat: Phase 10 - UI Notifications (request-only)
Implement visual feedback for MCP tool calls with configurable notifications.

Features:
- Real-time notifications when tools are called (request only, no completion)
- Tool-specific emoji icons for visual clarity
- Rate limiting (max 10 notifications/second)
- Notification history tracking (last 100 entries)
- Configurable settings: enable/disable, show parameters, duration, console logging
- History modal with filtering and export to clipboard

Implementation:
- Created NotificationManager with queue-based rate limiting
- Created NotificationHistoryModal for viewing past tool calls
- Integrated into tool call interceptor in ToolRegistry
- Added notification settings UI section
- Added 'View MCP Notification History' command

Benefits:
- Visual feedback for debugging and monitoring
- Transparency into AI agent actions
- Simple on/off toggle, no complex verbosity settings
- Zero performance impact when disabled
- History tracks success/failure/duration for all calls

All 10 phases of the roadmap are now complete\!
2025-10-17 01:11:10 -04:00

1418 lines
55 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
All notable changes to the Obsidian MCP Server plugin will be documented in this file.
## [9.0.0] - 2025-10-17
### 🎨 Phase 10: UI Notifications
This release adds visual feedback for MCP tool calls with configurable notifications in the Obsidian UI. Provides transparency into API activity, easier debugging, and optional notification history tracking.
#### Added
**Notification System**
- Real-time notifications for MCP tool calls displayed in Obsidian UI
- Shows notification when tool is called (request only, no completion notifications)
- Configurable notification duration (default: 3 seconds)
- Rate limiting (max 10 notifications/second) to prevent UI spam
- Simple on/off toggle - no verbosity levels needed
- Tool-specific icons for visual clarity:
- 📖 Read operations (`read_note`, `read_excalidraw`)
- ✏️ Write operations (`create_note`, `update_note`, `update_frontmatter`, `update_sections`)
- 🗑️ Delete operations (`delete_note`)
- 📝 Rename operations (`rename_file`)
- 🔍 Search operations (`search`, `search_waypoints`)
- 📋 List operations (`list`)
- 📊 Stat operations (`stat`, `exists`)
- Info operations (`get_vault_info`)
- 🗺️ Waypoint operations (`get_folder_waypoint`)
- 📁 Folder operations (`is_folder_note`)
- 🔗 Link operations (`validate_wikilinks`, `resolve_wikilink`, `backlinks`)
**Notification Settings**
- `Enable notifications` - Toggle notifications on/off
- `Show parameters` - Include tool parameters in notifications (truncated for readability)
- `Notification duration` - How long notifications stay visible (milliseconds)
- `Log to console` - Also log tool calls to browser console for debugging
- All settings available in plugin settings UI under "UI Notifications" section
**Notification History**
- Stores last 100 tool calls in memory
- View history via command palette: "View MCP Notification History"
- View history via settings: "View History" button
- History modal features:
- Filter by tool name
- Filter by type (all/success/error)
- Shows timestamp, duration, parameters, and error messages
- Export history to clipboard as JSON
- Clear history button
- Each history entry includes:
- `timestamp` - When the tool was called
- `toolName` - Name of the tool
- `args` - Tool parameters
- `success` - Whether the call succeeded
- `duration` - Execution time in milliseconds
- `error` - Error message (if failed)
**Notification Example**
- Tool call: `🔧 MCP: list({ path: "projects", recursive: true })`
- Note: Only request notifications are shown, not completion or error notifications
**Implementation Details**
- Non-blocking notification display (async queue)
- Notification queue with rate limiting to prevent UI freezing
- Parameter truncation for long values (max 50 chars)
- Privacy-aware: sensitive data not shown in notifications
- Zero performance impact when disabled
- Integrates seamlessly with existing tool call flow
#### Files Added
- `src/ui/notifications.ts` - Notification manager with rate limiting
- `src/ui/notification-history.ts` - History modal for viewing past tool calls
#### Files Modified
- `src/types/settings-types.ts` - Added notification settings types
- `src/settings.ts` - Added notification settings UI
- `src/tools/index.ts` - Integrated notifications into tool call interceptor
- `src/server/mcp-server.ts` - Added notification manager support
- `src/main.ts` - Initialize notification manager and add history command
#### Benefits
- **Developer Experience**: Visual feedback for API activity, easier debugging
- **User Experience**: Awareness when tools are called, transparency into AI agent actions
- **Debugging**: See exact parameters, track execution times in history, identify bottlenecks
- **Optional**: Can be completely disabled for production use
- **Simple**: Single toggle to enable/disable, no complex verbosity settings
## [8.0.0] - 2025-10-17
### 🚀 Phase 9: Linking & Backlinks
This release adds powerful tools for working with wikilinks, resolving links, and querying backlinks. Enables programmatic link validation, resolution, and knowledge graph exploration.
#### Added
**New Tool: `validate_wikilinks`**
- Validate all wikilinks in a note and report unresolved links
- Parses all `[[wikilinks]]` in the file using regex
- Resolves links using Obsidian's MetadataCache for accuracy
- Provides suggestions for broken links using fuzzy matching
- Returns structured JSON with:
- `path` - File path
- `totalLinks` - Total number of links found
- `resolvedLinks` - Array of resolved links with:
- `text` - Full link text including brackets
- `target` - Resolved target file path
- `alias` - Display alias (if present)
- `unresolvedLinks` - Array of unresolved links with:
- `text` - Full link text including brackets
- `line` - Line number where link appears
- `suggestions` - Array of suggested target paths
- Supports both `[[link]]` and `[[link|alias]]` formats
- Handles links with headings `[[note#heading]]`
- Use to identify and fix broken links in notes
**New Tool: `resolve_wikilink`**
- Resolve a single wikilink from a source note to its target path
- Uses Obsidian's MetadataCache.getFirstLinkpathDest() for accurate resolution
- Follows Obsidian's link resolution rules:
- Shortest path matching
- Relative paths
- Aliases
- Headings and blocks
- Returns structured JSON with:
- `sourcePath` - Source note path
- `linkText` - Link text to resolve (without brackets)
- `resolved` - Boolean indicating if link was resolved
- `targetPath` - Resolved target file path (if found)
- `suggestions` - Array of suggested paths (if not found)
- Parameters:
- `sourcePath` - Path of note containing the link
- `linkText` - Link text without brackets (e.g., "target note", "folder/note", "note#heading")
- Supports complex link formats (headings, aliases, relative paths)
- Use to programmatically resolve links before following them
**New Tool: `backlinks`**
- Get all backlinks to a note with optional unlinked mentions
- Uses Obsidian's MetadataCache.getBacklinksForFile() for linked backlinks
- Optional text-based search for unlinked mentions
- Returns structured JSON with:
- `path` - Target note path
- `backlinks` - Array of backlinks with:
- `sourcePath` - Source file path containing the link
- `type` - Either "linked" (wikilink) or "unlinked" (text mention)
- `occurrences` - Array of occurrences with:
- `line` - Line number (1-indexed)
- `snippet` - Context snippet around the link
- `totalBacklinks` - Total number of backlinks
- Parameters:
- `path` - Target note path
- `includeUnlinked` - Include unlinked mentions (default: false)
- `includeSnippets` - Include context snippets (default: true)
- Efficient use of Obsidian's built-in caching and indexing
- Use to explore note connections and build knowledge graphs
- Warning: `includeUnlinked` can be slow for large vaults
**New Utility: `link-utils.ts`**
- `LinkUtils` class for wikilink operations
- `parseWikilinks()` - Parse all wikilinks from content with positions
- `resolveLink()` - Resolve a wikilink to its target file
- `findSuggestions()` - Find potential matches for unresolved links
- `getBacklinks()` - Get all backlinks to a file
- `validateWikilinks()` - Validate all wikilinks in a file
- Regex-based wikilink parsing: `/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g`
- Fuzzy matching algorithm for link suggestions
- Handles edge cases (circular links, missing files)
#### Modified
**Updated: `vault-tools.ts`**
- Added `validateWikilinks()` method
- Added `resolveWikilink()` method
- Added `getBacklinks()` method
- Imports LinkUtils for wikilink operations
**Updated: `index.ts` (Tool Registry)**
- Added `validate_wikilinks` tool definition
- Added `resolve_wikilink` tool definition
- Added `backlinks` tool definition
- Added case handlers for three new tools
**Updated: `mcp-types.ts`**
- Added Phase 9 types:
- `ResolvedLink` - Resolved wikilink information
- `UnresolvedLink` - Unresolved wikilink information
- `ValidateWikilinksResult` - Result from validate_wikilinks
- `ResolveWikilinkResult` - Result from resolve_wikilink
- `BacklinkOccurrence` - Backlink occurrence in a file
- `BacklinkInfo` - Backlink from a source file
- `BacklinksResult` - Result from backlinks operation
#### Benefits
- **Link Validation**: Identify and fix broken links in notes
- **Link Resolution**: Programmatically resolve links before following them
- **Knowledge Graphs**: Explore note connections and build knowledge graphs
- **Complex Links**: Support for headings, aliases, and relative paths
- **Accurate Resolution**: Uses Obsidian's native link resolution rules
- **Performance**: Efficient use of MetadataCache and built-in indexing
- **Suggestions**: Fuzzy matching helps find intended targets for broken links
#### Technical Details
- Wikilink parsing uses regex: `/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g`
- Link resolution uses `MetadataCache.getFirstLinkpathDest()`
- Backlink detection uses `MetadataCache.getBacklinksForFile()`
- Suggestion engine uses multi-factor scoring (basename, path, character matching)
- Unlinked mentions use word boundary regex for whole-word matching
- Context snippets extracted with configurable length (default: 100 chars)
---
## [7.0.0] - 2025-10-17
### 🚀 Phase 8: Write Operations & Concurrency
This release implements safe write operations with concurrency control, partial updates, conflict resolution, and file rename/move with automatic link updates.
#### Added
**New Tool: `update_frontmatter`**
- Update frontmatter fields without modifying note content
- Supports patch operations (add/update fields) via `patch` parameter
- Supports field removal via `remove` parameter (array of field names)
- Returns structured JSON with:
- `success` - Boolean operation status
- `path` - File path
- `versionId` - New version ID for subsequent operations
- `modified` - Modification timestamp
- `updatedFields` - Array of fields that were added/updated
- `removedFields` - Array of fields that were removed
- Includes concurrency control via optional `ifMatch` parameter
- Preserves content and formatting
- Automatically creates frontmatter if none exists
- Use for metadata-only updates to avoid race conditions
**New Tool: `update_sections`**
- Update specific sections of a note by line range
- Reduces race conditions by avoiding full file overwrites
- Supports multiple edits in a single operation
- Edits applied from bottom to top to preserve line numbers
- Returns structured JSON with:
- `success` - Boolean operation status
- `path` - File path
- `versionId` - New version ID
- `modified` - Modification timestamp
- `sectionsUpdated` - Count of sections updated
- Each edit specifies:
- `startLine` - Starting line number (1-indexed, inclusive)
- `endLine` - Ending line number (1-indexed, inclusive)
- `content` - New content to replace the section
- Includes concurrency control via optional `ifMatch` parameter
- Validates line ranges before applying edits
- Use for surgical edits to specific parts of large notes
**New Tool: `rename_file`**
- Rename or move files with automatic wikilink updates
- Uses Obsidian's FileManager to maintain link integrity
- Supports both rename (same folder) and move (different folder)
- Returns structured JSON with:
- `success` - Boolean operation status
- `oldPath` - Original file path
- `newPath` - New file path
- `linksUpdated` - Always 0 (tracking not available in current API)
- `affectedFiles` - Always empty array (tracking not available in current API)
- `versionId` - New version ID
- Parameters:
- `path` - Current file path
- `newPath` - New file path (can be in different folder)
- `updateLinks` - Auto-update wikilinks (default: true)
- `ifMatch` - Optional version ID for concurrency control
- Automatically creates parent folders if needed
- Prevents conflicts with existing files
- Links are automatically updated by Obsidian's FileManager
- Use to reorganize vault structure while preserving links
- Note: Link tracking fields return placeholder values due to API limitations
**New Utility: `version-utils.ts`**
- `VersionUtils` class for ETag-based concurrency control
- `generateVersionId()` - Create version ID from file mtime and size
- `validateVersion()` - Check if provided version matches current
- `versionMismatchError()` - Generate 412 Precondition Failed error
- `createVersionedResponse()` - Add version info to responses
- Uses SHA-256 hash with URL-safe base64 encoding
**Enhanced Tool: `create_note`**
- Added `onConflict` parameter with three strategies:
- `error` (default) - Fail if file exists
- `overwrite` - Delete existing file and create new
- `rename` - Auto-generate unique name by appending number
- Returns structured JSON with:
- `success` - Boolean operation status
- `path` - Created file path (may differ if renamed)
- `versionId` - Version ID for subsequent operations
- `created` - Creation timestamp
- `renamed` - Boolean indicating if file was renamed
- `originalPath` - Original path if renamed
- Existing `createParents` parameter still supported
- Better conflict handling and error messages
**Enhanced Tool: `delete_note`**
- Added `soft` parameter (default: true):
- `true` - Move to `.trash` folder (recoverable)
- `false` - Permanent deletion (cannot be undone)
- Added `dryRun` parameter (default: false):
- `true` - Preview deletion without executing
- `false` - Perform actual deletion
- Added `ifMatch` parameter for concurrency control
- Returns structured JSON with:
- `deleted` - Boolean indicating if deletion occurred
- `path` - File path
- `destination` - Trash destination (for soft deletes)
- `dryRun` - Boolean indicating preview mode
- `soft` - Boolean indicating soft delete mode
- Use for safer file operations with preview and recovery
**Type Definitions (`src/types/mcp-types.ts`)**
- `ConflictStrategy` - Type for conflict resolution strategies
- `SectionEdit` - Interface for section edit operations
- `UpdateFrontmatterResult` - Result from frontmatter updates
- `UpdateSectionsResult` - Result from section updates
- `CreateNoteResult` - Enhanced result from note creation
- `RenameFileResult` - Result from file rename/move
- `DeleteNoteResult` - Enhanced result from deletion
**Frontmatter Serialization (`src/utils/frontmatter-utils.ts`)**
- `serializeFrontmatter()` - Convert frontmatter object to YAML string
- Handles arrays, objects, strings, numbers, booleans
- Automatic quoting for strings with special characters
- Proper YAML formatting with delimiters
#### Improvements
**Concurrency Control**
- ETag-based optimistic locking across all write operations
- `ifMatch` parameter prevents lost updates in concurrent scenarios
- Version mismatch returns 412 Precondition Failed with clear error
- All write operations return `versionId` for subsequent operations
- Get `versionId` from read operations to ensure consistency
**Conflict Resolution**
- Three strategies for handling file conflicts in `create_note`
- Automatic unique name generation for rename strategy
- Clear error messages for each conflict scenario
- Prevents accidental overwrites
**Link Integrity**
- Automatic wikilink updates when renaming/moving files
- Uses Obsidian's FileManager for reliable link maintenance
- Tracks affected files and link update count
- Supports moving files between folders
**Safe Operations**
- Soft delete moves files to trash instead of permanent deletion
- Dry-run preview for deletions
- Parent folder auto-creation for rename operations
- Validation before destructive operations
**Partial Updates**
- Update frontmatter without touching content
- Update specific sections without full file overwrites
- Reduces race conditions in concurrent editing
- Fine-grained control over modifications
#### Breaking Changes
None - All changes are additive or enhance existing functionality with backward compatibility.
#### Implementation
**Files Created:**
- `src/utils/version-utils.ts` - ETag/version control utilities
**Files Modified:**
- `src/tools/note-tools.ts` - Added new methods and enhanced existing ones
- `src/utils/frontmatter-utils.ts` - Added serializeFrontmatter method
- `src/tools/index.ts` - Added new tool definitions and updated callTool
- `src/types/mcp-types.ts` - Added Phase 8 type definitions
#### Benefits
- **Concurrency safety** - Prevents lost updates in concurrent editing scenarios
- **Safer operations** - Preview and recovery options for destructive operations
- **Link integrity** - Maintained vault link integrity during reorganization
- **Fine-grained control** - Update specific parts without full file overwrites
- **Better UX** - Clear error messages and conflict resolution strategies
- **Production-ready** - Robust error handling and validation
#### Notes
- Manual testing recommended before production use
- All write operations now support concurrency control via `ifMatch`
- Soft delete is the default for `delete_note` (safer)
- Rename/move operations automatically update all wikilinks by default
---
## [6.0.0] - 2025-10-17
### 🚀 Phase 7: Waypoint Support
This release adds specialized tools for working with Waypoint plugin markers and implements edit protection for auto-generated content.
#### Added
**New Tool: `get_folder_waypoint`**
- Extract Waypoint block from a folder note
- Returns structured JSON with:
- `path` - File path
- `hasWaypoint` - Boolean indicating waypoint presence
- `waypointRange` - Line range of waypoint block (start/end)
- `links` - Array of extracted wikilinks from waypoint content
- `rawContent` - Raw waypoint content between markers
- Automatically parses `[[wikilinks]]` from waypoint blocks
- Use to inspect folder note navigation structures
**New Tool: `is_folder_note`**
- Check if a note is a folder note
- Returns structured JSON with:
- `path` - File path
- `isFolderNote` - Boolean result
- `reason` - Detection method: `basename_match`, `waypoint_marker`, `both`, or `none`
- `folderPath` - Parent folder path
- Detects folder notes by:
- Basename matching parent folder name
- Presence of Waypoint markers
- Use to identify navigation/index notes in vault
**New Utilities (`src/utils/waypoint-utils.ts`)**
- `WaypointUtils` class for waypoint operations
- `extractWaypointBlock()` - Extract waypoint from content with line ranges
- `hasWaypointMarker()` - Quick check for waypoint presence
- `isFolderNote()` - Detect folder notes by multiple criteria
- `wouldAffectWaypoint()` - Check if edit would modify waypoint block
- Handles edge cases: unclosed waypoints, malformed markers, nested content
**Type Definitions (`src/types/mcp-types.ts`)**
- `FolderWaypointResult` - Waypoint extraction result
- `FolderNoteResult` - Folder note detection result
**Waypoint Edit Protection**
- `update_note` now validates edits against waypoint blocks
- Prevents accidental modification of auto-generated content
- Returns clear error message with:
- Waypoint line range
- Troubleshooting tips
- Suggestion to use `get_folder_waypoint()` for inspection
- Detects both content changes and waypoint removal
#### Improvements
- **Smart detection** - Multiple criteria for folder note identification
- **Link extraction** - Automatic wikilink parsing from waypoint content
- **Edit safety** - Prevents corruption of auto-generated navigation structures
- **Clear errors** - Actionable guidance when waypoint edits are blocked
- **Flexible checking** - Allows edits that don't affect waypoint content
#### Implementation
**Files Modified:**
- `src/utils/waypoint-utils.ts` (new) - Core waypoint utilities
- `src/tools/vault-tools.ts` - Added `getFolderWaypoint()` and `isFolderNote()` methods
- `src/tools/note-tools.ts` - Added waypoint edit protection to `updateNote()`
- `src/tools/index.ts` - Registered new tools in tool registry
- `src/types/mcp-types.ts` - Added Phase 7 type definitions
#### Benefits
- **Waypoint integration** - First-class support for Waypoint plugin workflows
- **Data integrity** - Prevents accidental corruption of auto-generated content
- **Better navigation** - Tools to discover and inspect folder structures
- **Developer-friendly** - Clear APIs for working with folder notes
#### Notes
- `update_sections` tool (with waypoint protection) will be implemented in Phase 8
- Manual testing recommended for various waypoint formats and edge cases
---
## [5.0.0] - 2025-10-16
### 🚀 Phase 6: Powerful Search
This release introduces a completely redesigned search system with regex support, advanced filtering, and specialized waypoint search capabilities.
#### Added
**New Tool: `search`**
- **Regex support** - Full JavaScript regex pattern matching with `isRegex` parameter
- **Case sensitivity control** - Toggle case-sensitive search with `caseSensitive` parameter
- **Advanced filtering**:
- `includes` - Glob patterns to include specific files (e.g., `['*.md', 'projects/**']`)
- `excludes` - Glob patterns to exclude files (e.g., `['.obsidian/**', '*.tmp']`)
- `folder` - Limit search to specific folder path
- **Snippet extraction** - Configurable context snippets with `snippetLength` parameter
- **Result limiting** - Control maximum results with `maxResults` parameter (default: 100)
- **Snippet control** - Toggle snippet extraction with `returnSnippets` parameter
- Returns enhanced `SearchResult` with:
- `query` - Search query string
- `isRegex` - Boolean indicating regex mode
- `matches` - Array of `SearchMatch` objects with line, column, snippet, and match ranges
- `totalMatches` - Total number of matches found
- `filesSearched` - Number of files searched
- `filesWithMatches` - Number of files containing matches
**New Tool: `search_waypoints`**
- Specialized tool for finding Waypoint plugin markers
- Searches for `%% Begin Waypoint %%` ... `%% End Waypoint %%` blocks
- **Wikilink extraction** - Automatically extracts `[[wikilinks]]` from waypoint content
- **Folder scoping** - Optional `folder` parameter to limit search scope
- Returns structured `WaypointSearchResult` with:
- `waypoints` - Array of waypoint locations with content and links
- `totalWaypoints` - Total number of waypoints found
- `filesSearched` - Number of files searched
**New Utilities (`src/utils/search-utils.ts`)**
- `SearchUtils` class for advanced search operations
- `search()` - Main search method with regex, filtering, and snippet extraction
- `searchInFile()` - Search within single file with match highlighting
- `searchInFilename()` - Search in file basenames
- `searchWaypoints()` - Specialized waypoint marker search
- Handles edge cases: zero-width regex matches, invalid patterns, large files
**Type Definitions (`src/types/mcp-types.ts`)**
- Updated `SearchResult` - Added `isRegex` field
- `WaypointResult` - Individual waypoint location with content and links
- `WaypointSearchResult` - Waypoint search results with statistics
**Implementation (`src/tools/vault-tools.ts`)**
- New `search()` method with full parameter support
- New `searchWaypoints()` method for waypoint discovery
- Updated `searchNotes()` to include `isRegex: false` in results
**Tool Registry (`src/tools/index.ts`)**
- Registered `search` tool with comprehensive schema
- Registered `search_waypoints` tool
- Marked `search_notes` as DEPRECATED (kept for backward compatibility)
- Updated callTool to handle new search tools
#### Improvements
- **Regex power** - Full JavaScript regex syntax support with global flag for multiple matches per line
- **Smart snippet extraction** - Centers matches in snippets with configurable length
- **Consistent filtering** - Uses existing GlobUtils for glob pattern matching
- **Filename search** - Searches both content and filenames automatically
- **Error handling** - Clear error messages for invalid regex patterns
- **Performance** - Efficient search with early termination when maxResults reached
#### Breaking Changes
- **`search_notes` tool removed** - Replaced by enhanced `search` tool
- Old tool completely removed (no backward compatibility)
- Use `search` tool with `isRegex: false` for equivalent literal search
- Migration: Replace `search_notes` calls with `search` tool
#### Benefits
- **Powerful queries** - Use regex for complex search patterns (e.g., `^# Heading`, `TODO.*urgent`)
- **Precise control** - Fine-tune search with case sensitivity and glob filtering
- **Better results** - Context snippets with match highlighting for easier review
- **Waypoint discovery** - Find all folder notes and navigation structures
- **Cleaner API** - Single powerful search tool instead of multiple limited ones
---
## [4.0.0] - 2025-10-16
### 🚀 Phase 5: Advanced Read Operations
This release adds frontmatter parsing capabilities to `read_note` and introduces specialized support for Excalidraw files. All features have been manually tested and refined based on user feedback.
#### Added
**Enhanced Tool: `read_note`**
- **Frontmatter parsing** - New `parseFrontmatter` option to separate frontmatter from content
- **Structured response** - Returns `ParsedNote` object with parsed YAML frontmatter
- **Flexible options**:
- `withFrontmatter` (default: true) - Include frontmatter in response
- `withContent` (default: true) - Include full content in response
- `parseFrontmatter` (default: false) - Parse and structure frontmatter
- **Backward compatible** - Default behavior unchanged (returns raw content)
- Returns structured JSON when `parseFrontmatter: true` with:
- `path` - File path
- `hasFrontmatter` - Boolean indicating presence
- `frontmatter` - Raw YAML string
- `parsedFrontmatter` - Parsed YAML object
- `content` - Full file content
- `contentWithoutFrontmatter` - Content excluding frontmatter
**New Tool: `read_excalidraw`**
- Specialized tool for reading Excalidraw drawing files
- **Metadata extraction** - Element count, compressed data status
- **Preview text** - Extract text elements without parsing full drawing
- **Optional compressed data** - Include full drawing data with `includeCompressed: true`
- Returns structured `ExcalidrawMetadata` with:
- `path` - File path
- `isExcalidraw` - Validation boolean
- `elementCount` - Number of drawing elements
- `hasCompressedData` - Boolean for compressed files
- `metadata` - Drawing metadata (appState, version)
- `preview` - Text elements preview (optional)
- `compressedData` - Full drawing data (optional)
**New Utilities (`src/utils/frontmatter-utils.ts`)**
- `FrontmatterUtils` class for YAML parsing
- `extractFrontmatter()` - Extract and parse YAML frontmatter using Obsidian's parseYaml
- `extractFrontmatterSummary()` - Extract common fields (title, tags, aliases)
- `hasFrontmatter()` - Quick check for frontmatter presence
- `parseExcalidrawMetadata()` - Parse Excalidraw file structure
- Handles edge cases: no frontmatter, malformed YAML, invalid Excalidraw files
**Type Definitions (`src/types/mcp-types.ts`)**
- `ParsedNote` - Structured note with separated frontmatter
- `ExcalidrawMetadata` - Excalidraw file metadata structure
**Implementation (`src/tools/note-tools.ts`)**
- Enhanced `readNote()` method with options parameter
- New `readExcalidraw()` method for Excalidraw files
- Integrated frontmatter parsing with FrontmatterUtils
- Maintains backward compatibility for existing clients
**Tool Registry (`src/tools/index.ts`)**
- Updated `read_note` schema with new optional parameters
- Registered `read_excalidraw` tool with comprehensive schema
- Updated callTool to pass options to readNote and handle read_excalidraw
#### Improvements (Post-Testing)
- **Enhanced error handling** - Graceful handling of non-Excalidraw files with structured responses
- **Comprehensive documentation** - Detailed field descriptions in tool schema with explicit categorization
- **Full metadata exposure** - All Excalidraw metadata fields properly exposed per spec:
- `elementCount` - Number of drawing elements (always returned)
- `hasCompressedData` - Boolean for embedded images (always returned)
- `metadata` - Object with appState and version (always returned)
- `preview` - Text elements (conditional on includePreview)
- `compressedData` - Full drawing data (conditional on includeCompressed)
- **Enhanced type definitions** - JSDoc comments on all ExcalidrawMetadata fields
- **Complete specification** - New EXCALIDRAW_METADATA_SPEC.md with comprehensive documentation
#### Bug Fixes (Post-Testing)
- **Fixed missing metadata fields** - Resolved issue where `elementCount`, `hasCompressedData`, and `metadata` were not returned
- Added support for `compressed-json` code fence format (Excalidraw's actual format)
- Detects compressed (base64) vs uncompressed JSON data
- For compressed files: Returns `hasCompressedData: true` and `metadata.compressed: true`
- For uncompressed files: Extracts actual element count and metadata
- Multiple regex patterns to handle different Excalidraw formats
- Always return metadata fields with appropriate values
- **Known Limitation:** `elementCount` returns 0 for compressed files
- Most Excalidraw files use compressed base64 format by default
- Decompression would require pako library (not included to minimize dependencies)
- Text elements are still extracted in `preview` field
- Use `hasCompressedData: true` to identify compressed files
- This is expected behavior, not a bug
#### Benefits
- **Better frontmatter handling** - Separate frontmatter from content for easier processing
- **Excalidraw support** - First-class support for Excalidraw drawings with complete metadata
- **Flexible reading** - Choose what data to include in responses
- **Backward compatible** - Existing code continues to work unchanged
- **Type-safe** - Structured responses with proper TypeScript types
- **Robust** - Graceful error handling for edge cases
## [3.0.0] - 2025-10-16
### 🚀 Phase 4: Enhanced List Operations
This release replaces `list_notes` with a powerful new `list` tool featuring advanced filtering, recursion, pagination, and frontmatter summaries.
#### Breaking Changes
**Removed Tools**
- `list_notes` - Replaced with the more powerful `list` tool
- **Migration:** Replace `list_notes({ path })` with `list({ path })`
- The new `list` tool is backwards compatible for basic usage
#### Added
**New Tool: `list`**
- Advanced file/directory listing with comprehensive filtering options
- **Recursive listing** - Traverse entire directory trees with `recursive: true`
- **Glob pattern filtering** - Include/exclude patterns supporting `*`, `**`, `?`, `[abc]`, `{a,b}`
- **Type filtering** - Filter by `files`, `directories`, or `any`
- **Cursor-based pagination** - Handle large result sets efficiently with `limit` and `cursor`
- **Frontmatter summaries** - Extract title, tags, aliases without reading full content
- Returns structured `ListResult` with items, totalCount, hasMore, and nextCursor
**New Utilities (`src/utils/glob-utils.ts`)**
- `GlobUtils` class for pattern matching
- Supports wildcards: `*` (any chars except /), `**` (any chars including /), `?` (single char)
- Supports character classes: `[abc]`, alternatives: `{a,b,c}`
- `shouldInclude()` - Combined include/exclude filtering
- `matches()` - Test path against glob pattern
**Type Definitions (`src/types/mcp-types.ts`)**
- `FrontmatterSummary` - Parsed frontmatter fields (title, tags, aliases, custom fields)
- `FileMetadataWithFrontmatter` - Extended file metadata with optional frontmatter
- `ListResult` - Paginated list response structure
**Implementation (`src/tools/vault-tools.ts`)**
- `list(options)` method - Enhanced listing with all Phase 4 features
- `createFileMetadataWithFrontmatter()` - Efficient frontmatter extraction using metadata cache
- Recursive directory traversal
- Glob pattern filtering integration
- Cursor-based pagination logic
**Tool Registry (`src/tools/index.ts`)**
- Registered `list` tool with comprehensive schema
- Removed `list_notes` tool definition
- Updated call handler to route `list` requests
#### Features in Detail
**Recursive Listing**
```typescript
// List all markdown files in vault recursively
list({ recursive: true, includes: ["*.md"] })
```
**Glob Filtering**
```typescript
// Include only markdown files, exclude .obsidian folder
list({
includes: ["*.md"],
excludes: [".obsidian/**"]
})
```
**Type Filtering**
```typescript
// List only directories
list({ only: "directories" })
```
**Pagination**
```typescript
// First page
list({ limit: 50 })
// Next page using cursor
list({ limit: 50, cursor: "path/from/previous/response" })
```
**Frontmatter Summaries**
```typescript
// Get file list with frontmatter metadata
list({
withFrontmatterSummary: true,
includes: ["*.md"]
})
```
#### Example Response
```json
{
"items": [
{
"kind": "directory",
"name": "projects",
"path": "projects",
"childrenCount": 15,
"modified": 1697500800000
},
{
"kind": "file",
"name": "README.md",
"path": "README.md",
"extension": "md",
"size": 2048,
"modified": 1697500800000,
"created": 1697400000000,
"frontmatterSummary": {
"title": "Project Overview",
"tags": ["documentation", "readme"],
"aliases": ["index"]
}
}
],
"totalCount": 2,
"hasMore": false
}
```
#### Performance
- Frontmatter extraction uses Obsidian's metadata cache (no file reads)
- Glob matching uses efficient regex compilation
- Pagination prevents memory issues with large vaults
- Recursive listing optimized for vault structure
---
## [2.1.0] - 2025-10-16
### ✨ Phase 3: Discovery Endpoints
This release adds new tools for exploring vault structure and testing path validity.
#### Added
**New Tools**
- `stat` - Get detailed metadata for a file or folder at a specific path
- Returns existence status, kind (file/directory), and full metadata
- Includes size, dates, child count, etc.
- More detailed than `exists()` but slightly slower
- `exists` - Quickly check if a file or folder exists
- Fast path validation without fetching full metadata
- Returns existence status and kind only
- Optimized for quick existence checks
**Type Definitions (`src/types/mcp-types.ts`)**
- `StatResult` - Structured result for stat operations (path, exists, kind, metadata)
- `ExistsResult` - Structured result for exists operations (path, exists, kind)
**Implementation (`src/tools/vault-tools.ts`)**
- `stat(path)` method - Comprehensive path metadata retrieval
- `exists(path)` method - Fast existence checking
- Both methods use PathUtils for consistent path normalization
- Both methods validate paths and return structured JSON
**Tool Registry (`src/tools/index.ts`)**
- Registered `stat` and `exists` tools with complete schemas
- Added call handlers for both new tools
- Comprehensive descriptions for AI agent usage
#### Use Cases
**`stat` Tool:**
- Verify a path exists before operations
- Get detailed file/folder information
- Check file sizes and modification dates
- Determine if a path is a file or directory
**`exists` Tool:**
- Quick existence checks before create operations
- Validate paths in batch operations
- Fast pre-flight checks
- Minimal overhead for simple validation
#### Example Responses
**stat (file exists):**
```json
{
"path": "folder/note.md",
"exists": true,
"kind": "file",
"metadata": {
"kind": "file",
"name": "note.md",
"path": "folder/note.md",
"extension": "md",
"size": 1234,
"modified": 1697500800000,
"created": 1697400000000
}
}
```
**exists (folder exists):**
```json
{
"path": "projects",
"exists": true,
"kind": "directory"
}
```
**stat (path doesn't exist):**
```json
{
"path": "missing/file.md",
"exists": false
}
```
---
## [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 `isRootPath` check
**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 `modified` timestamp from filesystem if available
- Falls back to `0` when filesystem metadata is not available (which is typical for directories)
- Added documentation explaining when `modified` may be `0`
- **Note:** Obsidian's TFolder API doesn't include `stat` property, so directories will typically show `modified: 0`
**Documentation (`src/tools/index.ts`)**
- Updated `list_notes` description 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:**
```typescript
// All of these list the vault root:
list_notes() // undefined
list_notes({ path: "" }) // empty string
list_notes({ path: "." }) // dot
```
**Invalid Paths:**
```typescript
// 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 - `folder` parameter removed)
- Response: Now returns array of `FileMetadata` and `DirectoryMetadata` objects
- 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 `SearchResult` object
- 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 `VaultInfo` object
- Added: `totalFolders` count
- Added: `totalSize` in bytes
- Renamed: `rootPath``path`
**Tool Descriptions**
- Updated all tool descriptions to reflect structured JSON responses
- Clarified return value formats
- Removed deprecated `folder` parameter
#### Implementation Details
**`src/tools/vault-tools.ts`**
- `searchNotes()` - Complete rewrite with line-by-line search and snippet extraction
- `getVaultInfo()` - Added folder counting and size calculation
- `listNotes()` - 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 `path` parameter only
- Updated tool descriptions to document structured responses
- Modified `callTool()` to pass `path` parameter
#### Migration Guide
**Before (v1.x):**
```javascript
// 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):**
```javascript
// 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 `createParents` parameter 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 `createParents` boolean parameter to `create_note` tool
- 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 using `createParents: 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 optional `createParents` parameter
- Parent folder validation now happens before file creation attempt
- Error messages include `createParents` usage 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 `mcpServers` format with `serverUrl` field
- 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 checks
- `PathUtils.resolveFile()` / `resolveFolder()` - Type-safe path resolution
- `PathUtils.fileExists()` / `folderExists()` - Existence checking
- `PathUtils.getPathType()` - Determine if path is file or folder
- `PathUtils.ensureMarkdownExtension()` - Auto-add .md extension
- `PathUtils.getParentPath()` / `getBasename()` - Path manipulation
- `PathUtils.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 tips
- `ErrorMessages.folderNotFound()` - Folder not found with navigation tips
- `ErrorMessages.invalidPath()` - Invalid path with format examples
- `ErrorMessages.pathAlreadyExists()` - Conflict resolution guidance
- `ErrorMessages.parentFolderNotFound()` - Parent folder missing with verification steps
- `ErrorMessages.cannotDeleteFolder()` - Folder deletion attempt with alternatives
- `ErrorMessages.notAFile()` / `notAFolder()` - Type mismatch errors
- `ErrorMessages.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:coverage` scripts
**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 documentation
- `docs/TOOL_DESCRIPTION_IMPROVEMENTS.md` - AI agent tool description improvements
- `tests/README.md` - Testing setup and guidelines
- `PHASE_1.1_IMPLEMENTATION.md` - Complete implementation summary
#### Changed
**All Tool Implementations Enhanced**
- `readNote()` - Path validation, better error messages, folder detection
- `createNote()` - Path normalization, conflict detection, parent folder validation
- `updateNote()` - Enhanced validation, clearer error messages
- `deleteNote()` - Folder detection with specific error message
- `listNotes()` - 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 vault
- `create_note` - Create new notes
- `update_note` - Update existing notes
- `delete_note` - Delete notes
- `search_notes` - Search notes by content or filename
- `list_notes` - List all notes or notes in specific folder
- `get_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](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 `stat` and `exists` tools 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:
1. Backup your settings (optional, but recommended)
2. Update the plugin files
3. 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:
1. Backup your settings
2. Disable the plugin
3. Delete the old plugin folder
4. Install version 1.0.0
5. 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 ❤️