obsidianreadermcp


Nameobsidianreadermcp JSON
Version 0.1.5 PyPI version JSON
download
home_pageNone
SummaryA comprehensive Python MCP server for managing Obsidian vaults via obsidian-local-rest-api
upload_time2025-08-27 20:22:23
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT
keywords ai-assistant knowledge-management mcp model-context-protocol obsidian
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ObsidianReaderMCP

[![GitHub](https://img.shields.io/badge/GitHub-QianJue--CN%2FObsidianReaderMCP-blue?logo=github)](https://github.com/QianJue-CN/ObsidianReaderMCP)
[![Python](https://img.shields.io/badge/Python-3.10%2B-blue?logo=python)](https://www.python.org/)
[![MCP](https://img.shields.io/badge/MCP-Compatible-green)](https://modelcontextprotocol.io/)
[![License](https://img.shields.io/badge/License-MIT-green)](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

[![Star History Chart](https://api.star-history.com/svg?repos=QianJue-CN/ObsidianReaderMCP&type=Date)](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[![GitHub](https://img.shields.io/badge/GitHub-QianJue--CN%2FObsidianReaderMCP-blue?logo=github)](https://github.com/QianJue-CN/ObsidianReaderMCP)\n[![Python](https://img.shields.io/badge/Python-3.10%2B-blue?logo=python)](https://www.python.org/)\n[![MCP](https://img.shields.io/badge/MCP-Compatible-green)](https://modelcontextprotocol.io/)\n[![License](https://img.shields.io/badge/License-MIT-green)](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[![Star History Chart](https://api.star-history.com/svg?repos=QianJue-CN/ObsidianReaderMCP&type=Date)](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"
}
        
Elapsed time: 1.19341s