{"_id":"@avinsonmassif/mcp-evernote","_rev":"2-20150d6785f9bb9510616d217bd62be3","name":"@avinsonmassif/mcp-evernote","dist-tags":{"latest":"1.3.1"},"versions":{"1.2.3":{"name":"@avinsonmassif/mcp-evernote","version":"1.2.3","keywords":["mcp","mcp-server","modelcontextprotocol","evernote","notes","knowledge-management","oauth"],"author":{"name":"avinsonmassif"},"license":"GPL-3.0","_id":"@avinsonmassif/mcp-evernote@1.2.3","maintainers":[{"name":"avinsonmassif","email":"avinsonmassif@gmail.com"}],"homepage":"https://github.com/avinsonmassif/mcp-evernote#readme","bugs":{"url":"https://github.com/avinsonmassif/mcp-evernote/issues"},"bin":{"mcp-evernote":"dist/index.js","mcp-evernote-auth":"dist/auth-standalone.js"},"dist":{"shasum":"8108a2fe9fc13047d8b9eeabf480b6c5d4f8db86","tarball":"https://registry.npmjs.org/@avinsonmassif/mcp-evernote/-/mcp-evernote-1.2.3.tgz","fileCount":48,"integrity":"sha512-CM527JrOFmUQljxCSQMcOOIUDa3cezy4ExylkeezMs5acvBBD4Dug5+4Y9Gw7rhxO2mLFz3wodHkFI9+LOtHRQ==","signatures":[{"sig":"MEQCID812t92FuY8knO95BYoG/Ovy4rII6VJqBvGl15XbxTfAiAFFBmVVPXBExp+vmeH2kCnhXFE1BUleQNS2wtNe6xEKA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":300508},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.17.0"},"gitHead":"f4f94c7b9f4259e94b851166bfe92e56f87cc913","mcpName":"io.github.avinsonmassif/mcp-evernote","scripts":{"dev":"tsx watch src/index.ts","auth":"tsx src/auth-standalone.ts","lint":"eslint src/**/*.ts","test":"jest","build":"tsc && npm run postbuild","setup":"node scripts/setup.js","start":"node dist/index.js","format":"prettier --write src/**/*.ts","test:e2e":"jest __tests__/e2e","auth:prod":"node dist/auth-standalone.js","postbuild":"node -e \"if(process.platform!=='win32')require('child_process').execSync('chmod +x dist/index.js dist/auth-standalone.js')\"","test:unit":"jest __tests__/unit","test:watch":"jest --watch","postinstall":"node scripts/post-install.js 2>/dev/null || true","setup:claude":"node scripts/install-to-claude.js","test:coverage":"jest --coverage","prepublishOnly":"npm run build","test:integration":"jest __tests__/integration"},"_npmUser":{"name":"avinsonmassif","email":"avinsonmassif@gmail.com"},"repository":{"url":"git+https://github.com/avinsonmassif/mcp-evernote.git","type":"git"},"_npmVersion":"11.12.0","description":"MCP server for Evernote integration with note management and synchronization","directories":{},"_nodeVersion":"24.14.0","dependencies":{"zod":"^3.22.4","open":"^8.4.2","dotenv":"^16.3.1","marked":"^12.0.2","cheerio":"1.1.0","express":"^4.18.2","evernote":"^2.0.5","turndown":"^7.2.0","mime-types":"^2.1.35","node-fetch":"^3.3.2","sanitize-html":"^2.13.0","turndown-plugin-gfm":"^1.0.2","@modelcontextprotocol/sdk":"^1.25.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.6.0","jest":"^29.7.0","eslint":"^8.54.0","ts-jest":"^29.4.5","audit-ci":"^6.6.1","prettier":"^3.1.0","typescript":"5.3.3","@types/jest":"^29.5.14","@types/node":"^20.10.0","@types/express":"^4.17.21","@types/turndown":"^5.0.5","@types/mime-types":"^2.1.3","@types/sanitize-html":"^2.13.0","@typescript-eslint/parser":"^6.13.0","@typescript-eslint/eslint-plugin":"^6.13.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-evernote_1.2.3_1776909053147_0.9620936865163594","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"@avinsonmassif/mcp-evernote","version":"1.3.1","description":"MCP server for Evernote integration with note management and synchronization","main":"dist/index.js","type":"module","mcpName":"io.github.avinsonmassif/mcp-evernote","engines":{"node":">=18.17.0"},"bin":{"mcp-evernote":"dist/index.js","mcp-evernote-auth":"dist/auth-standalone.js"},"scripts":{"build":"tsc && npm run postbuild","postbuild":"node -e \"if(process.platform!=='win32')require('child_process').execSync('chmod +x dist/index.js dist/auth-standalone.js')\"","dev":"tsx watch src/index.ts","start":"node dist/index.js","setup":"node scripts/setup.js","setup:claude":"node scripts/install-to-claude.js","auth":"tsx src/auth-standalone.ts","auth:prod":"node dist/auth-standalone.js","test":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage","test:unit":"jest __tests__/unit","test:integration":"jest __tests__/integration","test:e2e":"jest __tests__/e2e","lint":"eslint src/**/*.ts","format":"prettier --write src/**/*.ts","prepublishOnly":"npm run build","postinstall":"node scripts/post-install.js 2>/dev/null || true"},"keywords":["mcp","mcp-server","modelcontextprotocol","evernote","notes","knowledge-management","oauth"],"author":{"name":"avinsonmassif"},"license":"GPL-3.0","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/avinsonmassif/mcp-evernote.git"},"homepage":"https://github.com/avinsonmassif/mcp-evernote#readme","bugs":{"url":"https://github.com/avinsonmassif/mcp-evernote/issues"},"dependencies":{"@modelcontextprotocol/sdk":"^1.25.3","cheerio":"1.1.0","dotenv":"^16.3.1","evernote":"^2.0.5","express":"^4.18.2","marked":"^12.0.2","mime-types":"^2.1.35","node-fetch":"^3.3.2","open":"^8.4.2","sanitize-html":"^2.13.0","turndown":"^7.2.0","turndown-plugin-gfm":"^1.0.2","zod":"^3.22.4"},"devDependencies":{"@types/express":"^4.17.21","@types/jest":"^29.5.14","@types/mime-types":"^2.1.3","@types/node":"^20.10.0","@types/sanitize-html":"^2.13.0","@types/turndown":"^5.0.5","@typescript-eslint/eslint-plugin":"^6.13.0","@typescript-eslint/parser":"^6.13.0","audit-ci":"^6.6.1","eslint":"^8.54.0","jest":"^29.7.0","prettier":"^3.1.0","ts-jest":"^29.4.5","tsx":"^4.6.0","typescript":"5.3.3"},"gitHead":"56b1201da448eb8a6b8ff48afc292935d62700ed","types":"./dist/index.d.ts","_id":"@avinsonmassif/mcp-evernote@1.3.1","_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-n05Wg0RDxo9bfhIqankorGs+Nmaw0UnUHyRJmIxTpleNm9zKwlee5NXJsrco1BFY+3iPQXgIG10fdSUps3y6Iw==","shasum":"6b2a105564a6b155c76aff518ad8bdbad6c69e03","tarball":"https://registry.npmjs.org/@avinsonmassif/mcp-evernote/-/mcp-evernote-1.3.1.tgz","fileCount":48,"unpackedSize":298301,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@avinsonmassif%2fmcp-evernote@1.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDoSLb+bUQUhB6ofAvo8KV5yydoB3B0k5YyfdueJoxRUQIhALJxH+AXQNHRfvqiJa7n6DqEuEuwOrfKtqu8AeC71bQq"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:df0492ba-f4da-41d5-b317-a47cda5187df"}},"directories":{},"maintainers":[{"name":"avinsonmassif","email":"avinsonmassif@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-evernote_1.3.1_1776925931223_0.24344734611664487"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-23T01:50:53.072Z","modified":"2026-04-23T06:32:11.691Z","1.2.3":"2026-04-23T01:50:53.302Z","1.3.1":"2026-04-23T06:32:11.386Z"},"bugs":{"url":"https://github.com/avinsonmassif/mcp-evernote/issues"},"author":{"name":"avinsonmassif"},"license":"GPL-3.0","homepage":"https://github.com/avinsonmassif/mcp-evernote#readme","keywords":["mcp","mcp-server","modelcontextprotocol","evernote","notes","knowledge-management","oauth"],"repository":{"type":"git","url":"git+https://github.com/avinsonmassif/mcp-evernote.git"},"description":"MCP server for Evernote integration with note management and synchronization","maintainers":[{"name":"avinsonmassif","email":"avinsonmassif@gmail.com"}],"readme":"# MCP Evernote Server\n\n[![Version](https://img.shields.io/npm/v/@avinsonmassif/mcp-evernote)](https://www.npmjs.com/package/@avinsonmassif/mcp-evernote)\n[![License](https://img.shields.io/npm/l/@avinsonmassif/mcp-evernote)](LICENSE)\n\nA Model Context Protocol (MCP) server that provides seamless integration with Evernote for note management, organization, and knowledge capture. Works with both Claude Code and Claude Desktop.\n\n> **This is a fork of [verygoodplugins/mcp-evernote](https://github.com/verygoodplugins/mcp-evernote)** with two additions:\n> - **Evertoken auth mode** — authenticate without an Evernote developer key using tokens extracted from the Evernote desktop app via [evertoken](https://github.com/vzhd1701/evertoken)\n> - **Docker deployment** — run the server in a container behind [mcp-auth-proxy](https://github.com/sigbit/mcp-auth-proxy)\n\n## Installation Requirements\n\n### For Claude Desktop Users:\n- **OAuth Authentication Required**: Yes, run the auth command once (prompts for API keys)\n- **Repository Download**: No, you can use npx directly from npm\n- **API Credentials**: The auth script will prompt you for your Evernote API keys\n- **Simple Setup**: Just one command to authenticate and configure\n\n### For Claude Code Users:\n- **OAuth Authentication**: Handled automatically via `/mcp` command\n- **Repository Download**: Not required\n- **Setup**: Single command installation\n\n## Current Status\n\n### ✅ Working Features\n\n- 🔐 **OAuth Authentication** - Interactive setup for Claude Desktop, automatic for Claude Code\n- 📝 **Note Operations**\n  - Create notes with plain text or markdown content\n  - Read and retrieve note contents\n  - Update existing notes\n  - Delete notes\n  - Automatic Markdown ↔ ENML conversion (GFM + local attachments)\n- 📚 **Notebook Management**\n  - List all notebooks\n  - Create new notebooks\n  - Organize with stacks\n- 🏷️ **Tag System**\n  - List all tags\n  - Create new tags\n  - Hierarchical tag support\n- 🔍 **Advanced Search** - Full Evernote search syntax support\n- 👤 **User Info** - Get account details and quota usage\n- 🤖 **Smart Setup** - Interactive credential prompts and environment detection\n\n## Quick Start\n\n### Installation Methods\n\n#### Option 1: Using NPX (No Installation Required)\n\nThe simplest way - no need to install anything globally:\n\n```bash\n# For Claude Desktop - Run authentication\nnpx -y -p @avinsonmassif/mcp-evernote mcp-evernote-auth\n\n# For Claude Code - Just add the server\nclaude mcp add evernote \"npx -y -p @avinsonmassif/mcp-evernote mcp-evernote\"\n```\n\n## Change Notifications\n\n### Polling for Changes\n\nThe server can poll Evernote for changes and send webhook notifications when notes are created, updated, or deleted.\n\n#### Configuration\n\n```env\n# Enable auto-start polling (default: false)\nEVERNOTE_POLLING_ENABLED=true\n\n# Poll interval in milliseconds (default: 3600000 = 1 hour, min: 900000 = 15 min)\nEVERNOTE_POLL_INTERVAL=3600000\n\n# Webhook URL to receive change notifications\nEVERNOTE_WEBHOOK_URL=https://your-endpoint.com/webhooks/evernote\n```\n\n#### Webhook Payload\n\nWhen changes are detected, a POST request is sent to your webhook URL:\n\n```json\n{\n  \"source\": \"mcp-evernote\",\n  \"timestamp\": \"2025-12-15T10:30:00.000Z\",\n  \"changes\": [\n    {\n      \"type\": \"note_created\",\n      \"guid\": \"abc123...\",\n      \"title\": \"My New Note\",\n      \"notebookGuid\": \"def456...\",\n      \"timestamp\": \"2025-12-15T10:29:55.000Z\"\n    }\n  ]\n}\n```\n\n#### Manual Control\n\nUse these tools to control polling:\n- `evernote_start_polling` - Start polling manually\n- `evernote_stop_polling` - Stop polling\n- `evernote_poll_now` - Check for changes immediately\n- `evernote_polling_status` - Get polling configuration and status\n\n### Evernote Webhooks (Real-time)\n\nFor real-time notifications, Evernote supports webhooks but requires manual registration:\n\n1. Email `devsupport@evernote.com` with:\n   - Your Consumer Key\n   - Webhook URL endpoint\n   - Any filters (optional)\n\n2. They'll configure your webhook to receive HTTP GET requests on note create/update events.\n\n---\n\n#### Option 2: Global Installation\n\nInstall once, use anywhere:\n\n```bash\n# Install globally\nnpm install -g @avinsonmassif/mcp-evernote\n\n# For Claude Desktop - Run authentication\nmcp-evernote-auth\n\n# For Claude Code - Add the server\nclaude mcp add evernote \"mcp-evernote\"\n```\n\n#### Option 3: Local Development\n\nFor contributing or customization:\n\n```bash\n# Clone and install\ngit clone https://github.com/avinsonmassif/mcp-evernote.git\ncd mcp-evernote\nnpm install\n\n# Run setup wizard\nnpm run setup\n```\n\n## Configuration\n\n### 1. Get Evernote API Credentials\n\n1. Visit [Evernote Developers](https://dev.evernote.com/)\n2. Create a new application\n3. Copy your Consumer Key and Consumer Secret\n\n### 2. Authentication Options\n\n#### Interactive Setup (Recommended)\n\nThe auth script will prompt you for credentials if not found:\n\n```bash\n# Run authentication - prompts for API keys if needed\nnpx -p @avinsonmassif/mcp-evernote mcp-evernote-auth\n```\n\n#### Environment Variables (Optional)\n\nFor automation, you can set credentials via environment variables:\n\n```env\n# Create .env file (optional)\nEVERNOTE_CONSUMER_KEY=your-consumer-key\nEVERNOTE_CONSUMER_SECRET=your-consumer-secret\nEVERNOTE_ENVIRONMENT=production  # or 'sandbox'\nOAUTH_CALLBACK_PORT=3000        # Default: 3000\n\n# Polling configuration (optional)\nEVERNOTE_POLLING_ENABLED=true                                  # Auto-start polling\nEVERNOTE_POLL_INTERVAL=3600000                                 # 1 hour (min: 900000 = 15 min)\nEVERNOTE_WEBHOOK_URL=https://your-endpoint.com/webhooks/evernote  # Webhook for change notifications\n```\n\n### 3. Configure Your Client\n\n<details>\n<summary><b>Claude Code Configuration</b></summary>\n\n#### Quick Setup (Using NPX)\n```bash\nclaude mcp add evernote \"npx -y -p @avinsonmassif/mcp-evernote -c mcp-evernote\" \\\n  --env EVERNOTE_CONSUMER_KEY=your-key \\\n  --env EVERNOTE_CONSUMER_SECRET=your-secret\n```\n\n#### OAuth Authentication\n1. In Claude Code, type `/mcp`\n2. Select \"Evernote\"\n3. Choose \"Authenticate\"\n4. Follow the browser OAuth flow\n5. Tokens are stored and refreshed automatically by Claude Code\n\n**Note:** Claude Code handles OAuth automatically - no manual token management needed!\n\n</details>\n\n<details>\n<summary><b>Claude Desktop Configuration</b></summary>\n\n#### Step 1: Authenticate\n\nUsing NPX (no installation required):\n```bash\nnpx -y -p @avinsonmassif/mcp-evernote mcp-evernote-auth\n```\n\nThe auth script will:\n1. Prompt for your API credentials (if not in environment)\n2. Optionally save credentials for future use\n3. Open your browser for OAuth authentication\n4. Save the token to `.evernote-token.json`\n5. Display the configuration to add to Claude Desktop\n\nOr if installed globally:\n```bash\nmcp-evernote-auth\n```\n\n#### Step 2: Add to Configuration\n\n**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`\n**Windows**: `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"evernote\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"-p\", \"@avinsonmassif/mcp-evernote\", \"-c\", \"mcp-evernote\"],\n      \"env\": {\n        \"EVERNOTE_CONSUMER_KEY\": \"your-consumer-key\",\n        \"EVERNOTE_CONSUMER_SECRET\": \"your-consumer-secret\",\n        \"EVERNOTE_ENVIRONMENT\": \"production\"\n      }\n    }\n  }\n}\n```\n\n**Or** if installed globally:\n```json\n{\n  \"mcpServers\": {\n    \"evernote\": {\n      \"command\": \"mcp-evernote\",\n      \"env\": {\n        \"EVERNOTE_CONSUMER_KEY\": \"your-consumer-key\",\n        \"EVERNOTE_CONSUMER_SECRET\": \"your-consumer-secret\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n## Authentication Methods\n\n### 1. Claude Code (Automatic)\nClaude Code handles OAuth automatically via the `/mcp` command. Tokens are managed by Claude Code.\n\n### 2. Claude Desktop (Manual)\nRun `npx -y -p @avinsonmassif/mcp-evernote mcp-evernote-auth` to authenticate via browser. Token saved to `.evernote-token.json`.\n\n### 3. Environment Variables (CI/CD)\n```env\nEVERNOTE_ACCESS_TOKEN=your-token\nEVERNOTE_NOTESTORE_URL=your-notestore-url\n```\n\n### 4. Direct Token (Advanced)\n```json\n{\n  \"env\": {\n    \"EVERNOTE_ACCESS_TOKEN\": \"your-access-token\",\n    \"EVERNOTE_NOTESTORE_URL\": \"your-notestore-url\"\n  }\n}\n```\n\n### 5. Evertoken (No Developer Key Required)\n\nEvernote stopped issuing new API developer keys. If you can't obtain a `CONSUMER_KEY` / `CONSUMER_SECRET`, use **evertoken mode** instead. It extracts a valid token directly from the Evernote desktop app's local encrypted storage — no developer key needed.\n\n#### Prerequisites\n\n1. Install the [Evernote desktop app](https://evernote.com/download) on Windows and sign in\n2. Download [evertoken](https://github.com/vzhd1701/evertoken) for Windows ([releases](https://github.com/vzhd1701/evertoken/releases))\n\n#### Extract your tokens\n\n```powershell\n.\\evertoken.exe new\n```\n\nCopy the **Refresh Token (JWT)** and **Client ID** values from the output.\n\n#### Configure\n\n```json\n{\n  \"mcpServers\": {\n    \"evernote\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/mcp-evernote/dist/index.js\"],\n      \"env\": {\n        \"EVERNOTE_AUTH_MODE\": \"evertoken\",\n        \"EVERNOTE_SEED_NRT\": \"<Refresh Token (JWT)>\",\n        \"EVERNOTE_SEED_NCI\": \"<Client ID>\",\n        \"EVERNOTE_DEVICE_ID\": \"<generate once: node -e \\\"console.log(require('crypto').randomUUID())\\\">\"\n      }\n    }\n  }\n}\n```\n\n#### Environment variables\n\n| Variable | Required | Default | Description |\n|---|---|---|---|\n| `EVERNOTE_AUTH_MODE` | Yes | — | Set to `evertoken` to activate this mode |\n| `EVERNOTE_SEED_NRT` | Yes* | — | JWT refresh token from `evertoken.exe new` |\n| `EVERNOTE_SEED_NCI` | Yes* | — | Client ID from `evertoken.exe new` |\n| `EVERNOTE_DEVICE_ID` | Yes | — | Stable UUID — generate once, keep forever |\n| `EVERNOTE_DEVICE_DESCRIPTION` | No | `mcp-evernote` | Arbitrary label for this client |\n| `EVERNOTE_APP_VERSION` | No | `11.12.2` | Evernote desktop version to present |\n| `EVERNOTE_OS_PLATFORM` | No | `win32` | OS platform string |\n| `EVERNOTE_OS_RELEASE` | No | `10.0` | OS release string |\n| `MCP_EVERNOTE_SEED_PATH` | No | `~/.config/mcp-evernote-evertoken/seed.json` | Path to seed JSON file (alternative to env vars) |\n| `MCP_EVERNOTE_STATE_PATH` | No | `~/.config/mcp-evernote-evertoken/state.json` | Path to persisted token state |\n\n*Can alternatively be stored in a JSON file at `MCP_EVERNOTE_SEED_PATH` with `{ \"nrt\": \"...\", \"nci\": \"...\" }`.\n\n#### Token rotation and persistence\n\nThe JWT refresh token rotates on every use. The current token is saved to `state.json` (`MCP_EVERNOTE_STATE_PATH`). If that file is lost, the server will attempt a fresh refresh using the original `EVERNOTE_SEED_NRT` — this works until that token has itself been rotated out. For Docker deployments, always mount a volume for the state path (see below).\n\n## Available Tools\n\n## Markdown Support\n\nThis server automatically converts between Markdown and Evernote's ENML format:\n\n- Create/update: Markdown input is rendered to ENML-safe HTML inside `<en-note>`.\n  - GFM task lists `- [ ]` map to Evernote checkboxes `<en-todo/>`.\n  - Checked tasks `- [x]` map to `<en-todo checked=\"true\"/>`.\n-  - Local Markdown images/files (`![alt](./path.png)` or `file://...`) are uploaded as Evernote resources automatically.\n-  - Existing attachments are preserved by referencing `evernote-resource:<hash>` in Markdown.\n-  - Remote `http(s)` images remain links (download locally if you want them embedded).\n-  - Common Markdown elements (headings, lists, code blocks, tables, emphasis, links) are preserved.\n- Retrieve: ENML content is converted back to Markdown (GFM), including task lists and attachments.\n  - Embedded images become `![alt](evernote-resource:<hash>)` and other files become `[file](evernote-resource:<hash>)` so you can round-trip them safely.\n\nLimitations:\n- Remote URLs are not fetched automatically; save them locally and reference the file to embed.\n- Keep the `evernote-resource:<hash>` references in Markdown if you want existing attachments to survive edits.\n- Some exotic HTML not supported by ENML will be sanitized/removed.\n\n### Note Operations\n\n#### `evernote_create_note`\nCreate a new note in Evernote.\n\n**Parameters:**\n- `title` (required): Note title\n- `content` (required): Note content (plain text or markdown)\n- `notebookName` (optional): Target notebook name\n- `tags` (optional): Array of tag names\n\n**Example:**\n```\nCreate a note titled \"Meeting Notes\" with content \"Discussed Q4 planning\" in notebook \"Work\" with tags [\"meetings\", \"planning\"]\n```\n\n#### `evernote_search_notes`\nSearch for notes using Evernote's search syntax.\n\n**Parameters:**\n- `query` (required): Search query\n- `notebookName` (optional): Limit to specific notebook\n- `maxResults` (optional): Maximum results (default: 20, max: 100)\n\n**Example:**\n```\nSearch for notes containing \"project roadmap\" in the \"Work\" notebook\n```\n\n#### `evernote_get_note`\nRetrieve a specific note by GUID.\n\n**Parameters:**\n- `guid` (required): Note GUID\n- `includeContent` (optional): Include note content (default: true)\n\n> Returned Markdown represents embedded resources with `evernote-resource:<hash>` URLs. Leave those references intact so attachments stay linked when you edit the note.\n\n#### `evernote_update_note`\nUpdate an existing note.\n\n**Parameters:**\n- `guid` (required): Note GUID\n- `title` (optional): New title\n- `content` (optional): New content\n- `tags` (optional): New tags (replaces existing)\n\n#### `evernote_delete_note`\nDelete a note.\n\n**Parameters:**\n- `guid` (required): Note GUID\n\n### Notebook Operations\n\n#### `evernote_list_notebooks`\nList all notebooks in your account.\n\n#### `evernote_create_notebook`\nCreate a new notebook.\n\n**Parameters:**\n- `name` (required): Notebook name\n- `stack` (optional): Stack name for organization\n\n### Tag Operations\n\n#### `evernote_list_tags`\nList all tags in your account.\n\n#### `evernote_create_tag`\nCreate a new tag.\n\n**Parameters:**\n- `name` (required): Tag name\n- `parentTagName` (optional): Parent tag for hierarchy\n\n### Account Operations\n\n#### `evernote_get_user_info`\nGet current user information and quota usage.\n\n#### `evernote_revoke_auth`\nRevoke stored authentication token.\n\n### Diagnostic Operations\n\n#### `evernote_health_check`\nCheck the health and status of the Evernote MCP server.\n\n**Parameters:**\n- `verbose` (optional): Include detailed diagnostic information (default: false)\n\n**Returns:**\n- Server status (healthy, unhealthy, needs_auth, etc.)\n- Authentication status\n- Token information (when verbose)\n- Configuration details\n\n**Example:**\n```\nCheck Evernote connection health with verbose details\n```\n\n#### `evernote_reconnect`\nForce reconnection to Evernote. Useful when experiencing \"Not connected\" errors.\n\n**Use this when:**\n- You see \"Not connected\" errors\n- You've just refreshed your token\n- The server seems stuck in a failed state\n\n**Example:**\n```\nReconnect to Evernote\n```\n\n### Polling Operations\n\n#### `evernote_start_polling`\nStart polling for Evernote changes. Checks for new/updated/deleted notes and sends notifications to the configured webhook URL.\n\n**Example:**\n```\nStart polling for Evernote changes\n```\n\n#### `evernote_stop_polling`\nStop the polling process.\n\n#### `evernote_poll_now`\nCheck for changes immediately without waiting for the next poll interval. Returns a list of detected changes.\n\n**Example:**\n```\nCheck for Evernote changes now\n```\n\n#### `evernote_polling_status`\nGet the current polling configuration and status, including:\n- Whether polling is running\n- Poll interval\n- Configured webhook URL\n- Last poll time\n- Error count\n\n## Search Syntax\n\nEvernote supports advanced search operators:\n\n- `intitle:keyword` - Search in titles\n- `notebook:name` - Search in specific notebook\n- `tag:tagname` - Search by tag\n- `created:20240101` - Search by creation date\n- `updated:day-1` - Recently updated notes\n- `resource:image/*` - Notes with images\n- `todo:true` - Notes with checkboxes\n- `-tag:archive` - Exclude archived notes\n\n## Integration with Claude Automation Hub\n\nThis MCP server works seamlessly with the Claude Automation Hub for workflow automation:\n\n```javascript\n// Example workflow tool\nexport default {\n  name: 'capture-idea',\n  description: 'Capture an idea to Evernote',\n  handler: async ({ idea, category }) => {\n    // The MCP server handles the Evernote integration\n    return {\n      tool: 'evernote_create_note',\n      args: {\n        title: `Idea: ${new Date().toISOString().split('T')[0]}`,\n        content: idea,\n        notebookName: 'Ideas',\n        tags: [category, 'automated']\n      }\n    };\n  }\n};\n```\n\n## Memory Service Integration\n\nTo enable synchronization with MCP memory service:\n\n1. Set the memory service URL in your environment:\n```env\nMCP_MEMORY_SERVICE_URL=http://localhost:8765\n```\n\n2. Use the sync tools to persist important notes to memory:\n```\nSync my \"Important Concepts\" notebook to memory for long-term retention\n```\n\n## Connection Resilience (v1.2.0+)\n\nThe server includes automatic recovery from connection issues:\n\n### Automatic Features\n- **Auto-retry**: Failed connections automatically retry after 30 seconds\n- **Token validation**: Expired tokens are detected proactively\n- **Graceful degradation**: Server stays alive during failures\n- **Clear error messages**: Actionable feedback on connection issues\n\n### \"Not Connected\" Errors\n\nIf you see \"Not connected\" errors, the server will usually recover automatically. You can also:\n\n1. **Try the reconnect tool** (fastest):\n   ```\n   Reconnect to Evernote\n   ```\n\n2. **Check server health**:\n   ```\n   Check Evernote connection health with verbose details\n   ```\n\n3. **Re-authenticate if needed**:\n   - Claude Code: `/mcp` → Evernote → Authenticate\n   - Claude Desktop: `npx -p @avinsonmassif/mcp-evernote mcp-evernote-auth`\n\nFor detailed information about connection issues and recovery, see [CONNECTION_TROUBLESHOOTING.md](CONNECTION_TROUBLESHOOTING.md).\n\n## Troubleshooting\n\n### Authentication Issues\n\n#### \"Authentication required\" error in Claude Desktop\nThis means you haven't authenticated yet. Run the authentication script:\n```bash\nnpx -p @avinsonmassif/mcp-evernote mcp-evernote-auth\n```\n\nOr if installed globally:\n```bash\nmcp-evernote-auth\n```\n\n#### OAuth callback fails\nIf the OAuth callback doesn't work:\n1. Make sure port 3000 is available (or set `OAUTH_CALLBACK_PORT` in `.env`)\n2. Check your firewall settings\n3. Try using a different browser\n\n#### Token expired\nIf your token expires, the server will now detect this automatically and prompt you to re-authenticate:\n1. In Claude Code: Use `/mcp` command to re-authenticate\n2. In Claude Desktop: Run `npx -p @avinsonmassif/mcp-evernote mcp-evernote-auth`\n\nOr use the reconnect tool to force immediate retry:\n```\nReconnect to Evernote\n```\n\n### Connection Errors\n\nThe server now handles most connection errors automatically:\n- **Transient failures**: Auto-retry after 30 seconds\n- **Token expiry**: Clear error message with re-auth instructions\n- **Network issues**: Server stays alive and retries\n\nIf issues persist:\n- Check your API credentials are correct\n- Verify you're using the right environment (sandbox vs production)\n- See [CONNECTION_TROUBLESHOOTING.md](CONNECTION_TROUBLESHOOTING.md) for detailed guidance\n\n### Rate Limiting\n\nEvernote API has rate limits. If you encounter limits:\n- Reduce the frequency of requests\n- Use batch operations where possible\n- Implement caching for frequently accessed data\n\n## Docker Deployment\n\nRun the server in a Docker container behind [mcp-auth-proxy](https://github.com/sigbit/mcp-auth-proxy), which handles HTTPS and authentication for you. This is the recommended approach for self-hosted setups — no Evernote developer key required.\n\n### Prerequisites\n\n- Docker + Docker Compose\n- Evernote desktop app on Windows (to run `evertoken.exe` once)\n- [evertoken](https://github.com/vzhd1701/evertoken) ([releases](https://github.com/vzhd1701/evertoken/releases))\n\n### 1. Extract your tokens (Windows, one-time)\n\n```powershell\n.\\evertoken.exe new\n```\n\nCopy **Refresh Token (JWT)** → `EVERNOTE_SEED_NRT` and **Client ID** → `EVERNOTE_SEED_NCI`.\n\n### 2. Configure environment\n\n```bash\ncp .env.example .env\n```\n\nFill in your `.env`:\n\n```env\n# mcp-auth-proxy\nMCP_PASSWORD=your-strong-password\nMCP_EXTERNAL_URL=https://mcp-evernote.yourdomain.com\n\n# Evertoken seed (from evertoken.exe new)\nEVERNOTE_SEED_NRT=eyJ...\nEVERNOTE_SEED_NCI=3FE74DA6-...\n\n# Device ID — generate once, keep stable\n# node -e \"console.log(require('crypto').randomUUID())\"\nEVERNOTE_DEVICE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n```\n\n### 3. Build and run\n\n```bash\ndocker compose up -d --build\n```\n\nThe Dockerfile builds both mcp-auth-proxy (from source) and mcp-evernote in a single image. The entrypoint wrapper passes your `docker compose command:` flags to the proxy and appends `-- node /app/dist/index.js` automatically.\n\n### 4. Connect your MCP client\n\nPoint your Claude Desktop or Claude Code config at the proxy URL:\n\n```json\n{\n  \"mcpServers\": {\n    \"evernote\": {\n      \"type\": \"sse\",\n      \"url\": \"https://mcp-evernote.yourdomain.com/sse\",\n      \"headers\": {\n        \"Authorization\": \"Bearer your-strong-password\"\n      }\n    }\n  }\n}\n```\n\n### State persistence\n\nThe rotating JWT refresh token is saved to `/data/mcp-evernote/state.json` inside the container. The `docker-compose.yml` mounts a named volume (`evernote-state`) at that path so the token survives container restarts and image upgrades.\n\n> If the volume is lost, the server recovers automatically on next start using `EVERNOTE_SEED_NRT` — as long as that token hasn't been rotated out since the volume was last written.\n\n---\n\n## Development\n\n### Building from Source\n\n```bash\nnpm install\nnpm run build\n```\n\n### Running in Development Mode\n\n```bash\nnpm run dev\n```\n\n### Testing\n\n```bash\nnpm test\n```\n\n### Linting\n\n```bash\nnpm run lint\nnpm run format\n```\n\n## Security\n\n- OAuth tokens are stored locally in `.evernote-token.json`\n- Never commit token files to version control\n- Use environment variables for sensitive configuration\n- Tokens expire after one year by default\n\n## Contributing\n\nContributions are welcome! Please:\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests if applicable\n5. Submit a pull request (target `develop`; `main` is kept stable for Railway template deployments)\n\n## License\n\nGPL-3.0 - See [LICENSE](LICENSE) file for details.\n\n## Support\n\n- **Issues**: [GitHub Issues](https://github.com/avinsonmassif/mcp-evernote/issues)\n\n## Acknowledgments\n\n- Built with [Model Context Protocol SDK](https://github.com/anthropics/model-context-protocol)\n- Powered by [Evernote API](https://dev.evernote.com/)\n- Fork of [verygoodplugins/mcp-evernote](https://github.com/verygoodplugins/mcp-evernote)\n\n## Roadmap\n\n### Near Term\n- [ ] **Tag Management** - Add/remove tags from existing notes\n- [x] **ENML ↔ Markdown Converter** - Bidirectional conversion between Evernote's ENML format and Markdown\n- [ ] **Real-time Sync Hooks** - Detect changes made via Evernote desktop/mobile apps\n- [ ] **Database Monitoring** - Watch Evernote DB service for live updates\n\n### Future Enhancements\n- [ ] Web clipper functionality\n- [ ] Rich text editing support\n- [ ] File attachment handling\n- [ ] Shared notebook support\n- [ ] Business account features\n- [ ] Template system\n- [ ] Bulk operations\n- [ ] Export/Import tools\n- [ ] Advanced filtering options\n- [ ] Reminder management\n","readmeFilename":"README.md"}