open-project-sidecar-mcp (1.4.2-alpha)
Installation
registry=npm install open-project-sidecar-mcp@1.4.2-alpha"open-project-sidecar-mcp": "1.4.2-alpha"About this package
open-project-mcp
MCP server for OpenProject project management. Works with Claude Code, Cursor, Windsurf, or any MCP-compatible client.
Provides 57 tools for managing projects, work packages, versions, time tracking, wiki pages, boards, news, forums, and more -- all through the Model Context Protocol.
Why this package?
Existing OpenProject MCP servers (openproject-mcp, openproject-mcp-server) cover basic CRUD for projects, work packages, and time tracking -- roughly 8-27 tools depending on the package. This server goes further with 57 tools, adding coverage for areas the others don't touch:
- Wiki pages -- create, read, update, and delete project documentation
- Boards -- create Kanban boards (status, assignee, version, or free-form layouts)
- Saved queries -- manage filtered work package views with custom columns and sorting
- News and release notes -- publish project updates and auto-generate changelogs from version data
- Forums -- create discussion boards, post topics, and manage threads
- Sprint overview -- get structured breakdowns of version progress with work package counts
- Work package relations -- manage blocks, follows, relates, and other dependency links
- Comments and activity -- read activity history and post comments on work packages
- Project memberships -- add/remove users and manage role assignments
- Notifications -- list and manage in-app notifications
- Commit message formatting -- generate conventional commits with OpenProject references
What this is (and isn't)
This is an MCP server -- it exposes 57 tools that any MCP-compatible AI client can call, but it does not include agent skills, prompt templates, or workflow automation. It is a bridge between your AI coding tool and your OpenProject instance.
Tested with Claude Code. Other MCP clients (Cursor, Windsurf, etc.) should work since the server follows the MCP specification, but they are not actively tested. Bug reports and contributions for other clients are welcome.
Agent skills are separate. If you want guided workflows (e.g., "work on ticket #123" with automatic branching and commit conventions), those are configured as client-side skills in your AI tool, not part of this server.
Quick start
npx open-project-sidecar-mcp
On first run, the interactive installer walks you through:
- Deployment mode -- Direct (stdio) or Docker sidecar
- Credentials -- OpenProject URL and API key (plus mode-specific settings)
- Connectivity test -- verifies your OpenProject instance is reachable
.envcreation -- saves credentials to a local.envfile- Client registration -- writes the config to
~/.claude.json(or your preferred MCP client)
The server loads .env from your current working directory automatically -- no need to export variables or hardcode keys in config files. See Configuration for all available options, or Manual configuration if you prefer non-interactive setup.
Deployment modes
Pick the mode that fits your setup:
| Direct (stdio) | Docker sidecar | |
|---|---|---|
| Best for | Any developer, solo or team | admin_command, persistent server |
| Transport | stdio (default) | HTTP (always enabled) |
| Requires | Node 18+ | Docker, Docker Compose |
| API tools (56) | All | All |
admin_command |
No | Yes |
What does admin_command add? It runs Rails console commands inside the OpenProject container -- operations the REST API cannot perform: enabling/disabling project modules, creating custom types and statuses, defining custom fields, configuring backlogs, and running direct database queries. If you only need the 56 API tools, Direct mode works. Choose Docker sidecar when you need admin_command.
Direct (stdio)
Your AI client launches the MCP server as a child process. Works for any developer -- OpenProject can be local or remote.
1. Run the installer:
npx open-project-sidecar-mcp
The installer creates a .env with your OpenProject URL and API key, tests connectivity, and offers to register the server in your MCP client config. See Manual configuration for non-interactive setup.
2. Verify: Open Claude Code -- OpenProject tools should appear.
Docker sidecar
Persistent Docker container with HTTP transport always enabled. Provides admin_command -- the tool that runs Rails console commands inside the OpenProject container for operations the REST API doesn't expose (bulk status changes, data migrations, database queries). Team members connect by URL without needing Node.js or local credentials.
Setting up a new sidecar
1. Run the installer and choose Docker sidecar → Set up a new sidecar:
npx open-project-sidecar-mcp
The installer prompts for your OpenProject credentials and container name, auto-generates an MCP_API_KEY for HTTP auth, and creates a .env with Docker and HTTP transport settings. At the end, it prints the connection URL and API key to share with team members.
2. Add the MCP service to your OpenProject docker-compose.yml:
services:
mcp:
image: node:18-slim
container_name: open-project-mcp
restart: unless-stopped
command: npx -y open-project-sidecar-mcp
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
OPENPROJECT_URL: http://openproject:80
OPENPROJECT_API_KEY: ${OPENPROJECT_API_KEY}
OPENPROJECT_CONTAINER: openproject-openproject-1
MCP_TRANSPORT: http
MCP_PORT: 3000
MCP_API_KEY: ${MCP_API_KEY}
ports:
- "3000:3000"
networks:
- openproject
Note: OPENPROJECT_URL uses the internal Docker network address (http://openproject:80), not the external domain. OPENPROJECT_API_KEY and MCP_API_KEY are pulled from your .env file via Docker Compose variable interpolation.
3. Add credentials to your .env (next to docker-compose.yml):
# Append to existing .env or create a new one
cat >> .env << EOF
OPENPROJECT_API_KEY=your-api-key-here
MCP_API_KEY=$(openssl rand -base64 32)
EOF
4. Start the sidecar:
docker compose up -d mcp
5. Verify: curl http://localhost:3000/health should return 200. Test admin_command in Claude Code to confirm Docker socket access.
Connecting to an existing sidecar
Team members run the installer and choose Docker sidecar → Connect to an existing sidecar:
npx open-project-sidecar-mcp
Enter the server URL and API key provided by the sidecar admin. The installer tests connectivity, then writes a URL-based config to your MCP client. No .env file is created on the client machine.
See Manual configuration for non-interactive setup.
Manual configuration
If you prefer non-interactive setup (CI, scripted environments, Dockerfiles), create a .env file manually:
Direct (stdio):
cat > .env << 'EOF'
OPENPROJECT_URL=https://your-instance.example.com
OPENPROJECT_API_KEY=your-api-key-here
EOF
Then add to ~/.claude.json:
{
"mcpServers": {
"openproject": {
"command": "npx",
"args": ["-y", "open-project-sidecar-mcp"]
}
}
}
Docker sidecar (server) -- .env next to docker-compose.yml for variable interpolation:
cat >> .env << EOF
OPENPROJECT_API_KEY=your-api-key-here
MCP_API_KEY=$(openssl rand -base64 32)
EOF
The remaining settings (OPENPROJECT_URL, OPENPROJECT_CONTAINER, MCP_TRANSPORT, MCP_PORT) are set directly in the compose service environment block -- see the compose example above.
Docker sidecar (client) -- no .env needed, just add to ~/.claude.json:
{
"mcpServers": {
"openproject": {
"url": "https://your-server:3000/mcp",
"headers": { "Authorization": "Bearer <MCP_API_KEY>" }
}
}
}
Configuration
All variables can be set in a .env file (recommended) or as environment variables.
The server looks for .env in this order:
- Current working directory (
cwd) -- where you runnpxfrom (recommended for most users) - Package directory -- next to
index.js(for cloned-repo or Docker setups)
The first file found wins. Existing environment variables are never overwritten.
| Variable | Required | Default | Description |
|---|---|---|---|
OPENPROJECT_URL |
Yes | -- | Base URL of your OpenProject instance |
OPENPROJECT_API_KEY |
Yes | -- | API key (create one in OpenProject > My Account > Access Tokens) |
OPENPROJECT_CONTAINER |
Docker sidecar | openproject-openproject-1 |
Docker container name for admin_command |
OPENPROJECT_COMPOSE_FILE |
No | -- | Path to docker-compose.yml (alternative to container name) |
MCP_TRANSPORT |
Docker sidecar | stdio |
Set to http for Docker sidecar (always enabled) |
MCP_PORT |
No | 3000 |
HTTP server port (Docker sidecar only) |
MCP_API_KEY |
Docker sidecar | -- | Bearer token for HTTP auth (Docker sidecar only) |
Security
Use .env files for all credentials. The server loads .env automatically, and the file is already in .gitignore. Never hardcode API keys in ~/.claude.json, shell scripts, or docker-compose files.
Generate strong keys:
# For MCP_API_KEY (Docker sidecar) or any secret
openssl rand -base64 32
Key rotation:
- Generate a new key:
openssl rand -base64 32 - Update your
.envfile with the new value - Restart the server (
docker compose restart mcpor re-runnpx) - Update client configs -- re-run
npx open-project-sidecar-mcp --setupor manually update~/.claude.json
Docker sidecar requires MCP_API_KEY -- the server refuses to start in HTTP mode without one. The key is sent as a Bearer token, so use TLS in production (put a reverse proxy like Traefik, Caddy, or nginx in front).
Docker socket grants root-equivalent access -- only mount it when you need admin_command. All other tools work without it.
The health endpoint (/health) is unauthenticated -- it returns server status and OpenProject reachability but never exposes API keys or sensitive config.
Available tools
All tools work in every deployment mode unless noted. The Mode column shows: All = Direct and Docker sidecar; Sidecar = requires Docker socket access.
Projects
| Tool | Description | Mode |
|---|---|---|
list_projects |
List projects, optionally filtered by search term | All |
get_project |
Get project details by ID or identifier | All |
create_project |
Create a new project | All |
update_project |
Update project name, description, or status | All |
Work packages
| Tool | Description | Mode |
|---|---|---|
list_work_packages |
List work packages with filters, sorting, and pagination | All |
get_work_package |
Get work package details by ID | All |
create_work_package |
Create a new work package (task, bug, feature, epic, etc.) | All |
update_work_package |
Update work package fields (status, assignee, description, etc.) | All |
Work package relations
| Tool | Description | Mode |
|---|---|---|
list_relations |
List relations for a work package (blocks, follows, relates, etc.) | All |
create_relation |
Create a relation between two work packages with type and optional lag | All |
delete_relation |
Delete a relation by ID | All |
Work package comments & activity
| Tool | Description | Mode |
|---|---|---|
list_work_package_activities |
List activity history (comments, status changes, updates) | All |
add_work_package_comment |
Post a comment on a work package | All |
update_comment |
Edit an existing comment by activity ID | All |
Lookups
| Tool | Description | Mode |
|---|---|---|
list_statuses |
List all available work package statuses | All |
list_types |
List all available work package types | All |
list_priorities |
List all available priorities | All |
list_users |
Search and list users | All |
Versions and sprints
| Tool | Description | Mode |
|---|---|---|
list_versions |
List versions for a project | All |
create_version |
Create a new version/sprint | All |
update_version |
Update version details or status | All |
delete_version |
Delete a version | All |
sprint_overview |
Get sprint summary with work package counts and breakdowns | All |
Time tracking
| Tool | Description | Mode |
|---|---|---|
log_time |
Log time spent on a work package | All |
list_time_entries |
List time entries for a work package or project | All |
Wiki
| Tool | Description | Mode |
|---|---|---|
list_wiki_pages |
List wiki pages for a project | All |
get_wiki_page |
Get wiki page content and metadata | All |
create_wiki_page |
Create a new wiki page | All |
update_wiki_page |
Update wiki page content or title | All |
delete_wiki_page |
Delete a wiki page | All |
Queries
| Tool | Description | Mode |
|---|---|---|
list_queries |
List saved queries for a project | All |
create_query |
Create a saved query with filters, columns, and sorting | All |
update_query |
Update a saved query | All |
delete_query |
Delete a saved query | All |
Boards
| Tool | Description | Mode |
|---|---|---|
list_boards |
List boards for a project | All |
create_board |
Create a board (status, assignee, version, or free-form) | All |
delete_board |
Delete a board | All |
News
| Tool | Description | Mode |
|---|---|---|
list_news |
List news articles for a project | All |
create_news |
Create a news article | All |
update_news |
Update a news article | All |
delete_news |
Delete a news article | All |
create_release_notes |
Generate structured release notes from version data | All |
Forums
| Tool | Description | Mode |
|---|---|---|
list_forums |
List discussion forums for a project | All |
create_forum |
Create a new forum | All |
list_forum_messages |
List messages/topics in a forum | All |
create_forum_message |
Create a topic or reply in a forum | All |
update_forum_message |
Update a forum message (subject, content, sticky, locked) | All |
Project memberships
| Tool | Description | Mode |
|---|---|---|
list_memberships |
List project members with roles, filterable by project or user | All |
add_membership |
Add a user or group to a project with specified roles | All |
update_membership |
Update roles for an existing membership | All |
remove_membership |
Remove a user or group from a project | All |
list_roles |
List all available roles for assignment | All |
Notifications
| Tool | Description | Mode |
|---|---|---|
list_notifications |
List notifications with read status and project filters | All |
mark_notification_read |
Mark a single notification as read | All |
mark_all_notifications_read |
Mark all notifications as read | All |
Admin
| Tool | Description | Mode |
|---|---|---|
admin_command |
Run administrative Rails console commands (requires Docker access) | Sidecar |
The admin_command tool runs predefined Rails console commands inside the OpenProject container. It covers operations that the REST API does not expose, grouped into four areas:
Module management -- Many API tools (wiki, boards, forums) depend on the corresponding OpenProject module being enabled for a project. Without admin_command, an admin must enable these modules manually through the web UI (Project Settings > Modules). With admin_command, your AI client can enable them on the fly.
| Action | Description | Parameters |
|---|---|---|
enable_module |
Enable a project module (wiki, boards, backlogs, etc.) | identifier, module_name |
disable_module |
Disable a project module | identifier, module_name |
list_modules |
List enabled modules for a project | identifier |
Type and status management -- The REST API can list types and statuses but cannot create new ones or control which types are available per project. admin_command fills this gap.
| Action | Description | Parameters |
|---|---|---|
create_type |
Create a new work package type | name, color (hex), is_milestone |
enable_type |
Enable a type for a specific project | identifier, type_name |
disable_type |
Disable a type for a specific project | identifier, type_name |
create_status |
Create a new work package status | name, color (hex), is_closed, is_default |
Custom fields -- The REST API can read custom fields but not create them. admin_command can create work package custom fields that apply to all projects.
| Action | Description | Parameters |
|---|---|---|
create_custom_field |
Create a work package custom field | name, field_format (string/text/int/float/list/date/bool) |
Backlogs and done-status configuration -- These settings control agile workflow behavior and have no REST API equivalent.
| Action | Description | Parameters |
|---|---|---|
configure_backlogs |
Set story types and task type for the backlogs plugin | story_types, task_type |
get_backlogs_settings |
Read current backlogs configuration | (none) |
set_done_statuses |
Set which statuses count as "done" for a project | identifier, status_ids |
get_done_statuses |
List current done statuses for a project | identifier |
Why this matters: Without admin_command, an OpenProject administrator must perform these actions through the web UI before the API tools can use them. With it, your AI client can fully bootstrap a project -- create types, statuses, and custom fields, enable the right modules, and configure agile workflows -- all in one session.
Utilities
| Tool | Description | Mode |
|---|---|---|
format_commit_message |
Generate a conventional commit message with OpenProject references | All |
Troubleshooting
Verify your setup
Direct (stdio): Run npx open-project-sidecar-mcp -- it should start without errors. Open Claude Code and confirm OpenProject tools appear.
Docker sidecar: curl http://your-server:3000/health should return 200 with the OpenProject version. docker logs open-project-mcp should show the server started. Test admin_command in Claude Code to confirm Docker socket access.
Common issues
| Problem | Cause | Fix |
|---|---|---|
OPENPROJECT_URL is required |
.env file missing or not found |
Create .env in your working directory (where you run npx). Run interactively for guided setup. |
Connection refused |
Server not running or wrong port | Check that the server is running and MCP_PORT matches your client config |
401 Unauthorized |
Wrong or missing MCP_API_KEY |
Verify the key in .env matches what the client sends in the Authorization header |
| Tools not appearing in Claude Code | Config syntax error | Validate JSON in ~/.claude.json -- missing commas and trailing commas are common |
admin_command fails |
Docker socket not mounted | Add /var/run/docker.sock:/var/run/docker.sock to your compose volumes |
admin_command wrong container |
Container name mismatch | Set OPENPROJECT_CONTAINER to match your actual container name (docker ps) |
Development
# Install dependencies
npm install
# Run tests
npm test
# Lint (uses Biome)
npm run lint
# Auto-fix lint issues
npm run lint:fix
# Check for vulnerable dependencies
npm run audit
Adding tools
All tools are defined in index.js using the MCP SDK's server.tool() method. Each tool specifies its name, description, Zod schema for parameters, and handler function. Pure helper functions are exported and tested in test.js.
License
MIT
Dependencies
Dependencies
| ID | Version |
|---|---|
| @modelcontextprotocol/sdk | ^1.12.0 |
| zod | ^3.23.0 |
Development dependencies
| ID | Version |
|---|---|
| @biomejs/biome | ^1.9.0 |