Content
# my-evernote-mcp
A minimal local Evernote MCP server for personal use.
## Current Status
The first read-only implementation is now in the repository.
Implemented:
- Node.js CommonJS project skeleton
- MCP server over `stdio`
- Static `.env` configuration loading
- Read-only Evernote client wrapper
- `search_notes`
- `get_note`
- `get_note_content`
- ENML to plain text conversion
- Shared error mapping and `stderr` logging
Validated locally:
- Startup fails fast when required env vars are missing
- MCP `tools/list` returns the three expected tools
- MCP `tools/call` returns mapped Evernote auth errors for an invalid token
Not yet validated with real Evernote credentials:
- Successful `search_notes`
- Successful `get_note`
- Successful `get_note_content` in `text`
- Successful `get_note_content` in `enml`
## Goal
Build a first-version Evernote MCP server with these constraints:
- Node.js 18+
- CommonJS
- MCP over `stdio` only
- Read-only only
- Static credentials from `.env`
- Minimal dependencies
## Required Environment
Create a local `.env` file:
```bash
EVERNOTE_ACCESS_TOKEN=
EVERNOTE_EDAM_NOTE_STORE_URL=
```
The server fails fast at startup if either value is missing.
## Install
```bash
npm install
```
## Run
```bash
npm start
```
The server uses MCP over `stdio` only. Operational logs go to `stderr`. MCP protocol traffic uses `stdout`.
## Tools
### `search_notes`
Search Evernote note metadata only.
Example input:
```json
{
"query": "tag:\"project-x\"",
"limit": 10,
"offset": 0
}
```
Normalized output fields:
- `query`
- `total`
- `notes`
Each note includes:
- `guid`
- `title`
- `created`
- `updated`
- `contentLength`
- `notebookGuid`
- `tagGuids`
### `get_note`
Fetch note metadata without note content.
Example input:
```json
{
"guid": "NOTE_GUID"
}
```
Normalized output fields:
- `guid`
- `title`
- `created`
- `updated`
- `contentLength`
- `notebookGuid`
- `tagGuids`
- `attributes`
### `get_note_content`
Fetch note content as plain text or raw ENML.
Example input:
```json
{
"guid": "NOTE_GUID",
"format": "text"
}
```
Normalized output fields:
- `guid`
- `title`
- `format`
- `content`
Supported `format` values:
- `text`
- `enml`
## Project Structure
```text
my-evernote-mcp/
AGENTS.md
TODO.md
ISSUE_LIST.md
README.md
package.json
package-lock.json
.env.example
server.js
config.js
auth.js
evernote-client.js
errors.js
enml.js
note-normalizer.js
tools/
search-notes.js
get-note.js
get-note-content.js
```
## Implementation Notes
- `AGENTS.md` remains the source of truth for scope and constraints.
- Evernote SDK access is isolated in `evernote-client.js`.
- The server only uses `findNotesMetadata` and `getNote`.
- Startup and operational diagnostics are written to `stderr`.
- `dotenv` is loaded with quiet mode to avoid polluting MCP `stdout`.
## Known Limitations
- Read-only only
- No notebook name lookup
- No tag name lookup
- No HTML output
- No OAuth automation
- No HTTP transport
- No cache layer
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
Python tool for converting files and office documents to Markdown.
awesome-claude-skills
A curated list of awesome Claude Skills, resources, and tools for...
antigravity-awesome-skills
The Ultimate Collection of 130+ Agentic Skills for Claude...
claude-context-mode
claude-context-mode plugin reduces MCP context bloat, saving up to 99% of tokens.
context-mode
MCP is the protocol for tool access. We're the virtualization layer for context.