Ajoute la base organisable par carnet (schéma, champs partagés, valeurs par note) avec activation guidée, tableau éditable, kanban et suppression de colonnes. Corrige le multiselect en vue tableau et enrichit sidebar, grille et i18n FR/EN. Inclut aussi les améliorations flashcards SM-2, l'audit consentement IA et la robustesse du serveur MCP (config, validation, rate-limit, métriques). Co-authored-by: Cursor <cursoragent@cursor.com>
329 lines
8.0 KiB
Markdown
329 lines
8.0 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
cd mcp-server
|
|
npm install
|
|
```
|
|
|
|
### stdio Mode (Claude Desktop, Cline)
|
|
|
|
```bash
|
|
npm start
|
|
# or
|
|
node index.js
|
|
```
|
|
|
|
Claude Desktop configuration:
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"memento": {
|
|
"command": "docker",
|
|
"args": ["exec", "-i", "memento-mcp", "node", "index.js"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### HTTP Streamable Mode (N8N, remote)
|
|
|
|
```bash
|
|
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**.
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```json
|
|
{
|
|
"_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
|
|
|
|
1. Add a **MCP Client** node in N8N
|
|
2. Select **Streamable HTTP** as transport
|
|
3. Endpoint: `http://memento-mcp:3001/mcp` (Docker) or `http://YOUR_IP:3001/mcp`
|
|
4. Add **Header Auth**: `x-api-key` = your MCP API key
|
|
|
|
### Example Workflow: Create a note from email
|
|
|
|
```json
|
|
{
|
|
"tool": "create_note",
|
|
"arguments": {
|
|
"title": "{{ $json.subject }}",
|
|
"content": "{{ $json.body }}",
|
|
"labels": ["email", "inbox"],
|
|
"notebookId": "inbox-notebook-id"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Docker Deployment
|
|
|
|
```yaml
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
1. **Always use authentication in production** (`MCP_REQUIRE_AUTH=true`)
|
|
2. **Use HTTPS** when exposing the server over the internet
|
|
3. **Set appropriate rate limits** for your use case
|
|
4. **Monitor metrics** for unusual activity
|
|
5. **Keep dependencies updated** with `npm audit`
|
|
6. **Use environment variables** for sensitive configuration
|
|
|
|
## Troubleshooting
|
|
|
|
### Database connection failed
|
|
|
|
```
|
|
FATAL: Database connection failed
|
|
```
|
|
|
|
- Verify `DATABASE_URL` is 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-After` header)
|
|
- Increase `MCP_RATE_LIMIT` if needed
|
|
- Use multiple API keys for different applications
|
|
|
|
### Authentication failed
|
|
|
|
```
|
|
401 Unauthorized
|
|
```
|
|
|
|
- Verify API key is correct and active
|
|
- Check that `MCP_REQUIRE_AUTH=true` if using API keys
|
|
- Ensure API key hasn't been revoked
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# Run with debug logging
|
|
MCP_LOG_LEVEL=debug npm run dev
|
|
|
|
# Check configuration
|
|
npm run validate
|
|
|
|
# Run tests
|
|
npm test
|
|
```
|
|
|
|
## License
|
|
|
|
MIT
|