Evernote

by brentmid

Not rated
GitHub

About

Connects your Evernote account to an LLM, enabling natural language search and queries over your notes.

Details

Author
brentmid
Categories
Productivity, Other, AI, Search

Setup

Install Evernote in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/brentmid/evernote-mcp-server

Follow the installation instructions in the repository README, then restart your MCP client.

A local MCP server that connects Claude Desktop (or any MCP-compatible LLM) with your Evernote account, allowing contextual queries and searches over your notes using natural language.

Enable local, secure AI-assisted access to your Evernote notes. For example:

"Summarize all my Evernotes regarding my Sea Pro boat."

This project allows the LLM to send MCP calls likecreateSearch,getNote, andgetNoteContent, which are translated into API calls to Evernote. The response is returned to the LLM in a structured format.

v2.0.0: Production-Ready Docker Deployment

- 🐳One-command setup:docker-compose upfor instant deployment
- πŸ”Persistent authentication: OAuth tokens survive container restarts
- πŸ›‘οΈSecurity-first: Red Hat Hummingbird minimal base images with zero CVEs
- ⚑Optimized builds: Multi-stage Docker builds for minimal production footprint
- πŸ”§Auto-configuration: SSL certificates and environment setup handled automatically

- 🌐Remote MCP Server: HTTP/JSON-RPC 2.0 support for containerized Claude Desktop integration
- πŸ”„Dual Integration Modes: Choose between local stdin/stdout or remote HTTPS integration
- πŸ“‹MCP Specification Compliance: Updated tool definitions and method names to match official MCP spec
- 🎯Intelligent Responses: Human-readable summaries instead of raw JSON dumps
- 🌍Cross-Platform Compatibility: Overcomes Docker stdin/stdout limitations for Windows/Linux

v2.1.0: Container Stability and Error Resilience

- πŸ›‘οΈGlobal Error Handling: Added uncaught exception and unhandled rejection handlers to prevent process crashes
- πŸ”„Container Stability: Eliminated 2-3 minute restart cycles in containerized deployments (Podman/Docker)
- πŸ“ŠEnhanced Error Logging: Improved production error visibility with timestamps and PID tracking
- 🎯Graceful Degradation: Server continues running even with authentication or API failures
- 🚫Removed Process Exits: Replaced fatal process.exit() calls with graceful error handling
- ⚑Production Tested: Container stability verified in production mode without DEV_MODE debug logging

- 🧹Minimal Production Logging: Cleaned up verbose debugging code for production deployments
- 🎯Essential Stability Components: Maintained critical signal handlers and global error handling
- πŸ“DEV_MODE Conditional Logging: Optional debug output only appears when DEV_MODE=true
- ⚑Event Loop Stability: Minimal keepalive prevents Node.js from becoming inactive in containers
- βœ…Verified Container Stability: 10+ minute stability testing confirmed no restart cycles in production mode

- Supportsread-only Evernote access(searching, reading, and listing notes)
- OAuth 1.0a authenticationwith browser auto-launch for secure authorization
- Automatic token persistencein .env file for seamless re-authentication
- πŸ†• v1.1.0: Automatic token expiration detection- Server checks token validity on startup
- πŸ†• v1.1.0: Interactive re-authentication prompts- User-friendly prompts when tokens expire
- πŸ†• v1.1.0: Enhanced error handling- Specific EDAMUserException error code reporting
- πŸ†• v1.1.0: Proactive token management- Prevents API failures from expired credentials
- πŸ†• v1.1.1: Automatic .env token persistence- Tokens saved to .env file automatically (replaced macOS Keychain for cross-platform compatibility)
- πŸ†• v1.1.2: Security hardening- Zero CVEs with npm overrides for vulnerable dependencies
- πŸ†• v2.0.0: Production-ready Docker deployment- Full containerization with Chainguard secure images
- πŸ†• v2.0.1: Enhanced MCP protocol compliance- Remote HTTP/JSON-RPC server support and intelligent response formatting
- πŸ†• v2.1.0: Container stability improvements- Eliminated restart cycles with global error handling and graceful degradation
- πŸ†• v2.1.1: Production logging optimization- Clean minimal logging for production with DEV_MODE conditional debug output
- HTTPS-only serverwith self-signed certificates for local development
- Designed to work withClaude Desktop MCP integrations, with future-proofing for other LLMs (e.g., ChatGPT Desktop)
- Configurable debug loggingviaDEV_MODEenvironment variable with automatic token redaction for security
- Easy to extend later for note creation, updates, or deletion

