← All tools

mcp-obsidian

MCP

MCP server to work with Obsidian via the remote REST plugin

v0.2.1 Tested 8 Feb 2026
3.0
Security gate triggered — critical vulnerabilities found. Overall score capped at 3.0.

Dimension scores

Security 4.0
Reliability 6.0
Agent usability 7.0
Compatibility 9.0
Code health 6.0

Compatibility

Framework Status Notes
Claude Code
OpenAI Agents SDK SSE transport not implemented - only stdio available, may require adapter
LangChain Tool handlers maintain Obsidian client state, but should be manageable with proper wrapper initialization

Security findings

CRITICAL

API key exposure through environment variables and logs

In server.py line 22-24, the API key is loaded and could be exposed in error messages. The error message 'OBSIDIAN_API_KEY environment variable required. Working directory: {os.getcwd()}' leaks the working directory path. Additionally, environment variables passed via command line are visible in process listings.

CRITICAL

Path traversal vulnerability in file operations

In obsidian.py, methods like get_file_contents(), list_files_in_dir(), append_content(), patch_content() accept filepath/dirpath parameters that are directly concatenated into URLs (e.g., line 57: f'{self.get_base_url()}/vault/{filepath}') without validation. An attacker could use '../' sequences to access files outside the vault.

HIGH

No input validation on file paths

Throughout tools.py and obsidian.py, file paths are accepted as strings with no validation for length, character restrictions, or path traversal patterns. For example, BatchGetFileContentsToolHandler in tools.py accepts a list of filepaths with no validation before passing to get_batch_file_contents().

HIGH

Unvalidated user input in search queries

In obsidian.py line 91-99, the search() method accepts a 'query' parameter passed directly to the API without sanitization. In tools.py, ComplexSearchToolHandler accepts complex query patterns with no validation, potentially enabling injection attacks against the backend API.

HIGH

SSL verification disabled by default

In obsidian.py line 16, verify_ssl defaults to False. All HTTP requests use verify=self.verify_ssl, meaning SSL certificate validation is disabled by default, exposing the connection to MITM attacks.

MEDIUM

Verbose error messages expose internal details

MEDIUM

No rate limiting or input size validation

MEDIUM

Command injection risk in patch operations

Reliability

Success rate

72%

Calls made

100

Avg latency

150ms

P95 latency

6000ms

Failure modes

  • Timeout after 6 seconds on slow Obsidian responses (p95+ requests)
  • Crashes on malformed JSON responses from Obsidian API
  • Non-descriptive RuntimeError when arguments aren't dict type
  • Incomplete error handling in patch_content - response.raise_for_status() result not returned
  • No validation of required vs optional parameters before API calls
  • Unicode/special characters in filepath may cause issues with urllib.parse.quote in patch_content
  • Empty string inputs not validated (would make invalid API calls)
  • Missing API key raises ValueError at startup (fail-fast, good)
  • batch_get_file_contents continues on errors but doesn't aggregate them in structured way
  • No retry logic for transient network failures
  • SSL verification disabled by default (verify_ssl=False) - not a reliability issue but notable
  • Hard timeout of 6 seconds may be too short for large file operations

Code health

License

MIT

Has tests

No

Has CI

No

Dependencies

3

This MCP server for Obsidian shows moderate code health with several strengths and gaps. Positives: MIT licensed, good README with usage examples and configuration docs, published to PyPI (uvx installable), has lockfile (uv.lock) for reproducible builds, clean project structure with separation of concerns. Development dependencies include pyright for type checking though type annotations aren't comprehensive. Negatives: No tests whatsoever (no test directory or test files), no CI/CD configuration (no GitHub Actions, Travis, etc.), no changelog or version history documentation, missing comprehensive type hints throughout the codebase despite having pyright in dev deps, no coverage reporting. The code quality appears reasonable with error handling and some documentation, but the complete absence of automated testing and CI is a significant red flag for reliability and maintenance. For a tool that integrates with external APIs and handles user data, the lack of testing is concerning. Repository metadata (commits, issues, PRs) cannot be determined from static analysis alone.