Labsco
MCP SERVER

Spring Openproject MCP Server

by tmskln

Read and write OpenProject work packages from a model — the API token travels in the request header and is never stored in the container.

Project & Task Management
Summary
Keeping the token out of the container is the design decision worth copying.

Because the token arrives per request, the running container holds no credentials, and the same instance can serve different users and different OpenProject servers without a redeploy. Version compatibility was handled deliberately rather than generated: the author dropped a generated OpenAPI client because it broke on minor spec differences, and mapped values directly instead, which is why a spread of OpenProject releases works. Pick your transport before you deploy — switching later means restarting with a different protocol setting.

What it is

A Java proxy in front of the OpenProject API, packaged as a Docker container. It lets a model list projects, read work packages and write them back, which is what turns 'add acceptance criteria to every epic in this project' into something a model can carry out rather than describe.

What you get
  • Project and work-package access over the OpenProject API — list projects, pull work packages for a project, analyse them, and write changes back
  • Bulk editorial work on a whole project, such as translating every epic or adding INVEST criteria, Gherkin acceptance criteria and a definition of done
  • Generating new work packages from a description, so a set of epics can be created from a paragraph about the product
  • Authentication per request: your OpenProject API token is sent as a bearer header from the client and is not kept in the container
  • Multi-server operation — start the container with `OPENPROJECT_ALLOW_HEADER_BASE_URL` and the target instance travels in an `X-OpenProject-Base-Url` header, so one container serves several OpenProject servers
  • Compatibility tested against OpenProject 14, 15, 16.6 and 17.5
Requirements

Docker, and an OpenProject instance the container can reach — `OPENPROJECT_URL` is set when the container starts and the service listens on port 8080. The client connects over SSE at `/sse` with the API token as an `Authorization: Bearer` header. Spring binds one transport at a time, so a server started for SSE exposes `GET /sse` and `POST /mcp/message`, while the streamable mode exposes a single `/mcp` endpoint instead — the two cannot run together.

Setup effort

One command plus a key — 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, then supply credentials