# Evernote Mcp Server

> Evernote MCP server - allows LLMs that support MCP (like Claude Desktop) to query your notes in Evernote

- **Type:** MCP server
- **Install:** `agentstack add mcp-brentmid-evernote-mcp-server`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [brentmid](https://agentstack.voostack.com/s/brentmid)
- **Installs:** 0
- **Category:** [Security](https://agentstack.voostack.com/c/security)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [brentmid](https://github.com/brentmid)
- **Source:** https://github.com/brentmid/evernote-mcp-server

## Install

```sh
agentstack add mcp-brentmid-evernote-mcp-server
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Evernote MCP Server

[](https://opensource.org/licenses/MIT)

[](https://github.com/brentmid/evernote-mcp-server/commits/main)
[](https://github.com/brentmid/evernote-mcp-server/issues)
[](https://github.com/brentmid/evernote-mcp-server/stargazers)

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.

## 🎯 Project Goal

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 like `createSearch`, `getNote`, and `getNoteContent`, which are translated into API calls to Evernote. The response is returned to the LLM in a structured format.

## 🚀 What's New in v2.0+

**v2.0.0: Production-Ready Docker Deployment**
- 🐳 **One-command setup**: `docker-compose up` for 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

**v2.0.1: Enhanced MCP Protocol Support**
- 🌐 **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

**v2.1.1: Production Logging Optimization**
- 🧹 **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

## ✅ Features

- Supports **read-only Evernote access** (searching, reading, and listing notes)
- **OAuth 1.0a authentication** with browser auto-launch for secure authorization
- **Automatic token persistence** in .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 server** with self-signed certificates for local development
- Designed to work with **Claude Desktop MCP integrations**, with future-proofing for other LLMs (e.g., ChatGPT Desktop)
- **Configurable debug logging** via `DEV_MODE` environment variable with automatic token redaction for security
- Easy to extend later for note creation, updates, or deletion

## 🧰 Tech Stack

- 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

## 🗝️ Authentication

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

## 🔒 Security

### Vulnerability Management

This project uses npm `overrides` to ensure all dependencies use secure versions, eliminating nested vulnerable packages:

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

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

**Security features**:
- ✅ 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

## 💻 Setup

### 🐳 Docker Deployment (Recommended)

**Quick Start**:
```bash
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
```

**What you get**:
- ✅ 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

### 🛠️ Local Development

**Requirements**:
- 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)

### Clone & Setup

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

#### Get Evernote API Credentials

1. **Register your application** at [Evernote Developers](https://dev.evernote.com/)
2. **Create a new app** and note your Consumer Key and Consumer Secret
3. **Set callback URL** to `https://localhost:3443/oauth/callback`

#### Configure Environment Variables

Set your Evernote API credentials:

```bash
# 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
```

#### Generate SSL Certificates

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

```bash
# 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"
```

#### Start the Server

```bash
npx node index.js
```

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

### ⏰ Token Expiration Handling (v1.1.0+)

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

**For Valid Tokens:**
```
🚀 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
```

**For Expired Tokens:**
```
🚀 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 choose `N` (no), the server will exit gracefully with instructions to restart and choose `y` when ready to re-authenticate.

### First Run & OAuth Flow

1. **Generate SSL certificates** (see setup instructions above)
2. **Set environment variables** with your Evernote API credentials
3. **Start the server**: `npx node index.js`
4. **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

#### OAuth Flow Details

The server implements Evernote's OAuth 1.0a flow:

1. **Request Token**: Server generates temporary request token
2. **User Authorization**: Browser opens Evernote authorization URL
3. **Callback**: User authorizes app, Evernote redirects to callback URL
4. **Access Token**: Server exchanges request token for permanent access token
5. **Storage**: Access token stored securely in .env file

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

## 🐳 Docker Deployment

### Quick Start with Docker

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

```bash
# 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 at `https://localhost:3443`.

### Docker Architecture

The Docker setup uses **Chainguard'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

### Docker Files Overview

The Docker setup includes several key files:

#### `Dockerfile`
Multi-stage build process:
- **Builder stage**: Uses `cgr.dev/chainguard/node:latest-dev` with git and openssl for setup
- **Production stage**: Uses minimal `cgr.dev/chainguard/node:latest` for 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

#### `docker-compose.yml`
Orchestration configuration:
- **Environment variables**: Loads from `.env` file 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

#### `.dockerignore`
Optimizes build context by excluding:
- Node modules, logs, and development files
- Git repository data and documentation
- Test files and configurations
- SSL certificates (generated in container)

#### `.env.example`
Template for environment variables:
```env
EVERNOTE_CONSUMER_KEY=your_consumer_key_here
EVERNOTE_CONSUMER_SECRET=your_consumer_secret_here
DEV_MODE=false
```

### Docker Build Options

#### Option 1: Docker Compose (Recommended)
```bash
# 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
```

#### Option 2: Direct Docker Build
```bash
# 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
```

### Automated Container Updates

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

```bash
# 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
```

**What the script does:**
- Pulls the latest `cgr.dev/chainguard/node:latest` base image
- Rebuilds the container with `--no-cache` to ensure fresh dependencies
- Restarts the service with zero downtime using Docker Compose

**Security benefits:**
- 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

### Docker Configuration

#### Environment Variables
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)

#### Volume Mounts (Optional)
For persistent token storage across container restarts:
```yaml
volumes:
  - ./tokens:/app/tokens  # If implementing file-based token storage
```

#### Health Checks
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

### Docker Troubleshooting

#### Common Issues

**Build fails with "git not found":**
- Ensure your GitHub repository is public or configure authentication
- Check the `GITHUB_REPO_URL` build argument in docker-compose.yml

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

**Container health check failures:**
- 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
- ✅ *

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [brentmid](https://github.com/brentmid)
- **Source:** [brentmid/evernote-mcp-server](https://github.com/brentmid/evernote-mcp-server)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-brentmid-evernote-mcp-server
- Seller: https://agentstack.voostack.com/s/brentmid
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
