
MCP Evernote
io.github.verygoodpluginsPublished by GitHub account verygoodpluginsv1.2.3Updated Oct 24, 2026
Evernote note management with OAuth and ENML conversion
Overview
Lets an assistant create, search, read, update, and delete Evernote notes, notebooks, and tags, with Markdown-to-ENML conversion and attachment handling.
- What you can do
- Provides 15 tools covering note operations (create, search, get, update, delete), notebook and tag management, attachment reading and upload, and connection/account checks. Content is converted between Markdown and Evernote's ENML format, including task lists and local file attachments. Search supports Evernote's query syntax with paging, and optional polling can notify a webhook when notes change.
- When to use it
- Useful when you want an assistant to capture, organize, or retrieve notes in an existing Evernote account, or to export and search notebooks from a chat session. It fits personal knowledge capture and note-driven workflows rather than general web or file access.
- Requirements
- Runs locally over stdio as an npm package, so Node.js is required (20.16+ or 22.3+, not 21.x or 22.0-22.2). Needs Evernote credentials: either OAuth consumer key and secret plus an access token, or a browser cookie token supplied as EVERNOTE_ACCESS_TOKEN. Optional settings include EVERNOTE_ENVIRONMENT, OAUTH_CALLBACK_PORT, polling and webhook variables, and EVERNOTE_ALLOWED_FILE_ROOTS.
Installation
In SourceWeft
- Open MCP Evernote in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
MCP Evernote Server
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 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_resourceto 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.
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
/mcpcommand - 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:
Change Notifications
Polling for Changes
The server can poll Evernote for changes and send webhook notifications when notes are created, updated, or deleted.
Configuration
Webhook Payload
When changes are detected, a POST request is sent to your webhook URL:
Manual Control
Use the evernote_polling tool to control polling:
polling({action:"start"})- Start polling manuallypolling({action:"stop"})- Stop pollingpolling({action:"poll"})- Check for changes immediatelypolling({action:"status"})- Get polling configuration and status
Evernote Webhooks (Real-time)
For real-time notifications, Evernote supports webhooks but requires manual registration:
-
Email
[email protected]with:- Your Consumer Key
- Webhook URL endpoint
- Any filters (optional)
-
They'll configure your webhook to receive HTTP GET requests on note create/update events.
Option 2: Global Installation
Install once, use anywhere:
Option 3: Local Development
For contributing or customization:
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 instead.
- Visit Evernote Developers
- Create a new application
- Copy your Consumer Key and Consumer Secret
2. Authentication Options
Interactive Setup (Recommended)
The auth script will prompt you for credentials if not found:
Environment Variables (Optional)
For automation, you can set credentials via environment variables:
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)
OAuth Authentication
- In Claude Code, type
/mcp - Select "Evernote"
- Choose "Authenticate"
- Follow the browser OAuth flow
- 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):
The auth script will:
- Prompt for your API credentials (if not in environment)
- Open your browser for OAuth authentication
- Save a compatible token file to
.evernote-token.json - Display the access token so you can use
EVERNOTE_ACCESS_TOKENinstead
Or if installed globally:
Step 2: Add to Configuration
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Or if installed globally:
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)
Step 1: Extract the Cookie
- Log in to www.evernote.com in your browser
- Open DevTools: F12 (Windows/Linux) or Cmd+Option+I (Mac)
- Navigate to the Application tab → Cookies →
www.evernote.com - Find the cookie named
clipper-sso - Copy its Value — it looks like:
Step 2: Configure Your Client
Claude Code:
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):
Note:
EVERNOTE_NOTESTORE_URLis not required when using the cookie token — the server fetches it automatically at startup.
Caveats
- Token expiry: The
clipper-ssotoken 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, re-extract the cookie, and updateEVERNOTE_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).
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)
4. Direct Token (Advanced)
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 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
<en-note>.- GFM task lists
- [ ]map to Evernote checkboxes<en-todo/>. - Checked tasks
- [x]map to<en-todo checked="true"/>.
- GFM task lists
-
- Local Markdown images/files (
orfile://...) are uploaded as Evernote resources automatically.
- Local Markdown images/files (
-
- Existing attachments are preserved by referencing
evernote-resource:<hash>in Markdown.
- Existing attachments are preserved by referencing
-
- Remote
http(s)images remain links (download locally if you want them embedded).
- Remote
-
- 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
and other files become[file](evernote-resource:<hash>)so you can round-trip them safely.
- Embedded images become
Limitations:
- Remote URLs are not fetched automatically; save them locally and reference the file to embed.
- Keep the
evernote-resource:<hash>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 titlecontent(required): Note content (plain text or markdown)notebookName(optional): Target notebook nametags(optional): Array of tag names
Example:
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 notebookmaxResults(optional): Results per page (default: 20, max: 100; capped at 25 whenincludeContentis true)offset(optional): Result offset for paging (default: 0)includeContent(optional): Include each note's full body incontent, one API call per note (default: false)format(optional): Body projection whenincludeContentis true —markdown(default),text, orenmlincludePreview(optional): Include a ~300-char plain-text preview per note (ignored whenincludeContentis true)
Export a whole notebook as text without a dedicated tool: query: "*", set notebookName + includeContent, and page with offset until hasMore is false.
Example:
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 textguids: array of up to 25 GUIDs — metadata +contentonly (no attachment text; use a singleguidfor 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, orenmlincludeContent(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:<hash>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 GUIDtitle(optional): New titlecontent(optional): New content (Markdown supported)notebookName(optional): Move the note to this notebooktags(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 namestack(optional): Stack name for organization
evernote_update_notebook
Rename a notebook or move it between stacks.
Parameters:
guid(required): Notebook GUIDname(optional): New notebook namestack(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 nameparentTagName(optional): Parent tag for hierarchy
evernote_update_tag
Rename a tag or re-parent it.
Parameters:
guid(required): Tag GUIDname(optional): New tag nameparentTagName(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'sresources[], viaevernote_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, andhasRecognition.
includeData(optional, deprecated):truemaps toas:"binary",falsetoas:"metadata".
There is no separate tool to list a note's attachments — evernote_get_note
returns them in resources[].
Example:
evernote_add_resource_to_note
Attach a local file to an existing note.
Parameters:
noteGuid(required): Target note GUIDfilePath(required): Path to the local file. Must sit under an allowed root — seeEVERNOTE_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). Passverbose:truefor 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:
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:
Search Syntax
Evernote supports advanced search operators:
intitle:keyword- Search in titlesnotebook:name- Search in specific notebooktag:tagname- Search by tagcreated:20240101- Search by creation dateupdated:day-1- Recently updated notesresource:image/*- Notes with imagestodo: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:
Memory Service Integration
To enable synchronization with MCP memory service:
- Set the memory service URL in your environment:
- Use the sync tools to persist important notes to memory:
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:
-
Try the reconnect tool (fastest):
-
Check server health:
-
Re-authenticate if needed:
- Claude Code:
/mcp→ Evernote → Authenticate - Claude Desktop:
npx -p @verygoodplugins/mcp-evernote mcp-evernote-auth
- Claude Code:
For detailed information about connection issues and recovery, see CONNECTION_TROUBLESHOOTING.md.
Troubleshooting
Authentication Issues
"Authentication required" error in Claude Desktop
This means you haven't authenticated yet. Run the authentication script:
Or if installed globally:
OAuth callback fails
If the OAuth callback doesn't work:
- Make sure port 3000 is available (or set
OAUTH_CALLBACK_PORTin.env) - Check your firewall settings
- Try using a different browser
Token expired
If your token expires, the server will now detect this automatically and prompt you to re-authenticate:
- In Claude Code: Use
/mcpcommand to re-authenticate - In Claude Desktop: Run
npx -p @verygoodplugins/mcp-evernote mcp-evernote-auth
Or use the reconnect tool to force immediate retry:
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 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
Running in Development Mode
Testing
Linting
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:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request against
main
License
GPL-3.0 - See LICENSE file for details.
Support
- Issues: GitHub Issues
Acknowledgments
- Built with Model Context Protocol SDK
- Powered by Evernote API
- Part of the Very Good Plugins ecosystem
Roadmap
Near Term
- Tag Management - Add/remove tags from existing notes
- 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
Source: README.md at commit 39891a1
Tools
0Version history
1- v1.2.3LatestSep 16, 2026
Score
40% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts
Declare a license in the repository or the registry entry.