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.
Version: 1.0.0
Release Date: August 29th, 2025
- 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
- OAuth Authentication: Handled automatically via
/mcpcommand - Repository Download: Not required
- Setup: Single command installation
- 🔐 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
The simplest way - no need to install anything globally:
# For Claude Desktop - Run authentication
npx -p @verygoodplugins/mcp-evernote mcp-evernote-auth
# For Claude Code - Just add the server
claude mcp add evernote "npx @verygoodplugins/mcp-evernote"The server can poll Evernote for changes and send webhook notifications when notes are created, updated, or deleted.
# 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/evernoteWhen changes are detected, a POST request is sent to your webhook URL:
{
"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"
}
]
}Use these tools to control polling:
evernote_start_polling- Start polling manuallyevernote_stop_polling- Stop pollingevernote_poll_now- Check for changes immediatelyevernote_polling_status- Get polling configuration and status
For real-time notifications, Evernote supports webhooks but requires manual registration:
-
Email
devsupport@evernote.comwith:- Your Consumer Key
- Webhook URL endpoint
- Any filters (optional)
-
They'll configure your webhook to receive HTTP GET requests on note create/update events.
Install once, use anywhere:
# 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"For contributing or customization:
# Clone and install
git clone https://github.com/verygoodplugins/mcp-evernote.git
cd mcp-evernote
npm install
# Run setup wizard
npm run setup- Visit Evernote Developers
- Create a new application
- Copy your Consumer Key and Consumer Secret
The auth script will prompt you for credentials if not found:
# Run authentication - prompts for API keys if needed
npx -p @verygoodplugins/mcp-evernote mcp-evernote-authFor automation, you can set credentials via environment variables:
# 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 notificationsClaude Code Configuration
claude mcp add evernote "npx @verygoodplugins/mcp-evernote" \
--env EVERNOTE_CONSUMER_KEY=your-key \
--env EVERNOTE_CONSUMER_SECRET=your-secret- 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
Using NPX (no installation required):
npx -p @verygoodplugins/mcp-evernote mcp-evernote-authThe auth script will:
- Prompt for your API credentials (if not in environment)
- Optionally save credentials for future use
- Open your browser for OAuth authentication
- Save the token to
.evernote-token.json - Display the configuration to add to Claude Desktop
Or if installed globally:
mcp-evernote-authmacOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"evernote": {
"command": "npx",
"args": ["@verygoodplugins/mcp-evernote"],
"env": {
"EVERNOTE_CONSUMER_KEY": "your-consumer-key",
"EVERNOTE_CONSUMER_SECRET": "your-consumer-secret",
"EVERNOTE_ENVIRONMENT": "production"
}
}
}
}Or if installed globally:
{
"mcpServers": {
"evernote": {
"command": "mcp-evernote",
"env": {
"EVERNOTE_CONSUMER_KEY": "your-consumer-key",
"EVERNOTE_CONSUMER_SECRET": "your-consumer-secret"
}
}
}
}Claude Code handles OAuth automatically via the /mcp command. Tokens are managed by Claude Code.
Run npx -p @verygoodplugins/mcp-evernote mcp-evernote-auth to authenticate via browser. Token saved to .evernote-token.json.
EVERNOTE_ACCESS_TOKEN=your-token
EVERNOTE_NOTESTORE_URL=your-notestore-url{
"env": {
"EVERNOTE_ACCESS_TOKEN": "your-access-token",
"EVERNOTE_NOTESTORE_URL": "your-notestore-url"
}
}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.
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:
Create a note titled "Meeting Notes" with content "Discussed Q4 planning" in notebook "Work" with tags ["meetings", "planning"]
Search for notes using Evernote's search syntax.
Parameters:
query(required): Search querynotebookName(optional): Limit to specific notebookmaxResults(optional): Maximum results (default: 20, max: 100)
Example:
Search for notes containing "project roadmap" in the "Work" notebook
Retrieve a specific note by GUID.
Parameters:
guid(required): Note GUIDincludeContent(optional): Include note content (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.
Update an existing note.
Parameters:
guid(required): Note GUIDtitle(optional): New titlecontent(optional): New contenttags(optional): New tags (replaces existing)
Delete a note.
Parameters:
guid(required): Note GUID
List all notebooks in your account.
Create a new notebook.
Parameters:
name(required): Notebook namestack(optional): Stack name for organization
List all tags in your account.
Create a new tag.
Parameters:
name(required): Tag nameparentTagName(optional): Parent tag for hierarchy
Get current user information and quota usage.
Revoke stored authentication token.
Check the health and status of the Evernote MCP server.
Parameters:
verbose(optional): Include detailed diagnostic information (default: false)
Returns:
- Server status (healthy, unhealthy, needs_auth, etc.)
- Authentication status
- Token information (when verbose)
- Configuration details
Example:
Check Evernote connection health with verbose details
Force reconnection to Evernote. Useful when experiencing "Not connected" errors.
Use this when:
- You see "Not connected" errors
- You've just refreshed your token
- The server seems stuck in a failed state
Example:
Reconnect to Evernote
Start polling for Evernote changes. Checks for new/updated/deleted notes and sends notifications to the configured webhook URL.
Example:
Start polling for Evernote changes
Stop the polling process.
Check for changes immediately without waiting for the next poll interval. Returns a list of detected changes.
Example:
Check for Evernote changes now
Get the current polling configuration and status, including:
- Whether polling is running
- Poll interval
- Configured webhook URL
- Last poll time
- Error count
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
This MCP server works seamlessly with the Claude Automation Hub for workflow automation:
// 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']
}
};
}
};To enable synchronization with MCP memory service:
- Set the memory service URL in your environment:
MCP_MEMORY_SERVICE_URL=http://localhost:8765- Use the sync tools to persist important notes to memory:
Sync my "Important Concepts" notebook to memory for long-term retention
The server includes automatic recovery from connection issues:
- 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
If you see "Not connected" errors, the server will usually recover automatically. You can also:
-
Try the reconnect tool (fastest):
Reconnect to Evernote -
Check server health:
Check Evernote connection health with verbose details -
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.
This means you haven't authenticated yet. Run the authentication script:
npx -p @verygoodplugins/mcp-evernote mcp-evernote-authOr if installed globally:
mcp-evernote-authIf 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
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:
Reconnect to Evernote
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
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
npm install
npm run buildnpm run devnpm testnpm run lint
npm run format- OAuth tokens are stored locally in
.evernote-token.json - Never commit token files to version control
- Use environment variables for sensitive configuration
- Tokens expire after one year by default
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
GPL-3.0 - See LICENSE file for details.
- Issues: GitHub Issues
- Built with Model Context Protocol SDK
- Powered by Evernote API
- Part of the Very Good Plugins ecosystem
- 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
- 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