Evernote

Conecta sua conta do Evernote a um LLM, permitindo pesquisa e consultas em linguagem natural sobre suas notas.

Documentação

Servidor MCP Evernote

License: MIT Node.js Last Commit Issues Stars

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 up para 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_MODE com 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

  1. Registre seu aplicativo em Evernote Developers
  2. Crie um novo aplicativo e anote sua Consumer Key e Consumer Secret
  3. 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

  1. Gere certificados SSL (veja instruções de configuração acima)
  2. Defina variáveis de ambiente com suas credenciais da API do Evernote
  3. Inicie o servidor: npx node index.js
  4. 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:

  1. Token de Solicitação: O servidor gera um token de solicitação temporário
  2. Autorização do Usuário: O navegador abre a URL de autorização do Evernote
  3. Callback: O usuário autoriza o aplicativo, o Evernote redireciona para a URL de callback
  4. Token de Acesso: O servidor troca o token de solicitação por um token de acesso permanente
  5. 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-dev com git e openssl para configuração
  • Estágio de produção: Usa cgr.dev/chainguard/node:latest mí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 .env ou 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:latest mais recente
  • Reconstrói o contêiner com --no-cache para 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_URL no 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.js localmente 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:

  1. Copie o exemplo: cp claude_desktop_config.json ~/Library/Application\ Support/Claude/claude_desktop_config.json
  2. 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 docker por podman e atualize o nome do contêiner (verifique com podman ps)
    • Configuração local: Use a configuração da Opção A
  3. 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 ps ou podman ps
  • Runtime diferente: Substitua docker por podman, 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

  1. Saia do Claude Desktop completamente (⌘+Q ou clique com o botão direito no ícone do dock → Sair)
  2. Reabra o Claude Desktop
  3. 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 natural
  • getSearch: Recuperar resultados de pesquisa em cache
  • getNote: Obter metadados detalhados para uma nota específica
  • getNoteContent: 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 args seja absoluto e correto (mcp-server.js não index.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.js primeiro

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/stat evitando 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=true está 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 alterado inputSchema para parameters
  • 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.