-
Notifications
You must be signed in to change notification settings - Fork 361
Description
Disclaimer: I am not a developer but I investigated this issue for my personal use case with the help of Claude Sonnet 4. Hope this helps.
Deployed using the dockerized version https://github.com/docker/mcp-obsidian
Summary
The MCP Obsidian server fails to connect to Obsidian instances running on non-default ports (anything other than 27124) due to how environment variables are evaluated in default parameter values. When multiple Obsidian vaults are configured on different ports, only the vault on port 27124 works correctly, while others fail with authorization errors.
Root Cause
The issue is in src/mcp_obsidian/obsidian.py in the Obsidian class constructor:
python
def init(
self,
api_key: str,
protocol: str = os.getenv('OBSIDIAN_PROTOCOL', 'https').lower(),
host: str = str(os.getenv('OBSIDIAN_HOST', '127.0.0.1')),
port: int = int(os.getenv('OBSIDIAN_PORT', '27124')), # Problem here
verify_ssl: bool = False,
):
The os.getenv() calls in default parameters are evaluated when the module is imported, not when __init__() is called. This means if OBSIDIAN_PORT is not set during module import, it defaults to 27124 and never changes, even if the environment variable is set correctly at runtime.
Additionally, src/mcp_obsidian/tools.py doesn't explicitly pass the port parameter when instantiating the Obsidian class:
python
api = obsidian.Obsidian(api_key=api_key, host=obsidian_host) # port not passed
This relies on the default parameter behavior, which is broken.
Solution
Option 1 (Recommended): Read environment variables inside __init__() instead of as default parameters:
python
def init(
self,
api_key: str,
protocol: str = None,
host: str = None,
port: int = None,
verify_ssl: bool = False,
):
self.api_key = api_key
protocol = protocol or os.getenv('OBSIDIAN_PROTOCOL', 'https')
self.protocol = 'http' if protocol.lower() == 'http' else 'https'
self.host = host or os.getenv('OBSIDIAN_HOST', '127.0.0.1')
self.port = port if port is not None else int(os.getenv('OBSIDIAN_PORT', '27124'))
self.verify_ssl = verify_ssl
self.timeout = (3, 6)
Option 2: Explicitly pass the port in tools.py:
python
# At the top of tools.py with other environment variables obsidian_port = int(os.getenv("OBSIDIAN_PORT", "27124"))
# In each tool handler's run_tool method api = obsidian.Obsidian(api_key=api_key, host=obsidian_host, port=obsidian_port)
Reproduction
- Set up two Obsidian vaults with Local REST API plugin on different ports (e.g., 27124 and 27126)
- Configure two MCP servers with different
OBSIDIAN_PORTvalues - The server with port 27124 works, but the one with 27126 fails with "Error 40101: Authorization required"
- Despite
OBSIDIAN_PORT=27126being correctly set in the container environment, the code uses port 27124
Impact
This bug prevents users from running multiple MCP Obsidian servers to access different vaults simultaneously, which is a common use case for users managing multiple knowledge bases.