- Node.js + Express with HTTPS
- Evernote API (OAuth 1.0a + REST)
- Environment variable token storage with dotenv
- MCP protocol compliance
- Docker containerization with Chainguard secure base images

Evernote uses OAuth 1.0a (not OAuth 2.0) for API authentication:

- First-time setup: Browser-based OAuth 1.0a flow with automatic token exchange
- Token storage: Access tokens automatically saved to .env file for persistence
- Automatic reuse: Stored tokens are automatically loaded and used for subsequent API calls
- Production environment: Uses Evernote production API (sandbox decommissioned)
- Cross-platform compatibility: Works on macOS, Linux, and Windows with file-based token storage

This project uses npmoverridesto ensure all dependencies use secure versions, eliminating nested vulnerable packages:

{ "overrides": { "ws": "^8.18.3" } }

Why overrides are needed: Dependencies likethriftmay bundle their own vulnerable versions (e.g.,ws@5.2.4) in nestednode_modules. Standard npm updates only affect top-level dependencies, leaving vulnerable nested packages. Theoverridesfield forces ALL instances of a package to use the secure version.

- βœ… Zero CVEs in Docker vulnerability scans
- βœ… Chainguard secure base images (distroless, minimal attack surface)
- βœ… HTTPS-only with certificate validation
- βœ… Read-only Evernote API access
- βœ… No third-party data transmission except to Evernote
- βœ… Automatic token redaction in debug logs

git clone https://github.com/brentmid/evernote-mcp-server.git cd evernote-mcp-server cp .env.example .env # Edit .env with your Evernote API credentials docker-compose up --build

- βœ… Instant setup with zero local dependencies
- βœ… Production-ready Chainguard secure base images
- βœ… Automatic SSL certificate generation
- βœ… OAuth tokens persist across container restarts
- βœ… Zero CVE security scanning

- Node.js 18+
- OpenSSL for SSL certificate generation
- Evernote developer account and API credentials
- Docker Desktop(for containerized deployment)
- GitHub SSH key configured via 1Password (for development)
- Visual Studio Code with GitHub Copilot and Copilot Chat extensions (for development)

git clone git@github.com:brentmid/evernote-mcp-server.git cd evernote-mcp-server npm install

- Register your applicationatEvernote Developers
- Create a new appand note your Consumer Key and Consumer Secret
- Set callback URLtohttps://localhost:3443/oauth/callback

# Add to your shell profile (.zshrc, .bashrc, etc.) export EVERNOTE_CONSUMER_KEY="your-consumer-key-here" export EVERNOTE_CONSUMER_SECRET="your-consumer-secret-here" # Optional: Enable detailed debug logging for development export DEV_MODE=true # Reload your shell or run: source ~/.zshrc

The server runs over HTTPS and requires SSL certificates for local development:

# Create certificate directory mkdir cert # Generate self-signed certificate (valid for 365 days) openssl req -x509 -newkey rsa:4096 -keyout cert/localhost.key -out cert/localhost.crt -days 365 -nodes -subj "/C=US/ST=Local/L=Local/O=Local/OU=Local/CN=localhost"

The server will start onhttps://localhost:3443. Your browser will show a security warning for the self-signed certificate - this is normal for local development.

The server now automatically checks for expired authentication tokens on startup:

