Skip to content

fix(cli): install-mcp bootstraps the kb when .vouch/ is missing#516

Merged
plind-junior merged 2 commits into
testfrom
fix/install-mcp-auto-init
Jul 17, 2026
Merged

fix(cli): install-mcp bootstraps the kb when .vouch/ is missing#516
plind-junior merged 2 commits into
testfrom
fix/install-mcp-auto-init

Conversation

@plind-junior

@plind-junior plind-junior commented Jul 17, 2026

Copy link
Copy Markdown
Member

a fresh project's vouch install-mcp claude-code used to exit 0 with "0 failed", create no .vouch/, and print no warning — reproduced on the released pypi 1.3.0. every installed hook then no-oped silently forever (all wired || true), the mcp server exited 2, and the only diagnostic that exists (vouch status, which prints the vouch init hint) is itself muffled by || true in the sessionstart hook. a new user who reads "install vouch" as install-mcp ends up wired but permanently inert, with nothing ever telling them why.

install-mcp now probes discover_root(target) before writing adapter files. no kb discoverable means it runs the same bootstrap as vouch init — a shared _bootstrap_kb helper covers both so the paths cannot drift: same starter seed through the normal approved path, same index rebuild, same audit event — making install a one-command setup. --no-init opts out, and the warning it leaves behind names the remedy on stderr. a kb discovered above the target prints "Using existing KB at …" instead of being shadowed by a second one, and unknown hosts keep the clean adapter error without planting a kb as a side effect.

three hardenings came out of adversarial review of the diff. staging-dir hosts opt out of bootstrap via a new manifest key (kb_bootstrap: false): claude-desktop sets it, because its target is a paste-ready staging dir for user-global config, and a kb planted at whatever cwd the user ran the command from — often $HOME — would become the ambient capture target for every child project via upward discovery. the preflight passes respect_env=False to discover_root so a shell-exported VOUCH_KB_PATH neither suppresses a needed bootstrap nor triggers a bogus re-init of an existing kb (the override is surfaced as a stderr note instead). and a bootstrap failure exits as a clean click error naming --no-init, not a traceback.

docs follow the new story: the readme's step 1 is one command, the adapter readme gains the manual path's vouch init prerequisite (it previously never mentioned init at all), install.sh's nudges and docs/INSTALL_FOR_AGENTS.md steps 2/4 teach the one-command flow, and the readme's step-4 region drops its three duplicate copies of the review cli commands.

verified live from a fresh dir: one command yields a seeded kb plus 12 adapter files and vouch recall works immediately; re-runs are flat-noop (12 skipped, no re-init); --no-init warns and creates nothing; claude-desktop writes its 2 staging files and no kb. full gate green: pytest (with 11 new tests), mypy 99 files clean, ruff clean.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • vouch install-mcp <host> now auto-initializes and seeds a knowledge base when none is discoverable, and generates the related .mcp.json/hooks.
    • Added --init/--no-init (default: init enabled) to control bootstrapping.
    • Clearer output for discovered/created KB locations, including when VOUCH_KB_PATH is set.
  • Bug Fixes
    • Unknown hosts fail cleanly without creating any KB artifacts.
    • Staging-only hosts no longer auto-create KBs.
  • Documentation
    • Updated install guides, Claude Code adapter instructions, and review UI/browser UI walkthroughs (including expanded hook lifecycle coverage).
  • Tests
    • Added integration tests covering one-command bootstrap and --no-init/KB discovery edge cases.

a fresh project's `vouch install-mcp claude-code` used to exit 0 with
"0 failed", create no .vouch/, and print no warning. every installed
hook then no-oped silently forever (they are all wired `|| true`), the
mcp server exited 2, and nothing anywhere told the user to run
`vouch init` — the only diagnostic that exists (`vouch status`) is
itself muffled by `|| true` in the sessionstart hook. reproduced on the
released pypi 1.3.0.

install-mcp now probes discover_root(target) before writing adapter
files: no kb found means it runs the same bootstrap as `vouch init`
(shared `_bootstrap_kb` helper, so the two paths cannot drift — same
starter seed through the normal approved path, same index rebuild, same
audit event), making install a one-command setup. `--no-init` opts out
and a loud stderr warning then names the remedy. a kb discovered above
the target is reported ("Using existing KB at …") instead of being
shadowed by a second one. unknown hosts keep the clean adapter error
and never plant a kb as a side effect.

