使用说明
Evernote MCP服务器
evernote-mcp-server 是一个Python MCP服务器,通过MCP公开Evernote笔记本和笔记操作 stdio.
它主要是为那些想在已发布的Docker镜像中从Gemini CLI使用它的人记录的。贡献者和维护者的工作流程将在本README的后面出现,因此第一个运行路径保持简单。
概述
此服务器将Evernote操作作为MCP工具公开。当前刀具表面包括:
- 笔记本工具:
list_notebooks - 阅读工具:
search_notes,get_note,get_note_metadata - 写入工具:
append_to_note_plaintext,insert_into_note_plaintext,set_note_title,add_tags_by_name,move_note,create_note,delete_note
insert_into_note_plaintext 通过获取当前ENML,在可见文本锚点之前或之后插入转义的明文块,并以乐观的并发性将完整的ENML文档保存回Evernote,支持富笔记的无损中间插入。它不接受原始ENML或HTML。
开始前的重要默认设置
READ_ONLY=true默认情况下,除非您明确选择加入,否则写入工具将被阻止。- 在正常运行时启动之前,需要一次OAuth引导才能与Evernote通信。
- OAuth访问令牌不存储在
.env;它们保存在Evernote MCP配置目录中。 - 仅
stdio传输是在v0.1中实现的。--transport sse故意不可用。
选择安装路径
大多数人应该使用已发布的Docker路径。这是到工作的Gemini MCP服务器的最短路径,不需要克隆此存储库。
- 使用 快速入门:发布Docker+Gemini 如果你想要默认的最终用户设置。
- 使用 参与者设置 如果您正在更改代码、运行测试或在本地调试。
- 使用 本机Windows本地Python安装程序 如果您希望Gemini CLI通过以下方式启动克隆的仓库
.venv\Scripts\python.exe没有WSL、Bash或Docker。 - 使用 故障排除 如果遵循以下匹配路径后安装失败。
配置和身份验证模型
这些设置适用于所有运行时路径。将本节作为配置行为的规范参考。
共享先决条件
每个运行时路径都需要相同的Evernote端先决条件:
- Evernote消费者凭证:
EVERNOTE_CONSUMER_KEY和EVERNOTE_CONSUMER_SECRET - 一个支持浏览器的环境,用于在本地主机上进行一次性OAuth授权
环境变量
| 变量 | 必填 | 默认 | 用途 |
|---|---|---|---|
EVERNOTE_CONSUMER_KEY |
需要 auth |
无 | Evernote OAuth消费者密钥 |
EVERNOTE_CONSUMER_SECRET |
需要 auth |
无 | Evernote OAuth消费者秘密 |
EVERNOTE_SANDBOX |
没有 | false |
使用Evernote沙箱OAuth和API端点 |
READ_ONLY |
没有 | true |
除非设置为,否则阻止写入工具 false |
LOG_LEVEL |
没有 | INFO |
流程日志冗长 |
接受的布尔值 EVERNOTE_SANDBOX 和 READ_ONLY:
true/false1/0yes/noon/off
按路径配置文件位置
- 发布的Docker路径在以下位置使用主机环境文件
~/.config/evernote-mcp-server/evernote-mcp.env - 参与者本地路径使用本地存储库
.env,通常由.env.example
保存的令牌位置和持久性
OAuth引导程序将Evernote访问令牌保存在Evernote MCP配置目录中,而不是 .env.
- 在一台普通的本地机器上,被拯救的代币存活在
$XDG_CONFIG_HOME/evernote-mcp-server/token.json当XDG_CONFIG_HOME已设置 - 否则,它就住在
~/.config/evernote-mcp-server/token.json - 在发布的Docker路径中,推荐的持久性模型是一个名为Docker的卷,挂载在
/home/appuser/.config/evernote-mcp-server
这种分离很重要,因为启动程序会从磁盘读取保存的令牌。如果令牌丢失,正常的服务器启动将失败,直到您再次运行OAuth引导程序。
快速入门:发布Docker+Gemini
这是大多数用户的推荐路径。它配置Gemini CLI以运行已发布的GHCR映像,在需要时创建持久的env文件,并为保存的OAuth状态创建Docker卷。
特定路径的先决条件
在运行安装程序之前,请确保这些本地工具可用:
bashcurldockerpython3- Gemini CLI
安装Gemini MCP入口
运行发布安装程序,使用最新发布的版本配置Gemini v* 图像标签。
curl -fsSL https://raw.githubusercontent.com/CopyPasteFail/evernote-mcp-server/main/scripts/install_gemini_mcp_release.sh | bash
安装程序对此路径执行三个重要操作:
- 配置Gemini MCP设置以使用已发布的GHCR映像
- 创造
~/.config/evernote-mcp-server/evernote-mcp.env如果它不存在 - 创建Docker卷
evernote-mcp-auth如果它不存在
填写环境文件
在尝试OAuth引导之前,请编辑生成的env文件。至少,填写Evernote消费者凭证。离开 READ_ONLY=true 除非您有意启用写入工具。
- 环境文件:
~/.config/evernote-mcp-server/evernote-mcp.env
运行一次性OAuth Bootstrap
填充env文件后,初始化Docker卷所有权一次,然后运行一次性OAuth引导命令。安装程序会打印带有配置的映像标签和卷的两个命令。
Docker命名的卷最初可能由root拥有,而此映像以非root身份运行 appuser。初始化卷所有权一次可以避免令牌保存失败:
docker run --rm --user root \
-v evernote-mcp-auth:/home/appuser/.config/evernote-mcp-server \
ghcr.io/CopyPasteFail/evernote-mcp-server:latest \
python -c "import os; p='/home/appuser/.config/evernote-mcp-server'; os.makedirs(p, exist_ok=True); os.chown(p, 1000, 1000); os.chmod(p, 0o700)"
然后运行容器身份验证:
docker run --rm -it \
--env-file ~/.config/evernote-mcp-server/evernote-mcp.env \
-v evernote-mcp-auth:/home/appuser/.config/evernote-mcp-server \
-p 8765:8765 \
ghcr.io/CopyPasteFail/evernote-mcp-server:latest \
python -m evernote_mcp auth \
--listen-host 0.0.0.0 \
--listen-port 8765 \
--callback-url http://127.0.0.1:8765/callback
OAuth引导程序打开浏览器进行Evernote授权,然后将令牌保存到已挂载的配置卷中,以便Gemini可以在以后的运行中重用它。
为什么有效:监听器在容器内绑定(0.0.0.0:8765)而Evernote重定向到主机可见的回调URL(127.0.0.1:8765)通过已发布的Docker端口。
WSL注释:浏览器自动打开在某些环境中仍可能失败;CLI会打印授权URL,以便您可以手动打开它。
参与者设置
如果您正在迭代代码、运行测试或在本地调试服务器,请使用此路径。
共享贡献者先决条件
稍后选择您想要的本地运行时,但存储库引导是共享的:
- Git
- Python 3.13
- 如果您希望Gemini启动本地运行时,请使用Gemini CLI
- 仅当您选择本地Docker运行时
克隆回购并创建本地配置
在选择运行时路径之前,克隆存储库并创建本地env文件。
git clone https://github.com/CopyPasteFail/evernote-mcp-server.git
cd evernote-mcp-server
cp .env.example .env
在共享设置之后,选择一个本地运行时。
选项A:本地Python运行时
当您想要最快的编辑-运行-测试循环并直接访问Python进程时,请使用此路径。
在本机Windows上,请按照专用 本机Windows本地Python安装程序 而不是下面的POSIX shell命令。
python3.13 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
PYTHONPATH=src python -m evernote_mcp auth
python3 scripts/install_gemini_mcp.py --mode python
此路径安装开发依赖项,对本地环境运行OAuth引导程序,并可选择更新Gemini设置,以便Gemini可以启动本地Python运行时。不要使用手动启动的 --transport stdio 作为端到端测试的过程;stdio MCP期望客户端提供JSON-RPC。
本地安装程序写入Gemini CLI设置。在运行它之前,请确认Gemini CLI已安装 gemini --version 或 Get-Command gemini,然后运行 gemini 只需一次,即可使用拥有Gemini订阅的Google帐户登录。使用 --print-config 当您只希望JSON手动检查或复制到另一个MCP客户端时。
选项B:本地Docker运行时
当您希望将本地代码更改打包在容器中,同时保持与基于Docker的使用相同的通用运行时模型时,请使用此路径。
docker build -t evernote-mcp-server:local .
docker volume create evernote-mcp-auth
初始化卷所有权一次:
docker run --rm --user root \
-v evernote-mcp-auth:/home/appuser/.config/evernote-mcp-server \
evernote-mcp-server:local \
python -c "import os; p='/home/appuser/.config/evernote-mcp-server'; os.makedirs(p, exist_ok=True); os.chown(p, 1000, 1000); os.chmod(p, 0o700)"
然后运行容器身份验证:
docker run --rm -it \
--env-file .env \
-v evernote-mcp-auth:/home/appuser/.config/evernote-mcp-server \
-p 8765:8765 \
evernote-mcp-server:local \
python -m evernote_mcp auth \
--listen-host 0.0.0.0 \
--listen-port 8765 \
--callback-url http://127.0.0.1:8765/callback
然后将Gemini配置为本地Docker模式:
python3 scripts/install_gemini_mcp.py --mode docker
在OAuth引导和Gemini设置之后,运行时使用相同的Docker卷
您可以通过运行以下命令来检查卷现在是否具有令牌:
docker run --rm -it \
-v evernote-mcp-auth:/home/appuser/.config/evernote-mcp-server \
evernote-mcp-server:local \
python -c "from pathlib import Path; p=Path('/home/appuser/.config/evernote-mcp-server/token.json'); print(p.exists(), p)"
它应该打印 True 和路径。
验证安装
完成任一设置路径后,在尝试任何更复杂的操作之前,请使用简单的只读调用验证服务器。
使用这样的Gemini提示:
Use MCP server "evernote-mcp-server" and call list_notebooks. Return the names of 2 notebooks.
如果这有效,MCP接线、Evernote身份验证和保存的令牌状态都在预期的位置。
第二个健全性检查是保持 READ_ONLY=true 起初。这证实了写入工具在您有意启用之前一直处于阻止状态。
故障排除
缺少消费者凭据
如果OAuth引导程序因缺少凭据而失败,请验证是否在所选路径的env文件中设置了这两个凭据:
EVERNOTE_CONSUMER_KEYEVERNOTE_CONSUMER_SECRET
丢失已保存的令牌
如果启动失败是因为缺少Evernote令牌,请使用相同的env文件和所选路径的相同持久性位置再次运行OAuth引导程序。
沙盒不匹配警告
如果保存的令牌是使用与当前不同的沙盒设置创建的 EVERNOTE_SANDBOX 值,使用您实际想要使用的沙盒模式重新运行OAuth引导程序。
写入被阻止
如果写入工具失败,请检查 READ_ONLY。安全默认值为 true,因此在您设置之前,写入操作将一直被阻止 READ_ONLY=false 并重新启动读取该env文件的运行时。
sse 不起作用
sse v0.1中故意不实现传输。使用 --transport stdio.
贡献者工作流
这些步骤用于在本地设置工作后进行持续开发。
运行开发检查
在推动更改之前,运行完整的本地检查套件。
make lint
make security
make test
make check
需要验证时,单独运行容器漏洞扫描 Docker镜像在本地运行,而不将其作为默认贡献者循环的一部分。
make container-security
此目标构建 evernote-mcp-server:local 并运行Trivy图像扫描
失败在 HIGH 或 CRITICAL 调查结果。
此可选检查需要本地Docker和 trivy 待安装。
本地Trivy运行故意比GitHub Actions更严格,可能会在
CI忽略的未修复的基础映像漏洞。
可选预推钩
如果你想让Git运行 make check 自动推送之前 main,将Git指向存储库挂钩路径。
git config core.hooksPath .githooks
chmod +x .githooks/pre-push
维护人员工作流程
本节有意与首次设置和贡献者入职分开。
创建发布标签
使用发布脚本创建并推送下一个语义版本标签 main.
./scripts/release.sh patch
支持的凹凸类型有 patch, minor,以及 major.
如果标签推送被拒绝 GH013 和 creations being restricted,您的存储库标记规则集正在阻止为您的参与者创建标记。将旁路参与者(维护者用户/团队/应用程序)添加到 v* 标记规则集,然后再次运行release命令。
发布工作流行为
发布过程受到保护:
- 仅从匹配的标签创建发布
v* - 脚本需要一个干净的工作树
main - 脚本获取
origin/main如果是当地人,则拒绝继续HEAD不匹配 make check在创建标记之前必须通过- GitHub发布工作流验证标记的提交是否可从以下位置访问
origin/main,重播make check,然后发布GHCR镜像和GitHub版本
可选的存储库强化脚本
这些脚本是维护人员专用的存储库强化工具,通常每个存储库只需要运行一次:
建议一次性设置Dependabot默认值和漏洞警报:
./scripts/setup-dependabot.sh
建议一次性设置释放标签保护规则:
./scripts/setup-tag-protection.sh
重要提示:限制创建的标签保护规则必须包括一个显式的绕过角色,用于运行维护者身份 ./scripts/release.sh,否则所有标签推送都被阻止。
这两个脚本都使用经过身份验证的GitHub CLI会话来应用存储库设置。
建筑与进一步阅读
本自述文件有意专注于入职培训和常见工作流程。有关更深入的设计和实现细节,请阅读 docs/ARCHITECTURE.md.
该文件涵盖:
- 交通抽象与当前
stdio/未来sse分裂 - MCP工具如何注册并向客户端公开
- 安全模型,包括令牌持久性和写策略执行
- Evernote Thrift整合理论
- 发布模型细节和未来改进领域