πŸš€ Starting Evernote MCP Server... πŸ” Token status: Token valid until 8/21/2025, 1:20:00 AM βœ… Using existing valid authentication tokens βœ… Authentication ready 🌐 Evernote MCP Server listening on HTTPS port 3443
πŸš€ Starting Evernote MCP Server... πŸ” Token status: Token expired on 6/16/2025, 9:55:49 PM ⚠️ Your Evernote authentication tokens have expired. Would you like to re-authenticate now? (y/N): y 🧹 Re-authenticating with Evernote... πŸš€ Starting Evernote OAuth flow...

If you chooseN(no), the server will exit gracefully with instructions to restart and chooseywhen ready to re-authenticate.
- Generate SSL certificates(see setup instructions above)
- Set environment variableswith your Evernote API credentials
- Start the server:npx node index.js
- Complete OAuth authentication:

- Server automatically opens your browser to Evernote's authorization page
- Accept the self-signed certificate warning in your browser
- Log in to your Evernote account and authorize the application
- You'll be redirected back to the server with a success message
- Access token is automatically stored in .env file for future use

The server implements Evernote's OAuth 1.0a flow:
- Request Token: Server generates temporary request token
- User Authorization: Browser opens Evernote authorization URL
- Callback: User authorizes app, Evernote redirects to callback URL
- Access Token: Server exchanges request token for permanent access token
- Storage: Access token stored securely in .env file

Note: The server uses Evernote's production environment (sandbox has been decommissioned by Evernote).

The easiest way to run the Evernote MCP server is using Docker with the provided Chainguard-based secure container image:

# Clone the repository git clone https://github.com/brentmid/evernote-mcp-server.git cd evernote-mcp-server # Copy environment template cp .env.example .env # Edit .env with your Evernote API credentials vim .env # Build and run the container docker-compose up --build

The server will be available athttps://localhost:3443.

The Docker setup usesChainguard's secure Node.js base image(cgr.dev/chainguard/node:latest) which provides:

- Zero vulnerabilities- Minimal attack surface with only essential packages
- Signed container images- All images signed with Sigstore for supply chain security
- SBOM included- Software Bill of Materials generated at build time
- Non-root execution- Containers run as non-root user for enhanced security
- Minimal size- Only 145MB compared to 1.12GB for standard Node.js images

The Docker setup includes several key files:

- Builder stage: Usescgr.dev/chainguard/node:latest-devwith git and openssl for setup
- Production stage: Uses minimalcgr.dev/chainguard/node:latestfor runtime
- GitHub integration: Clones latest code directly from your GitHub repository
- SSL certificates: Automatically generates self-signed certificates for HTTPS
- Security: Runs as non-root user with minimal dependencies

- Environment variables: Loads from.envfile or environment
- Port mapping: Exposes HTTPS port 3443 to host
- Health checks: Built-in container health monitoring
- Restart policy: Automatically restarts on failure
- Build arguments: Configurable GitHub repository URL

- Node modules, logs, and development files
- Git repository data and documentation
- Test files and configurations
- SSL certificates (generated in container)

EVERNOTE_CONSUMER_KEY=your_consumer_key_here EVERNOTE_CONSUMER_SECRET=your_consumer_secret_here DEV_MODE=false
# Build and run with compose docker-compose up --build # Run in background docker-compose up -d --build # View logs docker-compose logs -f # Stop and remove docker-compose down
# Build image docker build \ --build-arg GITHUB_REPO_URL=https://github.com/yourusername/evernote-mcp-server.git \ -t evernote-mcp-server . # Run container docker run -d \ --name evernote-mcp \ -p 3443:3443 \ -e EVERNOTE_CONSUMER_KEY=your_key \ -e EVERNOTE_CONSUMER_SECRET=your_secret \ evernote-mcp-server # View logs docker logs -f evernote-mcp

The repository includesevernote-mcp-daily-rebuild.sh, a shell script designed for daily automated rebuilds to keep your Chainguard base images up to date:

# Set up daily rebuild (example cron job) 0 2   * /path/to/your/evernote-mcp-server/evernote-mcp-daily-rebuild.sh >> /tmp/evernote-mcp-rebuild.log 2>&1

