# ObsidianReaderMCP
[](https://github.com/QianJue-CN/ObsidianReaderMCP)
[](https://www.python.org/)
[](https://modelcontextprotocol.io/)
[](LICENSE)
A comprehensive Python MCP (Model Context Protocol) server for managing Obsidian vaults through the obsidian-local-rest-api plugin.
## Features
### Core CRUD Operations
- **Create**: Create new notes with content, metadata, and tags
- **Read**: Retrieve note content and metadata by path
- **Update**: Modify existing notes (content, metadata, tags)
- **Delete**: Remove notes from the vault
### Extended Functionality
- **Batch Operations**: Create, update, or delete multiple notes at once
- **Template System**: Create and use note templates with variables
- **Link Analysis**: Analyze relationships between notes
- **Search & Filter**: Advanced search by content, tags, date range, word count
- **Vault Statistics**: Generate comprehensive vault analytics
- **Backup Management**: Create and manage vault backups
### MCP Server Integration
- Full MCP protocol support for AI assistant integration
- Async/await support for high performance
- Comprehensive error handling and logging
- Rate limiting and connection management
## Installation
### Prerequisites
1. **Obsidian** with the **obsidian-local-rest-api** plugin installed and configured
2. **Python 3.10+**
### Method 1: Using uvx (Recommended)
The easiest way to use ObsidianReaderMCP is with `uvx`, which allows you to run it without installation:
```bash
# Run directly without installation
uvx obsidianreadermcp
# Or install as a tool
uv tool install obsidianreadermcp
obsidianreadermcp
```
### Method 2: Using pip
```bash
# Install from PyPI
pip install obsidianreadermcp
# Run the server
obsidianreadermcp
```
### Method 3: Install from Source
```bash
# Clone the repository
git clone https://github.com/QianJue-CN/ObsidianReaderMCP.git
cd ObsidianReaderMCP
# Install dependencies
uv sync
# Or with pip
pip install -e .
```
## Configuration
### Environment Variables
Create a `.env` file in the project root (copy from `.env.example`):
```env
# Obsidian API Configuration
OBSIDIAN_HOST=localhost
OBSIDIAN_PORT=27123
OBSIDIAN_API_KEY=your_api_key_here
OBSIDIAN_USE_HTTPS=false
OBSIDIAN_TIMEOUT=30
OBSIDIAN_MAX_RETRIES=3
OBSIDIAN_RATE_LIMIT=10
# MCP Server Configuration
LOG_LEVEL=INFO
ENABLE_DEBUG=false
```
### Obsidian Setup
1. Install the **obsidian-local-rest-api** plugin from the Community Plugins
2. Enable the plugin in Obsidian settings
3. Configure the plugin:
- Set API port (default: 27123)
- Generate an API key
- Enable CORS if needed
4. Start the local REST API server
## Usage
### As a Python Library
```python
import asyncio
from obsidianreadermcp import ObsidianClient
from obsidianreadermcp.config import ObsidianConfig
from obsidianreadermcp.models import NoteMetadata
async def main():
# Create configuration
config = ObsidianConfig() # Uses environment variables
# Create and connect client
async with ObsidianClient(config) as client:
# Create a note
metadata = NoteMetadata(
tags=["example", "demo"],
frontmatter={"title": "My Note", "author": "Me"}
)
note = await client.create_note(
path="my_note.md",
content="# My Note\n\nThis is my note content.",
metadata=metadata
)
# Read the note
retrieved_note = await client.get_note("my_note.md")
print(f"Note content: {retrieved_note.content}")
# Update the note
await client.update_note(
path="my_note.md",
content="# Updated Note\n\nThis content has been updated."
)
# Search notes
results = await client.search_notes("updated")
print(f"Found {len(results)} matching notes")
# Delete the note
await client.delete_note("my_note.md")
asyncio.run(main())
```
### As an MCP Server
```bash
# Method 1: Using uvx (recommended)
uvx obsidianreadermcp
# Method 2: Using installed package
obsidianreadermcp
# Method 3: Using Python module
python -m obsidianreadermcp.server
# Method 4: Programmatically
python -c "
import asyncio
from obsidianreadermcp.server import main
asyncio.run(main())
"
```
### Claude Desktop Integration
Add to your Claude Desktop configuration file:
```json
{
"mcpServers": {
"obsidian": {
"command": "uvx",
"args": ["obsidianreadermcp"],
"env": {
"OBSIDIAN_HOST": "localhost",
"OBSIDIAN_PORT": "27123",
"OBSIDIAN_API_KEY": "your-api-key-here"
}
}
}
}
```
Or if you have it installed globally:
```json
{
"mcpServers": {
"obsidian": {
"command": "obsidianreadermcp",
"env": {
"OBSIDIAN_HOST": "localhost",
"OBSIDIAN_PORT": "27123",
"OBSIDIAN_API_KEY": "your-api-key-here"
}
}
}
}
```
### Extended Features
```python
from obsidianreadermcp.extensions import ObsidianExtensions
async with ObsidianClient(config) as client:
extensions = ObsidianExtensions(client)
# Create a template
template = extensions.create_template(
name="daily_note",
content="# {{date}}\n\n## Tasks\n- {{task}}\n\n## Notes\n{{notes}}",
description="Daily note template"
)
# Create note from template
note = await extensions.create_note_from_template(
template_name="daily_note",
path="daily/2024-01-15.md",
variables={
"date": "2024-01-15",
"task": "Review project status",
"notes": "All systems operational"
}
)
# Batch operations
batch_notes = [
{"path": "note1.md", "content": "Content 1", "tags": ["batch"]},
{"path": "note2.md", "content": "Content 2", "tags": ["batch"]},
]
result = await extensions.batch_create_notes(batch_notes)
# Analyze vault
stats = await extensions.generate_vault_stats()
print(f"Vault has {stats.total_notes} notes with {stats.total_words} words")
# Find orphaned notes
orphaned = await extensions.find_orphaned_notes()
print(f"Found {len(orphaned)} orphaned notes")
```
## MCP Tools
When running as an MCP server, the following tools are available:
### Core Operations
- `create_note`: Create a new note with content and metadata
- `get_note`: Retrieve a note by path
- `update_note`: Update an existing note
- `delete_note`: Delete a note
- `list_notes`: List all notes in vault or folder
- `search_notes`: Search notes by content
### Vault Management
- `get_vault_info`: Get vault information and statistics
- `get_tags`: List all tags used in the vault
- `get_notes_by_tag`: Find notes with specific tags
## API Reference
### ObsidianClient
The main client class for interacting with Obsidian.
#### Methods
- `async create_note(path: str, content: str = "", metadata: Optional[NoteMetadata] = None) -> Note`
- `async get_note(path: str) -> Note`
- `async update_note(path: str, content: Optional[str] = None, metadata: Optional[NoteMetadata] = None) -> Note`
- `async delete_note(path: str) -> bool`
- `async list_notes(folder: str = "") -> List[str]`
- `async search_notes(query: str, limit: int = 50, context_length: int = 100) -> List[SearchResult]`
- `async get_vault_info() -> VaultInfo`
- `async get_tags() -> List[str]`
- `async get_notes_by_tag(tag: str) -> List[Note]`
### ObsidianExtensions
Extended functionality for advanced vault management.
#### Methods
- `async batch_create_notes(notes_data: List[Dict], continue_on_error: bool = True) -> Dict`
- `async batch_update_notes(updates: List[Dict], continue_on_error: bool = True) -> Dict`
- `async batch_delete_notes(paths: List[str], continue_on_error: bool = True) -> Dict`
- `create_template(name: str, content: str, variables: Optional[List[str]] = None, description: Optional[str] = None) -> Template`
- `async create_note_from_template(template_name: str, path: str, variables: Optional[Dict[str, str]] = None, metadata: Optional[NoteMetadata] = None) -> Note`
- `async create_backup(backup_path: str, include_attachments: bool = True) -> BackupInfo`
- `async analyze_links() -> List[LinkInfo]`
- `async find_orphaned_notes() -> List[str]`
- `async find_broken_links() -> List[LinkInfo]`
- `async generate_vault_stats() -> VaultStats`
- `async search_by_date_range(start_date: Optional[datetime] = None, end_date: Optional[datetime] = None, date_field: str = "created") -> List[Note]`
- `async search_by_word_count(min_words: Optional[int] = None, max_words: Optional[int] = None) -> List[Note]`
## Testing
Run the test suite:
```bash
# With uv
uv run pytest
# With pip
pytest
# With coverage
pytest --cov=obsidianreadermcp --cov-report=html
```
## Examples
See the `examples/` directory for more detailed usage examples:
- `basic_usage.py`: Demonstrates core CRUD operations
- `advanced_features.py`: Shows extended functionality
- `mcp_integration.py`: MCP server integration examples
## Contributing
We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes
4. Add tests for new functionality
5. Run the test suite (`uv run pytest`)
6. Commit your changes (`git commit -m 'Add some amazing feature'`)
7. Push to the branch (`git push origin feature/amazing-feature`)
8. Open a Pull Request
## Issues and Support
- 🐛 **Bug Reports**: [GitHub Issues](https://github.com/QianJue-CN/ObsidianReaderMCP/issues)
- 💡 **Feature Requests**: [GitHub Issues](https://github.com/QianJue-CN/ObsidianReaderMCP/issues)
- 📖 **Documentation**: [API Documentation](docs/API.md)
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Acknowledgments
- [obsidian-local-rest-api](https://github.com/coddingtonbear/obsidian-local-rest-api) - The Obsidian plugin that makes this possible
- [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) - The protocol for AI assistant integration
- [Obsidian](https://obsidian.md/) - The knowledge management application
## Star History
[](https://star-history.com/#QianJue-CN/ObsidianReaderMCP&Date)
Raw data
{
"_id": null,
"home_page": null,
"name": "obsidianreadermcp",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": "QianJue <QianJue1003@qq.com>",
"keywords": "ai-assistant, knowledge-management, mcp, model-context-protocol, obsidian",
"author": null,
"author_email": "QianJue <QianJue1003@qq.com>",
"download_url": "https://files.pythonhosted.org/packages/a2/f8/26f8ac4cd00d4f3b122ab8b7377fdea5d375626b4de59407cf2724c5305d/obsidianreadermcp-0.1.5.tar.gz",
"platform": null,
"description": "# ObsidianReaderMCP\n\n[](https://github.com/QianJue-CN/ObsidianReaderMCP)\n[](https://www.python.org/)\n[](https://modelcontextprotocol.io/)\n[](LICENSE)\n\nA comprehensive Python MCP (Model Context Protocol) server for managing Obsidian vaults through the obsidian-local-rest-api plugin.\n\n## Features\n\n### Core CRUD Operations\n- **Create**: Create new notes with content, metadata, and tags\n- **Read**: Retrieve note content and metadata by path\n- **Update**: Modify existing notes (content, metadata, tags)\n- **Delete**: Remove notes from the vault\n\n### Extended Functionality\n- **Batch Operations**: Create, update, or delete multiple notes at once\n- **Template System**: Create and use note templates with variables\n- **Link Analysis**: Analyze relationships between notes\n- **Search & Filter**: Advanced search by content, tags, date range, word count\n- **Vault Statistics**: Generate comprehensive vault analytics\n- **Backup Management**: Create and manage vault backups\n\n### MCP Server Integration\n- Full MCP protocol support for AI assistant integration\n- Async/await support for high performance\n- Comprehensive error handling and logging\n- Rate limiting and connection management\n\n## Installation\n\n### Prerequisites\n1. **Obsidian** with the **obsidian-local-rest-api** plugin installed and configured\n2. **Python 3.10+**\n\n### Method 1: Using uvx (Recommended)\n\nThe easiest way to use ObsidianReaderMCP is with `uvx`, which allows you to run it without installation:\n\n```bash\n# Run directly without installation\nuvx obsidianreadermcp\n\n# Or install as a tool\nuv tool install obsidianreadermcp\nobsidianreadermcp\n```\n\n### Method 2: Using pip\n\n```bash\n# Install from PyPI\npip install obsidianreadermcp\n\n# Run the server\nobsidianreadermcp\n```\n\n### Method 3: Install from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/QianJue-CN/ObsidianReaderMCP.git\ncd ObsidianReaderMCP\n\n# Install dependencies\nuv sync\n\n# Or with pip\npip install -e .\n```\n\n## Configuration\n\n### Environment Variables\n\nCreate a `.env` file in the project root (copy from `.env.example`):\n\n```env\n# Obsidian API Configuration\nOBSIDIAN_HOST=localhost\nOBSIDIAN_PORT=27123\nOBSIDIAN_API_KEY=your_api_key_here\nOBSIDIAN_USE_HTTPS=false\nOBSIDIAN_TIMEOUT=30\nOBSIDIAN_MAX_RETRIES=3\nOBSIDIAN_RATE_LIMIT=10\n\n# MCP Server Configuration\nLOG_LEVEL=INFO\nENABLE_DEBUG=false\n```\n\n### Obsidian Setup\n\n1. Install the **obsidian-local-rest-api** plugin from the Community Plugins\n2. Enable the plugin in Obsidian settings\n3. Configure the plugin:\n - Set API port (default: 27123)\n - Generate an API key\n - Enable CORS if needed\n4. Start the local REST API server\n\n## Usage\n\n### As a Python Library\n\n```python\nimport asyncio\nfrom obsidianreadermcp import ObsidianClient\nfrom obsidianreadermcp.config import ObsidianConfig\nfrom obsidianreadermcp.models import NoteMetadata\n\nasync def main():\n # Create configuration\n config = ObsidianConfig() # Uses environment variables\n\n # Create and connect client\n async with ObsidianClient(config) as client:\n # Create a note\n metadata = NoteMetadata(\n tags=[\"example\", \"demo\"],\n frontmatter={\"title\": \"My Note\", \"author\": \"Me\"}\n )\n\n note = await client.create_note(\n path=\"my_note.md\",\n content=\"# My Note\\n\\nThis is my note content.\",\n metadata=metadata\n )\n\n # Read the note\n retrieved_note = await client.get_note(\"my_note.md\")\n print(f\"Note content: {retrieved_note.content}\")\n\n # Update the note\n await client.update_note(\n path=\"my_note.md\",\n content=\"# Updated Note\\n\\nThis content has been updated.\"\n )\n\n # Search notes\n results = await client.search_notes(\"updated\")\n print(f\"Found {len(results)} matching notes\")\n\n # Delete the note\n await client.delete_note(\"my_note.md\")\n\nasyncio.run(main())\n```\n\n### As an MCP Server\n\n```bash\n# Method 1: Using uvx (recommended)\nuvx obsidianreadermcp\n\n# Method 2: Using installed package\nobsidianreadermcp\n\n# Method 3: Using Python module\npython -m obsidianreadermcp.server\n\n# Method 4: Programmatically\npython -c \"\nimport asyncio\nfrom obsidianreadermcp.server import main\nasyncio.run(main())\n\"\n```\n\n### Claude Desktop Integration\n\nAdd to your Claude Desktop configuration file:\n\n```json\n{\n \"mcpServers\": {\n \"obsidian\": {\n \"command\": \"uvx\",\n \"args\": [\"obsidianreadermcp\"],\n \"env\": {\n \"OBSIDIAN_HOST\": \"localhost\",\n \"OBSIDIAN_PORT\": \"27123\",\n \"OBSIDIAN_API_KEY\": \"your-api-key-here\"\n }\n }\n }\n}\n```\n\nOr if you have it installed globally:\n\n```json\n{\n \"mcpServers\": {\n \"obsidian\": {\n \"command\": \"obsidianreadermcp\",\n \"env\": {\n \"OBSIDIAN_HOST\": \"localhost\",\n \"OBSIDIAN_PORT\": \"27123\",\n \"OBSIDIAN_API_KEY\": \"your-api-key-here\"\n }\n }\n }\n}\n```\n\n### Extended Features\n\n```python\nfrom obsidianreadermcp.extensions import ObsidianExtensions\n\nasync with ObsidianClient(config) as client:\n extensions = ObsidianExtensions(client)\n\n # Create a template\n template = extensions.create_template(\n name=\"daily_note\",\n content=\"# {{date}}\\n\\n## Tasks\\n- {{task}}\\n\\n## Notes\\n{{notes}}\",\n description=\"Daily note template\"\n )\n\n # Create note from template\n note = await extensions.create_note_from_template(\n template_name=\"daily_note\",\n path=\"daily/2024-01-15.md\",\n variables={\n \"date\": \"2024-01-15\",\n \"task\": \"Review project status\",\n \"notes\": \"All systems operational\"\n }\n )\n\n # Batch operations\n batch_notes = [\n {\"path\": \"note1.md\", \"content\": \"Content 1\", \"tags\": [\"batch\"]},\n {\"path\": \"note2.md\", \"content\": \"Content 2\", \"tags\": [\"batch\"]},\n ]\n result = await extensions.batch_create_notes(batch_notes)\n\n # Analyze vault\n stats = await extensions.generate_vault_stats()\n print(f\"Vault has {stats.total_notes} notes with {stats.total_words} words\")\n\n # Find orphaned notes\n orphaned = await extensions.find_orphaned_notes()\n print(f\"Found {len(orphaned)} orphaned notes\")\n```\n\n## MCP Tools\n\nWhen running as an MCP server, the following tools are available:\n\n### Core Operations\n- `create_note`: Create a new note with content and metadata\n- `get_note`: Retrieve a note by path\n- `update_note`: Update an existing note\n- `delete_note`: Delete a note\n- `list_notes`: List all notes in vault or folder\n- `search_notes`: Search notes by content\n\n### Vault Management\n- `get_vault_info`: Get vault information and statistics\n- `get_tags`: List all tags used in the vault\n- `get_notes_by_tag`: Find notes with specific tags\n\n## API Reference\n\n### ObsidianClient\n\nThe main client class for interacting with Obsidian.\n\n#### Methods\n\n- `async create_note(path: str, content: str = \"\", metadata: Optional[NoteMetadata] = None) -> Note`\n- `async get_note(path: str) -> Note`\n- `async update_note(path: str, content: Optional[str] = None, metadata: Optional[NoteMetadata] = None) -> Note`\n- `async delete_note(path: str) -> bool`\n- `async list_notes(folder: str = \"\") -> List[str]`\n- `async search_notes(query: str, limit: int = 50, context_length: int = 100) -> List[SearchResult]`\n- `async get_vault_info() -> VaultInfo`\n- `async get_tags() -> List[str]`\n- `async get_notes_by_tag(tag: str) -> List[Note]`\n\n### ObsidianExtensions\n\nExtended functionality for advanced vault management.\n\n#### Methods\n\n- `async batch_create_notes(notes_data: List[Dict], continue_on_error: bool = True) -> Dict`\n- `async batch_update_notes(updates: List[Dict], continue_on_error: bool = True) -> Dict`\n- `async batch_delete_notes(paths: List[str], continue_on_error: bool = True) -> Dict`\n- `create_template(name: str, content: str, variables: Optional[List[str]] = None, description: Optional[str] = None) -> Template`\n- `async create_note_from_template(template_name: str, path: str, variables: Optional[Dict[str, str]] = None, metadata: Optional[NoteMetadata] = None) -> Note`\n- `async create_backup(backup_path: str, include_attachments: bool = True) -> BackupInfo`\n- `async analyze_links() -> List[LinkInfo]`\n- `async find_orphaned_notes() -> List[str]`\n- `async find_broken_links() -> List[LinkInfo]`\n- `async generate_vault_stats() -> VaultStats`\n- `async search_by_date_range(start_date: Optional[datetime] = None, end_date: Optional[datetime] = None, date_field: str = \"created\") -> List[Note]`\n- `async search_by_word_count(min_words: Optional[int] = None, max_words: Optional[int] = None) -> List[Note]`\n\n## Testing\n\nRun the test suite:\n\n```bash\n# With uv\nuv run pytest\n\n# With pip\npytest\n\n# With coverage\npytest --cov=obsidianreadermcp --cov-report=html\n```\n\n## Examples\n\nSee the `examples/` directory for more detailed usage examples:\n\n- `basic_usage.py`: Demonstrates core CRUD operations\n- `advanced_features.py`: Shows extended functionality\n- `mcp_integration.py`: MCP server integration examples\n\n## Contributing\n\nWe welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes\n4. Add tests for new functionality\n5. Run the test suite (`uv run pytest`)\n6. Commit your changes (`git commit -m 'Add some amazing feature'`)\n7. Push to the branch (`git push origin feature/amazing-feature`)\n8. Open a Pull Request\n\n## Issues and Support\n\n- \ud83d\udc1b **Bug Reports**: [GitHub Issues](https://github.com/QianJue-CN/ObsidianReaderMCP/issues)\n- \ud83d\udca1 **Feature Requests**: [GitHub Issues](https://github.com/QianJue-CN/ObsidianReaderMCP/issues)\n- \ud83d\udcd6 **Documentation**: [API Documentation](docs/API.md)\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\n- [obsidian-local-rest-api](https://github.com/coddingtonbear/obsidian-local-rest-api) - The Obsidian plugin that makes this possible\n- [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) - The protocol for AI assistant integration\n- [Obsidian](https://obsidian.md/) - The knowledge management application\n\n## Star History\n\n[](https://star-history.com/#QianJue-CN/ObsidianReaderMCP&Date)",
"bugtrack_url": null,
"license": "MIT",
"summary": "A comprehensive Python MCP server for managing Obsidian vaults via obsidian-local-rest-api",
"version": "0.1.5",
"project_urls": {
"Changelog": "https://github.com/QianJue-CN/ObsidianReaderMCP/releases",
"Documentation": "https://github.com/QianJue-CN/ObsidianReaderMCP/blob/main/README.md",
"Homepage": "https://github.com/QianJue-CN/ObsidianReaderMCP",
"Issues": "https://github.com/QianJue-CN/ObsidianReaderMCP/issues",
"Repository": "https://github.com/QianJue-CN/ObsidianReaderMCP"
},
"split_keywords": [
"ai-assistant",
" knowledge-management",
" mcp",
" model-context-protocol",
" obsidian"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "483a354d2c3cb922adc49f0fcc74afd2a2584b0b617aa590dc76ad439743d1c3",
"md5": "55ca1479054c4bb32c6f5a1767008c5a",
"sha256": "59fac874720b5e589ab20940eb64cc18db05ec7c33e722acd2a594d52365ffd7"
},
"downloads": -1,
"filename": "obsidianreadermcp-0.1.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "55ca1479054c4bb32c6f5a1767008c5a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 24222,
"upload_time": "2025-08-27T20:22:21",
"upload_time_iso_8601": "2025-08-27T20:22:21.417443Z",
"url": "https://files.pythonhosted.org/packages/48/3a/354d2c3cb922adc49f0fcc74afd2a2584b0b617aa590dc76ad439743d1c3/obsidianreadermcp-0.1.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a2f826f8ac4cd00d4f3b122ab8b7377fdea5d375626b4de59407cf2724c5305d",
"md5": "ad4a1e640f313e29fbeaa715db01b305",
"sha256": "30f2b10923a6a3f401a425da3f905be0b08ca57d5a06b641b7cf724981896ce8"
},
"downloads": -1,
"filename": "obsidianreadermcp-0.1.5.tar.gz",
"has_sig": false,
"md5_digest": "ad4a1e640f313e29fbeaa715db01b305",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 107752,
"upload_time": "2025-08-27T20:22:23",
"upload_time_iso_8601": "2025-08-27T20:22:23.453767Z",
"url": "https://files.pythonhosted.org/packages/a2/f8/26f8ac4cd00d4f3b122ab8b7377fdea5d375626b4de59407cf2724c5305d/obsidianreadermcp-0.1.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-27 20:22:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "QianJue-CN",
"github_project": "ObsidianReaderMCP",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "obsidianreadermcp"
}