Agama — Redmine MCP Server

Servidor MCP para Redmine. Permite que agentes de IA trabalhem com issues usando comandos simples em linguagem natural. Funciona tanto como ferramenta pessoal para um desenvolvedor individual — quanto implantado uma vez e compartilhado por toda a equipe.

Documentação

🦎 Agama — Redmine MCP Server

npm version License Node Version GitHub Issues CI Coverage npm downloads

Servidor MCP para Redmine. Permite que agentes de IA trabalhem com issues usando comandos simples em linguagem natural.

Funciona tanto como ferramenta pessoal para um desenvolvedor individual — ou implantado uma vez e compartilhado por toda a equipe.

┌──────────┐   MCP (stdio)   ┌─────────────────────┐   REST/JSON   ┌──────────┐
│  Agent   │ ──────────────▶ │  Redmine MCP Server │ ────────────▶ │ Redmine  │
│ (client) │ ◀────────────── │   (this project)    │ ◀──────────── │  server  │
└──────────┘   tool results  └─────────────────────┘     HTTP      └──────────┘

💬 Basta perguntar

"Quais issues estão atribuídas a mim? Ordene por prioridade."

"Crie um bug no projeto Web: o botão de login não responde no celular, marque como urgente."

"Resuma a issue #456 e todas as suas subtarefas."

"Quantas horas registrei esta semana, divididas por projeto?"

Requisitos

  • Node.js 22+
  • Uma instância do Redmine com a API REST habilitada (Administração → Configurações → API)
  • Uma chave de API do Redmine — vá em Minha conta → Chave de acesso à API enquanto estiver conectado

Início rápido

A maioria dos clientes MCP (ex.: Claude Desktop) inicia o servidor para você — configure uma vez e esqueça:

{
  "mcpServers": {
    "redmine": {
      "command": "npx",
      "args": ["-y", "@0xkillaflow/agama-redmine-mcp"],
      "env": {
        "REDMINE_URL": "https://redmine.example.com",
        "REDMINE_API_KEY": "your-redmine-api-key"
      }
    }
  }
}

Para o Claude Desktop, isso vai em claude_desktop_config.json (Configurações → Desenvolvedor → Editar Config). Reinicie o cliente e as ferramentas do Redmine aparecerão na lista de ferramentas.

Para executar de forma independente a partir de um shell:

REDMINE_URL=https://redmine.example.com REDMINE_API_KEY=your-redmine-api-key \
  npx -y @0xkillaflow/agama-redmine-mcp

O servidor fala MCP via stdio e registra logs no stderr, então o stdout permanece limpo para o protocolo.

Configuração

Definida por variáveis de ambiente, validadas na inicialização. Veja .env.example para um modelo.

VariávelObrigatóriaPadrãoFinalidade
REDMINE_URLsim—URL base da instância do Redmine
REDMINE_API_KEYsim—Chave de API para o usuário atuante
REDMINE_TIMEOUT_MSnão30000Tempo limite por requisição em milissegundos
REDMINE_ALLOWED_DIRECTORIESnãovazioDiretórios que as ferramentas de anexo podem usar
LOG_LEVELnãoinfodebug | info | warn | error
MCP_TRANSPORTnãostdiostdio (único modo suportado hoje)

Acesso a arquivos (REDMINE_ALLOWED_DIRECTORIES)

As ferramentas de anexo são as únicas que tocam no seu sistema de arquivos, e só podem tocar dentro desta lista de permissões — uma lista separada por : de diretórios absolutos (; no Windows). Ela governa ambas as direções: leituras para redmine_upload_attachment e gravações para redmine_download_attachment.

REDMINE_ALLOWED_DIRECTORIES=/Users/you/redmine-files:/tmp/redmine-downloads

O padrão é vazio, o que significa nenhum acesso a arquivos locais — ambas as ferramentas recusam qualquer caminho até que você opte por habilitar. Esse padrão é deliberado: um agente que pode ser convencido a enviar um arquivo é um agente que pode ser convencido a enviar ~/.ssh/id_rsa ou o .env que contém sua chave de API. Permita apenas o diretório mais restrito que atenda à necessidade. Os caminhos são totalmente resolvidos (segmentos .. e symlinks incluídos) antes da verificação, então um symlink dentro de um diretório permitido não pode apontar para fora dele, e downloads nunca sobrescrevem um arquivo existente.

