### Install Dependencies Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Install project dependencies using uv. ```bash uv sync --dev ``` -------------------------------- ### Direct CLI Launch and Development Setup Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Launch the Obsidian Brain MCP server directly using uvx for testing or development. Override the Obsidian CLI path with an environment variable if needed. Includes commands for development setup, testing, and linting. ```bash # Direct CLI launch (for testing or development) uvx --from git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP obsidian-brain ``` ```bash # Environment variable override for non-PATH Obsidian binary OBSIDIAN_CLI_PATH=/Applications/Obsidian.app/Contents/MacOS/obsidian obsidian-brain ``` ```bash # Development setup git clone https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP.git cd The-Obsidian-Brain-MCP uv sync --dev uv run pytest uv run ruff check . ``` -------------------------------- ### Get Vault Configuration Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Reads the vault configuration file. Returns an error if the vault has not been onboarded. ```python result = await get_vault_config() # Returns: # { # "exists": true, # "path": ".obsidian-brain/config.yml", # "content": "vault_profile:\n organizational_system: PARA\n naming_convention: Title Case\n..." # } # Not yet onboarded: # {"exists": false, "path": ".obsidian-brain/config.yml", "message": "Vault not onboarded. Run run_onboarding first."} ``` -------------------------------- ### Get Notes by Tag Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Finds and returns a list of all note file paths associated with a specific tag. ```python result = await get_notes_by_tag(tag="ml") ``` -------------------------------- ### Direct CLI Usage of Obsidian Brain MCP Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Run The Obsidian Brain MCP directly from the command line for testing purposes or install it as a tool for easier access. ```bash # Run directly (for testing) uvx --from git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP obsidian-brain # Or install as a tool uv tool install git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP obisidian-brain ``` -------------------------------- ### Get Knowledge Base Status Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Checks if the knowledge base exists. If it exists, it provides details about its creation and last update. If not, it recommends creating it. ```python result = await get_knowledge_base_status() # Exists: # { # "exists": true, # "path": ".obsidian-brain/knowledge-base.md", # "created": "2024-01-15", # "updated": "2024-01-20", # "generator": "obsidian-brain-mcp", # "vault_stats_at_generation": {"total_notes": 347, ...}, # "recommendation": "Knowledge base exists. Regenerate if vault has changed significantly." # } # Not yet generated: # { # "exists": false, # "path": ".obsidian-brain/knowledge-base.md", # "recommendation": "Knowledge base not found. Call create_vault_knowledge_base to generate it." # } ``` -------------------------------- ### Direct ObsidianCLIClient Usage Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Use ObsidianCLIClient directly for embedding or testing. It auto-detects the obsidian binary or can be configured for multi-vault setups. ```python from obsidian_brain.cli_client import ObsidianCLIClient import asyncio async def main(): # Auto-detects obsidian binary via shutil.which or OBSIDIAN_CLI_PATH client = ObsidianCLIClient(timeout=30.0) # For multi-vault setups: # client = ObsidianCLIClient(vault="My Work Vault") # List root directory entries = await client.list_directory("/") # [{"name": "Projects", "type": "folder"}, {"name": "index.md", "type": "file"}] # Get all markdown files files = await client.get_all_files("/") # ["Projects/AI.md", "Learning/Python.md", ...] # Read a note data = await client.get_note("Projects/AI.md", include_metadata=True) # {"content": "...", "tags": [...], "frontmatter": {...}, "modified": "..."} # Full-text search results = await client.search_simple("transformer attention", context_length=100) # Tags tags = await client.get_tags() # {"ml": 27, "learning": 38, ...} # Backlinks and outgoing links backlinks = await client.get_backlinks("Projects/AI.md") links = await client.get_links("Projects/AI.md") # Daily note operations daily = await client.get_daily_note() # today daily_past = await client.get_daily_note("2024-01-15") await client.append_daily("\n- Entry text", "2024-01-15") asyncio.run(main()) ``` -------------------------------- ### Markdown for Daily Notes Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Example of how meeting notes can be appended to a daily note in Markdown format, including timestamps, discussion points, and tags. ```markdown ## 2023-10-27 ### Standup Notes - **10:00 AM**: Discussed progress on feature X. Blocked by API issue. - Action Item: @John to investigate API. - **10:15 AM**: Reviewed PR #123. Minor feedback. Tags: #meeting #standup #projectX ``` -------------------------------- ### get_linked_notes Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Traverses the link graph from a starting note using Breadth-First Search (BFS) up to a specified depth. ```APIDOC ## get_linked_notes ### Description Traverses the link graph (BFS, 1–3 hops) from a starting note, returning nodes (with depth) and edges (source → target). ### Method `get_linked_notes` ### Parameters - **path** (string) - Required - The starting note path for the traversal. - **depth** (integer) - Optional - The maximum depth of the traversal (default is 1). - **direction** (string) - Optional - The direction of links to follow: "incoming", "outgoing", or "both" (default is "both"). ### Request Example ```python result = await get_linked_notes( path="Projects/AI.md", depth=2, direction="both", # "incoming", "outgoing", or "both" ) ``` ### Response #### Success Response (LinkGraph JSON) - **center** (string) - The starting note path. - **nodes** (array) - An array of objects, each representing a node in the graph. - **path** (string) - The path of the note. - **depth** (integer) - The depth of the note from the center node. - **edges** (array) - An array of objects, each representing an edge between two nodes. - **source** (string) - The source note path of the link. - **target** (string) - The target note path of the link. #### Response Example ```json { "center": "Projects/AI.md", "nodes": [ {"path": "Projects/AI.md", "depth": 0}, {"path": "Research/Papers.md", "depth": 1}, {"path": "Learning/NLP.md", "depth": 1}, {"path": "Research/Datasets.md", "depth": 2} ], "edges": [ {"source": "Projects/AI.md", "target": "Research/Papers.md"}, {"source": "Learning/NLP.md", "target": "Projects/AI.md"}, {"source": "Research/Papers.md", "target": "Research/Datasets.md"} ] } ``` ``` -------------------------------- ### Get Note Content and Metadata using MCP Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Retrieve the markdown content, YAML frontmatter, wikilinks, and tags of a specific note using the `get_note` MCP tool. Handles 'NoteNotFoundError' if the note does not exist. ```python result = await get_note(path="Projects/AI Safety.md") # Returns JSON: # { # "path": "Projects/AI Safety.md", # "content": "--- tags: - research - ai --- # AI Safety See [[Alignment]].", # "tags": ["research", "ai"], # "outgoing_links": ["Alignment"], # "frontmatter": {"tags": ["research", "ai"], "created": "2024-01-15"}, # "modified": "2024-01-20T10:30:00" # } # Error case — note not found: # {"error": true, "type": "NoteNotFoundError", "message": "Note not found: Projects/AI Safety.md"} ``` -------------------------------- ### Get Daily Note Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Retrieves the content of the daily note for the current date or a specified date. The date format must be YYYY-MM-DD. ```python # Today's note result = await get_daily_note() ``` ```python # Specific date result = await get_daily_note(date="2024-01-20") ``` ```python # Invalid format: # {"error": true, "type": "ValidationError", "message": "Invalid date format: 20-01-2024. Use YYYY-MM-DD"} ``` -------------------------------- ### Traverse Link Graph Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Use `get_linked_notes` to perform a breadth-first traversal of the link graph starting from a given note. Specify depth and direction (incoming, outgoing, or both). ```python result = await get_linked_notes( path="Projects/AI.md", depth=2, direction="both", # "incoming", "outgoing", or "both" ) # Returns (LinkGraph JSON): # { # "center": "Projects/AI.md", # "nodes": [ # {"path": "Projects/AI.md", "depth": 0}, # {"path": "Research/Papers.md", "depth": 1}, # {"path": "Learning/NLP.md", "depth": 1}, # {"path": "Research/Datasets.md", "depth": 2} # ], # "edges": [ # {"source": "Projects/AI.md", "target": "Research/Papers.md"}, # {"source": "Learning/NLP.md", "target": "Projects/AI.md"}, # {"source": "Research/Papers.md", "target": "Research/Datasets.md"} # ] # } ``` -------------------------------- ### Get Backlinks for a Note Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Use `get_backlinks` to retrieve a list of all notes that link to a specified note. This relies on the backlink index built by `refresh_vault_structure`. ```python result = await get_backlinks(path="Research/Papers.md") # Returns: # { # "success": true, # "path": "Research/Papers.md", # "backlinks": ["Projects/AI.md", "Learning/NLP.md"], # "count": 2 # } # Cache not yet initialized: # {"error": true, "type": "CacheNotInitializedError", "message": "Vault cache not initialized. Call refresh_vault_structure first."} ``` -------------------------------- ### Access Aggregate Vault Statistics (JSON) Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Get aggregate vault statistics like total notes, folders, and links via the `vault://stats` MCP resource. Returns a JSON object with key statistics. ```json # Returns: {"total_notes": 347, "total_folders": 42, "total_tags": 89, "total_links": 1204, "orphan_notes": 23} ``` -------------------------------- ### Navigate to Project Directory Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Change into the cloned repository's directory. ```bash cd The-Obsidian-Brain-MCP ``` -------------------------------- ### FastMCP Server Initialization Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/SPECIFICATION.md Sets up the FastMCP server and registers various tools for interacting with the Obsidian vault. ```python from mcp.server.fastmcp import FastMCP server = FastMCP("obsidian-brain") client = ObsidianCLIClient() register_vault_tools(server, client) register_link_tools(server, client) register_tag_tools(server, client) # ... etc ``` -------------------------------- ### Clone Repository Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Clone the repository to your local machine to begin development. ```bash git clone https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP.git ``` -------------------------------- ### run_onboarding Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Initiates the vault analysis process, which includes detecting organizational patterns (like PARA, Zettelkasten), tag hierarchies, naming conventions, and frontmatter patterns. This function creates configuration files such as `.obsidian-brain/config.yml`, `memories/vault-overview.md`, and `memories/conventions.md`. ```APIDOC ## run_onboarding — Analyze vault structure and write configuration files Detects organizational patterns (PARA, Zettelkasten, etc.), tag hierarchies, naming conventions, and frontmatter patterns. Creates `.obsidian-brain/config.yml`, `memories/vault-overview.md`, and `memories/conventions.md`. ```python # Prerequisite: call refresh_vault_structure first result = await run_onboarding() ``` ``` -------------------------------- ### Get Outgoing Links from a Note Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Use `get_outgoing_links` to find all notes that a specific note links to by extracting `[[wikilinks]]` directly from its content. ```python result = await get_outgoing_links(path="Projects/AI.md") # Returns: # { # "success": true, # "path": "Projects/AI.md", # "outgoing_links": ["Research/Papers", "Alignment", "RLHF"], # "count": 3 # } ``` -------------------------------- ### Run Vault Onboarding Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Analyzes the vault structure, detects organizational patterns, and creates configuration files. This function requires `refresh_vault_structure` to be called beforehand. ```python # Prerequisite: call refresh_vault_structure first result = await run_onboarding() ``` -------------------------------- ### Create Note with Metadata using MCP Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Create a new note with specified content, tags, and backlinks using the `create_note` MCP tool. Auto-generates frontmatter and validates backlink targets. Handles 'InvalidBacklinkError' if targets are not found. ```python result = await create_note( path="Research/Transformer Architecture.md", content="Transformers use self-attention to process sequences in parallel.", tags=["ml", "nlp", "deep-learning"], backlinks=["Attention Mechanism", "BERT"], ) # Returns: # { # "success": true, # "path": "Research/Transformer Architecture.md", # "message": "Created note: Research/Transformer Architecture.md", # "tags": ["ml", "nlp", "deep-learning"], # "backlinks": ["Attention Mechanism", "BERT"] # } # The created note content: # --- # created: 2024-01-20 # tags: # - deep-learning # - ml # - nlp # --- # # # Transformer Architecture # # Transformers use self-attention to process sequences in parallel. # # ## See Also # # - [[Attention Mechanism]] # - [[BERT]] # Backlink validation failure: # {"error": true, "type": "InvalidBacklinkError", "message": "Backlink target does not exist: BERT"} ``` -------------------------------- ### check_onboarding_status Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Checks if the vault has undergone the initial analysis and configuration process. ```APIDOC ## check_onboarding_status — Check if the vault has been analyzed ```python result = await check_onboarding_status() # Not yet onboarded: # { # "onboarded": false, # "message": "Vault has not been onboarded", # "recommendation": "Run refresh_vault_structure then run_onboarding" # } # Already onboarded: # { # "onboarded": true, # "message": "Vault is configured", # "recommendation": "Read memories with list_memories and read_memory" # } ``` ``` -------------------------------- ### Run Tests Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Execute the project's tests using pytest via uv. ```bash uv run pytest ``` -------------------------------- ### Check Onboarding Status Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Checks if the Obsidian vault has been analyzed and configured. Provides a recommendation for the next steps. ```python result = await check_onboarding_status() ``` -------------------------------- ### Wikilink Utilities: Extract, Inject, Create Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Utilities for parsing, injecting, and constructing Obsidian `[[wikilinks]]`. Includes functions for extracting targets, checking existence, creating links with aliases, and injecting links into content. ```python from obsidian_brain.utils.wikilinks import extract_wikilinks, inject_wikilink, create_wikilink, contains_wikilink # Extract all wikilink targets (aliases stripped) links = extract_wikilinks("See [[Note A]] and [[Folder/Note B|display name]]") # ["Note A", "Folder/Note B"] # Check for a specific link has_link = contains_wikilink("See [[Note A]]", "Note A") # True # Create a wikilink string link = create_wikilink("Folder/Note") # "[[Folder/Note]]" link_alias = create_wikilink("Folder/Note", "My Note") # "[[Folder/Note|My Note]]" # Inject a link under "See Also" (creates section if absent) new_content = inject_wikilink("# Title\n\nContent", "Related Note") # "# Title\n\nContent\n\n## See Also\n\n- [[Related Note]]\n" new_content = inject_wikilink("# Title", "Note", context="Related to") # "# Title\n\n## See Also\n\n- Related to [[Note]]\n" ``` -------------------------------- ### Configure OpenCode for Obsidian Brain MCP Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Add this JSON configuration to your `opencode.json` file in your project to integrate with The Obsidian Brain MCP server. ```json { "$schema": "https://opencode.ai/config.json", "mcp": { "obsidian-brain": { "type": "local", "command": "uvx", "args": ["--from", "git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP", "obsidian-brain"], "enabled": true } } } ``` -------------------------------- ### VaultClient Method to CLI Command Mapping Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/SPECIFICATION.md Maps VaultClient methods to their corresponding CLI commands for interacting with the Obsidian vault. ```text obsidian files folder="{path}" format=json ``` ```text obsidian files ext=md format=json ``` ```text obsidian read path="{path}" format=json ``` ```text obsidian read ``` ```text obsidian create name="{name}" path="{folder}" content="{content}" --silent ``` ```text obsidian create --overwrite --silent ``` ```text obsidian append file="{name}" content="{content}" ``` ```text obsidian delete file="{name}" ``` ```text obsidian search query="{query}" format=json ``` ```text obsidian daily:read format=json ``` ```text obsidian daily:append content="{content}" ``` ```text obsidian tags format=json ``` ```text obsidian backlinks file="{name}" format=json ``` ```text obsidian links file="{name}" format=json ``` -------------------------------- ### create_note Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Creates a new note with specified content, tags, and backlinks. Validates backlink targets and generates frontmatter. ```APIDOC ## create_note ### Description Creates a note with frontmatter, tags, and backlinks. ### Method APICALL ### Endpoint create_note ### Parameters #### Query Parameters - **path** (string) - Required - The desired path for the new note (e.g., "Research/Transformer Architecture.md"). - **content** (string) - Required - The markdown content for the new note. - **tags** (array) - Optional - An array of tags to associate with the note. - **backlinks** (array) - Optional - An array of existing note paths to link to from the new note. ### Response #### Success Response (200) - **success** (boolean) - True if the note was created successfully. - **path** (string) - The path of the created note. - **message** (string) - A confirmation message. - **tags** (array) - The tags applied to the created note. - **backlinks** (array) - The backlinks associated with the created note. #### Error Response - **error** (boolean) - True if an error occurred. - **type** (string) - The type of error (e.g., "InvalidBacklinkError"). - **message** (string) - A description of the error. ``` -------------------------------- ### Frontmatter Utilities: Create, Add Tags, Parse Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Utilities for manipulating YAML frontmatter in notes using `python-frontmatter`. Supports creating notes with frontmatter, adding/removing tags, parsing frontmatter and body, and setting arbitrary frontmatter values. ```python from obsidian_brain.utils.frontmatter import ( create_note_with_frontmatter, add_frontmatter_tags, remove_frontmatter_tags, parse_note, set_frontmatter_value, ) # Create full note with frontmatter content = create_note_with_frontmatter( title="My Note", content="Some content here.", tags=["learning", "python"], ) # "---\ncreated: 2024-01-20\ntags:\n- learning\n- python\n---\n\n# My Note\n\nSome content here." # Parse frontmatter and body separately fm, body = parse_note("---\ntags: [a, b]\n---\n# Title\nBody text") # fm = {"tags": ["a", "b"]}, body = "# Title\nBody text" # Add tags (dedup, sorted) new_content = add_frontmatter_tags("---\ntags: [a]\n---\nBody", ["b", "c"]) # "---\ntags:\n- a\n- b\n- c\n---\nBody" # Remove tags new_content = remove_frontmatter_tags("---\ntags: [a, b, c]\n---\nBody", ["b"]) # "---\ntags:\n- a\n- c\n---\nBody" # Set arbitrary frontmatter key new_content = set_frontmatter_value("---\ntags: [a]\n---\nBody", "status", "complete") # "---\nstatus: complete\ntags:\n- a\n---\nBody" ``` -------------------------------- ### Configure Zed for Obsidian Brain MCP Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Add this JSON configuration to your Zed settings file (`~/.config/zed/settings.json` or `~/Library/Application Support/Zed/settings.json`) to integrate with The Obsidian Brain MCP server. ```json { "context_servers": { "obsidian-brain": { "command": { "path": "uvx", "args": ["--from", "git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP", "obsidian-brain"] } } } } ``` -------------------------------- ### Obsidian CLI Exception Hierarchy Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Demonstrates the exception hierarchy for Obsidian CLI operations. Use specific exceptions for targeted error handling. ```python from obsidian_brain.exceptions import ( ObsidianCLIError, # Base: non-zero CLI exit code NoteNotFoundError, # Subclass of ObsidianCLIError; note missing from vault CLITimeoutError, # Subclass of ObsidianCLIError; subprocess exceeded timeout CLINotFoundError, # Standalone: obsidian binary not on PATH / OBSIDIAN_CLI_PATH invalid ObsidianNotRunningError # Standalone: Obsidian desktop app is not running ) from obsidian_brain.cli_client import ObsidianCLIClient import asyncio async def example(): client = ObsidianCLIClient(timeout=30.0) # 30s default timeout try: note = await client.get_note("Projects/Missing.md") except NoteNotFoundError as e: print(f"Not found: {e.path}") except CLITimeoutError as e: print(f"Timed out after {e.timeout}s: {e.command}") except ObsidianCLIError as e: print(f"CLI error {e.returncode}: {e.stderr}") except ObsidianNotRunningError: print("Launch the Obsidian desktop app first") except CLINotFoundError: print("Set OBSIDIAN_CLI_PATH or add obsidian to PATH") ``` -------------------------------- ### Manually Configure Codex CLI for Obsidian Brain MCP Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Manually edit the Codex CLI configuration file (`~/.codex/config.toml`) to add The Obsidian Brain MCP server. ```toml [mcp_servers.obsidian-brain] command = "uvx" args = ["--from", "git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP", "obsidian-brain"] ``` -------------------------------- ### get_vault_config Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Reads the vault configuration file. Returns the configuration if the vault is onboarded, or an error message if it is not. ```APIDOC ## get_vault_config ### Description Read the vault configuration file. ### Method ```python result = await get_vault_config() ``` ### Response **Onboarded Vault:** ```json { "exists": true, "path": ".obsidian-brain/config.yml", "content": "vault_profile:\n organizational_system: PARA\n naming_convention: Title Case\n..." } ``` **Not Yet Onboarded:** ```json { "exists": false, "path": ".obsidian-brain/config.yml", "message": "Vault not onboarded. Run run_onboarding first." } ``` ``` -------------------------------- ### Configure VS Code (GitHub Copilot) for Obsidian Brain MCP Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Add this JSON configuration to your VS Code `.vscode/mcp.json` (project) or global settings to integrate with The Obsidian Brain MCP server. ```json { "servers": { "obsidian-brain": { "type": "stdio", "command": "uvx", "args": ["--from", "git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP", "obsidian-brain"] } } } ``` -------------------------------- ### Project Dependencies Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/SPECIFICATION.md Specifies the required package versions for the project. Ensure these versions are met for compatibility. ```toml dependencies = [ "mcp>=1.26.0", "pydantic>=2.0.0", "python-frontmatter>=1.1.0", ] ``` -------------------------------- ### create_vault_knowledge_base Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Generates a persistent Markdown overview of the vault, including folder structure, tag taxonomy, hub notes, link patterns, and optionally orphan notes. This is designed for LLM consumption and persists across sessions. ```APIDOC ## create_vault_knowledge_base ### Description Generate a persistent Markdown overview of the vault for LLM consumption. ### Method ```python result = await create_vault_knowledge_base( include_orphans=True, include_link_patterns=True, ) ``` ### Parameters #### Optional Parameters - **include_orphans** (boolean) - Whether to include orphan notes in the knowledge base. - **include_link_patterns** (boolean) - Whether to include link patterns in the knowledge base. ### Response ```json { "success": true, "path": ".obsidian-brain/knowledge-base.md", "message": "Knowledge base created/updated at .obsidian-brain/knowledge-base.md", "stats": { "total_notes": 347, "total_folders": 42, "total_tags": 89, "total_links": 1204, "orphan_notes": 23 }, "sections_included": {"orphans": true, "link_patterns": true} } ``` ``` -------------------------------- ### Lint Code Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Check the code for style and potential errors using ruff via uv. ```bash uv run ruff check . ``` -------------------------------- ### Create Vault Knowledge Base Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Generates a persistent Markdown overview of the vault, including folder structure, tag taxonomy, and optionally orphan notes and link patterns. This is designed for LLM consumption and persists across sessions. Call `refresh_vault_structure` first. ```python # Prerequisite: call refresh_vault_structure first result = await create_vault_knowledge_base( include_orphans=True, include_link_patterns=True, ) # Returns: # { # "success": true, # "path": ".obsidian-brain/knowledge-base.md", # "message": "Knowledge base created/updated at .obsidian-brain/knowledge-base.md", # "stats": { # "total_notes": 347, # "total_folders": 42, # "total_tags": 89, # "total_links": 1204, # "orphan_notes": 23 # }, # "sections_included": {"orphans": true, "link_patterns": true} # } ``` -------------------------------- ### MCP Server Configuration for AI Clients Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Configure AI clients like Claude Desktop, Cursor, and Windsurf to connect to the Obsidian Brain MCP server using uvx. For VS Code, use the stdio type. ```json // Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json // Cursor: ~/.cursor/mcp.json // Windsurf: ~/.codeium/windsurf/mcp_config.json { "mcpServers": { "obsidian-brain": { "command": "uvx", "args": [ "--from", "git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP", "obsidian-brain" ] } } } ``` ```json // VS Code (.vscode/mcp.json) { "servers": { "obsidian-brain": { "type": "stdio", "command": "uvx", "args": ["--from", "git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP", "obsidian-brain"] } } } ``` -------------------------------- ### List Vault Files using MCP Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Use the `list_vault_files` MCP tool to retrieve a list of files and folders within a specified path in the Obsidian vault. The path defaults to the vault root if not provided. ```python # MCP tool call (as seen by the AI assistant) result = await list_vault_files(path="Projects") # Returns: # [ # {"name": "Active", "type": "folder"}, # {"name": "Archive", "type": "folder"}, # {"name": "index.md", "type": "file"} # ] result = await list_vault_files() # path defaults to "/" # Returns root-level entries ``` -------------------------------- ### Configure Cursor for Obsidian Brain MCP Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Add this JSON configuration to your MCP client configuration file (`~/.cursor/mcp.json` or `.cursor/mcp.json`) to integrate with The Obsidian Brain MCP server. ```json { "mcpServers": { "obsidian-brain": { "command": "uvx", "args": ["--from", "git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP", "obsidian-brain"] } } } ``` -------------------------------- ### Configure Claude Desktop/Code for Obsidian Brain MCP Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Add this JSON configuration to your Claude Desktop or Claude Code configuration file to integrate with The Obsidian Brain MCP server. Ensure the config file path is correct for your OS. ```json { "mcpServers": { "obsidian-brain": { "command": "uvx", "args": [ "--from", "git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP", "obsidian-brain" ] } } } ``` -------------------------------- ### ObsidianCLIClient - Direct Backend Usage Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt The ObsidianCLIClient can be used directly for embedding or testing. It implements the VaultClient Protocol and allows for various operations on the Obsidian vault. ```APIDOC ## ObsidianCLIClient — Direct Backend Usage The `ObsidianCLIClient` implements the `VaultClient` Protocol and can be used directly for embedding or testing outside of the MCP server. ```python from obsidian_brain.cli_client import ObsidianCLIClient import asyncio async def main(): # Auto-detects obsidian binary via shutil.which or OBSIDIAN_CLI_PATH client = ObsidianCLIClient(timeout=30.0) # For multi-vault setups: # client = ObsidianCLIClient(vault="My Work Vault") # List root directory entries = await client.list_directory("/") # [{"name": "Projects", "type": "folder"}, {"name": "index.md", "type": "file"}] # Get all markdown files files = await client.get_all_files("/") # ["Projects/AI.md", "Learning/Python.md", ...] # Read a note data = await client.get_note("Projects/AI.md", include_metadata=True) # {"content": "...", "tags": [...], "frontmatter": {...}, "modified": "..."} # Full-text search results = await client.search_simple("transformer attention", context_length=100) # Tags tags = await client.get_tags() # {"ml": 27, "learning": 38, ...} # Backlinks and outgoing links backlinks = await client.get_backlinks("Projects/AI.md") links = await client.get_links("Projects/AI.md") # Daily note operations daily = await client.get_daily_note() # today daily_past = await client.get_daily_note("2024-01-15") await client.append_daily("\n- Entry text", "2024-01-15") asyncio.run(main()) ``` ``` -------------------------------- ### create_daily_entry Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Creates a timestamped bullet entry in a daily note, formatted as `- [HH:MM] content [[links]] #tags`. The entry is appended to the note. ```APIDOC ## create_daily_entry — Create a timestamped bullet entry in a daily note Formats a bullet point as `- [HH:MM] content [[links]] #tags` and appends it to the daily note. ```python result = await create_daily_entry( content="Discussed authentication flow refactor", tags=["standup", "decision"], links=["Project Alpha", "Auth Middleware"], date="2024-01-20", ) # Returns: # { # "success": true, # "date": "2024-01-20", # "entry": "- [10:30] Discussed authentication flow refactor [[Project Alpha]] [[Auth Middleware]] #standup #decision", # "timestamp": "10:30", # "tags": ["standup", "decision"], # "links": ["Project Alpha", "Auth Middleware"], # "message": "Created entry in daily note for 2024-01-20" # } ``` ``` -------------------------------- ### Add Obsidian Brain MCP Server via Codex CLI Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/README.md Use the Codex CLI to add the Obsidian Brain MCP server. This command registers the server for use with the CLI. ```bash codex mcp add obsidian-brain \ -- uvx --from git+https://github.com/OriginalByteMe/The-Obsidian-Brain-MCP obsidian-brain ``` -------------------------------- ### Frontmatter Utilities Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Utilities for manipulating YAML frontmatter in notes using `python-frontmatter`. ```APIDOC ## Frontmatter Utilities ### `create_note_with_frontmatter` / `add_frontmatter_tags` — Frontmatter utilities Manipulate YAML frontmatter using `python-frontmatter`. ### Method Signatures - `create_note_with_frontmatter(title: str, content: str, tags: Optional[list[str]] = None, **kwargs) -> str` - `parse_note(content: str) -> tuple[dict, str]` - `add_frontmatter_tags(content: str, tags: list[str]) -> str` - `remove_frontmatter_tags(content: str, tags: list[str]) -> str` - `set_frontmatter_value(content: str, key: str, value: Any) -> str` ### Parameters - **title** (str) - The title of the note. - **content** (str) - The main content of the note. - **tags** (Optional[list[str]]) - A list of tags to include in the frontmatter. - **key** (str) - The frontmatter key to set or modify. - **value** (Any) - The value to set for the specified frontmatter key. ### Usage Examples ```python from obsidian_brain.utils.frontmatter import ( create_note_with_frontmatter, add_frontmatter_tags, remove_frontmatter_tags, parse_note, set_frontmatter_value, ) # Create full note with frontmatter content = create_note_with_frontmatter( title="My Note", content="Some content here.", tags=["learning", "python"], ) # Expected output: # "---\ncreated: 2024-01-20\ntags:\n- learning\n- python\n---\n\n# My Note\n\nSome content here." # Parse frontmatter and body separately fm, body = parse_note("---\ntags: [a, b]\n---\n# Title\nBody text") # Expected: fm = {"tags": ["a", "b"]}, body = "# Title\nBody text" # Add tags (dedup, sorted) new_content = add_frontmatter_tags("---\ntags: [a]\n---\nBody", ["b", "c"]) # Expected output: # "---\ntags:\n- a\n- b\n- c\n---\nBody" # Remove tags new_content = remove_frontmatter_tags("---\ntags: [a, b, c]\n---\nBody", ["b"]) # Expected output: # "---\ntags:\n- a\n- c\n---\nBody" # Set arbitrary frontmatter key new_content = set_frontmatter_value("---\ntags: [a]\n---\nBody", "status", "complete") # Expected output: # "---\nstatus: complete\ntags:\n- a\n---\nBody" ``` ``` -------------------------------- ### Wikilink Utilities Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Utilities for parsing, injecting, and constructing Obsidian `[[wikilinks]]` from markdown content. ```APIDOC ## Wikilink Utilities ### `extract_wikilinks` / `inject_wikilink` / `create_wikilink` — Wikilink utilities Parse, inject, and construct Obsidian `[[wikilinks]]` from markdown content. ### Method Signatures - `extract_wikilinks(text: str) -> list[str]` - `contains_wikilink(text: str, link_target: str) -> bool` - `create_wikilink(target: str, alias: Optional[str] = None) -> str` - `inject_wikilink(content: str, link_target: str, context: Optional[str] = None) -> str` ### Parameters - **text** (str) - The markdown content to process. - **link_target** (str) - The target of the wikilink. - **alias** (Optional[str]) - An optional alias for the wikilink. - **context** (Optional[str]) - Optional context for injecting the link. ### Usage Examples ```python from obsidian_brain.utils.wikilinks import extract_wikilinks, inject_wikilink, create_wikilink, contains_wikilink # Extract all wikilink targets (aliases stripped) links = extract_wikilinks("See [[Note A]] and [[Folder/Note B|display name]]") # Expected: ["Note A", "Folder/Note B"] # Check for a specific link has_link = contains_wikilink("See [[Note A]]", "Note A") # Expected: True # Create a wikilink string link = create_wikilink("Folder/Note") # Expected: "[[Folder/Note]]" link_alias = create_wikilink("Folder/Note", "My Note") # Expected: "[[Folder/Note|My Note]]" # Inject a link under "See Also" (creates section if absent) new_content = inject_wikilink("# Title\n\nContent", "Related Note") # Expected: "# Title\n\nContent\n\n## See Also\n\n- [[Related Note]]\n" new_content = inject_wikilink("# Title", "Note", context="Related to") # Expected: "# Title\n\n## See Also\n\n- Related to [[Note]]\n" ``` ``` -------------------------------- ### Create Timestamped Daily Entry Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Creates a timestamped bullet entry in a daily note, formatted as '- [HH:MM] content [[links]] #tags'. Optional tags and links can be included. The date defaults to today. ```python result = await create_daily_entry( content="Discussed authentication flow refactor", tags=["standup", "decision"], links=["Project Alpha", "Auth Middleware"], date="2024-01-20", ) ``` -------------------------------- ### list_vault_files Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Lists files and folders at a specified path within the Obsidian vault. If no path is provided, it defaults to the root of the vault. ```APIDOC ## list_vault_files ### Description Lists files and folders at a vault path. ### Method APICALL ### Endpoint list_vault_files ### Parameters #### Query Parameters - **path** (string) - Optional - The path within the vault to list entries from. Defaults to "/". ``` -------------------------------- ### VaultClient Protocol Definition Source: https://github.com/originalbyteme/the-obsidian-brain-mcp/blob/main/SPECIFICATION.md Defines the abstract asynchronous interface for interacting with an Obsidian vault. Implementations should provide methods for file operations, search, daily notes, tags, backlinks, and links. ```python from typing import Any, Protocol @runtime_checkable class VaultClient(Protocol): async def list_directory(self, path: str = "/") -> list[dict[str, Any]]: ... async def get_all_files(self, path: str = "/") -> list[str]: ... async def get_note(self, path: str, include_metadata: bool = True) -> dict[str, Any]: ... async def note_exists(self, path: str) -> bool: ... async def create_note(self, path: str, content: str) -> None: ... async def update_note(self, path: str, content: str) -> None: ... async def append_to_note(self, path: str, content: str) -> None: ... async def delete_note(self, path: str) -> None: ... async def search_simple(self, query: str, context_length: int = 100) -> list[dict[str, Any]]: ... async def get_daily_note(self, date: str | None = None) -> dict[str, Any]: ... async def append_daily(self, content: str, date: str | None = None) -> None: ... async def get_tags(self) -> dict[str, int]: ... async def get_backlinks(self, path: str) -> list[str]: ... async def get_links(self, path: str) -> list[str]: ... ``` -------------------------------- ### get_knowledge_base_status Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Checks if the knowledge base exists and provides its status, including path, creation/update times, and a recommendation for regeneration. ```APIDOC ## get_knowledge_base_status ### Description Check if the knowledge base exists and retrieve its status. ### Method ```python result = await get_knowledge_base_status() ``` ### Response **Knowledge Base Exists:** ```json { "exists": true, "path": ".obsidian-brain/knowledge-base.md", "created": "2024-01-15", "updated": "2024-01-20", "generator": "obsidian-brain-mcp", "vault_stats_at_generation": {"total_notes": 347, ...}, "recommendation": "Knowledge base exists. Regenerate if vault has changed significantly." } ``` **Knowledge Base Not Generated:** ```json { "exists": false, "path": ".obsidian-brain/knowledge-base.md", "recommendation": "Knowledge base not found. Call create_vault_knowledge_base to generate it." } ``` ``` -------------------------------- ### Write Memory Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Creates a new memory or updates an existing one. Automatically handles frontmatter with `created`/`updated` timestamps. Specify the memory name, content, and optionally its type. ```python result = await write_memory( name="auth-refactor", content="## Auth Refactor Context\n\n- Using JWT with 24h expiry\n- Refresh tokens stored in httpOnly cookies\n- Middleware in `src/middleware/auth.ts`", memory_type="project", ) # Returns: # { # "success": true, # "action": "created", # or "updated" if memory already existed # "name": "auth-refactor", # "path": ".obsidian-brain/memories/auth-refactor.md", # "message": "Memory 'auth-refactor' created successfully" ``` -------------------------------- ### update_note Source: https://context7.com/originalbyteme/the-obsidian-brain-mcp/llms.txt Replaces the full content of an existing note, including frontmatter. ```APIDOC ## update_note ### Description Replaces the full content of an existing note, including frontmatter. ### Method `update_note` ### Parameters - **path** (string) - Required - The path to the note. - **content** (string) - Required - The new content for the note. ### Request Example ```python result = await update_note( path="Projects/MyProject.md", content="---\nstatus: complete\ntags:\n- project\n---\n\n# My Project\n\nCompleted Q1 2024.", ) ``` ### Response #### Success Response - **success** (boolean) - Indicates if the operation was successful. - **path** (string) - The path of the updated note. - **message** (string) - A confirmation message. #### Response Example ```json { "success": true, "path": "Projects/MyProject.md", "message": "Updated note: Projects/MyProject.md" } ``` ```