The Memory Journal MCP server implements comprehensive security measures to protect your personal journal data.
The server uses the native better-sqlite3 driver with sqlite-vec for vector operations, running directly against the filesystem.
- β
PRAGMA foreign_keys = ON β enforces referential integrity and
ON DELETE CASCADE - β
Parameterized queries β all user input bound via
?placeholders - β
WAL journal mode β high concurrency with non-blocking reads (
PRAGMA journal_mode = WAL) - β
Synchronous Normal β optimized durability and performance (
PRAGMA synchronous = NORMAL)
- β
Data directory:
700(full access for owner only) in Docker - β
Non-root user (
appuser:appgroup) owns data directory
- Journal entries: 50,000 characters maximum
- Tags: 100 characters maximum
- Entry types: 50 characters maximum
- Significance types: 50 characters maximum
- HTTP request body: 1MB maximum (prevents memory exhaustion)
Tags are stored as-is via parameterized queries. Special characters in tags are safely handled by the database layer and do not pose injection risks.
- β Parameterized queries used throughout
- β Input validation via Zod schemas before database operations
- β Warning system for potentially dangerous content patterns
- β
FTS5 / LIKE pattern sanitization (escapes
%,_,\wildcards and handles FTS5 syntax errors gracefully) - β Date format whitelisting (prevents strftime injection)
- β
Backup filenames validated - rejects
/,\,..in paths - β Typed security errors with consistent error codes
When running in HTTP mode (--transport http), the following security measures apply:
- β
Configurable multiple origins via comma-separated
--cors-originflag orMCP_CORS_ORIGINenvironment variable - β Exact-match verification (no wildcard matching for custom domains)
β οΈ Default:*(allow all origins) for backward compatibility- π Recommended: Set specific origins for production deployments
# Restrict CORS to specific origins
memory-journal-mcp --transport http --cors-origin "http://localhost:3000,https://my-app.com"
# Or via environment variable
export MCP_CORS_ORIGIN="http://localhost:3000,https://my-app.com"- β
DNS Rebinding Protection β
hostHeaderValidationmiddleware prevents CVE-2025-66414 - β
Strict-Transport-Security (HSTS) β max-age=31536000; includeSubDomains (opt-in via
--enable-hsts) - β X-Content-Type-Options: nosniff β prevents MIME sniffing
- β X-Frame-Options: DENY β prevents clickjacking
- β Content-Security-Policy: default-src 'none'; frame-ancestors 'none' β prevents XSS and framing
- β Cache-Control: no-store, no-cache, must-revalidate β prevents caching of sensitive journal data
- β Referrer-Policy: no-referrer β prevents referrer leakage
β οΈ CORS wildcard warning β server logs a warning when CORS origin is*
- β
Built-in Rate Limiting β 100 requests/minute per IP (sliding window with
Retry-Afterheader) - β HTTP Timeouts β Request timeout (120s), keep-alive timeout (65s), headers timeout (66s)
- β UUID-based session IDs (cryptographically random)
- β 30-minute session timeout - idle sessions automatically expired
- β 5-minute sweep interval - periodic cleanup of abandoned sessions
- β
Explicit session termination via
DELETE /mcp
- β 1MB body limit on JSON requests (prevents memory exhaustion DoS)
- β Environment variables only - tokens never stored in config files
- β Error message scrubbing - Authorization headers stripped from error logs
- β Optional integration - server works fully offline without GitHub token
- β
Minimal scopes - only requires
repo,project,read:org
# Required for GitHub features
GITHUB_TOKEN=ghp_... # GitHub personal access token
# Optional
GITHUB_ORG_TOKEN=ghp_... # For organization projects
PROJECT_REGISTRY='{"my-repo":{"path":"/path/to/repo","project_number":1}}' # Multi-project routing
DEFAULT_PROJECT_NUMBER=1 # Default project for issue assignment
MCP_CORS_ORIGIN=* # CORS origin (default: *)
MCP_HOST=localhost # Server bind host
AUTO_REBUILD_INDEX=true # Rebuild vector index on startup- β
Dedicated user:
appuser(UID 1001) with minimal privileges - β
Restricted group:
appgroup(GID 1001) - β
Restricted data directory:
700permissions
- β
Minimal base image:
node:24-alpine - β Multi-stage build: Build dependencies not in production image
- β Process isolation from host system
- β No shell access needed for production
# Secure volume mounting
docker run -v ./data:/app/data:rw,noexec,nosuid,nodev memory-journal-mcp# Apply resource limits
docker run --memory=1g --cpus=1 memory-journal-mcp- β No external services: All processing happens locally
- β No telemetry: No data sent to external servers
- β Full data ownership: SQLite database stays on your machine
- β
Semantic search: ML model runs locally via
@huggingface/transformers
- β Git context: Only reads local repository information
- β No sensitive data: Doesn't access private keys or credentials
- β Optional GitHub integration: Only if explicitly configured with token
- β CodeQL analysis - automated static analysis on push/PR
- β Trivy container scanning - Docker image vulnerability detection
- β TruffleHog + Gitleaks - secret scanning on push/PR
- β npm audit - dependency vulnerability checking
- β Dependabot - automated dependency update PRs
- Set a CORS origin when exposing the HTTP transport on a network
- Keep Node.js updated: Use Node.js 24+ (LTS)
- Secure host system: Ensure your host machine is secure
- Regular backups: Use the
backup_journaltool or back up your.dbfile - Limit network access: Don't expose the HTTP transport to untrusted networks
- Use resource limits: Apply Docker
--memoryand--cpuslimits
- Regular updates: Keep Node.js and npm dependencies updated
- Security scanning: Regularly scan Docker images for vulnerabilities
- Code review: All database operations use parameterized queries
- Input validation: All tool inputs validated via Zod schemas
- Foreign key enforcement (
PRAGMA foreign_keys = ON) - Input validation and length limits (Zod schemas)
- Parameterized SQL queries
- SQL injection detection heuristics (defense-in-depth)
- Path traversal protection (
assertNoPathTraversal) - FTS5 / LIKE pattern sanitization (
sanitizeSearchQuery) - Date format whitelisting (
validateDateFormatPattern) - HTTP body size limit (1MB)
- Configurable CORS multi-origin with exact-match enforcement
- HTTP timeouts and built-in rate limiter (100 req/min)
- DNS rebinding protection and strict HSTS
- Security headers (CSP, X-Content-Type-Options, X-Frame-Options, Cache-Control, Referrer-Policy, Permissions-Policy)
- Session timeout (30 minutes)
- Non-root Docker user
- Multi-stage Docker build
- Local-first data architecture
- GitHub token error scrubbing
- CI/CD security pipeline (CodeQL, Trivy, secret scanning)
- Comprehensive security documentation
If you discover a security vulnerability, please:
- Do not open a public GitHub issue
- Contact the maintainers privately
- Provide detailed information about the vulnerability
- Allow time for the issue to be addressed before public disclosure
- Container updates: Rebuild Docker images when base images are updated
- Dependency updates: Keep npm packages updated via
npm auditand Dependabot - Database maintenance: Run
ANALYZEandPRAGMA optimizeregularly - Security patches: Apply host system security updates
The Memory Journal MCP server is designed with security-first principles to protect your personal journal data while maintaining excellent performance and usability.