# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Development Commands ### Building ```bash go build -o obsidian-mcp ./cmd/obsidian-mcp ``` ### Testing ```bash # Run all tests go test ./... # Run tests with coverage go test -cover ./... # Run tests for specific package go test ./internal/domain/ # Run specific test go test -run TestNoteName ./internal/domain/ ``` ### Running ```bash # Basic run with vault path ./obsidian-mcp --vault /path/to/vault # With config file ./obsidian-mcp --config config.yaml # With environment variables VAULT_PATH=/path/to/vault LOG_LEVEL=debug ./obsidian-mcp ``` ### Dependencies ```bash # Download dependencies go mod download # Update dependencies go mod tidy # Add new dependency go get github.com/package/name ``` ## Architecture Overview This is an Obsidian MCP (Model Context Protocol) Server implementing **Clean Architecture** with strict dependency inversion. The codebase follows Domain-Driven Design principles. ### Layer Dependencies (Dependency Rule) All dependencies point inward toward the domain: - **Domain Layer** (innermost): Pure business logic, no external dependencies - **Repository Layer**: Interfaces defining data access contracts - **Use Case Layer**: Business orchestration, depends only on domain + repository interfaces - **Infrastructure Layer**: Concrete implementations (filesystem, git, parsers) - **Adapter Layer**: MCP protocol handlers, DTOs, external interface adapters ### Key Domain Entities **Note**: Central entity representing an Obsidian note with: - Path validation (must end in .md, no path traversal) - Content with automatic extraction of WikiLinks and Tags - Frontmatter (YAML metadata) - Timestamps (created/modified) **Vault**: Aggregate root managing collections of notes with: - Graph of note relationships - Tag indexing with counts - Statistics calculation **WikiLink**: Value object for `[[Internal Links]]` with support for: - Aliases: `[[target|display text]]` - Sections: `[[note#section]]` **Tag**: Value object for `#tags` with: - Nested tag support: `#project/ai/research` - Validation (no spaces, proper format) **Graph**: Thread-safe adjacency list for note relationships ### Repository Pattern All data access goes through interfaces in `internal/repository/`: - **NoteRepository**: CRUD operations for notes - **GitRepository**: Version control operations - **VaultRepository**: Vault-level operations and statistics - **SearchIndex**: Full-text search capabilities - **GraphIndex**: Backlink/outlink indexing - **TagIndex**: Tag-based search and operations ### Configuration System Uses `internal/config/config.go` with: - YAML file configuration - Environment variable overrides - Validation with sensible defaults - Support for vault path, git settings, caching, logging, performance tuning ### Error Handling Domain errors defined in `internal/domain/errors.go`: - `ErrNoteNotFound`, `ErrNoteAlreadyExists` - `ErrInvalidPath`, `ErrInvalidTag` - `ErrCircularLink` ### Key Architectural Patterns 1. **Dependency Inversion**: Use cases depend on repository interfaces, not implementations 2. **Entity Encapsulation**: Domain entities manage their own business rules 3. **Value Objects**: Immutable types like WikiLink, Tag, Frontmatter 4. **Repository Pattern**: Clean separation between business logic and data access 5. **Configuration as Code**: Comprehensive config system with validation ### Implementation Status Currently implemented: - ✅ Complete domain layer with all entities - ✅ All repository interfaces - ✅ Configuration system - ✅ CLI entry point Still needed (per design.md roadmap): - Infrastructure implementations (filesystem, git, markdown parsing) - Use case implementations - MCP adapter layer with 45+ tools - Index implementations (search, graph, tag) ### MCP Integration When implementing MCP tools, they should: - Live in `internal/adapter/mcp/tools/` - Use DTOs from `internal/adapter/dto/` - Call use cases, never repositories directly - Handle MCP protocol specifics while keeping business logic in use cases