Ferramentas

Dezenove ferramentas moldadas por intenção, cada uma marcada com anotações de segurança MCP. Referência completa: docs/tools.md.

FerramentaTipoDescrição
redmine_list_issuesleituraBuscar/filtrar issues por status, responsável, tracker, datas…
redmine_get_issueleituraDetalhe completo da issue, opcionalmente com diários e anexos
redmine_create_issueescritaCriar uma issue
redmine_update_issueescritaEditar status, responsável, notas… de uma issue
redmine_delete_issueescrita · destrutivaExcluir permanentemente uma issue — sem desfazer, em cascata
redmine_manage_issue_watchersescritaAdicionar/remover um observador (assinatura de notificação)
redmine_list_issue_relationsleituraLinks de dependência de uma issue, ou uma relação pelo seu id
redmine_create_issue_relationescritaVincular duas issues (bloqueia, precede, duplica, relaciona…)
redmine_delete_issue_relationescrita · destrutivaRemover um link — escopo restrito e reversível
redmine_searchleituraBusca em texto livre em issues, wiki, notícias, projetos
redmine_list_projectsleituraListar projetos visíveis
redmine_get_projectleituraDetalhe completo do projeto, trackers/categorias/atividades
redmine_list_time_entriesleituraConsultar tempo registrado
redmine_create_time_entryescritaRegistrar horas em uma issue ou projeto
redmine_get_current_userleitura"Quem sou eu" — usuário da chave de API, associações, grupos
redmine_list_usersleituraEncontrar usuários por nome/status/grupo — restrito a admin na maioria dos sites
redmine_list_reference_dataleituraStatus, trackers, prioridades, atividades, categorias de documentos
redmine_upload_attachmentescritaEnviar um arquivo local → token para o array uploads de uma issue
redmine_download_attachmentescritaSalvar um anexo em um diretório local (grava no disco)

Atenção: redmine_delete_issue é a ferramenta que destrói dados — o Redmine não tem lixeira, e a exclusão leva junto os comentários, registros de tempo, anexos e relações da issue. Ela é anotada como destructiveHint: true para que um cliente MCP possa exigir confirmação; se o seu cliente não bloquear isso, trate cada chamada como definitiva. redmine_delete_issue_relation carrega a mesma anotação, mas é muito mais restrita: remove um link entre duas issues, e redmine_create_issue_relation o restaura em uma única chamada.

Atenção: ao gravar, o Redmine ignora silenciosamente um tracker_id, status_id ou fixed_version_id desconhecido em vez de retornar erro — sempre verifique a issue retornada. O mesmo se aplica a is_private, que é silenciosamente descartado se seu papel não tiver a permissão "definir público/privado".

Segurança

O servidor roda localmente e atua como um único usuário: seu REDMINE_API_KEY nunca sai da sua máquina, exceto como cabeçalho de requisição para sua própria instância do Redmine, e o servidor não pode fazer nada que sua conta já não pudesse. Transporte HTTP multiusuário está planejado, mas ainda não implementado — selecionar MCP_TRANSPORT=http encerra com um erro claro.

O acesso a arquivos locais está desativado por padrão e confinado a REDMINE_ALLOWED_DIRECTORIES quando você o habilita. Nada mais no servidor lê ou grava no seu sistema de arquivos.

Solução de problemas

SintomaCausa provável
Cliente não mostra ferramentasAlgo além de JSON-RPC está gravando no stdout — verifique qualquer wrapper
Encerra imediatamente na inicializaçãoUma variável de ambiente obrigatória está ausente ou inválida; o erro a nomeia
401 UnauthorizedChave de API ausente/incorreta, ou API REST desabilitada no lado do Redmine
403 ForbiddenO usuário da chave não tem permissão para essa ação
404 Not FoundO id não existe ou não é visível para a chave
422 Unprocessable EntityO Redmine rejeitou a gravação — verifique as mensagens de nível de campo retornadas

Documentação

Desenvolvimento

npm install       # install dependencies
npm run dev       # watch-run the stdio server
npm test          # run the test suite
npm run build     # bundle to dist/

Licença

MIT