# Implementation Plan: Obsidian MCP Bundle **Branch**: `001-obsidian-mcp-bundle` | **Date**: 2026-03-22 | **Spec**: [spec.md](spec.md) **Input**: Feature specification from `/specs/001-obsidian-mcp-bundle/spec.md` **Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/plan-template.md` for the execution workflow. ## Summary Build an MCP Bundle that exposes Obsidian CLI capabilities to AI assistants through the Model Context Protocol. The bundle will implement stdio transport communication, provide 95% coverage of Obsidian CLI commands as MCP tools, and enable users to manage their Obsidian vaults conversationally through natural language requests to AI assistants like Claude. ## Technical Context **Language/Version**: Node.js >=18.0.0 (TypeScript 5.x) **Primary Dependencies**: @modelcontextprotocol/sdk, child_process (Node.js built-in) **Storage**: N/A (operations target user's Obsidian vault files) **Testing**: Jest with TypeScript support, integration tests against real Obsidian CLI **Target Platform**: macOS, Windows, Linux (anywhere Obsidian CLI runs) **Project Type**: MCP Bundle (local MCP server packaged as .mcpb file) **Performance Goals**: <3s for basic file operations, <5s for search queries (vaults up to 10k notes) **Constraints**: <30s timeout for CLI commands, stderr-only logging, no stdout pollution **Scale/Scope**: Support vaults with 10,000+ notes, handle 95% of Obsidian CLI commands ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* ### I. MCP Protocol Compliance (MANDATORY) ✅ **PASS** - Design explicitly requires stdio transport, JSON-RPC format, proper initialize/tools/list handling per FR-001 ### II. Manifest Integrity (MANDATORY) ✅ **PASS** - FR-021 mandates valid manifest.json conforming to MCPB spec v0.3; FR-022 requires user_config for vault selection ### III. Local Execution Security ✅ **PASS** - FR-015 requires input validation; FR-020 mandates sanitized logging; FR-022 uses user_config for vault scoping ### IV. Defensive Programming (NON-NEGOTIABLE) ✅ **PASS** - FR-017 requires graceful error handling; FR-018 sets 30s timeout limits; clarifications specify error message strategies ### V. Structured Tool Responses ✅ **PASS** - FR-016 mandates structured JSON responses; FR-023 requires accurate tool descriptions; FR-025 supports format options ### VI. Stdio Transport Standard ✅ **PASS** - FR-020 explicitly requires stderr-only logging (never stdout); FR-001 mandates stdio transport ### Security & Privacy Requirements ✅ **PASS** - All operations are local (no external services); FR-020 sanitizes logged parameters; no privacy policies needed ### Quality Assurance Standards ✅ **PASS** - Testing framework defined (Jest); FR-016/FR-017 address error testing; multi-platform testing required per SC-008 **Overall Gate Status**: ✅ **APPROVED** - All constitutional principles satisfied. No violations to justify. ## Project Structure ### Documentation (this feature) ```text specs/001-obsidian-mcp-bundle/ ├── plan.md # This file (/speckit.plan command output) ├── spec.md # Feature specification ├── research.md # Phase 0 output (/speckit.plan command) ├── data-model.md # Phase 1 output (/speckit.plan command) ├── quickstart.md # Phase 1 output (/speckit.plan command) ├── contracts/ # Phase 1 output (/speckit.plan command) │ ├── mcp-protocol.md # MCP JSON-RPC communication contract │ └── tools.md # Tool schemas and examples └── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan) ``` ### Source Code (repository root) ```text obsidian-mcp/ ├── manifest.json # MCPB manifest (required) ├── package.json # Node.js dependencies ├── tsconfig.json # TypeScript configuration ├── .mcpbignore # Files to exclude from bundle ├── src/ │ ├── index.ts # Main entry point (MCP server) │ ├── server.ts # MCP server implementation │ ├── tools/ # Tool implementations │ │ ├── file-operations.ts # create, read, append, delete, move │ │ ├── search.ts # search, search:context │ │ ├── links.ts # backlinks, links, unresolved │ │ ├── tasks.ts # task list, toggle, mark done/todo │ │ ├── properties.ts # property CRUD operations │ │ ├── daily-notes.ts # daily note operations │ │ ├── tags-aliases.ts # tag and alias queries │ │ ├── vault-info.ts # files, folders, vault stats │ │ └── advanced.ts # templates, bookmarks, plugins, themes │ ├── cli/ # Obsidian CLI wrapper │ │ ├── executor.ts # CLI command execution with timeout │ │ └── parser.ts # CLI output parsing (JSON/TSV/CSV) │ ├── validation/ # Input validation │ │ ├── schemas.ts # Zod schemas for tool parameters │ │ └── sanitizer.ts # Parameter sanitization │ └── utils/ │ ├── logger.ts # stderr logging utility │ ├── error-handler.ts # Error formatting and mapping │ └── types.ts # TypeScript type definitions ├── tests/ │ ├── integration/ │ │ ├── file-operations.test.ts │ │ ├── search.test.ts │ │ └── mcp-protocol.test.ts │ └── unit/ │ ├── cli-executor.test.ts │ ├── validation.test.ts │ └── parser.test.ts ├── assets/ │ └── icon.png # Bundle icon └── README.md # Installation and usage docs ``` **Structure Decision**: Single project (MCP Bundle) - This is a Node.js application that implements an MCP server. The structure follows MCPB best practices with manifest.json at root, src/ for TypeScript source, and bundled node_modules. Tools are organized by functional category matching user stories. CLI wrapper layer abstracts Obsidian CLI execution and provides consistent error handling and timeout management. ## Complexity Tracking > **Fill ONLY if Constitution Check has violations that must be justified** | Violation | Why Needed | Simpler Alternative Rejected Because | |-----------|------------|-------------------------------------| | [e.g., 4th project] | [current need] | [why 3 projects insufficient] | | [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] |