Files
obsidian-wiki/obsidian_wiki/config.py
T
nac 76a480a0b7 feat(mcp): serve safe source file assets
Add a stdio MCP server for searching and reading safe engineering source files from the wiki file asset index.

The implementation uses registry-backed ACL checks, engineering-file whitelisting, asset:// resource URIs, read-only SQLite access, CLI entrypoints, optional MCP packaging, and unittest coverage for search, metadata, resource reads, blocked sources, bot ACLs, and size limits.

Validation: python3 -m unittest discover -v; python3 -m py_compile obsidian_wiki/config.py obsidian_wiki/file_assets.py obsidian_wiki/mcp_assets.py obsidian_wiki/mcp_server.py obsidian_wiki/cli.py tests/test_mcp_assets.py; real BJD vault search/read smoke tests.
2026-07-05 11:10:41 +00:00

59 lines
1.8 KiB
Python

"""Configuration resolution shared by CLI and MCP entrypoints."""
from __future__ import annotations
from pathlib import Path
from obsidian_wiki.file_assets import clean_config_value
GLOBAL_CONFIG = Path.home() / ".obsidian-wiki" / "config"
def parse_config_file(path: Path) -> dict[str, str]:
values: dict[str, str] = {}
if not path.is_file():
return values
for raw in path.read_text(encoding="utf-8", errors="ignore").splitlines():
line = raw.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
values[key.strip()] = clean_config_value(value)
return values
def find_config(start: str | Path | None = None) -> Path | None:
"""Resolve config using the llm-wiki protocol."""
current = Path(start or Path.cwd()).expanduser().resolve()
if current.is_file():
current = current.parent
home = Path.home().resolve()
while True:
candidate = current / ".env"
if candidate.is_file() and parse_config_file(candidate).get("OBSIDIAN_VAULT_PATH"):
return candidate
if current == home or current.parent == current:
break
current = current.parent
if GLOBAL_CONFIG.is_file():
return GLOBAL_CONFIG
return None
def load_config(start: str | Path | None = None) -> dict[str, str]:
path = find_config(start)
return parse_config_file(path) if path else {}
def resolve_vault_path(cli_vault: str | None = None, *, start: str | Path | None = None) -> str:
if cli_vault:
return str(Path(clean_config_value(cli_vault)).expanduser())
config = load_config(start)
return config.get("OBSIDIAN_VAULT_PATH", "")
def config_value(key: str, default: str = "", *, start: str | Path | None = None) -> str:
return load_config(start).get(key, default)