- Pulls the latestcgr.dev/chainguard/node:latestbase image
- Rebuilds the container with--no-cacheto ensure fresh dependencies
- Restarts the service with zero downtime using Docker Compose

- Ensures you always have the latest security patches from Chainguard
- Maintains zero-CVE status with automated base image updates
- No manual intervention required for security updates

The container accepts these environment variables:

- EVERNOTE_CONSUMER_KEY- Your Evernote API consumer key (required)
- EVERNOTE_CONSUMER_SECRET- Your Evernote API consumer secret (required)
- DEV_MODE- Enable debug logging (optional, default: false)
- NODE_ENV- Node.js environment (set to production in container)

For persistent token storage across container restarts:

volumes: - ./tokens:/app/tokens # If implementing file-based token storage

The container includes built-in health monitoring:

- Endpoint: Internal HTTPS health check on port 3443
- Interval: Every 30 seconds
- Timeout: 10 seconds
- Retries: 3 attempts before marking unhealthy
- Start period: 40 seconds for initial startup

Build fails with "git not found":

- Ensure your GitHub repository is public or configure authentication
- Check theGITHUB_REPO_URLbuild argument in docker-compose.yml

- Certificates are auto-generated in the container
- Your browser will show security warnings for self-signed certificates (normal)
- Accept the certificate warning to proceed

- Check container logs:docker-compose logs evernote-mcp-server
- Verify environment variables are set correctly
- Ensure Evernote API credentials are valid

Container restart loops (every 2-3 minutes):

- βœ…RESOLVED(August 5, 2025): Container stability issue fixed by optimized health check implementation
- βœ…Root cause identified: Node.js health check command was creating accumulating timeout processes
- βœ…Solution: Simplified Node.js health check with proper timeout handling eliminates process accumulation
- Details: See CLAUDE.md for complete investigation timeline and technical resolution analysis
- Diagnostic Tools: Use provided debugging scripts for similar issues (see Debugging section below)
- Status: Container running stable with proper health checks, no restart cycles detected

- Complete OAuth flow may require running the server locally first
- Container inherits tokens from host if using volume mounts
- Consider runningnode index.jslocally first, then containerize

# View container logs docker-compose logs -f evernote-mcp-server # Enable debug mode echo "DEV_MODE=true" >> .env docker-compose up --build # Execute commands in running container docker-compose exec evernote-mcp-server sh # Check container health docker-compose ps

The Docker setup implements several security best practices:

- Minimal base image: Chainguard's distroless Node.js image
- Non-root execution: Container runs asnodeuser (non-root)
- HTTPS only: All communication over secure HTTPS
- Environment isolation: Secrets passed via environment variables
- Network security: Only necessary port (3443) exposed
- Supply chain security: Signed base images with SBOMs

Docker deployment offers several performance benefits:

- Consistent environment: Identical runtime across different machines
- Resource limits: Can set CPU/memory limits via docker-compose
- Caching: Docker layer caching speeds up rebuilds
- Scaling: Easy to run multiple instances behind a load balancer

The server supports two integration methods with Claude Desktop:

Method 1: Local stdin/stdout Integration (Original)

After completing the server setup above, configure Claude Desktop for direct process execution.

Step 1: Locate Claude Desktop Configuration

~/Library/Application Support/Claude/claude_desktop_config.json

Choose one of these configurations based on your setup:

Option A: Direct Node.js execution (local development)

{ "mcpServers": { "evernote": { "command": "node", "args": ["/path/to/your/evernote-mcp-server/mcp-server.js"], "env": { "EVERNOTE_CONSUMER_KEY": "your-actual-consumer-key", "EVERNOTE_CONSUMER_SECRET": "your-actual-consumer-secret" } } } }

Option B: Docker container execution (recommended for production)

{ "mcpServers": { "evernote": { "command": "docker", "args": [ "exec", "-i", "--tty=false", "evernote-mcp-server-evernote-mcp-server-1", "node", "mcp-server.js" ] } } }
No reviews yet β€” be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.