hardening from review: staging-dir hosts opt out via a new manifest key
`kb_bootstrap: false` — claude-desktop sets it, because its target is a
paste-ready staging dir and a kb planted at an arbitrary cwd (often
$HOME for a user-global host) would become the ambient capture target
for every child project via upward discovery. the preflight passes
`respect_env=False` to discover_root so a shell-exported VOUCH_KB_PATH
neither suppresses a needed bootstrap nor fakes a "no kb" state (it is
surfaced as a stderr note instead), and a bootstrap failure exits as a
clean click error naming --no-init rather than a traceback.

docs follow the new story: the readme's step 1 is one command, the
adapter readme states the manual path's `vouch init` prerequisite,
install.sh's nudges and docs/INSTALL_FOR_AGENTS.md steps 2/4 teach the
one-command flow, and the redundant review-ui blocks in the readme's
step 4 are collapsed into one option list.
@github-actions github-actions Bot added docs documentation, specs, examples, and repo guidance cli command line interface adapters agent host adapters and install manifests storage kb storage, migrations, schemas, and proposals tests tests and fixtures size: M 200-499 changed non-doc lines labels Jul 17, 2026
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f9aa6a76-9dd8-4308-82e0-a7f9e9086d76

📥 Commits

Reviewing files that changed from the base of the PR and between 41aaee5 and f68c478.

📒 Files selected for processing (3)
  • install.sh
  • src/vouch/cli.py
  • src/vouch/install_adapter.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/vouch/install_adapter.py
  • install.sh
  • src/vouch/cli.py

Walkthrough

vouch install-mcp now auto-initializes missing knowledge bases by default, supports --no-init, respects adapter bootstrap policies, handles environment overrides during discovery, and reports bootstrap failures cleanly. Initialization logic is shared with vouch init, with documentation, installer messaging, and integration tests updated.

Changes

MCP knowledge-base bootstrap

Layer / File(s) Summary
Shared KB bootstrap path
src/vouch/cli.py
KB creation, starter seeding, index rebuilding, and audit logging are consolidated in _bootstrap_kb, which is reused by vouch init and install-mcp.
Install-mcp discovery and adapter policy
src/vouch/cli.py, src/vouch/install_adapter.py, src/vouch/storage.py, adapters/claude-desktop/install.yaml
install-mcp adds --init/--no-init, bootstraps missing KBs, bypasses VOUCH_KB_PATH for target preflight, reports resolved KB locations, and honors manifest-level kb_bootstrap settings.
Validation and installation guidance
tests/test_install_adapter.py, README.md, docs/INSTALL_FOR_AGENTS.md, adapters/claude-code/README.md, install.sh, CHANGELOG.md
Tests cover bootstrap and discovery edge cases, while documentation and installer output describe the consolidated installation flow and initialization options.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant install_mcp
  participant AdapterManifest
  participant KBStorage
  User->>install_mcp: run install-mcp host
  install_mcp->>AdapterManifest: read kb_bootstrap policy
  install_mcp->>KBStorage: discover target KB without env override
  KBStorage-->>install_mcp: return existing KB or not found
  install_mcp->>KBStorage: bootstrap target KB when enabled
  KBStorage-->>install_mcp: return initialized store and seed results
  install_mcp-->>User: write adapter files and status output
Loading

Possibly related PRs

  • vouchdev/vouch#55: Introduces starter KB seeding used by the shared bootstrap path.
  • vouchdev/vouch#151: Covers the Claude Code adapter installation workflow and related CLI integration.
  • vouchdev/vouch#303: Updates the same install-mcp adapter wiring and hook integration.

Suggested labels: mcp

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.10% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: install-mcp now bootstraps a KB when .vouch/ is missing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/install-mcp-auto-init

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the ci: passing ci is green label Jul 17, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/vouch/cli.py (1)

193-196: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

lowercase the newly added source prose.

the new comments and docstrings should follow the repository’s lowercase-prose convention.

  • src/vouch/cli.py#L193-L196: lowercase the helper docstring.
  • src/vouch/cli.py#L3933-L3939: lowercase the command docstring prose.
  • src/vouch/cli.py#L3963-L3969: lowercase the preflight comment.
  • src/vouch/cli.py#L3983-L3984: lowercase the error-boundary comment.
  • src/vouch/install_adapter.py#L99-L101: lowercase the field comment.
  • src/vouch/install_adapter.py#L213-L217: lowercase the helper docstring.
  • src/vouch/storage.py#L147-L155: lowercase the discovery docstring.

