- Complete project setup with TypeScript, Jest, MCPB manifest - Implement foundational infrastructure (CLI executor, logger, error handler) - Add 9 file operation tools for User Story 1 - Full MCP protocol compliance with stdio transport - Input validation and sanitization for security - Comprehensive error handling with actionable messages - Constitutional compliance: all 6 principles satisfied MVP includes: - obsidian_create_note, read, append, prepend, delete, move, rename, open, file_info - Zod validation schemas for all parameters - 30s timeout configuration with per-command overrides - Stderr-only logging with sanitized output - Graceful shutdown handling Build: ✅ 0 errors, 0 vulnerabilities Tasks: 48/167 complete (MVP milestone) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
13 KiB
Tool Schemas
Purpose: Define input/output schemas for all MCP tools exposed by the Obsidian bundle
Tool Naming Convention
All tools use prefix obsidian_ followed by the operation:
obsidian_create_noteobsidian_searchobsidian_list_tasks
This prevents naming conflicts with other MCP servers.
Priority 1 Tools: File Operations (15 tools)
obsidian_create_note
Description: Create a new note in the vault
Input Schema:
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Note name (without .md extension) or exact path",
"minLength": 1,
"maxLength": 255
},
"path": {
"type": "string",
"description": "Optional: Directory path within vault"
},
"content": {
"type": "string",
"description": "Initial note content (markdown)"
},
"template": {
"type": "string",
"description": "Template name to use"
},
"overwrite": {
"type": "boolean",
"description": "Overwrite if file exists (default: false)"
},
"open": {
"type": "boolean",
"description": "Open file after creating (default: false)"
}
},
"required": ["name"]
}
Output Example:
{
"success": true,
"data": {
"path": "Projects/Meeting Notes.md",
"created": true,
"opened": false
}
}
obsidian_read_note
Description: Read the contents of a note
Input Schema:
{
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "Note name (wikilink-style resolution)"
},
"path": {
"type": "string",
"description": "Exact path to note"
}
},
"oneOf": [{"required": ["file"]}, {"required": ["path"]}]
}
Output Example:
{
"success": true,
"data": {
"path": "Projects/Meeting Notes.md",
"content": "# Meeting Notes\n\n- Agenda item 1\n- Agenda item 2",
"size": 52,
"modified": "2026-03-22T15:30:00Z"
}
}
obsidian_append_to_note
Description: Append content to a note
Input Schema:
{
"type": "object",
"properties": {
"file": {"type": "string"},
"path": {"type": "string"},
"content": {
"type": "string",
"description": "Content to append (required)"
},
"inline": {
"type": "boolean",
"description": "Append without newline (default: false)"
}
},
"required": ["content"],
"oneOf": [{"required": ["file"]}, {"required": ["path"]}]
}
obsidian_delete_note
Description: Delete a note (moves to trash by default)
Input Schema:
{
"type": "object",
"properties": {
"file": {"type": "string"},
"path": {"type": "string"},
"permanent": {
"type": "boolean",
"description": "Skip trash, delete permanently (default: false)"
}
},
"oneOf": [{"required": ["file"]}, {"required": ["path"]}]
}
obsidian_move_note
Description: Move or rename a note
Input Schema:
{
"type": "object",
"properties": {
"file": {"type": "string"},
"path": {"type": "string"},
"to": {
"type": "string",
"description": "Destination folder or full path (required)"
}
},
"required": ["to"],
"oneOf": [{"required": ["file"]}, {"required": ["path"]}]
}
Priority 2 Tools: Search & Discovery (20 tools)
obsidian_search
Description: Search vault for text
Input Schema:
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query (required)"
},
"folder": {
"type": "string",
"description": "Limit search to specific folder"
},
"limit": {
"type": "number",
"description": "Maximum number of results"
},
"caseSensitive": {
"type": "boolean",
"description": "Case-sensitive search (default: false)"
}
},
"required": ["query"]
}
Output Example:
{
"success": true,
"data": {
"query": "machine learning",
"matchCount": 5,
"files": [
{"path": "Research/AI Notes.md", "matches": 3},
{"path": "Projects/ML Project.md", "matches": 2}
]
}
}
obsidian_get_backlinks
Description: List backlinks to a note
Input Schema:
{
"type": "object",
"properties": {
"file": {"type": "string"},
"path": {"type": "string"},
"counts": {
"type": "boolean",
"description": "Include link counts (default: false)"
}
},
"oneOf": [{"required": ["file"]}, {"required": ["path"]}]
}
Output Example:
{
"success": true,
"data": {
"target": "Projects/ML Project.md",
"backlinks": [
{"source": "Research/AI Notes.md", "count": 2},
{"source": "Weekly Review.md", "count": 1}
],
"totalBacklinks": 2
}
}
obsidian_list_tags
Description: List tags in the vault or specific file
Input Schema:
{
"type": "object",
"properties": {
"file": {"type": "string", "description": "Limit to specific file"},
"path": {"type": "string", "description": "Limit to specific path"},
"counts": {
"type": "boolean",
"description": "Include occurrence counts (default: false)"
},
"sortBy": {
"type": "string",
"enum": ["name", "count"],
"description": "Sort order (default: name)"
}
}
}
Output Example:
{
"success": true,
"data": {
"tags": [
{"name": "project", "count": 15},
{"name": "important", "count": 8},
{"name": "todo", "count": 5}
],
"totalTags": 3
}
}
Priority 3 Tools: Tasks & Properties (15 tools)
obsidian_list_tasks
Description: List tasks in the vault or specific file
Input Schema:
{
"type": "object",
"properties": {
"file": {"type": "string"},
"path": {"type": "string"},
"status": {
"type": "string",
"enum": ["todo", "done", "all"],
"description": "Filter by status (default: all)"
},
"verbose": {
"type": "boolean",
"description": "Group by file with line numbers (default: false)"
}
}
}
Output Example:
{
"success": true,
"data": {
"tasks": [
{
"ref": "Projects/TODO.md:5",
"file": "Projects/TODO.md",
"line": 5,
"text": "Finish documentation",
"status": "",
"done": false
},
{
"ref": "Weekly Review.md:12",
"file": "Weekly Review.md",
"line": 12,
"text": "Review PRs",
"status": "x",
"done": true
}
],
"totalTasks": 2
}
}
obsidian_toggle_task
Description: Toggle a task's completion status
Input Schema:
{
"type": "object",
"properties": {
"ref": {
"type": "string",
"description": "Task reference (path:line)"
},
"file": {"type": "string"},
"path": {"type": "string"},
"line": {
"type": "number",
"description": "Line number (1-indexed)"
}
},
"oneOf": [
{"required": ["ref"]},
{"required": ["file", "line"]},
{"required": ["path", "line"]}
]
}
obsidian_set_property
Description: Set a property value on a note
Input Schema:
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Property name (required)"
},
"value": {
"description": "Property value (required, type: string|number|boolean|array)"
},
"type": {
"type": "string",
"enum": ["text", "number", "checkbox", "date", "datetime", "list"],
"description": "Property type (optional, inferred from value)"
},
"file": {"type": "string"},
"path": {"type": "string"}
},
"required": ["name", "value"],
"oneOf": [{"required": ["file"]}, {"required": ["path"]}]
}
Priority 4 Tools: Vault Navigation (15 tools)
obsidian_list_files
Description: List files in the vault
Input Schema:
{
"type": "object",
"properties": {
"folder": {
"type": "string",
"description": "Filter by folder"
},
"extension": {
"type": "string",
"description": "Filter by extension (e.g., 'md')"
}
}
}
obsidian_get_vault_info
Description: Get vault statistics
Input Schema:
{
"type": "object",
"properties": {
"info": {
"type": "string",
"enum": ["name", "path", "files", "folders", "size", "all"],
"description": "Specific info to return (default: all)"
}
}
}
Output Example:
{
"success": true,
"data": {
"name": "My Vault",
"path": "/Users/user/Documents/Obsidian/My Vault",
"fileCount": 1234,
"folderCount": 56,
"totalSize": 5242880
}
}
Priority 5 Tools: Advanced Features (30 tools)
obsidian_daily_append
Description: Append content to today's daily note
Input Schema:
{
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "Content to append (required)"
},
"inline": {
"type": "boolean",
"description": "Append without newline (default: false)"
},
"open": {
"type": "boolean",
"description": "Open daily note after appending (default: false)"
}
},
"required": ["content"]
}
obsidian_list_templates
Description: List available templates
Input Schema:
{
"type": "object",
"properties": {}
}
obsidian_list_plugins
Description: List installed plugins
Input Schema:
{
"type": "object",
"properties": {
"filter": {
"type": "string",
"enum": ["core", "community", "all"],
"description": "Filter by plugin type (default: all)"
},
"enabledOnly": {
"type": "boolean",
"description": "Show only enabled plugins (default: false)"
},
"includeVersions": {
"type": "boolean",
"description": "Include version numbers (default: false)"
}
}
}
Complete Tool List (95 tools)
File Operations (15)
- obsidian_create_note
- obsidian_read_note
- obsidian_append_to_note
- obsidian_prepend_to_note
- obsidian_delete_note
- obsidian_move_note
- obsidian_rename_note
- obsidian_open_note
- obsidian_get_file_info
- obsidian_list_recents
- obsidian_get_outline
- obsidian_get_wordcount
- obsidian_random_note
- obsidian_open_file
- obsidian_list_orphans
Search & Discovery (20)
- obsidian_search
- obsidian_search_with_context
- obsidian_get_backlinks
- obsidian_get_outgoing_links
- obsidian_list_unresolved_links
- obsidian_list_tags
- obsidian_get_tag_info
- obsidian_list_aliases
- obsidian_list_properties
- obsidian_get_property_count
- obsidian_list_deadends
- obsidian_list_files
- obsidian_list_folders
- obsidian_get_folder_info
- obsidian_get_vault_info
- obsidian_list_vaults
- obsidian_open_search
- obsidian_get_version
- obsidian_reload_vault
- obsidian_list_workspace_tabs
Tasks & Properties (15)
- obsidian_list_tasks
- obsidian_toggle_task
- obsidian_mark_task_done
- obsidian_mark_task_todo
- obsidian_update_task_status
- obsidian_get_property
- obsidian_set_property
- obsidian_remove_property
- obsidian_list_note_properties
- obsidian_list_vault_properties
- obsidian_daily_tasks
- obsidian_active_file_tasks
- obsidian_active_file_properties
- obsidian_active_file_tags
- obsidian_active_file_aliases
Daily Notes (6)
- obsidian_open_daily_note
- obsidian_daily_append
- obsidian_daily_prepend
- obsidian_daily_read
- obsidian_daily_path
- obsidian_random_read
Templates & Bookmarks (8)
- obsidian_list_templates
- obsidian_read_template
- obsidian_insert_template
- obsidian_create_bookmark
- obsidian_list_bookmarks
- obsidian_bookmark_file
- obsidian_bookmark_search
- obsidian_bookmark_url
Plugins & Themes (12)
- obsidian_list_plugins
- obsidian_list_enabled_plugins
- obsidian_get_plugin_info
- obsidian_enable_plugin
- obsidian_disable_plugin
- obsidian_list_themes
- obsidian_get_active_theme
- obsidian_set_theme
- obsidian_list_css_snippets
- obsidian_enable_snippet
- obsidian_disable_snippet
- obsidian_restricted_mode_status
File History & Sync (12)
- obsidian_list_file_versions
- obsidian_read_version
- obsidian_restore_version
- obsidian_list_files_with_history
- obsidian_open_history
- obsidian_list_sync_versions
- obsidian_read_sync_version
- obsidian_restore_sync_version
- obsidian_get_sync_status
- obsidian_pause_sync
- obsidian_resume_sync
- obsidian_list_sync_deleted
Bases & Commands (7)
- obsidian_list_bases
- obsidian_list_base_views
- obsidian_query_base
- obsidian_create_base_item
- obsidian_list_commands
- obsidian_execute_command
- obsidian_get_hotkey
Error Response Format
All tools return errors in consistent structure:
{
"success": false,
"error": {
"code": "OBSIDIAN_NOT_RUNNING",
"message": "Obsidian application is not running. Please start Obsidian and try again.",
"details": {
"attempted": "create_note",
"file": "Meeting Notes.md"
}
}
}
Validation Rules
All input schemas enforce:
- String min/max lengths
- Required fields
- Enum constraints for predefined values
- Type coercion where safe
- Sanitization of special characters before CLI execution