# MCP Evernote Server [![Version](https://img.shields.io/npm/v/@verygoodplugins/mcp-evernote)](https://www.npmjs.com/package/@verygoodplugins/mcp-evernote) [![License](https://img.shields.io/npm/l/@verygoodplugins/mcp-evernote)](LICENSE) A 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. ## ⚠️ No API Key? Use Browser Cookie Auth > **Evernote stopped issuing new developer API keys.** If you are a new user and cannot obtain a Consumer Key/Secret, skip the standard OAuth setup and use the [cookie-based authentication method](#cookie-based-authentication-no-api-key-needed) instead — no API key required. ## Installation Requirements ### Node.js **Supported Node.js: `>=20.16.0 <21` or `>=22.3.0`.** In practice that means Node 20.16+, 22.3+, 24, or newer — the two gaps are Node 21.x and Node 22.0–22.2. This is not an arbitrary floor: it mirrors the `engines` range that the PDF attachment extraction path (`pdf-parse`, and its `pdfjs-dist` transitive dependency) actually declares, and the range is genuinely disjoint. Check with `node --version`. On Node 18 or 21, or on 22.0–22.2, upgrade before installing — Node 21 reached end-of-life in June 2024, and 22.3+ supersedes the early 22 patches. > **Upgrading from 1.x?** 2.0.0 raises the Node requirement from 18.18.0 and changes > `evernote_get_resource` to return extracted text by default instead of binary > data. The tool surface was also consolidated from 27 tools to 15 — the retired > names still work as deprecated aliases, so existing calls keep running. See > [MIGRATION.md](MIGRATION.md). ### For Claude Desktop Users: - **OAuth Authentication Required**: Yes, run the auth command once (prompts for API keys) - **Repository Download**: No, you can use npx directly from npm - **API Credentials**: The auth script will prompt you for your Evernote API keys - **Simple Setup**: Just one command to authenticate and configure ### For Claude Code Users: - **OAuth Authentication**: Handled automatically via `/mcp` command - **Repository Download**: Not required - **Setup**: Single command installation ## Current Status ### ✅ Working Features - 🔐 **OAuth Authentication** - Interactive setup for Claude Desktop, automatic for Claude Code - 📝 **Note Operations** - Create notes with plain text or markdown content - Read and retrieve note contents - Update existing notes - Delete notes - Automatic Markdown ↔ ENML conversion (GFM + local attachments) - 📚 **Notebook Management** - List all notebooks - Create new notebooks - Organize with stacks - 🏷️ **Tag System** - List all tags - Create new tags - Hierarchical tag support - 🔍 **Advanced Search** - Full Evernote search syntax support - 👤 **User Info** - Get account details and quota usage - 🤖 **Smart Setup** - Interactive credential prompts and environment detection ## Quick Start ### Installation Methods #### Option 1: Using NPX (No Installation Required) The simplest way - no need to install anything globally: ```bash # For Claude Desktop - Run authentication npx -y -p @verygoodplugins/mcp-evernote mcp-evernote-auth # For Claude Code - Just add the server claude mcp add evernote "npx -y -p @verygoodplugins/mcp-evernote mcp-evernote" ``` ## Change Notifications ### Polling for Changes The server can poll Evernote for changes and send webhook notifications when notes are created, updated, or deleted. #### Configuration ```env # Enable auto-start polling (default: false) EVERNOTE_POLLING_ENABLED=true # Poll interval in milliseconds (default: 3600000 = 1 hour, min: 900000 = 15 min) EVERNOTE_POLL_INTERVAL=3600000 # Webhook URL to receive change notifications EVERNOTE_WEBHOOK_URL=https://your-endpoint.com/webhooks/evernote ``` #### Webhook Payload When changes are detected, a POST request is sent to your webhook URL: ```json { "source": "mcp-evernote", "timestamp": "2025-12-15T10:30:00.000Z", "changes": [ { "type": "note_created", "guid": "abc123...", "title": "My New Note", "notebookGuid": "def456...", "timestamp": "2025-12-15T10:29:55.000Z" } ] } ``` #### Manual Control Use the `evernote_polling` tool to control polling: - `polling({action:"start"})` - Start polling manually - `polling({action:"stop"})` - Stop polling - `polling({action:"poll"})` - Check for changes immediately - `polling({action:"status"})` - Get polling configuration and status ### Evernote Webhooks (Real-time) For real-time notifications, Evernote supports webhooks but requires manual registration: 1. Email `devsupport@evernote.com` with: - Your Consumer Key - Webhook URL endpoint - Any filters (optional) 2. They'll configure your webhook to receive HTTP GET requests on note create/update events. --- #### Option 2: Global Installation Install once, use anywhere: ```bash # Install globally npm install -g @verygoodplugins/mcp-evernote # For Claude Desktop - Run authentication mcp-evernote-auth # For Claude Code - Add the server claude mcp add evernote "mcp-evernote" ``` #### Option 3: Local Development For contributing or customization: ```bash # Clone and install git clone https://github.com/verygoodplugins/mcp-evernote.git cd mcp-evernote npm install # Run setup wizard npm run setup ``` ## Configuration ### 1. Get Evernote API Credentials > **Note:** Evernote has stopped issuing new developer API keys to new applicants. If you are a new user, skip this section and use the [cookie-based authentication method](#cookie-based-authentication-no-api-key-needed) instead. 1. Visit [Evernote Developers](https://dev.evernote.com/) 2. Create a new application 3. Copy your Consumer Key and Consumer Secret ### 2. Authentication Options #### Interactive Setup (Recommended) The auth script will prompt you for credentials if not found: ```bash # Run authentication - prompts for API keys if needed npx -p @verygoodplugins/mcp-evernote mcp-evernote-auth ``` #### Environment Variables (Optional) For automation, you can set credentials via environment variables: ```env # Create .env file (optional) EVERNOTE_CONSUMER_KEY=your-consumer-key EVERNOTE_CONSUMER_SECRET=your-consumer-secret EVERNOTE_ENVIRONMENT=production # or 'sandbox' OAUTH_CALLBACK_PORT=3000 # Default: 3000 # Polling configuration (optional) EVERNOTE_POLLING_ENABLED=true # Auto-start polling EVERNOTE_POLL_INTERVAL=3600000 # 1 hour (min: 900000 = 15 min) EVERNOTE_WEBHOOK_URL=https://your-endpoint.com/webhooks/evernote # Webhook for change notifications # Rate-limit transport (optional) EVERNOTE_MAX_CONCURRENCY=3 # Max simultaneous NoteStore RPCs (default: 3) EVERNOTE_RATE_LIMIT_AUTO_RETRY_SECONDS=15 # Auto-retry a rate-limited call once if the wait is <= this many seconds; 0 = off EVERNOTE_MAX_RESPONSE_CHARS=60000 # Total note-body chars per multi-note response; bodies past this are dropped with truncated:true # Note body cache (optional) EVERNOTE_NOTE_CACHE_SIZE=200 # Max notes held in the USN-keyed body cache; 0 disables EVERNOTE_NOTE_CACHE_SYNC_TTL_MS=30000 # How long a getSyncState result is trusted before re-checking for external edits ``` On the hourly rate limit, tool errors return JSON with `error: "rate_limited"` and `retryAfterSeconds` (Evernote's exact backoff window). Bounding concurrency smooths bursts but cannot restore quota — the quota is a per-token hourly call count, so the durable fixes are fewer calls and honoring the backoff. Re-reading the same notes is served from an in-memory, USN-keyed body cache instead of re-spending `getNote` calls — the direct fix for the hourly limit tripping on repeat corpus reads. Notes you edit through this server are evicted immediately; edits made elsewhere are picked up within `EVERNOTE_NOTE_CACHE_SYNC_TTL_MS` via a sync-state probe. Extracted OCR / attachment text is always re-read live, never cached. ### 3. Configure Your Client
Claude Code Configuration #### Quick Setup (Using NPX) ```bash claude mcp add evernote "npx -y -p @verygoodplugins/mcp-evernote -c mcp-evernote" \ --env EVERNOTE_CONSUMER_KEY=your-key \ --env EVERNOTE_CONSUMER_SECRET=your-secret ``` #### OAuth Authentication 1. In Claude Code, type `/mcp` 2. Select "Evernote" 3. Choose "Authenticate" 4. Follow the browser OAuth flow 5. Tokens are stored and refreshed automatically by Claude Code **Note:** Claude Code handles OAuth automatically - no manual token management needed!
Claude Desktop Configuration #### Step 1: Authenticate Using NPX (no installation required): ```bash npx -y -p @verygoodplugins/mcp-evernote mcp-evernote-auth ``` The auth script will: 1. Prompt for your API credentials (if not in environment) 2. Open your browser for OAuth authentication 3. Save a compatible token file to `.evernote-token.json` 4. Display the access token so you can use `EVERNOTE_ACCESS_TOKEN` instead Or if installed globally: ```bash mcp-evernote-auth ``` #### Step 2: Add to Configuration **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` ```json { "mcpServers": { "evernote": { "command": "npx", "args": ["-y", "-p", "@verygoodplugins/mcp-evernote", "-c", "mcp-evernote"], "env": { "EVERNOTE_CONSUMER_KEY": "your-consumer-key", "EVERNOTE_CONSUMER_SECRET": "your-consumer-secret", "EVERNOTE_ACCESS_TOKEN": "your-access-token", "EVERNOTE_ENVIRONMENT": "production" } } } } ``` **Or** if installed globally: ```json { "mcpServers": { "evernote": { "command": "mcp-evernote", "env": { "EVERNOTE_CONSUMER_KEY": "your-consumer-key", "EVERNOTE_CONSUMER_SECRET": "your-consumer-secret" } } } } ```
## Cookie-Based Authentication (No API Key Needed) Since Evernote stopped issuing developer API keys to new applicants, new users can authenticate using the `clipper-sso` browser cookie from the Evernote web UI. This cookie carries the same format as a developer-issued access token and works directly as `EVERNOTE_ACCESS_TOKEN` — no Consumer Key or Consumer Secret required. > **Security warning:** Treat this value like a password. Anyone with it can access your Evernote account. Never commit it to git, paste it into chat logs, or share it publicly. **Credit:** Discovered by community member @tdrayson. ([Issue #49](https://github.com/verygoodplugins/mcp-evernote/issues/49)) ### Step 1: Extract the Cookie 1. Log in to [www.evernote.com](https://www.evernote.com) in your browser 2. Open DevTools: **F12** (Windows/Linux) or **Cmd+Option+I** (Mac) 3. Navigate to the **Application** tab → **Cookies** → `www.evernote.com` 4. Find the cookie named **`clipper-sso`** 5. Copy its **Value** — it looks like: ``` S=s101:U=XXX:XXXXX:C=XXXX:P=XXX:A=en-chrome-clipper-xauth-new:V=2:H=XXXXX ``` ### Step 2: Configure Your Client **Claude Code:** ```bash claude mcp add evernote "npx -y -p @verygoodplugins/mcp-evernote -c mcp-evernote" \ --env EVERNOTE_ACCESS_TOKEN="S=s101:U=XXX:..." ``` **Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows): ```json { "mcpServers": { "evernote": { "command": "npx", "args": ["-y", "-p", "@verygoodplugins/mcp-evernote", "-c", "mcp-evernote"], "env": { "EVERNOTE_ACCESS_TOKEN": "S=s101:U=XXX:..." } } } } ``` > **Note:** `EVERNOTE_NOTESTORE_URL` is **not required** when using the cookie token — the server fetches it automatically at startup. ### Caveats - **Token expiry**: The `clipper-sso` token typically expires after roughly one year, or when you explicitly log out of Evernote in your browser. When it expires, log back in to [www.evernote.com](https://www.evernote.com), re-extract the cookie, and update `EVERNOTE_ACCESS_TOKEN`. - **Browser session**: The cookie is tied to your browser login session. Logging out of the Evernote web app will invalidate the token. - **Production only**: This uses your live Evernote account. There is no sandbox equivalent for this method. ## Authentication Methods **Recommended for new users:** [Cookie-Based Authentication (No API Key Needed)](#cookie-based-authentication-no-api-key-needed). ### 1. Claude Code (Automatic) Claude Code handles OAuth automatically via the `/mcp` command. Tokens are managed by Claude Code. ### 2. Claude Desktop (Manual) Run `npx -y -p @verygoodplugins/mcp-evernote mcp-evernote-auth` to authenticate via browser. The script saves `.evernote-token.json` for compatibility and also prints a token you can set as `EVERNOTE_ACCESS_TOKEN`. ### 3. Environment Variables (CI/CD) ```env EVERNOTE_ACCESS_TOKEN=your-token EVERNOTE_NOTESTORE_URL=your-notestore-url EVERNOTE_ALLOWED_FILE_ROOTS=/Users/you/Documents:/Users/you/Projects ``` ### 4. Direct Token (Advanced) ```json { "env": { "EVERNOTE_ACCESS_TOKEN": "your-access-token", "EVERNOTE_NOTESTORE_URL": "your-notestore-url" } } ``` ## Available Tools The server exposes **15 tools** (consolidated from 27). Retired tool names still work as deprecated aliases and can be re-listed with `EVERNOTE_LEGACY_TOOLS=true` — see [MIGRATION.md](MIGRATION.md) for the full old→new mapping. Highlights: `get_resource({guid, as})` projects an attachment (`text`/`binary`/`recognition`/`metadata`); `list_notebooks`/`list_tags` return one entity when passed a `name`/`guid`; `update_note` takes `replacements[]` for patch-style edits; and the `polling` and `connection` tools dispatch on an `action`. ## Markdown Support This server automatically converts between Markdown and Evernote's ENML format: - Create/update: Markdown input is rendered to ENML-safe HTML inside ``. - GFM task lists `- [ ]` map to Evernote checkboxes ``. - Checked tasks `- [x]` map to ``. - - Local Markdown images/files (`![alt](./path.png)` or `file://...`) are uploaded as Evernote resources automatically. - - Existing attachments are preserved by referencing `evernote-resource:` in Markdown. - - Remote `http(s)` images remain links (download locally if you want them embedded). - - Common Markdown elements (headings, lists, code blocks, tables, emphasis, links) are preserved. - Retrieve: ENML content is converted back to Markdown (GFM), including task lists and attachments. - Embedded images become `![alt](evernote-resource:)` and other files become `[file](evernote-resource:)` so you can round-trip them safely. Limitations: - Remote URLs are not fetched automatically; save them locally and reference the file to embed. - Keep the `evernote-resource:` references in Markdown if you want existing attachments to survive edits. - Some exotic HTML not supported by ENML will be sanitized/removed. ### Note Operations #### `evernote_create_note` Create a new note in Evernote. **Parameters:** - `title` (required): Note title - `content` (required): Note content (plain text or markdown) - `notebookName` (optional): Target notebook name - `tags` (optional): Array of tag names **Example:** ``` Create a note titled "Meeting Notes" with content "Discussed Q4 planning" in notebook "Work" with tags ["meetings", "planning"] ``` #### `evernote_search_notes` Search for notes using Evernote's search syntax. Returns note metadata plus `totalNotes`; page with `offset`/`nextOffset`. **Parameters:** - `query` (required): Search query (use `"*"` to match all notes) - `notebookName` (optional): Limit to specific notebook - `maxResults` (optional): Results per page (default: 20, max: 100; capped at 25 when `includeContent` is true) - `offset` (optional): Result offset for paging (default: 0) - `includeContent` (optional): Include each note's full body in `content`, one API call per note (default: false) - `format` (optional): Body projection when `includeContent` is true — `markdown` (default), `text`, or `enml` - `includePreview` (optional): Include a ~300-char plain-text preview per note (ignored when `includeContent` is true) **Export a whole notebook** as text without a dedicated tool: `query: "*"`, set `notebookName` + `includeContent`, and page with `offset` until `hasMore` is false. **Example:** ``` Search for notes containing "project roadmap" in the "Work" notebook ``` #### `evernote_get_note` Retrieve one note (full detail) or a batch of up to 25 (body-focused). **Parameters:** provide exactly one of `guid` or `guids`. - `guid`: single note GUID — full detail, including PDF/image-OCR attachment text - `guids`: array of up to 25 GUIDs — metadata + `content` only (no attachment text; use a single `guid` for that). Returns `{ notes, failed?, aborted? }`; on a mid-batch rate limit it stops with partial results plus the guids left to resume. - `format` (optional): body projection — `markdown` (default), `text`, or `enml` - `includeContent` (optional): include note content (default: true) - `includeAttachmentText` (optional, single-note only): extract PDF/OCR attachment text (default: true) > Returned Markdown represents embedded resources with `evernote-resource:` URLs. Leave those references intact so attachments stay linked when you edit the note. #### `evernote_update_note` Update an existing note. Two mutually exclusive modes: **Full-update mode parameters:** - `guid` (required): Note GUID - `title` (optional): New title - `content` (optional): New content (Markdown supported) - `notebookName` (optional): Move the note to this notebook - `tags` (optional): New tags (replaces existing) **Patch mode parameter** (replaces the old `evernote_patch_note`): - `replacements` (optional): Array of `{find, replace, replaceAll?}` find-and-replace edits applied to the note body, preserving title, tags, notebook, and attachments. Cannot be combined with the full-update fields above. #### `evernote_delete_note` Delete a note. **Parameters:** - `guid` (required): Note GUID ### Notebook Operations #### `evernote_list_notebooks` List all notebooks in your account, or get one notebook's full detail by passing its `name` or `guid` (absorbs the old `evernote_get_notebook`). #### `evernote_create_notebook` Create a new notebook. **Parameters:** - `name` (required): Notebook name - `stack` (optional): Stack name for organization #### `evernote_update_notebook` Rename a notebook or move it between stacks. **Parameters:** - `guid` (required): Notebook GUID - `name` (optional): New notebook name - `stack` (optional): Stack name — pass an empty string to remove it from its stack ### Tag Operations #### `evernote_list_tags` List all tags in your account, or get one tag's full detail by passing its `name` or `guid` (absorbs the old `evernote_get_tag`). #### `evernote_create_tag` Create a new tag. **Parameters:** - `name` (required): Tag name - `parentTagName` (optional): Parent tag for hierarchy #### `evernote_update_tag` Rename a tag or re-parent it. **Parameters:** - `guid` (required): Tag GUID - `name` (optional): New tag name - `parentTagName` (optional): Parent tag name — pass an empty string to remove the parent ### Attachments & Resources #### `evernote_get_resource` Read one attachment, projected through one of four views. > **⚠️ Breaking change in 2.0.0.** This tool used to return base64 binary data by > default. It now returns **extracted text** by default. Pass `as: "binary"` to > get the old behavior. **Parameters:** - `guid` (required): Resource GUID (from a note's `resources[]`, via `evernote_get_note`) - `as` (optional, default `"text"`): How to project the attachment - `"text"` — extracted text. PDFs go through the text layer, falling back to Evernote's OCR data for scanned documents; images use OCR. - `"binary"` — base64-encoded file body. - `"recognition"` — raw Evernote OCR recognition data. - `"metadata"` — filename, MIME type, size, hash, and `hasRecognition`. - `includeData` (optional, **deprecated**): `true` maps to `as:"binary"`, `false` to `as:"metadata"`. There is no separate tool to list a note's attachments — `evernote_get_note` returns them in `resources[]`. **Example:** ``` Get the text of the PDF attached to that invoice note ``` #### `evernote_add_resource_to_note` Attach a local file to an existing note. **Parameters:** - `noteGuid` (required): Target note GUID - `filePath` (required): Path to the local file. Must sit under an allowed root — see `EVERNOTE_ALLOWED_FILE_ROOTS` (defaults to your home directory and the current working directory). - `filename` (optional): Override the attachment's display name ### Connection & Account #### `evernote_connection` Manage the Evernote connection and account. Dispatches on `action` (replaces the old `health_check`, `get_user_info`, `reconnect`, `revoke_auth`): - `action:"status"` — health/diagnostic check (server + auth state). Pass `verbose:true` for detailed diagnostics. - `action:"user"` — current user information and quota usage. - `action:"reconnect"` — force reconnection (useful on "Not connected" errors). - `action:"revoke"` — revoke the stored authentication token. **Example:** ``` Check Evernote connection health with verbose details ``` ### Polling Operations #### `evernote_polling` Manage background polling for changes (detected changes are sent to the configured webhook). Dispatches on `action` (replaces the old `start_polling`, `stop_polling`, `poll_now`, `polling_status`): - `action:"start"` — begin polling on the configured interval. - `action:"stop"` — halt polling. - `action:"poll"` — check for changes immediately; returns detected changes. - `action:"status"` — current polling configuration and state (running, interval, webhook URL, last poll time, error count). **Example:** ``` Start polling for Evernote changes ``` ## Search Syntax Evernote supports advanced search operators: - `intitle:keyword` - Search in titles - `notebook:name` - Search in specific notebook - `tag:tagname` - Search by tag - `created:20240101` - Search by creation date - `updated:day-1` - Recently updated notes - `resource:image/*` - Notes with images - `todo:true` - Notes with checkboxes - `-tag:archive` - Exclude archived notes ## Integration with Claude Automation Hub This MCP server works seamlessly with the Claude Automation Hub for workflow automation: ```javascript // Example workflow tool export default { name: 'capture-idea', description: 'Capture an idea to Evernote', handler: async ({ idea, category }) => { // The MCP server handles the Evernote integration return { tool: 'evernote_create_note', args: { title: `Idea: ${new Date().toISOString().split('T')[0]}`, content: idea, notebookName: 'Ideas', tags: [category, 'automated'] } }; } }; ``` ## Memory Service Integration To enable synchronization with MCP memory service: 1. Set the memory service URL in your environment: ```env MCP_MEMORY_SERVICE_URL=http://localhost:8765 ``` 2. Use the sync tools to persist important notes to memory: ``` Sync my "Important Concepts" notebook to memory for long-term retention ``` ## Connection Resilience The server includes automatic recovery from connection issues: ### Automatic Features - **Auto-retry**: Failed connections automatically retry after 30 seconds - **Token validation**: Expired tokens are detected proactively - **Graceful degradation**: Server stays alive during failures - **Clear error messages**: Actionable feedback on connection issues ### "Not Connected" Errors If you see "Not connected" errors, the server will usually recover automatically. You can also: 1. **Try the reconnect tool** (fastest): ``` Reconnect to Evernote ``` 2. **Check server health**: ``` Check Evernote connection health with verbose details ``` 3. **Re-authenticate if needed**: - Claude Code: `/mcp` → Evernote → Authenticate - Claude Desktop: `npx -p @verygoodplugins/mcp-evernote mcp-evernote-auth` For detailed information about connection issues and recovery, see [CONNECTION_TROUBLESHOOTING.md](CONNECTION_TROUBLESHOOTING.md). ## Troubleshooting ### Authentication Issues #### "Authentication required" error in Claude Desktop This means you haven't authenticated yet. Run the authentication script: ```bash npx -p @verygoodplugins/mcp-evernote mcp-evernote-auth ``` Or if installed globally: ```bash mcp-evernote-auth ``` #### OAuth callback fails If the OAuth callback doesn't work: 1. Make sure port 3000 is available (or set `OAUTH_CALLBACK_PORT` in `.env`) 2. Check your firewall settings 3. Try using a different browser #### Token expired If your token expires, the server will now detect this automatically and prompt you to re-authenticate: 1. In Claude Code: Use `/mcp` command to re-authenticate 2. In Claude Desktop: Run `npx -p @verygoodplugins/mcp-evernote mcp-evernote-auth` Or use the reconnect tool to force immediate retry: ``` Reconnect to Evernote ``` ### Connection Errors The server now handles most connection errors automatically: - **Transient failures**: Auto-retry after 30 seconds - **Token expiry**: Clear error message with re-auth instructions - **Network issues**: Server stays alive and retries If issues persist: - Check your API credentials are correct - Verify you're using the right environment (sandbox vs production) - See [CONNECTION_TROUBLESHOOTING.md](CONNECTION_TROUBLESHOOTING.md) for detailed guidance ### Rate Limiting Evernote API has rate limits. If you encounter limits: - Reduce the frequency of requests - Use batch operations where possible - Implement caching for frequently accessed data ## Development ### Building from Source ```bash npm install npm run build ``` ### Running in Development Mode ```bash npm run dev ``` ### Testing ```bash npm test ``` ### Linting ```bash npm run lint npm run format ``` ## Security - Token lookup prefers `EVERNOTE_ACCESS_TOKEN`, then Claude Code OAuth env, then `.evernote-token.json` - Never commit token files to version control - Use environment variables for sensitive configuration - Local file attachments are restricted to `EVERNOTE_ALLOWED_FILE_ROOTS`; by default this is your home directory and the current working directory - Tokens expire after one year by default ## Contributing Contributions are welcome! Please: 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Add tests if applicable 5. Submit a pull request against `main` ## License GPL-3.0 - See [LICENSE](LICENSE) file for details. ## Support - **Issues**: [GitHub Issues](https://github.com/verygoodplugins/mcp-evernote/issues) ## Acknowledgments - Built with [Model Context Protocol SDK](https://github.com/anthropics/model-context-protocol) - Powered by [Evernote API](https://dev.evernote.com/) - Part of the [Very Good Plugins](https://verygoodplugins.com?utm_source=github) ecosystem ## Roadmap ### Near Term - [ ] **Tag Management** - Add/remove tags from existing notes - [x] **ENML ↔ Markdown Converter** - Bidirectional conversion between Evernote's ENML format and Markdown - [ ] **Real-time Sync Hooks** - Detect changes made via Evernote desktop/mobile apps - [ ] **Database Monitoring** - Watch Evernote DB service for live updates ### Future Enhancements - [ ] Web clipper functionality - [ ] Rich text editing support - [ ] File attachment handling - [ ] Shared notebook support - [ ] Business account features - [ ] Template system - [ ] Bulk operations - [ ] Export/Import tools - [ ] Advanced filtering options - [ ] Reminder management