fix(mcp): stage remote ingest by default

Default ticket, multipart, and text-note ingest entry points to staging without launching a job. Propagate WIKI_ARCHIVE_SOURCES from project configuration into the managed service environment.\n\nValidated with the full 206-test suite.
This commit is contained in:
Codex
2026-07-16 15:56:54 +00:00
parent 2183404966
commit 6edf02c3eb
7 changed files with 106 additions and 20 deletions
+24 -1
View File
@@ -22,7 +22,7 @@ REPO_ROOT = Path(__file__).resolve().parent.parent
if str(REPO_ROOT) not in sys.path:
sys.path.insert(0, str(REPO_ROOT))
from obsidian_wiki.config import resolve_vault_path
from obsidian_wiki.config import load_config, resolve_vault_path
SERVICE_NAME = "obsidian-wiki-mcp.service"
@@ -37,6 +37,7 @@ PUBLIC_UPLOAD_URL_ENV = "OBSIDIAN_MCP_INGEST_PUBLIC_UPLOAD_URL"
ALLOW_SOURCE_FILES_ENV = "OBSIDIAN_MCP_ALLOW_SOURCE_FILES"
ALLOWED_HOSTS_ENV = "OBSIDIAN_MCP_ALLOWED_HOSTS"
ALLOWED_ORIGINS_ENV = "OBSIDIAN_MCP_ALLOWED_ORIGINS"
ARCHIVE_SOURCES_ENV = "WIKI_ARCHIVE_SOURCES"
DEFAULT_TOKEN_BYTES = 32
DEFAULT_UV_CACHE_DIR = "/tmp/uv-cache"
DEFAULT_OPENCODE_PATH = "opencode"
@@ -86,6 +87,11 @@ def parse_bool(value: str | None) -> bool:
return str(value or "").strip().lower() in {"1", "true", "yes", "on", "enabled"}
def project_archive_sources(project_root: Path, *, default: bool = False) -> bool:
value = load_config(project_root).get(ARCHIVE_SOURCES_ENV)
return default if value in (None, "") else parse_bool(value)
def parse_config_list(value: str | None) -> tuple[str, ...]:
return tuple(item.strip() for item in str(value or "").split(",") if item.strip())
@@ -155,6 +161,7 @@ class ServiceConfig:
public_upload_url: str = ""
enabled_tools: tuple[str, ...] = DEFAULT_ENABLED_TOOLS
allow_source_files: bool = False
archive_sources: bool = False
allowed_hosts: tuple[str, ...] = ()
allowed_origins: tuple[str, ...] = ()
ingest_job_timeout_seconds: int = DEFAULT_INGEST_JOB_TIMEOUT_SECONDS
@@ -295,6 +302,7 @@ def write_token_env_file(
enable_ingest: bool | None = None,
enable_query: bool | None = None,
allow_source_files: bool | None = None,
archive_sources: bool = False,
allowed_hosts: Sequence[str] | None = None,
allowed_origins: Sequence[str] | None = None,
ingest_job_timeout_seconds: int = DEFAULT_INGEST_JOB_TIMEOUT_SECONDS,
@@ -307,6 +315,7 @@ def write_token_env_file(
tools = update_ingest_tool(tools, enable_ingest)
tools = update_query_tool(tools, enable_query)
source_files_allowed = bool(allow_source_files)
archive_sources_enabled = bool(archive_sources)
models = model_settings or OpenCodeModelSettings()
normalized_public_base_url = normalize_public_base_url(public_base_url)
normalized_public_upload_url = normalize_public_upload_url(public_upload_url)
@@ -337,6 +346,7 @@ def write_token_env_file(
if normalized_public_upload_url:
env_file.write(f"{PUBLIC_UPLOAD_URL_ENV}={normalized_public_upload_url}\n")
env_file.write(f"{ALLOW_SOURCE_FILES_ENV}={1 if source_files_allowed else 0}\n")
env_file.write(f"{ARCHIVE_SOURCES_ENV}={1 if archive_sources_enabled else 0}\n")
env_file.write(f"{ALLOWED_HOSTS_ENV}={','.join(effective_allowed_hosts)}\n")
env_file.write(f"{ALLOWED_ORIGINS_ENV}={','.join(effective_allowed_origins)}\n")
env_file.write(f"OBSIDIAN_MCP_INGEST_JOB_TIMEOUT_SECONDS={max(1, int(ingest_job_timeout_seconds))}\n")
@@ -402,6 +412,7 @@ def saved_service_config(project_root: Path) -> ServiceConfig:
allow_source_files = parse_bool(values[ALLOW_SOURCE_FILES_ENV])
else:
allow_source_files = TOOL_FILE_ASSETS in enabled_tools
archive_sources = parse_bool(values.get(ARCHIVE_SOURCES_ENV))
allowed_hosts = parse_config_list(values.get(ALLOWED_HOSTS_ENV))
if not allowed_hosts:
allowed_hosts = derive_allowed_hosts(
@@ -425,6 +436,7 @@ def saved_service_config(project_root: Path) -> ServiceConfig:
public_upload_url=public_upload_url,
enabled_tools=enabled_tools,
allow_source_files=allow_source_files,
archive_sources=archive_sources,
allowed_hosts=allowed_hosts,
allowed_origins=allowed_origins,
ingest_job_timeout_seconds=max(
@@ -711,6 +723,7 @@ def write_service_config(env_path: Path, config: ServiceConfig) -> None:
public_upload_url=config.public_upload_url,
enabled_tools=config.enabled_tools,
allow_source_files=config.allow_source_files,
archive_sources=config.archive_sources,
allowed_hosts=config.allowed_hosts,
allowed_origins=config.allowed_origins,
ingest_job_timeout_seconds=config.ingest_job_timeout_seconds,
@@ -778,6 +791,10 @@ def new_token(
saved.allowed_origins if has_saved_config else (),
derive_allowed_origins(effective_public_base_url, effective_public_upload_url),
)
archive_sources = project_archive_sources(
paths.project_root,
default=saved.archive_sources,
)
config = replace(
saved,
token=generate_token(token_bytes),
@@ -786,6 +803,7 @@ def new_token(
path=effective_path,
public_base_url=effective_public_base_url,
public_upload_url=effective_public_upload_url,
archive_sources=archive_sources,
allowed_hosts=allowed_hosts,
allowed_origins=allowed_origins,
)
@@ -871,6 +889,10 @@ def start_service(
saved.allowed_origins if has_saved_config else (),
derive_allowed_origins(effective_public_base_url, effective_public_upload_url),
)
archive_sources = project_archive_sources(
paths.project_root,
default=saved.archive_sources,
)
config = replace(
saved,
host=effective_host,
@@ -883,6 +905,7 @@ def start_service(
allow_source_files=(
saved.allow_source_files if allow_source_files is None else allow_source_files
),
archive_sources=archive_sources,
allowed_hosts=allowed_hosts,
allowed_origins=allowed_origins,
)