Observation
The marketing site (website/src/components/CodeExample.astro:144,213) shows usage like:
npx @bitbonsai/mcpvault /path/to/vault --read-only true
But:
server.ts doesn't parse --read-only (the cliArgs handler only handles --version / --help)
CreateServerOptions has no readOnly field
- The dispatcher in
createServer.ts doesn't gate mutating tools
So an operator who sees the website and tries --read-only true gets the same behavior as without the flag — all 14 tools active, including mutating ones (write_note, patch_note, delete_note, etc.).
Verified at current main (commit dec984f).
Why this matters
A read-only mode is useful for:
- Letting an MCP client browse a sensitive vault without risk of accidental mutation
- CI / batch-analysis workflows that should not modify the vault
- Multi-client setups where some MCP clients should be read-only
Proposed approach
Implement the flag end-to-end:
server.ts parses --read-only (positional-tolerant — can appear anywhere in argv, including after a path-with-spaces)
CreateServerOptions accepts readOnly?: boolean (default false, so no behavior change for existing users)
- The dispatcher rejects calls to the 7 mutating tools (
write_note, patch_note, delete_note, move_note, move_file, update_frontmatter, manage_tags) with {isError: true} and a clear message when readOnly is true
Open questions for design
- Flag name:
--read-only matches the website wording — alternatively --readonly or --ro?
tools/list filtering: should mutating tools be filtered out of tools/list when read-only is active, or stay listed and rejected only on call (the current proposal)? The latter is closer to MCP convention and makes the read-only state discoverable, but the former is cleaner from a least-surprise standpoint.
Happy to draft a PR — let me know if you'd like to scope this differently first, or just go ahead with the proposal as-is.
Observation
The marketing site (
website/src/components/CodeExample.astro:144,213) shows usage like:npx @bitbonsai/mcpvault /path/to/vault --read-only trueBut:
server.tsdoesn't parse--read-only(the cliArgs handler only handles--version/--help)CreateServerOptionshas noreadOnlyfieldcreateServer.tsdoesn't gate mutating toolsSo an operator who sees the website and tries
--read-only truegets the same behavior as without the flag — all 14 tools active, including mutating ones (write_note,patch_note,delete_note, etc.).Verified at current
main(commitdec984f).Why this matters
A read-only mode is useful for:
Proposed approach
Implement the flag end-to-end:
server.tsparses--read-only(positional-tolerant — can appear anywhere in argv, including after a path-with-spaces)CreateServerOptionsacceptsreadOnly?: boolean(defaultfalse, so no behavior change for existing users)write_note,patch_note,delete_note,move_note,move_file,update_frontmatter,manage_tags) with{isError: true}and a clear message whenreadOnlyistrueOpen questions for design
--read-onlymatches the website wording — alternatively--readonlyor--ro?tools/listfiltering: should mutating tools be filtered out oftools/listwhen read-only is active, or stay listed and rejected only on call (the current proposal)? The latter is closer to MCP convention and makes the read-only state discoverable, but the former is cleaner from a least-surprise standpoint.Happy to draft a PR — let me know if you'd like to scope this differently first, or just go ahead with the proposal as-is.