Configuration¶
The config module loads configuration from environment variables and provides a typed dataclass for all settings.
Quick Start¶
to_vault_settings maps a loaded configuration onto a VaultSettings, and to_vault_instances resolves the constructed collaborators (embedding provider, summarizer, git strategy). Together they feed Vault construction:
import os
from markdown_vault_mcp.config import ProjectConfig
from markdown_vault_mcp.config_sections._assembly import (
to_vault_instances,
to_vault_settings,
)
from markdown_vault_mcp.vault import Vault
os.environ["MARKDOWN_VAULT_MCP_SOURCE_DIR"] = "/path/to/vault"
config = ProjectConfig.from_env()
instances = to_vault_instances(config)
settings = to_vault_settings(config, instances=instances)
vault = Vault(
source_dir=config.source_dir,
settings=settings,
embedding_provider=instances.embedding_provider,
summarizer=instances.summarizer,
git_strategy=instances.git_strategy,
on_write=instances.on_write,
)
Migrating from 4.x¶
to_vault_kwargs has been removed from both markdown_vault_mcp.config and markdown_vault_mcp.config_sections._assembly. Replace Vault(**to_vault_kwargs(config)) with the construction shown above. Resolve instances once and pass it to to_vault_settings so the provider is loaded once and its context limit determines the chunk size.
For overrides formerly applied to the keyword dictionary, use dataclasses.replace on the settings before constructing the vault:
from dataclasses import replace
from pathlib import Path
settings = replace(settings, index_path=Path("/path/to/other-index.db"))
Keep collaborator overrides on the corresponding Vault keyword arguments.
API Reference¶
ProjectConfig(server=ServerConfig(), server_name=_default_server_name(), source_dir=Path('/data/vault'), read_only=False, write_protect_existing=True, disable_apps_ui=False, index_path=None, state_path=None, embeddings_path=None, indexed_fields=None, required_fields=None, exclude=None, title_field='title', searchable_fields=None, templates_folder='_templates', prompts_folder=None, conventions_file='_conventions.md', okf_mode='auto', okf_write=False, okf_verify='elicit', attachment_extensions=None, max_attachment_size_mb=1.0, max_note_read_bytes=262144, default_search_mode='auto', chunks_per_file=2, snippet_words=200, length_downweight_alpha=0.25, max_chunk_words=400, max_chunk_chars=None, chunk_overlap_words=40, folder_weights=None, fts_weights=None, embedding_provider=None, ollama_host='http://localhost:11434', openai_api_key=None, voyage_api_key=None, voyage_model='voyage-4', ollama_model='nomic-embed-text', ollama_cpu_only=False, openai_base_url='https://api.openai.com/v1', openai_embedding_model='text-embedding-3-small', fastembed_model='BAAI/bge-small-en-v1.5', fastembed_cache_dir=None, embed_context=False, embed_timeout_s=30.0, embedding_batch_size=4, git_repo_url=None, git_token=None, git_username='x-access-token', git_pull_interval_s=600, git_push_delay_s=30.0, git_commit_name='markdown-vault-mcp', git_commit_email='noreply@markdown-vault-mcp', git_commit_name_claim=None, git_commit_email_claim=None, git_lfs=True, file_watcher=True, file_watcher_debounce_s=2.0, file_watcher_root_floor=True, github_webhook_secret=None, gitlab_webhook_signing_token=None, gitlab_webhook_secret_token=None, summarize_provider=None, summarize_openai_api_key=None, summarize_openai_base_url=None, summarize_openai_model='gpt-5-mini', summarize_max_tokens=8192, summarize_max_notes=50, summarize_max_input_chars=200000, summarize_timeout=120.0, transfer=TransferConfig(), jobs=JobsConfig())
dataclass
¶
Domain config for Markdown Vault MCP. Compose — don't inherit.
git
property
¶
The git section assembled from the flat git_* fields.
A property rather than a composed field so the config-surface
generator documents the flat fields' metadata. Construction runs
GitConfig.__post_init__ validation.
indexing
property
¶
The indexing section assembled from the flat index/frontmatter fields.
embeddings
property
¶
The embeddings section assembled from the flat embedding fields.
search
property
¶
The search section assembled from the flat ranking/chunking fields.
summarize
property
¶
The summarize section assembled from the flat summarize_* fields.
sync
property
¶
The sync section assembled from the flat watcher/webhook fields.
content
property
¶
The content section assembled from the flat attachment/folder fields.
A relative prompts_folder is resolved against source_dir here,
so direct construction and from_env behave identically.
__post_init__()
¶
Validate composed domain fields. Raise ValueError when invalid.
Runs on EVERY construction path — from_env and a direct
ProjectConfig(field=...) alike. That is what makes this the right
home for a field invariant: env_float / env_int bounds check
only the env-sourced value, never the default, so a direct
construction slips past them. They also cannot express an exclusive
bound (their minimum / maximum are inclusive, so "must be > 0"
lets 0 through) or a cross-field rule (A requires B,
mutually-exclusive pairs). All three belong here.
The dataclass is frozen=True: read fields freely, but plain
assignment raises. To normalise rather than merely check, use
object.__setattr__(self, "name", value).
from_env()
classmethod
¶
Load :class:ProjectConfig from MARKDOWN_VAULT_MCP_* env vars.