Multiple feature additions and improvements across the application: - NextGen Editor: drag handles, smart paste, block actions - Structured views: Kanban and table layouts for notes - Architectural Grid: new brainstorming/agent interface prototype - Flashcards: SM-2 revision algorithm with AI generation - MCP server: robustness improvements - Graph/PDF chat: fix click propagation and copy behavior - Various UI/UX enhancements and bug fixes Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Memento MCP Server
Model Context Protocol (MCP) server for integrating Memento note-taking app with N8N, Claude Desktop, Cursor, and other MCP clients.
Version 3.2.0 - Enhanced with error handling, observability, rate limiting, and input validation.
Features
- ✅ 22 Tools for notes, notebooks, labels, and reminders
- 🔒 API Key Authentication with secure storage
- 🚀 Performance Optimized with connection pooling and caching
- 📊 Observability with Prometheus metrics export
- 🛡️ Input Validation using Zod schemas
- ⏱️ Rate Limiting per-user and global
- 🚨 Structured Error Handling with detailed messages
- 📝 Audit Logging for compliance
Quick Start
cd mcp-server
npm install
stdio Mode (Claude Desktop, Cline)
npm start
# or
node index.js
Claude Desktop configuration:
{
"mcpServers": {
"memento": {
"command": "docker",
"args": ["exec", "-i", "memento-mcp", "node", "index.js"]
}
}
}
HTTP Streamable Mode (N8N, remote)
npm run start:http
# or
node index-sse.js
Authentication
When MCP_REQUIRE_AUTH=true (default in Docker), all requests require an x-api-key header.
Generate API keys from the Memento web UI: Settings > MCP.
# Example: health check with API key
curl -H "x-api-key: mcp_sk_xxx" http://localhost:3001/health
Available Tools (22)
Notes (13)
| Tool | Description |
|---|---|
create_note |
Create a new note |
get_notes |
List notes (filterable) |
get_note |
Get a specific note by ID |
update_note |
Update an existing note |
delete_note |
Delete a note permanently |
search_notes |
Search notes by keyword |
move_note |
Move a note to a notebook |
toggle_pin |
Pin/unpin a note |
toggle_archive |
Archive/unarchive a note |
append_to_note |
Append content to a note |
find_and_update_note |
Find and update a note |
batch_move_notes |
Move multiple notes at once |
batch_delete_notes |
Delete multiple notes at once |
Notebooks (6)
| Tool | Description |
|---|---|
create_notebook |
Create a notebook |
get_notebooks |
List all notebooks |
get_notebook |
Get notebook details |
update_notebook |
Update a notebook |
delete_notebook |
Delete a notebook |
reorder_notebooks |
Reorder notebooks |
get_notebook_hierarchy |
Get tree structure of notebooks |
Labels (4)
| Tool | Description |
|---|---|
create_label |
Create a label |
get_labels |
List labels |
update_label |
Update a label |
delete_label |
Delete a label |
Reminders (1)
| Tool | Description |
|---|---|
get_due_reminders |
Get due reminders |
Utilities (2)
| Tool | Description |
|---|---|
export_notes |
Export notes as JSON |
import_notes |
Import notes from JSON |
HTTP Endpoints
| Endpoint | Method | Description | Auth Required |
|---|---|---|---|
/ |
GET | Server info | No |
/health |
GET | Health check | No |
/metrics |
GET | Prometheus metrics | No* |
/sessions |
GET | Active sessions | Yes |
/mcp |
GET/POST | Main MCP endpoint | Yes |
/sse |
GET/POST | Legacy redirect to /mcp |
Yes |
*Metrics can be disabled with MCP_ENABLE_METRICS=false
Configuration
| Variable | Default | Description |
|---|---|---|
PORT |
3001 | Server port |
DATABASE_URL |
required | PostgreSQL connection string |
MCP_REQUIRE_AUTH |
false | Require x-api-key header |
MCP_API_KEY |
- | Static fallback API key |
MCP_LOG_LEVEL |
info | Log level (debug, info, warn, error, silent) |
MCP_REQUEST_TIMEOUT |
30000 | Request timeout in ms |
MCP_RATE_LIMIT |
100 | Requests per window per user |
MCP_RATE_LIMIT_WINDOW |
60000 | Rate limit window in ms |
MCP_MAX_SESSIONS |
500 | Maximum concurrent sessions |
MCP_SESSION_TTL |
3600000 | Session TTL in ms |
MCP_ENABLE_METRICS |
true | Enable metrics endpoint |
MCP_ENABLE_AUDIT_LOG |
true | Enable audit logging |
MCP_MAX_REQUEST_SIZE |
10485760 | Max request size in bytes (10MB) |
APP_BASE_URL |
http://localhost:3000 | Memento app URL |
USER_ID |
- | Optional user ID filter |
DB_CONNECTION_LIMIT |
10 | Prisma connection pool limit |
DB_POOL_TIMEOUT |
10 | Prisma pool timeout in seconds |
Error Handling
All errors follow a structured format:
{
"_error": true,
"code": -32602,
"httpCode": 400,
"message": "Invalid params",
"description": "Invalid method parameter(s)",
"detail": "Input validation failed",
"field": "content",
"category": "validation",
"timestamp": "2026-05-24T12:00:00.000Z"
}
Error Codes
| Code | HTTP | Name |
|---|---|---|
| -32700 | 400 | Parse error |
| -32600 | 400 | Invalid request |
| -32601 | 404 | Tool not found |
| -32602 | 400 | Invalid params |
| -32603 | 500 | Internal error |
| -32000 | 500 | Database error |
| 401 | 401 | Authentication failed |
| 403 | 403 | Forbidden |
| 429 | 429 | Rate limit exceeded |
| 408 | 408 | Request timeout |
| 409 | 409 | Conflict |
| 422 | 422 | Unprocessable entity |
| 503 | 503 | Service unavailable |
Metrics
Prometheus-compatible metrics are available at /metrics:
# HELP mcp_requests_total Total number of requests
mcp_requests_total 1234
# HELP mcp_latency_ms Request latency in milliseconds
mcp_latency_ms{quantile="0.5"} 45
mcp_latency_ms{quantile="0.95"} 120
mcp_latency_ms{quantile="0.99"} 250
# HELP mcp_errors_total Total number of errors
mcp_errors_total{category="validation"} 5
mcp_errors_total{category="database"} 2
# HELP mcp_auth_total Authentication attempts
mcp_auth_total{result="success"} 500
mcp_auth_total{result="failure"} 10
# HELP mcp_sessions_active Active sessions
mcp_sessions_active 15
N8N Integration
MCP Client Node Configuration
- Add a MCP Client node in N8N
- Select Streamable HTTP as transport
- Endpoint:
http://memento-mcp:3001/mcp(Docker) orhttp://YOUR_IP:3001/mcp - Add Header Auth:
x-api-key= your MCP API key
Example Workflow: Create a note from email
{
"tool": "create_note",
"arguments": {
"title": "{{ $json.subject }}",
"content": "{{ $json.body }}",
"labels": ["email", "inbox"],
"notebookId": "inbox-notebook-id"
}
}
Docker Deployment
services:
memento-mcp:
build: ./mcp-server
environment:
DATABASE_URL: ${DATABASE_URL}
MCP_REQUIRE_AUTH: "true"
MCP_LOG_LEVEL: "info"
ports:
- "3001:3001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
interval: 30s
timeout: 10s
retries: 3
Testing
# Run all tests
npm test
# Run performance tests
npm run test:perf
# Run connection tests
npm run test:connection
# Validate configuration
npm run validate
Security Considerations
- Always use authentication in production (
MCP_REQUIRE_AUTH=true) - Use HTTPS when exposing the server over the internet
- Set appropriate rate limits for your use case
- Monitor metrics for unusual activity
- Keep dependencies updated with
npm audit - Use environment variables for sensitive configuration
Troubleshooting
Database connection failed
FATAL: Database connection failed
- Verify
DATABASE_URLis correct and reachable - Check database credentials and permissions
- Ensure database is running and accessible
Rate limit exceeded
429 Too Many Requests
- Wait for the rate limit window to expire (check
Retry-Afterheader) - Increase
MCP_RATE_LIMITif needed - Use multiple API keys for different applications
Authentication failed
401 Unauthorized
- Verify API key is correct and active
- Check that
MCP_REQUIRE_AUTH=trueif using API keys - Ensure API key hasn't been revoked
Development
# Run with debug logging
MCP_LOG_LEVEL=debug npm run dev
# Check configuration
npm run validate
# Run tests
npm test
License
MIT