Skip to main content
Glama

Obsidian MCP Server

by suhailnajeeb
obsidian.pyโ€ข2.87 kB
"""Pydantic models for Obsidian data structures.""" from typing import Optional, List, Dict, Any from datetime import datetime from pydantic import BaseModel, Field, field_validator class NoteMetadata(BaseModel): """Metadata for an Obsidian note.""" created: Optional[datetime] = Field(None, description="Creation timestamp") modified: Optional[datetime] = Field(None, description="Last modification timestamp") tags: List[str] = Field(default_factory=list, description="List of tags") aliases: List[str] = Field(default_factory=list, description="Alternative names for the note") frontmatter: Dict[str, Any] = Field(default_factory=dict, description="Raw frontmatter data") class Note(BaseModel): """Represents an Obsidian note.""" path: str = Field(..., description="Path to the note relative to vault root") content: str = Field(..., description="Markdown content of the note") metadata: NoteMetadata = Field(default_factory=NoteMetadata, description="Note metadata") @field_validator("path") def validate_path(cls, v): """Ensure path doesn't contain invalid characters.""" if not v or ".." in v: raise ValueError("Invalid path") return v.strip("/") class VaultItem(BaseModel): """Represents an item in the vault (file or folder).""" path: str = Field(..., description="Path relative to vault root") name: str = Field(..., description="Name of the file or folder") is_folder: bool = Field(..., description="Whether this is a folder") children: Optional[List["VaultItem"]] = Field(None, description="Child items if this is a folder") class SearchResult(BaseModel): """Result from a search operation.""" path: str = Field(..., description="Path to the matching note") score: float = Field(..., description="Relevance score") matches: List[str] = Field(default_factory=list, description="Matching text excerpts") context: Optional[str] = Field(None, description="Context around the match") class Tag(BaseModel): """Represents a tag in the vault.""" name: str = Field(..., description="Tag name without the # prefix") count: int = Field(default=0, description="Number of notes with this tag") notes: List[str] = Field(default_factory=list, description="Paths to notes with this tag") @field_validator("name") def clean_tag_name(cls, v): """Remove # prefix if present.""" return v.lstrip("#") class Backlink(BaseModel): """Represents a backlink to a note.""" source_path: str = Field(..., description="Path of the note containing the link") link_text: str = Field(..., description="Text of the link") context: Optional[str] = Field(None, description="Text around the link for context") # Enable forward references VaultItem.model_rebuild()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/suhailnajeeb/obsidian-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server