Evernote
Conecta sua conta do Evernote a um LLM, permitindo pesquisa e consultas em linguagem natural sobre suas notas.
Documentação
Servidor MCP Evernote
Um servidor MCP local que conecta o Claude Desktop (ou qualquer LLM compatível com MCP) à sua conta Evernote, permitindo consultas contextuais e buscas em suas notas usando linguagem natural.
🎯 Objetivo do Projeto
Permitir acesso local e seguro às suas notas do Evernote com assistência de IA. Por exemplo:
"Resuma todas as minhas notas do Evernote sobre meu barco Sea Pro."
Este projeto permite que o LLM envie chamadas MCP como createSearch, getNote e getNoteContent, que são traduzidas em chamadas de API para o Evernote. A resposta é retornada ao LLM em um formato estruturado.
🚀 Novidades na v2.0+
v2.0.0: Implantação Docker pronta para produção
- 🐳 Configuração em um comando:
docker-compose uppara implantação instantânea - 🔐 Autenticação persistente: Tokens OAuth sobrevivem a reinicializações do contêiner
- 🛡️ Segurança em primeiro lugar: Imagens base mínimas Red Hat Hummingbird com zero CVEs
- ⚡ Builds otimizados: Builds Docker em múltiplas etapas para footprint mínimo de produção
- 🔧 Configuração automática: Certificados SSL e configuração de ambiente tratados automaticamente
v2.0.1: Suporte aprimorado ao protocolo MCP
- 🌐 Servidor MCP remoto: Suporte a HTTP/JSON-RPC 2.0 para integração com Claude Desktop em contêiner
- 🔄 Modos de integração dupla: Escolha entre integração local stdin/stdout ou HTTPS remota
- 📋 Conformidade com a especificação MCP: Definições de ferramentas e nomes de métodos atualizados para corresponder à especificação oficial do MCP
- 🎯 Respostas inteligentes: Resumos legíveis em vez de despejos JSON brutos
- 🌍 Compatibilidade entre plataformas: Supera limitações de stdin/stdout do Docker no Windows/Linux
v2.1.0: Estabilidade do contêiner e resiliência a erros
- 🛡️ Tratamento global de erros: Adicionados manipuladores de exceções não capturadas e rejeições não tratadas para evitar falhas no processo
- 🔄 Estabilidade do contêiner: Eliminados ciclos de reinicialização de 2 a 3 minutos em implantações conteinerizadas (Podman/Docker)
- 📊 Registro de erros aprimorado: Melhor visibilidade de erros em produção com carimbos de data/hora e rastreamento de PID
- 🎯 Degradação graciosa: O servidor continua em execução mesmo com falhas de autenticação ou API
- 🚫 Saídas de processo removidas: Chamadas fatais de process.exit() substituídas por tratamento gracioso de erros
- ⚡ Testado em produção: Estabilidade do contêiner verificada em modo de produção sem registro de depuração DEV_MODE
v2.1.1: Otimização de registro em produção
- 🧹 Registro mínimo em produção: Código de depuração detalhado limpo para implantações de produção
- 🎯 Componentes essenciais de estabilidade: Mantidos manipuladores críticos de sinais e tratamento global de erros
- 📝 Registro condicional DEV_MODE: Saída de depuração opcional aparece apenas quando DEV_MODE=true
- ⚡ Estabilidade do loop de eventos: Keepalive mínimo evita que o Node.js fique inativo em contêineres
- ✅ Estabilidade do contêiner verificada: Teste de estabilidade de 10+ minutos confirmou nenhum ciclo de reinicialização em modo de produção
✅ Recursos
- Suporta acesso somente leitura ao Evernote (buscar, ler e listar notas)
- Autenticação OAuth 1.0a com abertura automática do navegador para autorização segura
- Persistência automática de tokens no arquivo .env para reautenticação contínua
- 🆕 v1.1.0: Detecção automática de expiração de token - O servidor verifica a validade do token na inicialização
- 🆕 v1.1.0: Prompts interativos de reautenticação - Prompts amigáveis quando os tokens expiram
- 🆕 v1.1.0: Tratamento aprimorado de erros - Relato específico de códigos de erro EDAMUserException
- 🆕 v1.1.0: Gerenciamento proativo de tokens - Evita falhas de API por credenciais expiradas
- 🆕 v1.1.1: Persistência automática de tokens no .env - Tokens salvos automaticamente no arquivo .env (substituiu o macOS Keychain para compatibilidade entre plataformas)
- 🆕 v1.1.2: Endurecimento de segurança - Zero CVEs com overrides npm para dependências vulneráveis
- 🆕 v2.0.0: Implantação Docker pronta para produção - Conteinerização completa com imagens seguras Chainguard
- 🆕 v2.0.1: Conformidade aprimorada com o protocolo MCP - Suporte a servidor HTTP/JSON-RPC remoto e formatação inteligente de respostas
- 🆕 v2.1.0: Melhorias de estabilidade do contêiner - Ciclos de reinicialização eliminados com tratamento global de erros e degradação graciosa
- 🆕 v2.1.1: Otimização de registro em produção - Registro mínimo e limpo para produção com saída de depuração condicional DEV_MODE
- Servidor somente HTTPS com certificados autoassinados para desenvolvimento local
- Projetado para funcionar com integrações MCP do Claude Desktop, com preparação para outros LLMs (ex.: ChatGPT Desktop)
- Registro de depuração configurável via variável de ambiente
DEV_MODEcom redação automática de tokens por segurança - Fácil de estender posteriormente para criação, atualização ou exclusão de notas
🧰 Pilha de Tecnologias
- Node.js + Express com HTTPS
- API do Evernote (OAuth 1.0a + REST)
- Armazenamento de tokens em variáveis de ambiente com dotenv
- Conformidade com o protocolo MCP
- Conteinerização Docker com imagens base seguras Chainguard
🗝️ Autenticação
O Evernote usa OAuth 1.0a (não OAuth 2.0) para autenticação de API:
- Configuração inicial: Fluxo OAuth 1.0a baseado em navegador com troca automática de tokens
- Armazenamento de tokens: Tokens de acesso salvos automaticamente no arquivo .env para persistência
- Reutilização automática: Tokens armazenados são carregados e usados automaticamente para chamadas de API subsequentes
- Ambiente de produção: Usa a API de produção do Evernote (sandbox descontinuado)
- Compatibilidade entre plataformas: Funciona em macOS, Linux e Windows com armazenamento de tokens baseado em arquivo
🔒 Segurança
Gerenciamento de Vulnerabilidades
Este projeto usa npm overrides para garantir que todas as dependências usem versões seguras, eliminando pacotes vulneráveis aninhados:
{
"overrides": {
"ws": "^8.18.3"
}
}
Por que overrides são necessários: Dependências como thrift podem incluir suas próprias versões vulneráveis (ex.: ws@5.2.4) em node_modules aninhados. Atualizações npm padrão afetam apenas dependências de nível superior, deixando pacotes aninhados vulneráveis. O campo overrides força TODAS as instâncias de um pacote a usar a versão segura.
Recursos de segurança:
- ✅ Zero CVEs em varreduras de vulnerabilidade Docker
- ✅ Imagens base seguras Chainguard (distroless, superfície de ataque mínima)
- ✅ Somente HTTPS com validação de certificado
- ✅ Acesso somente leitura à API do Evernote
- ✅ Nenhuma transmissão de dados a terceiros, exceto para o Evernote
- ✅ Redação automática de tokens em registros de depuração
💻 Configuração
🐳 Implantação Docker (Recomendada)
Início rápido:
git clone https://github.com/brentmid/evernote-mcp-server.git
cd evernote-mcp-server
cp .env.example .env
# Edit .env with your Evernote API credentials
docker-compose up --build
O que você obtém:
- ✅ Configuração instantânea com zero dependências locais
- ✅ Imagens base seguras Chainguard prontas para produção
- ✅ Geração automática de certificados SSL
- ✅ Tokens OAuth persistem entre reinicializações do contêiner
- ✅ Varredura de segurança com zero CVE
🛠️ Desenvolvimento Local
Requisitos:
- Node.js 18+
- OpenSSL para geração de certificados SSL
- Conta de desenvolvedor Evernote e credenciais de API
- Docker Desktop (para implantação conteinerizada)
- Chave SSH do GitHub configurada via 1Password (para desenvolvimento)
- Visual Studio Code com extensões GitHub Copilot e Copilot Chat (para desenvolvimento)
Clonar e Configurar
git clone git@github.com:brentmid/evernote-mcp-server.git
cd evernote-mcp-server
npm install
Obter Credenciais da API do Evernote
- Registre seu aplicativo em Evernote Developers
- Crie um novo aplicativo e anote sua Consumer Key e Consumer Secret
- Defina a URL de callback para
https://localhost:3443/oauth/callback
Configurar Variáveis de Ambiente
Defina suas credenciais da API do Evernote:
# Add to your shell profile (.zshrc, .bashrc, etc.)
export EVERNOTE_CONSUMER_KEY="your-consumer-key-here"
export EVERNOTE_CONSUMER_SECRET="your-consumer-secret-here"
# Optional: Enable detailed debug logging for development
export DEV_MODE=true
# Reload your shell or run:
source ~/.zshrc
Gerar Certificados SSL
O servidor roda sobre HTTPS e requer certificados SSL para desenvolvimento local:
# Create certificate directory
mkdir cert
# Generate self-signed certificate (valid for 365 days)
openssl req -x509 -newkey rsa:4096 -keyout cert/localhost.key -out cert/localhost.crt -days 365 -nodes -subj "/C=US/ST=Local/L=Local/O=Local/OU=Local/CN=localhost"
Iniciar o Servidor
npx node index.js
O servidor iniciará em https://localhost:3443. Seu navegador mostrará um aviso de segurança para o certificado autoassinado - isso é normal para desenvolvimento local.
⏰ Tratamento de Expiração de Token (v1.1.0+)
O servidor agora verifica automaticamente tokens de autenticação expirados na inicialização:
Para Tokens Válidos:
🚀 Starting Evernote MCP Server...
🔍 Token status: Token valid until 8/21/2025, 1:20:00 AM
✅ Using existing valid authentication tokens
✅ Authentication ready
🌐 Evernote MCP Server listening on HTTPS port 3443
Para Tokens Expirados:
🚀 Starting Evernote MCP Server...
🔍 Token status: Token expired on 6/16/2025, 9:55:49 PM
⚠️ Your Evernote authentication tokens have expired.
Would you like to re-authenticate now? (y/N): y
🧹 Re-authenticating with Evernote...
🚀 Starting Evernote OAuth flow...
Se você escolher N (não), o servidor sairá graciosamente com instruções para reiniciar e escolher y quando estiver pronto para reautenticar.
Primeira Execução e Fluxo OAuth
- Gere certificados SSL (veja instruções de configuração acima)
- Defina variáveis de ambiente com suas credenciais da API do Evernote
- Inicie o servidor:
npx node index.js - Conclua a autenticação OAuth:
- O servidor abre automaticamente seu navegador na página de autorização do Evernote
- Aceite o aviso de certificado autoassinado no navegador
- Faça login na sua conta Evernote e autorize o aplicativo
- Você será redirecionado de volta ao servidor com uma mensagem de sucesso
- O token de acesso é armazenado automaticamente no arquivo .env para uso futuro
Detalhes do Fluxo OAuth
O servidor implementa o fluxo OAuth 1.0a do Evernote:
- Token de Solicitação: O servidor gera um token de solicitação temporário
- Autorização do Usuário: O navegador abre a URL de autorização do Evernote
- Callback: O usuário autoriza o aplicativo, o Evernote redireciona para a URL de callback
- Token de Acesso: O servidor troca o token de solicitação por um token de acesso permanente
- Armazenamento: O token de acesso é armazenado com segurança no arquivo .env
Nota: O servidor usa o ambiente de produção do Evernote (o sandbox foi descontinuado pelo Evernote).
🐳 Implantação Docker
Início Rápido com Docker
A maneira mais fácil de executar o servidor MCP Evernote é usando Docker com a imagem de contêiner segura baseada em Chainguard fornecida:
# Clone the repository
git clone https://github.com/brentmid/evernote-mcp-server.git
cd evernote-mcp-server
# Copy environment template
cp .env.example .env
# Edit .env with your Evernote API credentials
vim .env
# Build and run the container
docker-compose up --build
O servidor estará disponível em https://localhost:3443.
Arquitetura Docker
A configuração Docker usa a imagem base Node.js segura da Chainguard (cgr.dev/chainguard/node:latest), que fornece:
- Zero vulnerabilidades - Superfície de ataque mínima com apenas pacotes essenciais
- Imagens de contêiner assinadas - Todas as imagens assinadas com Sigstore para segurança da cadeia de suprimentos
- SBOM incluído - Bill of Materials de Software gerado no momento do build
- Execução não-root - Contêineres executados como usuário não-root para segurança aprimorada
- Tamanho mínimo - Apenas 145MB em comparação com 1.12GB para imagens Node.js padrão
Visão Geral dos Arquivos Docker
A configuração Docker inclui vários arquivos-chave:
Dockerfile
Processo de build em múltiplas etapas:
- Estágio de build: Usa
cgr.dev/chainguard/node:latest-devcom git e openssl para configuração - Estágio de produção: Usa
cgr.dev/chainguard/node:latestmínimo para runtime - Integração GitHub: Clona o código mais recente diretamente do seu repositório GitHub
- Certificados SSL: Gera automaticamente certificados autoassinados para HTTPS
- Segurança: Executa como usuário não-root com dependências mínimas
docker-compose.yml
Configuração de orquestração:
- Variáveis de ambiente: Carregadas do arquivo
.envou do ambiente - Mapeamento de portas: Expõe a porta HTTPS 3443 para o host
- Verificações de saúde: Monitoramento de saúde do contêiner integrado
- Política de reinicialização: Reinicia automaticamente em caso de falha
- Argumentos de build: URL do repositório GitHub configurável
.dockerignore
Otimiza o contexto de build excluindo:
- Módulos Node, registros e arquivos de desenvolvimento
- Dados do repositório Git e documentação
- Arquivos de teste e configurações
- Certificados SSL (gerados no contêiner)
.env.example
Modelo para variáveis de ambiente:
EVERNOTE_CONSUMER_KEY=your_consumer_key_here
EVERNOTE_CONSUMER_SECRET=your_consumer_secret_here
DEV_MODE=false
Opções de Build Docker
Opção 1: Docker Compose (Recomendado)
# Build and run with compose
docker-compose up --build
# Run in background
docker-compose up -d --build
# View logs
docker-compose logs -f
# Stop and remove
docker-compose down
Opção 2: Build Docker Direto
# Build image
docker build \
--build-arg GITHUB_REPO_URL=https://github.com/yourusername/evernote-mcp-server.git \
-t evernote-mcp-server .
# Run container
docker run -d \
--name evernote-mcp \
-p 3443:3443 \
-e EVERNOTE_CONSUMER_KEY=your_key \
-e EVERNOTE_CONSUMER_SECRET=your_secret \
evernote-mcp-server
# View logs
docker logs -f evernote-mcp
Atualizações Automatizadas de Contêiner
O repositório inclui evernote-mcp-daily-rebuild.sh, um script shell projetado para reconstruções automatizadas diárias para manter suas imagens base Chainguard atualizadas:
# Set up daily rebuild (example cron job)
0 2 * * * /path/to/your/evernote-mcp-server/evernote-mcp-daily-rebuild.sh >> /tmp/evernote-mcp-rebuild.log 2>&1
O que o script faz:
- Baixa a imagem base
cgr.dev/chainguard/node:latestmais recente - Reconstrói o contêiner com
--no-cachepara garantir dependências atualizadas - Reinicia o serviço com zero tempo de inatividade usando Docker Compose
Benefícios de segurança:
- Garante que você sempre tenha os patches de segurança mais recentes da Chainguard
- Mantém o status de zero CVE com atualizações automatizadas de imagem base
- Nenhuma intervenção manual necessária para atualizações de segurança
Configuração Docker
Variáveis de Ambiente
O contêiner aceita estas variáveis de ambiente:
EVERNOTE_CONSUMER_KEY- Sua chave de consumidor da API Evernote (obrigatória)EVERNOTE_CONSUMER_SECRET- Seu segredo de consumidor da API Evernote (obrigatório)DEV_MODE- Ativar registro de depuração (opcional, padrão: false)NODE_ENV- Ambiente Node.js (definido como production no contêiner)
Montagens de Volume (Opcional)
Para armazenamento persistente de tokens entre reinicializações do contêiner:
volumes:
- ./tokens:/app/tokens # If implementing file-based token storage
Verificações de Saúde
O contêiner inclui monitoramento de saúde integrado:
- Endpoint: Verificação de saúde HTTPS interna na porta 3443
- Intervalo: A cada 30 segundos
- Tempo limite: 10 segundos
- Tentativas: 3 tentativas antes de marcar como não saudável
- Período inicial: 40 segundos para inicialização
Solução de Problemas do Docker
Problemas Comuns
Falha na compilação com "git not found":
- Garanta que seu repositório GitHub seja público ou configure a autenticação
- Verifique o argumento de compilação
GITHUB_REPO_URLno docker-compose.yml
Erros de certificado SSL:
- Os certificados são gerados automaticamente no contêiner
- Seu navegador mostrará avisos de segurança para certificados autoassinados (normal)
- Aceite o aviso de certificado para continuar
Falhas na verificação de saúde do contêiner:
- Verifique os logs do contêiner:
docker-compose logs evernote-mcp-server - Verifique se as variáveis de ambiente estão definidas corretamente
- Garanta que as credenciais da API Evernote sejam válidas
Loops de reinicialização do contêiner (a cada 2-3 minutos):
- ✅ RESOLVIDO (5 de agosto de 2025): Problema de estabilidade do contêiner corrigido pela implementação otimizada da verificação de saúde
- ✅ Causa raiz identificada: O comando de verificação de saúde do Node.js estava criando processos de tempo limite acumulados
- ✅ Solução: Verificação de saúde simplificada do Node.js com tratamento adequado de tempo limite elimina o acúmulo de processos
- Detalhes: Consulte CLAUDE.md para a linha do tempo completa da investigação e análise da resolução técnica
- Ferramentas de diagnóstico: Use os scripts de depuração fornecidos para problemas semelhantes (consulte a seção Depuração abaixo)
- Status: Contêiner rodando estável com verificações de saúde adequadas, nenhum ciclo de reinicialização detectado
Problemas de fluxo OAuth no contêiner:
- O fluxo OAuth completo pode exigir a execução do servidor localmente primeiro
- O contêiner herda tokens do host se usar montagens de volume
- Considere executar
node index.jslocalmente primeiro e depois conteinerizar
Logs e Depuração do Docker
# View container logs
docker-compose logs -f evernote-mcp-server
# Enable debug mode
echo "DEV_MODE=true" >> .env
docker-compose up --build
# Execute commands in running container
docker-compose exec evernote-mcp-server sh
# Check container health
docker-compose ps
Considerações de Segurança
A configuração do Docker implementa várias práticas recomendadas de segurança:
- Imagem base mínima: Imagem distroless Node.js da Chainguard
- Execução não raiz: O contêiner roda como usuário
node(não raiz) - Somente HTTPS: Toda comunicação via HTTPS seguro
- Isolamento de ambiente: Segredos passados via variáveis de ambiente
- Segurança de rede: Apenas a porta necessária (3443) exposta
- Segurança da cadeia de suprimentos: Imagens base assinadas com SBOMs
Otimização de Desempenho
A implantação com Docker oferece vários benefícios de desempenho:
- Ambiente consistente: Runtime idêntico em diferentes máquinas
- Limites de recursos: Pode definir limites de CPU/memória via docker-compose
- Cache: Cache de camadas do Docker acelera recompilações
- Escala: Fácil executar múltiplas instâncias atrás de um balanceador de carga
🔗 Integração com Claude Desktop
O servidor suporta dois métodos de integração com Claude Desktop:
Método 1: Integração Local via stdin/stdout (Original)
Após concluir a configuração do servidor acima, configure Claude Desktop para execução direta do processo.
Passo 1: Localize a Configuração do Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json
Passo 2: Configure o Servidor MCP Local
Escolha uma destas configurações com base na sua configuração:
Opção A: Execução direta com Node.js (desenvolvimento local)
{
"mcpServers": {
"evernote": {
"command": "node",
"args": ["/path/to/your/evernote-mcp-server/mcp-server.js"],
"env": {
"EVERNOTE_CONSUMER_KEY": "your-actual-consumer-key",
"EVERNOTE_CONSUMER_SECRET": "your-actual-consumer-secret"
}
}
}
}
Opção B: Execução com contêiner Docker (recomendado para produção)
{
"mcpServers": {
"evernote": {
"command": "docker",
"args": [
"exec", "-i", "--tty=false",
"evernote-mcp-server-evernote-mcp-server-1",
"node", "mcp-server.js"
]
}
}
}
Opção C: Execução com contêiner Podman (alternativa ao Docker)
{
"mcpServers": {
"evernote": {
"command": "podman",
"args": [
"exec", "-i", "--tty=false",
"evernote-mcp-server_evernote-mcp-server_1",
"node", "mcp-server.js"
]
}
}
}
📁 Arquivo de Configuração de Exemplo
Um arquivo de exemplo claude_desktop_config.json está incluído neste repositório. Para usá-lo:
- Copie o exemplo:
cp claude_desktop_config.json ~/Library/Application\ Support/Claude/claude_desktop_config.json - Personalize para sua configuração:
- Usuários Docker: Atualize o nome do contêiner se for diferente (verifique com
docker ps) - Usuários Podman: Substitua
dockerporpodmane atualize o nome do contêiner (verifique compodman ps) - Configuração local: Use a configuração da Opção A
- Usuários Docker: Atualize o nome do contêiner se for diferente (verifique com
- Reinicie o Claude Desktop completamente (⌘+Q e reabra)
Personalização do Nome do Contêiner:
- Padrão Docker Compose:
evernote-mcp-server-evernote-mcp-server-1 - Padrão Podman Compose:
evernote-mcp-server_evernote-mcp-server_1(nota: sublinhados em vez de hífens) - Nome personalizado do contêiner: Verifique seus contêineres em execução com
docker psoupodman ps - Runtime diferente: Substitua
dockerporpodman,nerdctl, etc.
Método 2: Integração Remota HTTP/JSON-RPC (Novo na v2.0.1)
Para implantações conteinerizadas ou compatibilidade entre plataformas.
Passo 1: Inicie o Servidor Conteinerizado
docker-compose up -d
Passo 2: Configure o Servidor MCP Remoto
{
"mcpServers": {
"evernote": {
"command": "npx",
"args": [
"@modelcontextprotocol/server-everything",
"--url", "https://localhost:3443/mcp"
],
"env": {
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}
}
}
Benefícios da Integração Remota:
- ✅ Funciona com contêineres Docker (supera limitações de stdin/stdout)
- ✅ Compatibilidade entre plataformas (Windows, Linux, macOS)
- ✅ Pode conectar a instâncias de servidor remoto
- ✅ Melhor para implantações de produção
Importante: Substitua os valores de espaço reservado pelas suas credenciais reais da API Evernote.
Passo 3: Reinicie o Claude Desktop
- Saia do Claude Desktop completamente (⌘+Q ou clique com o botão direito no ícone do dock → Sair)
- Reabra o Claude Desktop
- Verifique a conexão: Você deve ver as ferramentas Evernote disponíveis na interface
Passo 4: Teste a Integração
Tente pedir ao Claude para pesquisar suas notas do Evernote:
"Pesquise no meu Evernote por notas sobre planejamento de projetos"
"Encontre minhas notas de reunião mais recentes no Evernote"
"Mostre-me todas as notas do Evernote marcadas com 'importante'"
Ferramentas Disponíveis no Claude Desktop
Uma vez conectado, o Claude Desktop terá acesso a estas ferramentas Evernote:
createSearch: Pesquisar notas usando consultas em linguagem naturalgetSearch: Recuperar resultados de pesquisa em cachegetNote: Obter metadados detalhados para uma nota específicagetNoteContent: Recuperar o conteúdo completo da nota em formato texto, HTML ou ENML
Solução de Problemas da Conexão com Claude Desktop
Falha na conexão com "upstream connect error":
- Reinicie o Claude Desktop completamente (⌘+Q e reabra)
- Verifique se as credenciais estão definidas corretamente em
claude_desktop_config.json - Garanta que o caminho do servidor em
argsseja absoluto e correto (mcp-server.jsnãoindex.js) - Teste o servidor MCP de forma independente:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node mcp-server.js
Ferramentas não visíveis:
- Aguarde alguns segundos após reiniciar o Claude Desktop
- Verifique o console do Claude Desktop para mensagens de erro
- Verifique se a autenticação OAuth foi concluída com sucesso executando
node index.jsprimeiro
Erros de autenticação:
- Conclua o fluxo OAuth executando o servidor HTTPS de forma independente primeiro:
node index.js - 🆕 v1.1.0: O servidor agora detecta automaticamente tokens expirados e solicita reautenticação
- Verifique se os tokens estão armazenados no arquivo .env ou nas variáveis de ambiente
- Verifique se as credenciais da API Evernote são válidas e ativas
- 🆕 v1.1.0: Se você receber erros
EDAMUserException, reinicie o servidor para verificar a expiração do token
Alternativas de Configuração
Opção 1: Variáveis de Ambiente (Recomendado)
Defina as credenciais no seu ambiente de shell e remova a seção env da configuração do Claude Desktop:
# In your ~/.zshrc or ~/.bashrc
export EVERNOTE_CONSUMER_KEY="your-consumer-key"
export EVERNOTE_CONSUMER_SECRET="your-consumer-secret"
Depois use esta configuração mais simples do Claude Desktop:
{
"mcpServers": {
"evernote": {
"command": "node",
"args": ["/path/to/your/evernote-mcp-server/mcp-server.js"]
}
}
}
Opção 2: Iniciar pelo Terminal Abra o Claude Desktop a partir de um terminal onde as variáveis de ambiente estão definidas:
# Set credentials
export EVERNOTE_CONSUMER_KEY="your-key"
export EVERNOTE_CONSUMER_SECRET="your-secret"
# Launch Claude Desktop
open -a "Claude"
🐛 Depuração e Desenvolvimento
Registro de Depuração
O servidor suporta registro de depuração detalhado via variável de ambiente DEV_MODE:
# Enable detailed debug logging
export DEV_MODE=true
# Or run with debug mode for a single session
DEV_MODE=true npx node index.js
Recursos de Depuração:
- Invocação de Ferramentas MCP: Registro detalhado de todas as chamadas de ferramentas com carimbos de data/hora
- Requisições à API Evernote: Payloads completos e parâmetros
- Respostas da API Evernote: Resumos de respostas e detalhes de erros
- Redação de Tokens: Redação automática de informações sensíveis (tokens, segredos, chaves)
- Detalhes de Erros: Registro de erros aprimorado com dados brutos de resposta
- Registro em stderr: Todas as mensagens de depuração vão para stderr para evitar interferência com o protocolo JSON-RPC
Modo Normal vs. Modo de Depuração:
- Normal: Registro básico com apenas informações principais (para stderr)
- Depuração: Registro JSON detalhado com dados sensíveis redigidos (para stderr)
Importante: Todas as mensagens de depuração baseadas em emoji são enviadas para stderr, não stdout, garantindo comunicação JSON-RPC limpa com Claude Desktop.
Exemplo de saída de depuração:
🔧 [2025-06-17T00:07:56.351Z] MCP Tool Invocation: createSearch
📥 Args: {
"query": "Sea Pro boat",
"authenticationToken": "[REDACTED:19chars]"
}
🌐 [2025-06-17T00:07:57.123Z] Evernote API Request: /findNotesMetadata
📤 Request: {
"filter": { "words": "Sea Pro boat" },
"authenticationToken": "[REDACTED:19chars]"
}
Ferramentas de Depuração de Contêiner
Este repositório inclui scripts de diagnóstico abrangentes para solucionar problemas de contêiner. Eles foram desenvolvidos durante a investigação de loops de reinicialização de contêiner e são úteis para depuração futura.
Scripts de Diagnóstico Disponíveis
1. catch_sigterm_sender.sh - Detecção de Origem do SIGTERM
./catch_sigterm_sender.sh
- Propósito: Identifica qual processo envia sinais SIGTERM para contêineres
- Principais Recursos: Monitoramento de processos em tempo real, correlação SIGTERM, análise de logs do sistema
- Resultados da Investigação: Identificou com sucesso podman-remote como executor da verificação de saúde
- Uso: Execute quando contêineres estiverem recebendo sinais SIGTERM inesperados
2. test_manual_healthcheck.sh - Teste de Confiabilidade da Verificação de Saúde
./test_manual_healthcheck.sh
- Propósito: Testa a confiabilidade da verificação de saúde em múltiplos métodos
- Métodos de Teste: curl (host→contêiner), Node.js (host→contêiner), Node.js (interno ao contêiner)
- Descoberta Principal: Revelou taxa de falha de 50% em verificações baseadas no host vs. 100% de sucesso para verificações internas ao contêiner
- Uso: Execute quando contêineres mostrarem status "unhealthy" ou falhas na verificação de saúde
3. monitor_app_failure.sh - Monitoramento de Aplicação em Runtime
./monitor_app_failure.sh
- Propósito: Monitora o comportamento da aplicação Node.js durante ciclos de falha do contêiner
- Monitoramento: Uso de memória, estado do processo, uso de recursos, logs da aplicação
- Descoberta Principal: Detectou processos de tempo limite acumulados causando falhas no contêiner
- Uso: Execute para capturar dados detalhados de falha durante ciclos de reinicialização do contêiner
4. analyze_app_code.sh - Análise de Código da Aplicação
./analyze_app_code.sh
- Propósito: Análise estática do código da aplicação para padrões comuns de falha
- Análise: Vazamentos de memória, listeners de eventos, manipuladores de erro, problemas SSL, configuração Docker
- Principais Recursos: Varredura automatizada para padrões de código problemáticos
- Uso: Ferramenta de análise de primeira linha para identificar possíveis problemas na aplicação
Metodologia de Depuração
Para problemas de estabilidade do contêiner, siga esta abordagem sistemática:
Fase 1: Análise de Código
./analyze_app_code.sh
Verifique problemas óbvios no código da aplicação antes da investigação em runtime.
Fase 2: Validação da Verificação de Saúde
./test_manual_healthcheck.sh
Valide a confiabilidade da verificação de saúde em diferentes métodos para identificar problemas de rede ou implementação.
Fase 3: Detecção da Origem do SIGTERM
./catch_sigterm_sender.sh
Se os contêineres estiverem reiniciando, identifique qual processo está enviando sinais de término.
Fase 4: Monitoramento em Runtime
./monitor_app_failure.sh
Para problemas contínuos, capture o comportamento detalhado em runtime durante ciclos de falha.
Recursos dos Scripts de Diagnóstico
Todos os scripts incluem:
- ✅ Documentação abrangente com propósito, uso e resultados da investigação
- ✅ Registro com carimbo de data/hora para correlação precisa de eventos
- ✅ Sem informações sensíveis - seguro para repositórios públicos no GitHub
- ✅ Parâmetros configuráveis - facilmente adaptáveis a diferentes configurações de contêiner
- ✅ Monitoramento em segundo plano - capture dados sem interferir na operação normal
- ✅ Orientação de análise - dicas integradas para interpretar resultados
Exemplo de uso para investigação de reinicialização de contêiner:
# Quick health check validation
./test_manual_healthcheck.sh
# If health checks are failing, identify the SIGTERM sender
./catch_sigterm_sender.sh
# For deeper analysis, monitor runtime behavior
./monitor_app_failure.sh
Resumo dos Resultados da Investigação
Problema de loop de reinicialização do contêiner (5 de agosto de 2025):
- ✅ Causa raiz: comando de verificação de integridade do Node.js criando processos de timeout acumulados
- ✅ Método de detecção: script de monitoramento em tempo de execução revelou padrão de acúmulo de processos
- ✅ Solução: verificação de integridade simplificada com tratamento adequado de timeout
- ✅ Resultado: estabilidade do contêiner restaurada, sem ciclos de reinicialização
Essas ferramentas fornecem uma abordagem sistemática para depuração de contêineres e podem ser adaptadas para outras aplicações Node.js conteinerizadas.
🧪 Testes
O projeto inclui uma suíte de testes abrangente com 38 testes cobrindo toda a funcionalidade crítica:
Comandos de Teste
# Run all tests
npm test
# Run tests with coverage report
npm run test:coverage
# Run tests in watch mode (for development)
npm run test:watch
Estrutura de Teste
tests/
├── auth.test.js # OAuth 1.0a authentication tests
├── server.test.js # Express server route tests
├── integration.test.js # End-to-end workflow tests
├── setup.js # Global test configuration
└── jest.config.js # Jest configuration
Detalhes da Cobertura de Teste
🔐 auth.test.js - Autenticação OAuth (12 testes)
- Geração de Parâmetros OAuth: Valida os parâmetros OAuth 1.0a necessários
- Geração de Assinatura HMAC-SHA1: Testa assinaturas criptográficas com vetores de teste conhecidos
- Armazenamento de Tokens: Armazenar/recuperar tokens no arquivo .env e variáveis de ambiente
- Fluxo de Autenticação: Reutilização de token existente vs. início de novo fluxo OAuth
- Validação de Configuração: Endpoints do Evernote e variáveis de ambiente
- Tratamento de Erros: Falhas de rede e erros de acesso a variáveis de ambiente
🌐 server.test.js - Rotas do Servidor Express (15 testes)
- Verificação de Integridade (
GET /): Status do servidor e respostas JSON - Callback OAuth (
GET /oauth/callback):- Troca de token bem-sucedida
- Validação de parâmetro ausente
- Tratamento de estado OAuth inválido
- Cenários de erro
- Endpoint MCP (
POST /mcp):- Tratamento de requisição autenticada
- Rejeição de requisição não autenticada (401)
- Análise de corpo JSON
- Tratamento de erro interno
- Tratamento de Content-Type: Validação JSON e tratamento de requisições malformadas
- Validação de Rotas: Erros 404 para rotas desconhecidas e métodos HTTP incorretos
🔄 integration.test.js - Fluxos de Trabalho de Ponta a Ponta (11 testes)
- Fluxo OAuth Completo: Token de requisição simulado → autorização → troca de token de acesso
- Gerenciamento de Estado OAuth: Preservação de estado entre fases de requisição e callback
- Integração com Navegador: Inicialização do navegador do sistema para autorização
- Cenários de Erro: Falhas de rede, respostas inválidas, erros de variáveis de ambiente
- Validação de Configuração: URLs de endpoint e validação de credenciais
- Ciclo de Vida do Token: Padrões de armazenamento, recuperação e reutilização
Requisitos de Cobertura
A suíte de testes mantém altos padrões de cobertura:
- Ramos: cobertura mínima de 70%
- Funções: cobertura mínima de 80%
- Linhas: cobertura mínima de 80%
- Declarações: cobertura mínima de 80%
Recursos de Teste
- Mock Abrangente: Todas as dependências externas (variáveis de ambiente, navegador, SSL, rede)
- Isolamento de Ambiente: Variáveis de ambiente específicas de teste evitam interferência
- Teste Criptográfico Real: Validação real de assinatura HMAC-SHA1 com vetores de teste conhecidos
- Cobertura de Cenários de Erro: Falhas de rede, respostas malformadas, negações de acesso
- Validação de Integração: Simulação completa do fluxo de trabalho OAuth sem chamadas de API externas
Executando Testes Específicos
# Run only authentication tests
npm test auth.test.js
# Run only server tests
npm test server.test.js
# Run only integration tests
npm test integration.test.js
# Run tests matching a pattern
npm test -- --testNamePattern="OAuth"
A suíte de testes garante a correta implementação do OAuth 1.0a, valida todos os endpoints do servidor e fornece confiança no fluxo de autenticação sem exigir chamadas reais à API do Evernote ou certificados SSL durante os testes. O Claude Desktop também pode ser usado para validar se o seu servidor MCP responde corretamente a prompts em linguagem natural.
📋 Registro de Alterações
v2.2.1 (Mais Recente)
- Migrou as imagens base do contêiner de Chainguard para Red Hat Project Hummingbird
v2.2.0
- Corrigiu a análise da data de expiração do token (removida a multiplicação errônea por *1000)
- Corrigiu a vulnerabilidade de injeção de comandos na função openBrowser
v2.1.3
🛡️ Implementação Confiável de Verificação de Integridade:
- Verificação de Integridade Baseada em Processo - Implementada verificação simples de sistema de arquivos
/proc/1/statevitando problemas de rede gvproxy - Confiabilidade de 100% na Verificação de Integridade - Verificados 20/20 testes aprovados com zero falhas de falso positivo
- Estabilidade do Contêiner Confirmada - 8+ minutos de operação estável com monitoramento de integridade adequado restaurado
- Configuração Generosa de Tentativas - Intervalo de 45s, timeout de 15s, 5 tentativas, período inicial de 60s para evitar falsos positivos
- Compatível com Monitoramento Externo - Fornece status padrão "(healthy)" do Docker/Podman para sistemas de monitoramento
- Independente de Rede - Elimina dependências de encaminhamento de porta gvproxy que causaram os loops de reinicialização originais
v2.1.2
🔧 Correção da Verificação de Integridade do Contêiner:
- Resolução do Loop de Reinicialização do Contêiner - Corrigidos ciclos de reinicialização de 2-3 minutos identificando verificações de integridade não confiáveis como causa raiz
- Investigação da Confiabilidade da Verificação de Integridade - Testes de diagnóstico abrangentes revelaram falhas ocasionais na verificação de integridade que acionavam reinicializações do contêiner
- Desativação Temporária da Verificação de Integridade - Desativadas verificações de integridade problemáticas para eliminar falhas de falso positivo
- Estabilidade do Contêiner Verificada - 8+ minutos de operação estável sem ciclos de reinicialização (anteriormente falhava a cada 2-3 minutos)
- Impacto na Produção - Resolve reinicializações frequentes do contêiner que afetavam a disponibilidade do serviço
- Metodologia de Diagnóstico - Abordagem de teste sistemática para isolar problemas de verificação de integridade vs. problemas de aplicação
v2.1.1
🧹 Otimização de Logs de Produção:
- Logs Mínimos de Produção - Removido código de depuração verboso (uso de memória, APIs privadas do Node.js)
- Estabilidade Essencial Mantida - Mantidos manipuladores de sinais críticos e tratamento global de erros da v2.1.0
- Condicional DEV_MODE - Logs de depuração aparecem apenas quando a variável de ambiente
DEV_MODE=trueestá definida - Estabilidade do Loop de Eventos - Função keepalive mínima evita que o Node.js fique inativo em contêineres
- Testes de Produção - Verificada estabilidade do contêiner por 10+ minutos sem ciclos de reinicialização
- Logs de Produção Limpos - Apenas mensagens essenciais de inicialização e erro aparecem no modo de produção
🔧 Implementação Técnica:
- Substituído o heartbeat verboso de 30 segundos por função keepalive mínima
- Mantidos manipuladores de sinais SIGTERM, SIGINT, SIGQUIT para depuração em produção
- Removidos logs de uso de memória e chamadas de API privadas do Node.js (_getActiveHandles, _getActiveRequests)
- Adicionado log condicional:
if (process.env.DEV_MODE === 'true')para saída de depuração - Preservados manipuladores de exceção não capturada e rejeição não tratada da v2.1.0
✅ Resultados dos Testes:
- Contêiner operou de forma estável por 8+ minutos sem reinicializações (meta: 10+ minutos alcançada)
- Nenhum ciclo de reinicialização detectado no modo de produção (DEV_MODE=false)
- Logs confirmaram saída mínima - apenas mensagens de inicialização, sem heartbeat verboso
- Contêiner manteve status "healthy" durante todo o período de teste
v2.0.1
🆕 Suporte Aprimorado ao Protocolo MCP:
- Suporte a Servidor MCP Remoto - Adicionado suporte ao protocolo HTTP/JSON-RPC 2.0 no endpoint
/mcp - Modos de Integração Dupla - Suporte para integração local stdin/stdout e remota via HTTPS
- Conformidade com a Especificação MCP - Definições de ferramentas e nomes de métodos atualizados para corresponder à especificação oficial do MCP
- Definições de Ferramentas Aprimoradas - Adicionado campo
type: 'tool'e alteradoinputSchemaparaparameters - Formatação Inteligente de Respostas - Resumos legíveis por humanos em vez de despejos JSON brutos
- Integração Docker Multiplataforma - Supera limitações de stdin/stdout para implantações conteinerizadas
- Suporte CORS - Cabeçalhos CORS adequados e tratamento OPTIONS para servidores remotos
- Detecção de Formato - Detecção automática entre formatos de requisição legados e JSON-RPC
🔧 Melhorias Técnicas:
- Roteamento de endpoint de formato duplo com compatibilidade retroativa
- Implementação do protocolo JSON-RPC 2.0 com tratamento de erros
- Experiência do usuário aprimorada com resumos de resposta contextuais
- Validação de parâmetros obrigatórios (ex.: parâmetro de consulta para createSearch)
v2.0.0
🐳 Implantação Docker Pronta para Produção:
- Conteinerização completa com imagens base seguras Chainguard
- Varredura de segurança Zero-CVE e overrides npm
- Persistência de token OAuth entre reinicializações do contêiner
- Builds Docker multi-estágio para imagens de produção otimizadas
v1.1.0
🆕 Novos Recursos:
- Detecção automática de expiração de token - O servidor verifica a validade do token na inicialização
- Prompts interativos de reautenticação - Prompts amigáveis para tokens expirados
- Tratamento de erros aprimorado - Relatório específico de código de erro EDAMUserException
- Gerenciamento proativo de tokens - Previne falhas de API devido a credenciais expiradas
🔧 Melhorias Técnicas:
- Adicionada função
checkTokenExpiration()com validação abrangente - Adicionado
askUserConfirmation()para prompts interativos ao usuário - Adicionado
clearStoredTokens()para limpeza segura de tokens - Fluxo de inicialização do servidor aprimorado com verificações de expiração
- Mensagens de erro melhoradas em todo o fluxo de autenticação
🧪 Testes:
- Todos os 38 testes existentes continuam passando
- Funcionalidade de expiração de token testada e validada
v1.0.0
- Lançamento inicial com implementação completa de OAuth 1.0a
- Integração completa do protocolo Apache Thrift
- Quatro ferramentas MCP: createSearch, getSearch, getNote, getNoteContent
- Suíte de testes abrangente (38 testes)
- Integração MCP com Claude Desktop
- Armazenamento de tokens em arquivo .env multiplataforma
- Servidor HTTPS com certificados autoassinados
🔒 Segurança
- Nenhum dado de terceiros é enviado a qualquer lugar, exceto para o Evernote via HTTPS.
- Tokens de autenticação armazenados com segurança em arquivos .env e variáveis de ambiente.
- Uso de chave de assinatura (GPG baseado em SSH) é obrigatório em todos os commits.
📄 Licença
Licenciado sob a Licença MIT. Consulte o arquivo LICENSE para os termos completos.
🙋♂️ Autor
Mantido por @brentmid. Este projeto é tanto uma integração funcional quanto uma experiência educacional em MCP, API do Evernote, fluxos de trabalho do GitHub e práticas modernas de Node.js.
Pull requests e contribuições são bem-vindos após a conclusão do MVP. Verifique a aba Issues para tarefas conhecidas.