Contributing to mnemon-mcp
July 17, 2026 · View on GitHub
Philosophy
Air-gapped by default. No telemetry, no analytics, no crash reporting, no pings to any external service — ever. All data stays on the user's machine in ~/.mnemon-mcp/memory.db.
The single exception is the optional embedder (src/embedder.ts): when the user explicitly configures MNEMON_EMBEDDING_PROVIDER, it calls the provider they chose — their own OpenAI key, or a local Ollama. Nothing else may reach the network, and vector search must always degrade cleanly to FTS when no embedder is configured.
PRs adding telemetry, analytics, or any network call outside that opt-in path will be rejected without review.
Development Setup
git clone https://github.com/nikitacometa/mnemon-memory-mcp.git
cd mnemon-memory-mcp
npm install
npm run build
npm test
Requires Node.js 20+ and TypeScript 5.9. CI tests against Node 20 and 22.
Running Locally
npm run dev
Smoke test — verify the server responds to JSON-RPC over stdio:
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | node dist/index.js
Code Guidelines
- TypeScript strict mode — no
any, no unsafe casts, return types on all exported functions. - Never use
console.log()insrc/tools/orsrc/import/— stdout is the MCP JSON-RPC transport. Any stray output will corrupt the protocol. Useconsole.error()for debugging. - Run
npm run build,npm run lint, andnpm testbefore opening a PR. All three must pass — CI runs the same three on Node 20 and 22. - Keep dependencies minimal. Before adding a package, consider whether the standard library or an existing dep covers the use case.
- No
any— preferunknownwith a type guard, or a generic with a constraint.
PR Guidelines
- One feature per PR. Split unrelated changes into separate PRs.
- Include tests for all new functionality. The test runner is Vitest (
npm test). - Update
README.mdif adding new MCP tools or changing observable behavior. - Changes to ranking or retrieval must come with numbers. State what moved on a golden set and what regressed — see docs/EVALUATION.md for the methodology. "Feels better" is not a measurement.
Security Policy
- Never include memory content in error messages or log output. Tool errors are sanitized before reaching the client — filesystem paths must not leak (see
src/server.ts). - Sanitize all user-supplied strings before embedding them in error responses.
- No network calls outside the opt-in embedder path — not in tools, not in the import pipeline, not in tests.
- Report security issues privately via GitHub Security Advisories, not in public issues.
Architecture Notes
Start with docs/ARCHITECTURE.md for the module map and the write/read paths. The decisions behind them are recorded as ADRs — read the relevant one before proposing a change that reverses it:
better-sqlite3is synchronous on purpose (ADR-0003) — the stdio transport handles one request at a time, and sync access is what makes multi-statement invariants composable. Do not replace it with an async driver.- Embeddings are optional on purpose (ADR-0001, ADR-0002). FTS5 must remain a complete, working default.
- FTS5 search lives in
src/tools/memory-search.ts. The tokenizer isunicode61(Cyrillic + Latin). Stemming improvements belong in the pre-processing layer, not in the tokenizer config.