openproject-mcp
Provides tools for managing OpenProject projects, work packages, relations, attachments, users, notifications, watchers, boards, and reference data via the OpenProject REST API.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@openproject-mcpshow open work packages assigned to me"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
openproject-mcp
An MCP server that exposes the OpenProject REST API (v3) as tools usable by Claude Desktop, Claude Code, Cursor, and any other MCP client.
Features
Projects -- list, get, create, update, delete
Work packages -- list, get, create, update (with
lockVersion), delete, activity/comment thread, inline file attachments on commentsRelations -- list, get, create, delete (blocks, precedes, relates, duplicates, etc.)
Attachments -- list, get (with download), upload (with auto-embed in description or comment), delete
Users -- current user, list, get
Notifications -- list, get, mark read, mark all read
Watchers -- list, add, remove watchers on work packages
Boards -- list and get Kanban-style boards
Reference data -- work package types, statuses, priorities, versions
Raw passthrough -- call any GET endpoint under
/api/v3directlyFilter, sort, group, and paginate via OpenProject's native query syntax
Requirements
Node.js >= 18.17
An OpenProject instance with API access enabled
An API token (from My account > Access tokens > API in OpenProject)
Installation
No clone or build step needed -- npx installs and builds directly from GitHub:
npx -y github:OliverRhyme/openproject-mcpConfiguration
The server reads environment variables at startup. No .env file is loaded
automatically -- pass them via your MCP client's env config or your shell.
Variable | Required | Default | Notes |
| yes | -- | e.g. |
| yes | -- | From My account > Access tokens > API |
| no |
| Default page size for list endpoints |
| no |
| HTTP request timeout in milliseconds |
The API key is sent via HTTP Basic auth with the literal username apikey,
which is the form OpenProject documents for token-based access.
Quick start
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"openproject": {
"command": "npx",
"args": ["-y", "github:OliverRhyme/openproject-mcp"],
"env": {
"OPENPROJECT_BASE_URL": "https://your-instance.openproject.com",
"OPENPROJECT_API_KEY": "your-token"
}
}
}
}Claude Code
claude mcp add openproject \
--env OPENPROJECT_BASE_URL=https://your-instance.openproject.com \
--env OPENPROJECT_API_KEY=your-token \
-- npx -y github:OliverRhyme/openproject-mcpCursor
Add to .cursor/mcp.json in your project root:
{
"mcpServers": {
"openproject": {
"command": "npx",
"args": ["-y", "github:OliverRhyme/openproject-mcp"],
"env": {
"OPENPROJECT_BASE_URL": "https://your-instance.openproject.com",
"OPENPROJECT_API_KEY": "your-token"
}
}
}
}Local development
If you're working on the server itself:
git clone https://github.com/OliverRhyme/openproject-mcp.git
cd openproject-mcp
npm install
npm run devTools reference
All tools are prefixed op_ to avoid collisions with other MCP servers.
Projects
Tool | Description |
| List projects with filter/sort/paginate |
| Get project by id or identifier slug |
| Create a new project |
| Patch project fields |
| Delete a project (destructive, async) |
Work packages
Tool | Description |
| List work packages, optionally scoped to a project |
| Get a single work package by id |
| Create a work package (requires subject, projectId, typeId) |
| Patch work package fields (requires |
| Delete a work package (destructive) |
| List comments and change history |
| Add a comment, optionally attaching and embedding a file inline |
Relations
Tool | Description |
| List relations on a work package (blocks, precedes, duplicates, etc.) |
| Get a single relation by id |
| Create a relation between two work packages |
| Delete a relation |
Attachments
Tool | Description |
| List attachments on a work package |
| Get attachment metadata; optionally download to a local path |
| Upload a local file; optionally embed in a comment or WP description |
| Delete an attachment (destructive) |
Users
Tool | Description |
| Get the user tied to the configured API key |
| List users with filter/sort/paginate |
| Get a user by id |
Notifications
Tool | Description |
| List in-app notifications for the current user |
| Get a single notification by id |
| Mark one notification as read |
| Mark all notifications as read |
Watchers
Tool | Description |
| List users watching a work package |
| Add a user as a watcher |
| Remove a user from watching |
Boards
Tool | Description |
| List Kanban-style boards for a project |
| Get board details including column config |
Reference data
Tool | Description |
| List work package types (Task, Bug, Feature, etc.) |
| List all work package statuses |
| List all priorities |
| List versions/milestones, optionally per project |
| Raw GET against any |
Usage patterns
Filter syntax
List endpoints accept OpenProject's structured filter format:
{
"projectIdOrIdentifier": "web",
"filters": [
{ "field": "status_id", "operator": "o", "values": null },
{ "field": "assignee", "operator": "=", "values": ["42"] },
{ "field": "type", "operator": "=", "values": ["1"] }
],
"sortBy": [["updatedAt", "desc"]],
"pageSize": 50
}Common operators:
Operator | Meaning |
| Equals |
| Not equals |
| Contains (substring) |
| Open statuses |
| Closed statuses |
| Greater or equal |
| Less or equal |
| Any (not empty) |
| None (empty) |
Filter values are always strings, even for numeric ids: "values": ["42"], not [42].
Updating work packages (lockVersion)
OpenProject uses optimistic locking. You must pass the current lockVersion
when updating a work package -- fetch it first with op_get_work_package:
// 1. Get current state
// op_get_work_package { "id": 17 }
// -> { ..., "lockVersion": 4 }
// 2. Update with lockVersion
// op_update_work_package
{
"id": 17,
"lockVersion": 4,
"statusId": 7,
"percentageDone": 50
}Uploading and embedding attachments
Upload a file and auto-embed it as an image in a comment:
// op_upload_attachment
{
"workPackageId": 17,
"filePath": "/path/to/screenshot.png",
"embedIn": "comment",
"embedText": "Here's the updated design:"
}Or attach a file when commenting:
// op_comment_work_package
{
"id": 17,
"comment": "Fixed in latest build, see attached screenshot.",
"attachFilePath": "/path/to/screenshot.png"
}Creating relations
Link work packages with dependency or reference relations:
// op_create_relation
{
"fromId": 17,
"toId": 23,
"type": "blocks"
}Relation types: relates, duplicates, blocks, precedes, follows,
includes, partOf, requires.
Raw mode
Most list and get tools accept a raw: true flag. By default, responses are
summarized into flat objects for smaller context windows. Set raw: true to
get the full HAL+JSON document from OpenProject:
// op_get_work_package
{ "id": 17, "raw": true }Scripts
Command | Purpose |
| Install dependencies |
| Compile TypeScript to |
| Run the compiled server (requires build) |
| Watch-mode server via |
| Run test suite |
| Run tests in watch mode |
| Type-check without emitting |
Smoke test
Verify the server boots and lists tools without a real OpenProject instance:
OPENPROJECT_BASE_URL=https://example.openproject.com OPENPROJECT_API_KEY=fake \
node dist/index.js <<'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"0.0.0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
EOFLicense
MIT
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/OliverRhyme/openproject-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server