As per path instructions, “Use lowercase prose in comments and review notes.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/vouch/cli.py` around lines 193 - 196, Lowercase all newly added prose
comments and docstrings at src/vouch/cli.py lines 193-196, 3933-3939, 3963-3969,
and 3983-3984; src/vouch/install_adapter.py lines 99-101 and 213-217; and
src/vouch/storage.py lines 147-155. Update the helper and command docstrings,
preflight and error-boundary comments, field comment, and discovery docstring
while preserving their wording and behavior.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@install.sh`:
- Line 313: Update the install-mcp help text in install.sh to qualify the claim
that wiring a host creates .vouch/, noting that this is host-dependent and does
not apply when kb_bootstrap is disabled, such as for claude-desktop.

In `@src/vouch/cli.py`:
- Around line 198-205: Update the initialization flow around seed_starter_kb and
the selected TEMPLATES seeder so all bootstrap source, claim, and page writes go
through proposals.approve() rather than direct store.put_source,
store.put_claim, or store.put_page calls. Preserve the existing seeding behavior
while ensuring vouch init and install-mcp cannot create durable KB artifacts
outside the review gate.

---

Nitpick comments:
In `@src/vouch/cli.py`:
- Around line 193-196: Lowercase all newly added prose comments and docstrings
at src/vouch/cli.py lines 193-196, 3933-3939, 3963-3969, and 3983-3984;
src/vouch/install_adapter.py lines 99-101 and 213-217; and src/vouch/storage.py
lines 147-155. Update the helper and command docstrings, preflight and
error-boundary comments, field comment, and discovery docstring while preserving
their wording and behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 37283973-9469-4b92-98d6-a14bba0d126d

📥 Commits

Reviewing files that changed from the base of the PR and between af8bd61 and 41aaee5.

📒 Files selected for processing (10)
  • CHANGELOG.md
  • README.md
  • adapters/claude-code/README.md
  • adapters/claude-desktop/install.yaml
  • docs/INSTALL_FOR_AGENTS.md
  • install.sh
  • src/vouch/cli.py
  • src/vouch/install_adapter.py
  • src/vouch/storage.py
  • tests/test_install_adapter.py

Comment thread install.sh Outdated
printf '\n'
info "${C_BOLD}Next:${C_RESET}"
info " ${C_BOLD}vouch init${C_RESET} # create a .vouch/ KB in your project"
info " ${C_BOLD}vouch install-mcp <host>${C_RESET} # wire a host (creates .vouch/ if missing)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

qualify the generic kb-creation promise.

claude-desktop deliberately sets kb_bootstrap: false, so not every <host> creates .vouch/.

proposed wording
-    info "  ${C_BOLD}vouch install-mcp <host>${C_RESET}  # wire a host (creates .vouch/ if missing)"
+    info "  ${C_BOLD}vouch install-mcp <host>${C_RESET}  # wire a host (project hosts create .vouch/ if missing)"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
info " ${C_BOLD}vouch install-mcp <host>${C_RESET} # wire a host (creates .vouch/ if missing)"
info " ${C_BOLD}vouch install-mcp <host>${C_RESET} # wire a host (project hosts create .vouch/ if missing)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@install.sh` at line 313, Update the install-mcp help text in install.sh to
qualify the claim that wiring a host creates .vouch/, noting that this is
host-dependent and does not apply when kb_bootstrap is disabled, such as for
claude-desktop.

Comment thread src/vouch/cli.py
Comment on lines +198 to +205
root.mkdir(parents=True, exist_ok=True)
store = KBStore.init(root)
seed = seed_starter_kb(store, approved_by=_whoami())
template_result: SeedResult | None = None
if template != DEFAULT_TEMPLATE:
template_result = TEMPLATES[template](store, approved_by=_whoami())
health.rebuild_index(store)
audit_mod.log_event(store.kb_dir, event="kb.init", actor=_whoami())

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
ast-grep outline src/vouch/onboarding.py \
  --items all \
  --match '_starter_claim|_starter_source|_starter_page|seed_starter_kb'

rg -n -C4 \
  '\b(proposals\.approve|approve|put_claim|put_page|put_source)\s*\(' \
  src/vouch/onboarding.py src/vouch/proposals.py

Repository: vouchdev/vouch

Length of output: 10032


🏁 Script executed:

#!/bin/bash
sed -n '1,220p' src/vouch/onboarding.py
printf '\n--- CLI ---\n'
sed -n '150,240p' src/vouch/cli.py

