spring-openproject-mcp-server

Servidor MCP para gerenciar work-packages do OpenProject realizado em Java.

Documentação

spring-openproject-mcp-server

Servidor MCP para gerenciar pacotes de trabalho do OpenProject, implementado em Java. O servidor atua como um proxy para a sua API do OpenProject. O token da API do OpenProject do usuário é usado para autenticação (não armazenado no contêiner!).

Compatibilidade com OpenProject

Testado contra OpenProject 14, 15, 16.6, 17.7

Começando (usando LM Studio)

  1. Inicie o contêiner Docker docker run -d -p 0.0.0.0:8080:8080 -e OPENPROJECT_URL=https://${yourOpenProjectUrl} --tmpfs /tmp docker.io/tmskln/spring-openproject-mcp-server:latest ou, se você compilou a imagem localmente docker run -d -p 0.0.0.0:8080:8080 -e OPENPROJECT_URL=https://${yourOpenProjectUrl} --tmpfs /tmp spring-openproject-mcp-server:dev
  2. Execute o LM Studio e escolha um modelo apropriado para o domínio do seu projeto. qwen/qwen3-coder-30b funciona bem para criar épicos técnicos e histórias de usuário. Para traduções simples e refinamentos de texto, um modelo menor é suficiente.
  3. Configure o arquivo mcp.json do LM Studio abaixo de "mcpServers":{...} e defina o token da API para o projeto a ser usado (veja abaixo)
  4. Se você vir "mcp/openproject-mcp" no lado direito, abaixo de Integrações, comece a fazer perguntas.
  5. Exemplos:
    1. Prompt: "Liste todos os projetos no OpenProject usando mcp/openproject-mcp."
    2. Prompt: "Use mcp/openproject-mcp para obter pacotes de trabalho do projeto id=10 e analise o projeto."
    3. Prompt: "Use mcp/openproject-mcp e traduza todos os épicos no projeto 'MyApp' para o alemão."
    4. Prompt: "Você é um assistente Ágil preciso. Ajude com a especificação do projeto. Use mcp/openproject-mcp e projeto id=10. Adicione critérios INVEST. Adicione critérios de aceitação Gherkin. Adicione Definição de Pronto (checklist). Adicione Riscos e Mitigações. Metas e KPIs/OKRs mensuráveis (SMART, incluindo valores-alvo)"
    5. Prompt: "Crie 10 Épicos para um novo WebApp que faz o seguinte: ... Use mcp/openproject-mcp e o projeto 'NewWebApp'."

Docker

Encontre a imagem mais recente em https://hub.docker.com/r/tmskln/spring-openproject-mcp-server

compilar

# convert java SBOM to optimized OCI format
docker run --rm \
  -v "./target/classes/META-INF/sbom:/work"  --platform linux/amd64 \
  cyclonedx/cyclonedx-cli \
  convert \
  --input-file /work/application.cdx.json \
  --output-file /work/application.spdx.json \
  --output-format spdxjson
  
PKG_VERSION="dev" && docker build \
 -f docker/Dockerfile \
 -t spring-openproject-mcp-server:${PKG_VERSION} \
 --attest type=sbom,generator=docker/scout-sbom-indexer:latest \
 --label org.opencontainers.image.build-date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
 --label org.opencontainers.image.revision=$(git rev-parse HEAD) \
 --label org.opencontainers.image.version=${PKG_VERSION} \
 --platform linux/amd64,linux/arm64 \
 . 

executar

docker run -d -p 0.0.0.0:8080:8080 -e OPENPROJECT_URL=https://${yourOpenProjectUrl} --tmpfs /tmp spring-openproject-mcp-server:dev
{
  "mcpServers": {
    "openproject-mcp": {
      "url": "http://127.0.0.1:8080/sse",
      "headers": {
        "Authorization": "Bearer {yourOpenProjectApiToken}"
      }
    }
  }
}

Se você quiser controlar o servidor OpenProject a partir do cliente MCP ou executar contra vários servidores OpenProject, inicie o contêiner com -e OPENPROJECT_ALLOW_HEADER_BASE_URL=true e defina a URL do servidor na configuração do MCP:

...
      "headers": {
        "Authorization": "Bearer {yourOpenProjectApiToken}"
        "X-OpenProject-Base-Url": "https://{yourOpenProjectUrl}"
      }
...

Testes de Integração

mvn test -Dopenproject.container.tag=17.5.1 -Dopenproject.container.port=18080

Lembre-se de remover os volumes entre os testes

TODO

  • MCP OpenProject com OTEL
  • usar resultados após patch JSON para evitar solicitações GET desnecessárias

SSE vs. Streamable

spring.ai.mcp.server.protocol=SSE spring.ai.mcp.server.protocol=STREAMABLE

O Spring cria um bean de servidor MCP com um transporte:

  • Protocolo SSE → expõe:
    • GET /sse para streaming servidor → cliente
    • POST /mcp/message para comunicação cliente → servidor
  • Protocolo STREAMABLE → expõe um único endpoint bidirecional (padrão /mcp) baseado na nova especificação HTTP streamable do MCP.

Como o transporte define a fiação, os endpoints e o roteamento de mensagens, o Spring não pode vincular dois protocolos simultaneamente.

FAQ

  • Por que não foi usado um cliente OpenAPI gerado, mas sim mapeamento de valores JSONNode com MapStruct?
    • A primeira abordagem foi usar um cliente OpenAPI gerado, mas havia muitos problemas:
      • a geração de código com org.openapitools:openapi-generator-maven-plugin não era totalmente limpa e exigia muitas correções manuais.
      • o cliente é muito rígido e falharia com mudanças mínimas na especificação
      • a especificação carece de valores, por exemplo, 'storyPoints', e aprimorar manualmente o código gerado não é aplicável
      • a compatibilidade com uma gama mais ampla de versões pode ser melhor alcançada com mapeamento direto de valores e testes de integração contra múltiplas versões do OpenProject

Licença

Este projeto está licenciado sob a Licença MIT – consulte o arquivo LICENSE para obter detalhes.