Files
Arnav 52c9f2bae2 feat(server): run a vault as a Dockerized HTTP + MCP memory service (#185)
Everything else here is local: skills on your machine, a vault on your disk.
This puts a vault behind a URL so an agent elsewhere can search and write it.

One container, one vault, one API key. The vault stays plain markdown on a
mounted volume, so Obsidian still opens it. The container does no LLM work --
search and packing delegate to the existing graphrag/context_pack modules, and
the caller's agent does the thinking.

- obsidian_wiki/server.py: four vault functions, five REST routes and four MCP
  tools as transport over them. Auth is one bearer key; the process refuses to
  start without WIKI_API_KEY unless WIKI_ALLOW_ANONYMOUS=1. Every path is
  resolved inside the vault or refused.
- Dockerfile, docker-compose.yml, .dockerignore, and a ghcr push on v* tags.
- New [server] extra; the core wheel stays dependency-free.
- docs/deployment.md, plus the WIKI_* vars in configuration.md and .env.example.

Requires mcp>=2.0: 2.0 renamed FastMCP to MCPServer, and session_manager only
exists once streamable_http_app() has been called -- a mounted sub-app's own
lifespan is ignored, so it is wired into the FastAPI lifespan by hand.
2026-08-21 14:37:37 -07:00

219 lines
9.5 KiB
Bash

# =============================================================================
# Obsidian Wiki — Environment Configuration
# Copy this to .env and set your vault path
# =============================================================================
# --- Required ---
# Absolute path to your Obsidian vault
OBSIDIAN_VAULT_PATH=
# --- Optional ---
# GitHub sync (any install path — pip/uv or setup.sh) is opt-in and configured
# with `obsidian-wiki sync-setup <repo-url>`, or the GitHub-sync prompt inside
# `obsidian-wiki setup` / `setup.sh`. There's no env var for it: the vault's own
# `git remote` is the source of truth, so it can't drift out of sync with this
# file. Run `obsidian-wiki sync` any time to commit and push pending changes.
# Comma-separated source directories to ingest documents from
# Leave empty to skip document ingestion
#
# Local git repo clones work here too (public or private, any host — GitHub,
# GitLab, self-hosted). Clone the repo locally first, then add its path here.
# Repo directories are auto-detected (a `.git` folder is present) and
# enumerated via `git ls-files`, so whatever the repo's own .gitignore
# excludes (node_modules, build output, venvs, secrets, ...) is skipped
# automatically instead of relying on a hardcoded skip-list.
OBSIDIAN_SOURCES_DIR=
# Wiki categories (directories created in the vault)
OBSIDIAN_CATEGORIES=concepts,entities,skills,references,synthesis,journal
# Max pages to create/update per ingest operation
OBSIDIAN_MAX_PAGES_PER_INGEST=15
# Projects to exclude from history ingest (claude/codex/hermes/… history-ingest skills).
# Comma-separated substrings matched against the project directory name. A project
# dir whose name contains any of these is skipped during scan, delta, and manifest steps.
# Example: WIKI_SKIP_PROJECTS=archived,scratch,sandbox
WIKI_SKIP_PROJECTS=
# Claude conversation history path (auto-discovered from ~/.claude if empty)
CLAUDE_HISTORY_PATH=
# Codex history path (defaults to ~/.codex if empty)
CODEX_HISTORY_PATH=
# Hermes history path (defaults to ~/.hermes if empty)
HERMES_HISTORY_PATH=
# OpenClaw history path (defaults to ~/.openclaw if empty)
OPENCLAW_HISTORY_PATH=
# GitHub Copilot CLI history path (defaults to ~/.copilot/session-state if empty)
COPILOT_HISTORY_PATH=
# Pi agent session history path (defaults to ~/.pi/agent/sessions if empty)
PI_HISTORY_PATH=
# Where the session-brain sidecar is written (defaults to ~/.claude/session-brain).
# This is a retrieval index over raw sessions — it never writes into the vault.
WIKI_SESSION_BRAIN_DIR=
# Lint schedule: daily | weekly | manual
LINT_SCHEDULE=weekly
# Internal link format for generated/updated pages
# wikilink (default) → [[concepts/foo]] or [[concepts/foo|display text]]
# markdown → [display text](relative/path.md)
# Only affects future writes — existing vault content is never migrated automatically.
OBSIDIAN_LINK_FORMAT=wikilink
# --- Staged writes (optional) ---
#
# When true, LLM-written pages land in <vault>/_staging/ for human review instead of
# going straight into the live wiki. Promote or reject them with /wiki-stage-commit.
# Staged pages are not visible in Obsidian's graph until promoted. wiki-status lists
# pending staged writes first when this is on.
WIKI_STAGED_WRITES=
# --- Trust ledger (optional) ---
#
# When 1, `obsidian-wiki lint` treats missing trust fields, ledger errors, stale
# reviews, and score mismatches as failures rather than warnings. Equivalent to
# passing --strict-trust on every lint run. See also: obsidian-wiki trust-check.
OBSIDIAN_TRUST_STRICT=
# --- Vault schema overrides (optional) ---
#
# Resolution precedence is CLI flags > these environment/config values >
# framework defaults. Lifecycle and relationship values extend the defaults;
# required trust fields replace default requiredness. Values are trimmed first.
# Empty or whitespace-only values fail closed. Do not use an
# empty assignment such as `OBSIDIAN_ALLOWED_LIFECYCLES=`; leave the variable
# commented out to use defaults. Empty comma-separated entries and trailing
# commas also fail closed.
# Additional lifecycle values. Framework defaults are:
# draft,reviewed,verified,disputed,archived
# OBSIDIAN_ALLOWED_LIFECYCLES=active,confirmed,stub
# Additional typed relationship values.
# OBSIDIAN_ALLOWED_RELATIONSHIP_TYPES=synthesizes,builds_on
# Effective required trust fields. Allowed values are base_confidence,
# lifecycle, lifecycle_changed, and updated. Lint defaults to
# base_confidence,lifecycle; standalone trust commands also require updated.
# OBSIDIAN_REQUIRED_TRUST_FIELDS=updated,lifecycle
# Owner authority locator emitted in schema reports.
# OBSIDIAN_SCHEMA_SOURCE=/absolute/path/to/vault/AGENTS.md
# --- QMD Semantic Search (optional) ---
#
# QMD indexes your wiki and sources for fast semantic search.
# Install: https://github.com/tobi/qmd
# After installing, point these at your QMD collection names (set when you ran `qmd collection add`).
#
# Without QMD: wiki-ingest and wiki-query fall back to Grep/Glob — fully functional, just slower.
# With QMD: semantic search replaces grep passes, enabling concept-level matches and cross-collection queries.
#
# IMPORTANT: the wiki collection and the papers collection must stay disjoint. wiki-query
# treats them as separate layers (compiled knowledge vs. raw staging) and cites them
# separately — if the wiki collection also indexes _raw/, superseded drafts become
# retrievable and citable as though they were compiled pages. OBSIDIAN_VAULT_PATH contains
# _raw/, so a plain `qmd collection add <vault>` over the whole vault merges the two layers.
# Exclude staging when you create the collection:
#
# qmd collection add /path/to/vault --name my-wiki
#
# then edit ~/.config/qmd/index.yml to scope it (qmd has no --ignore flag, so this is the
# only way to narrow an existing collection):
#
# collections:
# my-wiki:
# path: /path/to/vault
# pattern: "**/*.md"
# ignore:
# - "_raw/**"
# - "log.md"
#
# then run `qmd update`. Point QMD_PAPERS_COLLECTION at a separate collection rooted at
# OBSIDIAN_SOURCES_DIR or _raw/ if you want raw sources searchable too.
# Name of the QMD collection indexing your compiled wiki pages (OBSIDIAN_VAULT_PATH, excluding _raw/ — see above)
QMD_WIKI_COLLECTION=
# Name of the QMD collection indexing your raw source documents (OBSIDIAN_SOURCES_DIR or _raw/)
QMD_PAPERS_COLLECTION=
# QMD integration transport: mcp | cli
# mcp preserves the original behavior and uses an agent-configured QMD MCP server.
# cli runs the local qmd command directly; useful for agents without QMD MCP support.
QMD_TRANSPORT=mcp
# CLI search quality mode: quality | balanced | fast
# quality: qmd query with reranking (best relevance, slowest on CPU)
# balanced: qmd query --no-rerank (good hybrid results, faster)
# fast: qmd vsearch (semantic only) or qmd search when exact terms matter
QMD_CLI_SEARCH_MODE=quality
# Optional qmd binary override if qmd is not on PATH.
QMD_CLI=qmd
# --- Vault Skill Factory (optional) ---
#
# vault-skill-factory turns mature curated pages into portable Agent Skills.
# Generated skills land in a REVIEW directory — never auto-installed, never written to .skills/.
#
# Where generated skills are written (default: <OBSIDIAN_VAULT_PATH>/_generated-skills — a
# vault-level excluded dir like _raw/_staging, NOT the skills/ knowledge category).
SKILL_FACTORY_OUTPUT_DIR=
# Which lifecycle states count as "mature" enough to harvest (pages with tier: core also qualify).
SKILL_FACTORY_MATURITY=reviewed,verified
# --- PageIndex: structure-aware long-PDF preprocessing (optional) ---
#
# For long PDFs (books, reports), build a table-of-contents tree (section titles +
# summaries + page ranges) before ingest, so the agent reads only relevant sections.
# Install: clone https://github.com/VectifyAI/PageIndex, create a venv (uv), and put an
# LLM key in <repo>/.env (LiteLLM; e.g. deepseek/deepseek-v4-flash or openai/glm-4.6).
# See wiki-ingest/references/pageindex.md. Without it: wiki-ingest reads PDFs directly.
#
# Path to the PageIndex repo (enables the wiki-ingest long-PDF branch).
PAGEINDEX_REPO=
# LiteLLM model id PageIndex uses (default openai/glm-4.6).
PAGEINDEX_MODEL=openai/glm-4.6
# Only preprocess PDFs with at least this many pages.
PAGEINDEX_MIN_PAGES=30
# Optional cache dir for *_structure.json (default: <PAGEINDEX_REPO>/results).
PAGEINDEX_WORKSPACE=
# --- Code understanding (optional) ---
#
# How wiki-update understands project structure before distilling knowledge.
# auto: use CodeGraph when available, else the built-in ast-extract + rg (default)
# builtin: always use ast-extract + rg (dependency-free)
# codegraph: explicitly require CodeGraph; warn/error if unavailable
CODE_UNDERSTANDING_BACKEND=auto
# Optional path to the codegraph binary if it isn't on PATH
# (e.g. CODE_UNDERSTANDING_CODEGRAPH_BIN=/path/to/codegraph)
CODE_UNDERSTANDING_CODEGRAPH_BIN=
# --- Raw Staging Directory (optional) ---
#
# A directory inside OBSIDIAN_VAULT_PATH for unprocessed draft pages.
# Drop rough notes, clipboard pastes, or quick captures here.
# wiki-ingest will promote them to proper wiki pages when you run it.
# Promoted files are moved into _raw/_archived/ after processing, not deleted.
OBSIDIAN_RAW_DIR=_raw
# --- Memory server (optional) ---
#
# Only used by the Dockerized HTTP + MCP server (`python -m obsidian_wiki.server`),
# which puts this vault behind a URL so remote agents can use it as memory.
# Ignored entirely when you use the skills locally. See docs/deployment.md.
# The server refuses to start without a key unless WIKI_ALLOW_ANONYMOUS=1.
WIKI_API_KEY=
WIKI_PORT=8080