We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/adrienthebo/obsidian-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""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()