open-project-sidecar-mcp (1.4.4-alpha)
Installation
registry=npm install open-project-sidecar-mcp@1.4.4-alpha"open-project-sidecar-mcp": "1.4.4-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 -y open-project-sidecar-mcp --setup
The --setup flag launches an interactive wizard that walks you through:
- Deployment mode -- Direct (stdio) or Docker sidecar
- Credentials -- OpenProject URL and API key (plus mode-specific settings)
- Docker compose scaffolding (sidecar mode) -- auto-detects your compose file, adds the MCP service, and creates
.envsecrets - Connectivity test -- verifies your OpenProject instance is reachable
- Client registration -- registers the server globally in Claude Code (or Cursor) so it's available from any directory
Without --setup, the server starts normally and loads .env from your current working directory automatically. See Configuration for all available options, or Manual configuration if you prefer non-interactive setup.
Reinstall / repair a broken setup
Re-running --setup is safe on existing installations. The wizard will:
- Detect your existing Docker compose and offer to update or keep the current service
- Reuse your existing
MCP_API_KEYfrom the compose.envso the registered key matches your running sidecar (no 401 errors) - Clean up stale Claude Code registrations from all scopes (project and global) before writing a fresh global entry
If your AI client can't find OpenProject tools or you're getting auth errors after a previous install, --setup is the fix.
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 setup wizard:
npx -y open-project-sidecar-mcp --setup
The wizard creates a .env with your OpenProject URL and API key, tests connectivity, and registers the server globally in your MCP client. 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 setup wizard from your OpenProject compose directory and choose Docker sidecar → Set up a new sidecar:
cd /path/to/your/openproject-compose
npx -y open-project-sidecar-mcp --setup
The wizard will:
- Auto-detect your
docker-compose.ymland running OpenProject container - Prompt for your OpenProject API key
- Generate an
MCP_API_KEYfor HTTP auth (or reuse an existing one) - Add the MCP service block to your compose file
- Save credentials to your
.env - Offer to start the sidecar with
docker compose up -d mcp - Register the server globally in Claude Code (available from any directory)
At the end, it prints the connection URL and API key to share with team members.
2. Verify: curl http://localhost:3000/health should return 200. Open Claude Code and confirm OpenProject tools appear. Test admin_command to confirm Docker socket access.
What the wizard adds to your compose file
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
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.
Connecting to an existing sidecar
Team members run the wizard and choose Docker sidecar → Connect to an existing sidecar:
npx -y open-project-sidecar-mcp --setup
Enter the server URL and API key provided by the sidecar admin. The wizard tests connectivity, then registers the server globally in 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.
Something broken? Re-run setup
Most installation issues (auth errors, missing tools, stale config) are fixed by re-running the wizard:
npx -y open-project-sidecar-mcp --setup
The wizard detects your existing setup, reuses your current API keys, cleans up stale Claude Code registrations, and writes a fresh global config. It won't duplicate services or generate conflicting keys.
Common issues
| Problem | Cause | Fix |
|---|---|---|
OPENPROJECT_URL is required |
.env file missing or not found |
Run npx -y open-project-sidecar-mcp --setup 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 |
Key mismatch between client/server | Re-run --setup -- the wizard reads the existing key from your compose .env and registers it correctly |
| Tools not appearing in Claude Code | Stale or project-scoped config | Re-run --setup -- the wizard cleans old entries and registers globally |
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 |