Repository: vouchdev/vouch

Length of output: 10914


bootstrap seeding bypasses the review gate seed_starter_kb and the template seeders call store.put_source, store.put_claim, and store.put_page directly, so vouch init and install-mcp can create durable kb artifacts outside proposals.approve(). route these writes through the approval path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/vouch/cli.py` around lines 198 - 205, Update the initialization flow
around seed_starter_kb and the selected TEMPLATES seeder so all bootstrap
source, claim, and page writes go through proposals.approve() rather than direct
store.put_source, store.put_claim, or store.put_page calls. Preserve the
existing seeding behavior while ensuring vouch init and install-mcp cannot
create durable KB artifacts outside the review gate.

Sources: Coding guidelines, Path instructions

coderabbit review on #516: the new source comments now follow the
lowercase-prose convention, and install.sh's next-steps line says
"project hosts create .vouch/ if missing" since staging-dir hosts
(claude-desktop) opt out via kb_bootstrap: false.
@plind-junior

Copy link
Copy Markdown
Member Author

@coderabbitai both quick wins are in f68c478 — the new comments are lowercase now and install.sh says "project hosts create .vouch/ if missing".

on the review-gate finding: seed_starter_kb calling store.put_* directly is pre-existing vouch init behavior that this pr reuses unchanged via the shared _bootstrap_kb helper — it adds no new write path. the starter seed is the deliberate, human-initiated bootstrap of the kb itself (the readme documents "Seeded starter claim" as init output), stamped approved_by with the invoking human; the review gate governs agent proposals against an existing kb, and every agent-facing surface (mcp, jsonl, cli propose commands) still lands in proposals.*. routing the seed through file-then-approve would be a behavior-preserving refactor of onboarding.py that belongs in its own pr if the owner wants it, not in this fix. skipping here per your own "fix only still-valid issues, skip the rest with a brief reason" guidance.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== commit f68c478 ==='
git show --stat --oneline f68c478
git show --format=fuller --find-renames --find-copies f68c478 -- install.sh src/vouch/cli.py src/vouch/onboarding.py

echo '=== relevant Python structure ==='
ast-grep outline src/vouch/cli.py src/vouch/onboarding.py src/vouch/storage.py --items all --type function

echo '=== bootstrap and seed call sites ==='
rg -n -C 4 '\b(_bootstrap_kb|seed_starter_kb|put_[A-Za-z_]+)\s*\(' src/vouch tests

echo '=== install manifest and staging-host configuration ==='
cat -n adapters/claude-desktop/install.yaml

Length of output: 152510


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== f68c478: exact quick-win diff ==='
git diff f68c478^ f68c478 -- install.sh adapters/claude-desktop/install.yaml

echo '=== current bootstrap implementation ==='
sed -n '180,235p' src/vouch/cli.py
sed -n '3950,4010p' src/vouch/cli.py

echo '=== current starter-seed implementation ==='
ast-grep outline src/vouch/onboarding.py --items all
rg -n -C 8 'def seed_starter_kb\b|store\.put_(source|claim|entity|page)\b' src/vouch/onboarding.py

echo '=== parent of this PR: init and seed history ==='
git show HEAD^:src/vouch/cli.py 2>/dev/null | rg -n -C 6 'def init\b|seed_starter_kb\b' || true
git log -S'seed_starter_kb' --oneline --all -- src/vouch/cli.py src/vouch/onboarding.py | head -20

Length of output: 15246


@plind-junior Confirmed. Commit f68c478 updates install.sh exactly as stated: “project hosts create .vouch/ if missing.”

I also verified the review-gate path. _bootstrap_kb is shared by vouch init and auto-init, passes the invoking identity as approved_by, and reuses the deterministic starter seeding introduced earlier in 125c054. This PR does not add an agent-facing direct-write path or weaken the proposal flow for an existing KB.

I’m withdrawing that finding as out of scope for this PR. A proposal-based refactor of the pre-existing onboarding seed flow would be separate work.

🐇🔍

@plind-junior
plind-junior enabled auto-merge July 17, 2026 04:52
@plind-junior
plind-junior disabled auto-merge July 17, 2026 05:54
@plind-junior
plind-junior merged commit ca5a6ce into test Jul 17, 2026
19 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

adapters agent host adapters and install manifests ci: passing ci is green cli command line interface docs documentation, specs, examples, and repo guidance size: M 200-499 changed non-doc lines storage kb storage, migrations, schemas, and proposals tests tests and fixtures

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant