Skip to content
Agentmart
Submit a tool

OpenProject

91 tools for the OpenProject API v3, with read-only, admin-gate, profile and per-group switches.

Connector by kar-thik · GitHub account verified by the MCP Registry

IndexedMITLocal (stdio)★ 5
Write a review

Chalk Labs

Need help deploying OpenProject?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Codex, VS Code, Cursor, Windsurf, Claude Desktop. Read the repository before you give any tool access to your data.

npx agentmarket install connector/kar-thik-openproject-mcp-server

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

91 tools for the OpenProject API v3, with read-only, admin-gate, profile and per-group switches.

Use cases: project-management

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this server can do and what it asks for, from its tool list, install config and code. Checked Oct 25, 2026.

Tools
32 read · 32 write · 13 delete · 3 not yet classified
Secrets
2 (API keys, tokens or passwords)
Install scripts
None found
Runs as
Python package

Tools by what they do 80

Read from the source code; the running server may list different tools.

Read 32 · Look things up without changing anything.

  • get_document
  • get_github_pull_request
  • get_job_status
  • get_meeting
  • get_news
  • get_project
  • get_project_phase
  • get_project_report_data
  • get_recurring_meeting
  • get_sprint
  • get_user
  • get_wiki_page
Show 20 more tools
  • get_work_package_git_activity
  • list_attachments
  • list_budgets
  • list_documents
  • list_file_links
  • list_meetings
  • list_memberships
  • list_news
  • list_notifications
  • list_project_phase_definitions
  • list_projects
  • list_queries
  • list_recurring_meetings
  • list_reminders
  • list_roles
  • list_sprints
  • list_time_entries
  • list_versions
  • list_work_package_comments
  • search_principals

Write 32 · Create, change, send or run things.

  • add_meeting_agenda_item
  • add_meeting_outcome
  • add_work_package_comment
  • add_work_package_watcher
  • bulk_update_work_packages
  • cancel_recurring_meeting_occurrence
  • create_meeting
  • create_membership
  • create_news
  • create_project
  • create_recurring_meeting
  • create_version
Show 20 more tools
  • create_work_package_relation
  • download_attachment
  • edit_work_package_comment
  • execute_custom_action
  • log_time
  • mark_all_notifications_read
  • mark_notifications
  • save_query
  • set_work_package_reminder
  • toggle_comment_reaction
  • update_meeting
  • update_meeting_agenda_item
  • update_meeting_outcome
  • update_membership
  • update_news
  • update_project
  • update_time_entry
  • update_version
  • update_work_package_relation
  • upload_attachment

Delete 13 · Delete, drop, revoke or wipe things.

  • delete_attachment
  • delete_meeting
  • delete_meeting_agenda_item
  • delete_meeting_outcome
  • delete_membership
  • delete_news
  • delete_project
  • delete_recurring_meeting
  • delete_time_entry
  • delete_version
  • delete_work_package_relation
  • remove_work_package_watcher
Show 1 more tools
  • set_project_favorite

Not yet classified 3 · We could not tell from the name and description.

  • copy_project
  • init_recurring_meeting_occurrence
  • run_query

Secrets and settings it asks for

Secrets: values you paste in that let it act as you.

  • OPENPROJECT_API_KEY
  • OPENPROJECT_OAUTH_TOKEN

Other settings (environment variables or headers).

  • OPENPROJECT_MCP_ADMIN_TOOLS
  • OPENPROJECT_MCP_DISABLE
  • OPENPROJECT_MCP_PROFILE
  • OPENPROJECT_MCP_READ_ONLY
  • OPENPROJECT_URL

Network hosts it talks to 3

  • github.com · found in code
  • glama.ai · found in code
  • raw.githubusercontent.com · found in code

Files it touches

  • /tmp/mcp-bootstrap.rb
  • Any path the agent passes to its tools

Tools (80)

Read from the source code; the running server may differ. Descriptions are the server’s own words; hidden characters are shown as [U+…].

  • add_meeting_agenda_itemAdd meeting agenda item

    Add one item to a meeting's agenda, optionally pinned to a work package. Use it to build or extend an agenda: "add 'Release readiness' with 15 minutes", or "put #1234 on Thursday's agenda". Linking a work package is also how a ticket learns it was discussed — the link shows up on the work package's Meetings tab. Returns the created item: `{id, title, notes, duration_minutes, position, item_type, presenter, work_package, section, outcomes, meeting, created_at}`. `position` is where it landed in the agenda; items are appended to the meeting's last section. Pitfalls. This needs the 'manage age…

  • add_meeting_outcomeAdd meeting outcome

    Record an outcome — a decision, a note, a follow-up ticket — against an agenda item. This is how minutes are written through the API: "decision: ship on Friday" becomes `kind='decision'` with the text in `notes`; linking the follow-up work package makes it `kind='work_package'`. Outcomes appear under their agenda item in `get_meeting`. Returns the created outcome: `{id, kind, notes, author, work_package, agenda_item}`. Pitfalls — the timing rule matters most. Outcomes can only be written while the meeting state is exactly 'in_progress': before that, and again once it is closed, every outcom…

  • add_work_package_commentAdd work package comment

    Post a comment on a work package. Use this to reply in a ticket's thread, record a decision, or leave a handover note. Returns the created journal entry (activity id, author, markdown text, internal flag, timestamps) — the same shape ``list_work_package_comments`` returns, so the id can be reused. Pitfalls. Every call creates a new comment; it is not idempotent, so do not retry blindly after a timeout — read the thread first. ``internal=true`` is refused on OpenProject below 16.0 because those versions accept the flag and publish the comment anyway; upgrade or post publicly, deliberately. ``…

  • add_work_package_watcherAdd work package watcher

    Subscribe a user to a work package's notifications. Use this when someone should be kept in the loop on a ticket without being assigned to it. Watchers receive OpenProject's notifications for comments and changes. Returns the watcher (user id and name), the watch state after the call, and whether this call actually changed anything. Pitfalls. The user must already be able to see the work package; OpenProject answers 422 with a violation on ``user`` otherwise, and adding someone other than yourself needs the add-work-package-watchers permission (adding yourself only needs view access). Callin…

  • bulk_update_work_packagesPreview or apply work package updates

    Preview or apply up to 50 work-package updates, each with its own changes. First call with dry_run=true (default). Review each before/after diff and validation error, then submit the same updates with dry_run=false and each preview's lock_version. Omitted fields remain untouched; null clears clearable fields; target_versions=[] clears version assignments. Status/type/priority accept names or ids, as in update_work_package. All items are validated before any update. If any preflight fails, nothing is applied; correct those items or submit a valid subset. Execution is sequential and NOT atomic…

  • cancel_recurring_meeting_occurrenceCancel recurring meeting occurrence

    Cancel one occurrence of a series — skip a slot without touching the schedule. Use it for "no sync next Monday": the slot stays in the occurrences list as 'cancelled' (backed by a cancelled stub meeting) while the series keeps running. A cancelled occurrence is recoverable — `init_recurring_meeting_occurrence` at the same instant restores it to 'open' — but the cancellation itself may email participants when the series has `notify` set, which is why it is confirm-gated. Returns a small confirmation object carrying the normalized instant. Pitfalls. The instant is matched exactly and never va…

  • copy_projectCopy project

    Copy a project — its settings, and optionally its work packages — into a new one. Use it to spin a new engagement or release off a template project, which is the only way to reproduce a project's members, versions, categories and enabled modules in one call. The request goes through ``POST /projects/{id}/copy/form`` first, so a name that derives a taken identifier comes back as ``violations`` naming the attribute instead of a failed background job. Copying is ASYNCHRONOUS: OpenProject queues a job and answers immediately. This tool therefore returns ``{scheduled: true, job_id, status, messag…

  • create_meetingCreate meeting

    Schedule a meeting in a project and optionally invite participants. Use it for "book a review on Thursday" style requests. The call goes through `POST /meetings/form` first, so a missing permission, an impossible time or a participant who cannot see the project comes back as `violations` naming the attribute instead of an opaque rejection. Returns the created meeting in the same shape as `get_meeting` (its `agenda_items` are empty — add them with `add_meeting_agenda_item`). Pitfalls. Check `state` in the result: current OpenProject versions create meetings as 'draft', which means participan…

  • create_membershipGrant project membership

    Grant a principal one or more roles in a project (admin-gated). Use it to add somebody to a project, or to add a group so its members inherit access. The payload is validated through OpenProject's own membership form first, so a role id that does not exist or a principal that is already a member comes back as a typed validation error listing what would be accepted, instead of an opaque 422. Returns the created membership: `{id, project, principal, roles, created_at, notes}`. Keep the `id` — it is what `update_membership` and `delete_membership` take. Pitfalls. **No notification is sent unle…

  • create_newsCreate news

    Publish a news announcement in a project. Use it for release notes, a weekly report, a maintenance window — anything the whole project should see on its overview page. The author is the authenticated account and is set by the server; project members watching the project are notified. Returns the created entry ``{id, title, summary, description, project, author, created_at, updated_at, can_manage}``; the ``id`` is what ``update_news`` and ``delete_news`` consume. Pitfalls: this needs the 'manage news' permission in that project, which exists only while the project has the news module enabled…

  • create_projectCreate project

    Create a project, validated through OpenProject's own form endpoint first. Use it for a new workspace or, with ``parent_id``, for a subproject of an existing one. The call runs ``POST /projects/form`` before committing, so a taken identifier, an unusable parent or a bad status comes back as ``violations`` naming the attribute instead of an opaque failure — and the identifier OpenProject derives from the name is used verbatim on the commit. Returns the created project: ``{id, identifier, name, active, public, parent, status_code, description, status_explanation, created_at, updated_at}``. Kee…

  • create_recurring_meetingCreate recurring meeting

    Create a recurring meeting series: a schedule plus a template the occurrences copy. For "set up a weekly sync Mondays at 9" requests. frequency/end_after combinations are validated locally before anything is sent, rejecting a bad combination with the allowed matrix spelled out. Returns the created series in `get_recurring_meeting`'s shape, including computed next `occurrences` (their `start_time` is what occurrence tools take) and `template_meeting_id`. Pitfalls. The template meeting is created as a DRAFT: `notes` says so, and occurrences can't be initialized until `update_meeting(meeting_i…

  • create_versionCreate version

    Create a version (release, milestone or sprint) inside a project. Use it to open a new sprint or plan a release before assigning work packages to it. The call goes through ``POST /versions/form`` first, so a duplicate name or an impossible date range comes back as ``violations`` naming the attribute instead of an opaque rejection. Returns the created version ``{id, name, project, status, start_date, end_date, description, sharing, source, created_at, updated_at}``. The ``id`` is what ``update_work_package(version=...)`` and ``update_version`` consume. Pitfalls: ``end_date`` is the version's…

  • create_work_package_relationCreate work package relation

    Link two work packages (blocks, follows, duplicates, relates, ...). Use this to record a dependency the schedule or the reader needs to know about: "ship the client layer follows design sign-off", "this duplicates #4321". Returns the created relation with its id, type, reverse_type, both work packages, lag and description. Pitfalls. OpenProject stores one canonical direction per pair, so the passive spellings are rewritten on save: creating ``precedes`` from A to B comes back as B ``follows`` A, with ``from_work_package`` and ``to_work_package`` swapped. That is the same fact, not an error —…

  • delete_attachmentDelete attachment

    Permanently delete one attached file from OpenProject. Use it only on explicit user instruction, for example to remove a file uploaded to the wrong work package or a superseded document. The attachment's metadata is read first so the result names the file and the container it was attached to, and so an unknown id fails before anything is removed. Returns the attachment id, the file name, its container and a confirmation message. Pitfalls: this deletes the file itself, not a link to it — every work package, wiki page or comment that embedded it loses the image or download. Deleting needs *ed…

Show 65 more tools
  • delete_meetingDelete meeting

    Permanently delete a meeting, together with its agenda and recorded outcomes. Use only on explicit user instruction. The meeting, its agenda items, their outcomes and its attachments all go with it, and OpenProject offers no API-side undo. If the meeting merely did not happen, `update_meeting(meeting_id=..., state='cancelled')` is the reversible alternative that keeps the record. Returns a small confirmation object once OpenProject accepts the deletion. Pitfalls. This needs the 'delete meetings' permission, so a 403 is about the account, not the id. A 404 means the id is wrong, the meeting …

  • delete_meeting_agenda_itemDelete meeting agenda item

    Permanently delete one agenda item, with any outcomes recorded against it. Use only on explicit user instruction. The item and its recorded outcomes disappear from the agenda for good; the items after it move up. The meeting itself is untouched. Returns a small confirmation object once OpenProject accepts the deletion. Pitfalls. A CLOSED meeting's agenda is frozen: the delete answers a validation error, not a 403, until the meeting is reopened with `update_meeting(state='open')`. This needs the 'manage agendas' permission. A 404 means the id is wrong, the item is already gone — or, on OpenP…

  • delete_meeting_outcomeDelete meeting outcome

    Permanently delete a recorded outcome from a running meeting's minutes. Use only on explicit user instruction, for an outcome recorded by mistake or against the wrong item. If the text is merely wrong, `update_meeting_outcome` corrects it and keeps the record. Returns a small confirmation object once OpenProject accepts the deletion. Pitfalls. The outcome timing rule applies to deletion too: it only works while the meeting state is exactly 'in_progress' — a closed meeting's minutes are frozen, and the delete answers a validation error, not a 403. This needs the 'manage outcomes' permission.…

  • delete_membershipRevoke project membership

    Revoke a principal's access to a project (admin-gated, destructive). Use only on explicit user instruction. The principal immediately loses the roles this membership granted, along with any project visibility that depended on them; OpenProject offers no API-side undo. Work packages they authored, commented on or are assigned to are **not** deleted, but an assignee who is no longer a member may need to be reassigned. Returns a small confirmation object once OpenProject accepts the deletion. Pitfalls. If the principal also belongs to a group that is a member of the project, they keep access t…

  • delete_newsDelete news

    Permanently delete a news entry. Use it for an announcement published by mistake or in the wrong project. For an outdated but real announcement, ``update_news`` is usually the better answer: the entry stays part of the project's record. Returns a small confirmation once OpenProject accepts the deletion. Pitfalls: the entry and every comment left on it are removed for good — API v3 offers no undo and no trash. The 'manage news' permission is required, so a 403 is about the account or a disabled news module; a 404 means the id is wrong or its news is not visible to you. Cross-references: ``l…

  • delete_projectDelete project

    Schedule the permanent deletion of a project and everything inside it. Use only on an explicit, specific instruction. Deletion CASCADES: every subproject, work package, comment, attachment, time entry, version, wiki page and membership of this project goes with it, and OpenProject offers no API-side undo. If the goal is only to get the project out of the way, ``update_project(active=false)`` archives it instead — reversible, and it preserves the data. Deletion is ASYNCHRONOUS upstream: OpenProject accepts the request and runs it as a background job. This tool therefore returns ``{scheduled: …

  • delete_recurring_meetingDelete recurring meeting

    Permanently delete a recurring series: template, schedule, and EVERY occurrence. Use only on explicit user instruction, and make sure the user means the whole series: every instantiated meeting of the series — past minutes included — is destroyed with the template, and when the series has `notify` set, participants are emailed cancellations. To drop a single slot instead, `cancel_recurring_meeting_occurrence` is the right tool, and `delete_meeting` removes one instantiated meeting. Returns a small confirmation object once OpenProject accepts the deletion. Pitfalls. This needs the 'delete me…

  • delete_time_entryDelete time entry

    Permanently delete a logged time entry. Use only on explicit user instruction, and only for genuinely wrong entries. Deletion removes the booked hours from every cost report and from the work package's aggregated spent time, with no API-side undo. Returns a small confirmation object once OpenProject accepts the deletion. Pitfalls. If the entry is merely on the wrong day, has the wrong duration or the wrong activity, ``update_time_entry`` is the better answer — it keeps the audit trail. Deleting someone else's entry needs an administrative permission and otherwise fails with ``permission_den…

  • delete_versionDelete version

    Permanently delete a version. Use it only for a version created by mistake. For a finished release or sprint, ``update_version(status='closed')`` is almost always the right answer: it keeps the history and stops new assignments. Returns a small confirmation once OpenProject accepts the deletion. Work packages are NOT deleted — they simply lose their version — but that only happens on instances that allow the deletion at all. Pitfalls: OpenProject refuses (422) to delete a version that work packages still reference; the error hint explains how to find them. Deleting a shared version affects …

  • delete_work_package_relationDelete work package relation

    Remove the link between two work packages. Use it when a dependency no longer holds. Neither work package is touched, only the relation between them. Returns a small confirmation object. Pitfalls. Deleting a ``follows`` relation drops the scheduling constraint, so OpenProject may reschedule the work package that was waiting. There is no undo; recreating the relation with ``create_work_package_relation`` is the only way back. A second delete of the same id answers 404. Parent/child hierarchy is not a relation — clear it with ``update_work_package(parent_id=null)``. Cross-references: ``get_wo…

  • download_attachmentDownload attachment

    Download an attachment's bytes to a file on the machine running this server. Use it once list_attachments (or get_work_package(include=['attachments'])) has given you an attachment_id. Metadata is read first, then the bytes are streamed to disk in chunks with progress notifications, so a large file neither stalls the call nor buffers in memory. Returns path, file_name, size_bytes, content_type and the SHA-256 of the bytes (use it to verify or de-duplicate). With return_image=true an image of at most 1 MB comes back as an inline image block as well. Pitfalls: the file is written on the serve…

  • edit_work_package_commentEdit work package comment

    Rewrite the text of an existing work-package comment. Use this to fix a typo, correct a wrong statement, or extend a note you just posted. Returns the updated journal entry (activity id, author, markdown text, internal flag, timestamps) in the same shape ``list_work_package_comments`` returns. Pitfalls. Only **comment** entries are editable: the journal also holds field-change entries ("Status changed from New to In progress"), which OpenProject records automatically and refuses to alter — this tool rejects those locally, before any write. Editing needs the edit-work-package-comments permiss…

  • execute_custom_actionExecute custom action

    Run an instance-defined one-click action on a work package. Custom actions are shortcuts an administrator configured — "Accept and assign to me", "Reject", "Move to review" — that apply several field changes at once, sometimes under conditions (role, status, project). Use one when ``get_work_package(include=['custom_actions'])`` offers it, instead of reproducing its effects field by field. Returns the updated work package row (subject, type, status, priority, assignee, project, dates, percentage_done, updated_at). Pitfalls. The action decides what changes; this tool cannot influence it, and …

  • get_documentGet document

    Read one document with its full description text. Use it after `list_documents` when the title is not enough: this adds `description` as markdown, alongside `{id, title, project, created_at, updated_at}`. Pitfalls. The attached files are not part of this result — list them with `list_attachments(container_type='document', container_id=<this id>)`. A document created with OpenProject's block editor keeps its rich content in a field API v3 does not render, so `description` can be empty for a document that clearly has text in the UI; say so rather than reporting the document as blank. Editing d…

  • get_github_pull_requestGet GitHub pull request

    Read one linked GitHub pull request in full, including its CI check runs. Use it after `get_work_package_git_activity` when the summary is not enough: this adds the pull-request `body` (markdown), the diff size (`additions`, `deletions`, `changed_files`), comment counts, who merged it, and every work package the PR is linked to — plus the same `check_runs` with status and conclusion. Pitfalls. `github_pull_request_id` is OpenProject's id, never the GitHub number; the two are unrelated and there is no lookup by GitHub number. The record is a mirror that OpenProject refreshes from GitHub webho…

  • get_job_statusGet background job status

    Check whether a background job (a project copy, a scheduled deletion) has finished. OpenProject runs copies, deletions and exports asynchronously and hands back a job id. This is the only way to learn what happened to one: call it after ``copy_project`` or ``delete_project`` and wait for a terminal state before reporting an outcome to the user. Returns ``{id, status, finished, successful, message, project, result_url, notes}``. ``status`` is 'in_queue' or 'in_process' while the job runs and 'success', 'failure', 'error' or 'cancelled' once it is over; ``finished`` and ``successful`` are deri…

  • get_meetingGet meeting

    Read one meeting in full: participants, the agenda, and any recorded outcomes. This is the "what was discussed / what was decided" call. It returns the meeting fields (`title`, `project`, `start_time`, `end_time`, `duration_hours`, `location`, `state`, `author`, timestamps), the invited `participants` as `{id, name}` refs, and `agenda_items` in agenda order — each with its `title`, `notes` (markdown), `duration_minutes`, `presenter`, the `work_package` it discusses, its `section`, and the `outcomes` recorded against it (`kind`, `notes`, author, linked work package). Pitfalls. A work-package …

  • get_newsGet news entry

    Read one news entry in full, including the markdown body. Use it after ``list_news`` when the summary is not enough — this adds ``description``, the announcement's complete text as markdown (html is dropped), plus ``updated_at``. Returns ``{id, title, summary, description, project, author, created_at, updated_at, can_manage}``. ``author`` is the account that published the entry and cannot be changed; ``can_manage`` says whether editing or deleting it would be permitted. Pitfalls: a 404 here means "no such entry, or you may not read news in its project" — the news module is enabled per proje…

  • get_projectGet project

    Read one project in full. Use it after ``list_projects`` when you need the description, the status explanation or the parent of a specific project — or to verify that an id or identifier a user gave you actually resolves. Returns ``{id, identifier, name, active, public, parent, status_code, workspace_type, description, status_explanation, created_at, updated_at}``. Rich text comes back as markdown ``raw``; html is dropped. Pitfalls: ``status_code`` is one of on_track, at_risk, off_track, not_started, finished, discontinued — an empty ``status_code`` means the project has no status set, not …

  • get_project_phaseGet project phase

    Read one project's phase record: name, active flag and its definition. Use it after ``get_work_package`` surfaced a ``project_phase`` reference and you need to know which project and definition that phase belongs to, or whether it is still active. Returns ``{id, name, active, definition, project, created_at, updated_at}``. Pitfalls: the API has no phases index — ids only come from work packages' ``project_phase`` references. Phase dates are not exposed by the API (the ``notes`` say so), so "which projects are in this phase now" goes through ``list_projects(in_phase=...)`` instead. A 404 cov…

  • get_project_report_dataGet project report data

    Aggregate everything a status report needs about one project and one date window. Use it for weekly reports, sprint reviews, standups and "what happened in June" — one call replaces a dozen filtered listings. Sections: `created`, `updated` and `closed_updated` work-package buckets, `open` (total plus `by_status` counts computed server-side over the whole open set), `time` (hours with per-activity and per-user breakdowns) and the membership `roster`. Ask only for the `sections` you need. Every section has a `state`: 'complete', 'partial', 'unavailable' or 'not_requested'. A bucket's `total` i…

  • get_recurring_meetingGet recurring meeting

    Read one recurring series in full: the schedule plus its next occurrences. This is the step before touching any occurrence: the `occurrences` rows carry the exact `start_time` strings that `init_recurring_meeting_occurrence` and `cancel_recurring_meeting_occurrence` key on, and the `meeting_id` that `get_meeting` / `delete_meeting` take once a slot is instantiated. Returns the series fields (schedule, `duration_hours`, `location`, `author`, `template_meeting_id`) plus `occurrences` in date order: `{start_time, state, meeting_id}`. `state` is 'planned' for a slot that exists only in the sched…

  • get_sprintGet sprint

    Read one sprint in full: dates, workspace and lifecycle status. Use it once ``list_sprints`` has given you an id and the row is not enough — this adds ``created_at``/``updated_at`` to the same shape. Pitfalls: sprint ids and version ids are different id spaces — a version id from ``list_versions`` does not resolve here. Cross-references: ``list_sprints`` for the id; ``list_work_packages`` with ``sprint_ids`` for the work planned in this sprint.

  • get_userGet user detail

    Read one user's profile: name, login, email, admin flag and status. Use it after `search_principals` when you need more than a name — to confirm an account is `active` before assigning work, to check whether somebody is an instance administrator, or to learn which account the server itself is acting as (`id_or_me='me'`). Returns `{id, name, login, email, admin, status, language, created_at, updated_at}`. The avatar URL is deliberately dropped: it costs tokens and cannot be rendered here. Pitfalls. `email`, `login` and `admin` are visibility-dependent — a null means the authenticated account…

  • get_wiki_pageGet wiki page

    Read a wiki page's identity and project — NOT its content. Two limits define this tool, and both must be passed on to the user rather than worked around. First, `wiki_page_id` comes from a wiki page URL the user supplies: API v3 has no wiki index and no wiki search, so there is no way to look a page up by title or to list a project's pages. Second, the page's CONTENT is not exposed by the API at all — the response carries only `{id, title, project}` plus the page's attachments, and `notes` repeats that in-band. So: use it to confirm which page a URL points at, to get the project a page belon…

  • get_work_package_git_activityGet work package git activity

    Show the code behind a work package: commits, pull/merge requests and CI status. Use this for "is this ticket implemented", "what shipped for it", "did CI pass", "which branch/PR is this in". It returns, in one call: `revisions` (commits whose message references the work package, with full SHA, short SHA, author, message and commit time), `github_pull_requests` (title, state, draft, merged/merged_at, labels, author, URL and the CI `check_runs` with status and conclusion), `gitlab_merge_requests` (the same, with `pipelines` instead of check runs) and `gitlab_issues`. `available` says, per sou…

  • init_recurring_meeting_occurrenceInit recurring meeting occurrence

    Materialize one occurrence of a series as a real meeting, copied from the template. Use it when a specific slot needs its own agenda, minutes or attachments before the day: the occurrence becomes a normal meeting (template agenda and attachments copied) that every meeting tool can work on. Called on a cancelled occurrence it RESTORES it to 'open'; called where an open meeting already exists it idempotently returns that meeting. Returns the instantiated meeting in the same shape as `get_meeting` — its `id` is the meeting id for follow-up calls, distinct from the series id. Pitfalls — the ins…

  • list_attachmentsList attachments

    List the files attached to one container. Containers are work packages, wiki pages, meetings, documents, budgets and comments. Use this to discover attachment ids before calling download_attachment, or to check what a work package already carries. The upstream collection is not paginated, so it is fetched in full: the envelope always reports has_more=false and a total equal to the row count. Returns the standard list envelope; each row has id, file_name, size_bytes, content_type, description, author, created_at and status. status is the virus-scan state — 'uploaded' and 'scanned' are downloa…

  • list_budgetsList budgets

    List a project's budgets — their ids and names, which is all API v3 exposes. Use it to see whether a project tracks budgets at all and to get a budget id, which is what `list_attachments(container_type='budget', ...)` consumes. Returns the standard list envelope with rows of `{id, subject}`. The collection is fetched in full, so `has_more` is false. Pitfalls — read before answering a money question. API v3's budget representer carries **no amounts**: planned costs, spent costs, labor/material breakdowns and the assigned work packages are simply not there. Do not infer them and do not presen…

  • list_documentsList documents

    List the documents visible to you, across every project. Documents are OpenProject's filing cabinet: a title, a description, and attached files. Use this to find a document id for `get_document` or for `list_attachments(container_type='document', ...)`. Returns the standard list envelope: rows of `{id, title, project, created_at, updated_at}` plus `pagination`. The description is deliberately left out of the rows — `get_document` returns it in full. Pitfalls. This is instance-wide: the endpoint takes no project parameter here, so filter by reading `project` on the rows, and page through rat…

  • list_file_linksList file links

    List the external-storage files (Nextcloud, OneDrive/SharePoint) linked to a work package. File links are OpenProject's other kind of file: instead of living inside OpenProject like an attachment, the document stays in a connected storage and the work package points at it. Use this to answer "which documents belong to this ticket" — and pair it with list_attachments, because the two lists are disjoint and neither implies the other. Returns the standard list envelope, fetched in full (has_more is always false). Each row carries file_name, the storage it lives on, the file's origin_id inside t…

  • list_meetingsList meetings

    List meetings — the schedule side of a project: what is coming up, what already ran. Use it to answer "when do we next meet", "what meetings does this project have", or to find the meeting id that `get_meeting` and `add_meeting_agenda_item` need. Meeting ids are instance-wide and never guessable, so this is the way to get one. Returns the standard list envelope: rows of `{id, title, project, start_time, end_time, duration_hours, location, state}` plus `pagination` and `notes`. Times are ISO 8601 UTC and `duration_hours` is a float (1.5 = 90 minutes). Rows are ordered by start time — ascendin…

  • list_membershipsList project memberships

    List who has access to which project, and with which roles. Use it before granting or revoking access ("does she already have a role here?"), to audit a project's member list, or to see which projects a principal can reach. Called with no arguments it pages through every membership the authenticated account may see, which on a large instance is a lot — filter. Returns the standard list envelope: `items` of `{id, project, principal {id,name,type}, roles[], created_at, updated_at}` plus `pagination{total,page,page_size,has_more}`. Pitfalls. The `id` in each row is the **membership** id — the …

  • list_newsList news

    List project news — the announcements a team publishes on its project overview. Use it to answer "what was announced recently", to find the id of an entry before reading, editing or deleting it, or to check whether a report was already published. Results come back newest first (sorted by creation date descending). Returns the standard list envelope: ``items`` of ``{id, title, summary, project, author, created_at, can_manage}`` plus ``pagination`` and ``notes``. Rows carry the short ``summary`` only — the full markdown body is fetched per entry with ``get_news(news_id=...)``, which keeps a lo…

  • list_notificationsList notifications

    Read the authenticated user's OpenProject inbox. Use this to answer "what needs my attention?", "was I mentioned anywhere?" or "what changed on the things I watch?" — it is the only tool that sees notifications, and it always reports the inbox of the **token owner**, never another user's. Returns the standard list envelope: ``items`` of ``{id, reason, read, created_at, actor, project, resource}`` plus ``pagination`` with ``total``/``page``/``page_size``/``has_more``. ``resource`` is the thing the notification is about — ``{id, type, title}``, usually ``type='WorkPackage'``, so ``resource.id`…

  • list_project_phase_definitionsList project phase definitions

    List the instance-global phase definitions — the vocabulary of the project life cycle. Use it to learn which phases (Initiating, Planning, …) and gates this instance defines, and to get the definition id or name that ``list_projects(in_phase=...)`` accepts. Returns the standard list envelope of ``{id, name, start_gate, start_gate_name, finish_gate, finish_gate_name}`` rows. Gates are the checkpoints a phase can begin or end with; a definition without gates has both flags false. Pitfalls: definitions are the instance-wide *catalog*, not any project's actual phases — a project may deactivate …

  • list_projectsList projects

    List projects, filtered server-side, one page at a time. Use this to turn a project name into the id or identifier that every other tool consumes, to enumerate the sub-projects of a parent, or to review which projects are off track. It is the id-producing path for every ``project_id`` parameter in this server. Returns the standard list envelope: ``items`` of ``{id, identifier, name, active, public, parent, status_code, workspace_type}`` plus ``pagination`` with ``total``/``page``/``page_size``/``has_more``. Nothing is truncated silently — page explicitly until ``has_more`` is false. Pitfall…

  • list_queriesList saved queries

    List the saved work-package views (queries) this user can open. Use it to discover what a team already tracks — "Sprint board", "My open bugs", "Overdue in Platform" — before hand-building filters: running someone's saved view with `run_query` reproduces exactly what they see in the UI, including their grouping and sums. Returns the standard list envelope: rows of `{id, name, project, public, starred, updated_at}` plus `pagination`. `project` is null for a global query (saved outside any project); `public` false means the query is private to its owner, and only the owner's queries are visibl…

  • list_recurring_meetingsList recurring meetings

    List recurring meeting series — the repetition rules, not the individual meetings. Use it to answer "what regular meetings do we have" and to find the series id that `get_recurring_meeting`, the occurrence tools and `delete_recurring_meeting` need. Series ids are their own id space: a series id is never a meeting id, and the weekly occurrences themselves show up in `list_meetings`, not here. Returns the standard list envelope: rows of `{id, title, project, start_time, time_zone, frequency, interval, monthly_day, monthly_ordinal, monthly_weekday, end_after, end_date, iterations, duration_hour…

  • list_remindersList reminders

    List your own upcoming work-package reminders. Use this to answer "what have I asked to be reminded about", to check whether a reminder is already set before creating another one, or to find the work packages you deferred. Returns the standard list envelope: ``items`` of ``{id, remind_at, note, work_package, creator}`` plus ``pagination`` and ``notes``. Pitfalls. Reminders are personal — this only ever shows the ones the authenticated account created, never a colleague's, and there is no way to list someone else's. It only shows reminders that are still **upcoming**: once one has fired (or w…

  • list_rolesList roles

    List the roles this instance defines, with their ids. This is the id-producing tool for `create_membership.role_ids` and `update_membership.role_ids` (both admin-gated: hidden unless the server sets `OPENPROJECT_MCP_ADMIN_TOOLS=1`) — role names are never accepted there. Roles are instance-wide definitions ('Member', 'Reader', 'Project admin'); a membership binds one principal to one project with a set of them. Returns the standard list envelope with `has_more: false`: the role list is small and fetched in full. Each item is `{id, name}`, plus `permissions` when `include_permissions=true`. P…

  • list_sprintsList sprints

    List sprints (Scrum timeboxes) you can plan work packages into. Use it to turn "Sprint 11" into the sprint id that ``create_work_package``/``update_work_package`` consume via their ``sprint`` parameter, or to review a project's sprint plan with its ``in_planning``/``active``/``completed`` states. Returns the standard list envelope: ``items`` of ``{id, name, description, start_date, finish_date, workspace, status}`` plus ``pagination`` and ``notes``. A project-scoped listing is fetched in full, so ``has_more`` is false; the instance-wide listing is paginated. Pitfalls: sprints are not versio…

  • list_time_entriesList time entries

    List logged time, filtered server-side, with an optional accurate total. Answers "how much time went into this ticket?" or "how much did the team spend on project X in June?". Filters combine with AND, so `project_id` + `user='me'` + a date range is one call. Returns the standard list envelope: ``items`` of ``{id, hours, spent_on, comment, user, activity, work_package, project}`` plus ``pagination``. ``hours`` is a float (1.5 = 1h30), never an ISO duration. With ``sum_hours=true``, the envelope also carries ``sums.total_hours`` over all matches and a ``groups`` bucket per activity with its o…

  • list_versionsList versions

    List versions (releases, milestones, sprints) you can assign work packages to. Use it to turn "Sprint 12" or "release 2.1" into the version id that ``create_work_package``/``update_work_package`` need, to see which versions are still open, or to review a release plan's dates. With ``project_id`` it answers "what can I target in THIS project", which includes versions shared down from parent projects. Returns the standard list envelope: ``items`` of ``{id, name, project, status, start_date, end_date, description, sharing, source}`` plus ``pagination`` and ``notes``. A project-scoped listing is…

  • list_work_package_commentsList work package comments

    Read the comment thread and change history of a work package. Use this whenever the question is "what did people say about this ticket" or "what changed on it": it returns the full activity journal — comment entries (author, markdown text, internal flag, timestamps) and field-change entries whose details are parsed into ``{field, from, to}`` (for example ``{"field": "Status", "from": "New", "to": "In progress"}``). Returns the standard list envelope: ``items`` plus ``pagination{total,page,page_size,has_more}`` and ``notes``. Pitfalls. OpenProject's activities endpoint is **unpaginated** — t…

  • log_timeLog time

    Book time against a work package or a project. Use it when the user says "log 2 hours on #1234" or "book half a day to project X". The call is validated through OpenProject's own form endpoint first, so an activity this project does not allow, a missing permission or a closed cost-reporting period comes back as a typed error listing what would be accepted — nothing half-written is left behind. Returns the created entry: ``{id, hours, spent_on, comment, user, activity, work_package, project, created_at, updated_at, lock_version}``. ``hours`` comes back as a float. Pitfalls. This is **not** i…

  • mark_all_notifications_readMark all notifications read

    Mark **everything** matching the filters as read — the whole inbox by default. Use it for "clear my notifications" or "I have dealt with everything in project X". Called with no arguments it marks every unread notification of the token owner as read, across all projects; ``reason`` and ``project_id`` narrow that blast radius, they do not create a preview. Check what is about to disappear with ``list_notifications(unread_only=true, ...)`` using the same filters first — there is no undo beyond re-marking individual ids unread. Returns ``{marked, read, message}``, where ``marked`` is how many u…

  • mark_notificationsMark notifications read or unread

    Mark specific notifications read (or unread) in one bulk request. Use it after you have actually handled what a notification was about, so the user's inbox reflects reality. It is the id-consuming counterpart of ``list_notifications``: pass the row ``id`` values from that tool. Returns ``{marked, read, ids, message}``. OpenProject answers the bulk endpoint with ``204 No Content``, so ``marked`` is the number of ids the call covered — ids that were already in the requested state, or that belong to someone else's inbox, are simply not changed. Pitfalls. Marking is idempotent, so a retry after…

  • remove_work_package_watcherRemove work package watcher

    Unsubscribe a user from a work package's notifications. Use this to stop notifying someone who no longer needs the updates. Returns the user, the watch state after the call (always not watching) and a confirmation message. Pitfalls. OpenProject answers the same 204 whether or not the user was watching, so ``changed`` comes back null — do not report "removed" as proof that they were subscribed. Removing another user needs the delete-work-package-watchers permission; removing yourself only needs view access. A 404 means the *user* id is unknown (or the work package is), not that they were not …

  • run_queryRun a saved query

    Run a saved view and get its work packages — the fastest way to answer with a team's own definition of "the sprint" or "our bugs". OpenProject queries run on read: this returns the rows as they are right now, in the stored order and grouping. The result is the standard list envelope — `items` of compact work-package rows, `pagination`, plus `groups` when the query groups and `sums` when it asks for totals — with one addition: `query` carries the stored definition (name, project, readable `filters`, `group_by`, `sort_by`), so the rows can be interpreted without a second call. Pitfalls. `group…

  • save_querySave a query

    Save a filter set as a reusable OpenProject view. Use it to keep a filter combination — "Overdue in Platform", "My open bugs" — instead of rebuilding it each session: the view shows up in the OpenProject UI too, and `run_query` reproduces it exactly. Prove filters with `list_work_packages` first. Validated via `POST /queries/form` first, so an invalid filter name, unsupported operator, or project-scoped filter on a global view comes back as `violations` naming the attribute — nothing is saved. Returns the stored definition: `{id, name, project, public, starred, filters (as readable sentences…

  • search_principalsSearch users, groups and placeholder users

    Find users, groups and placeholder users, and get their ids. This is **the** id-producing tool for every principal parameter in this server: `assignee`/`responsible` on work packages, watcher ids, the `user_id` of a time entry, and `principal_id` for `create_membership` (admin-gated: hidden unless the server sets `OPENPROJECT_MCP_ADMIN_TOOLS=1`). Names are never accepted where an id is wanted — resolve here first, and never guess a numeric id. Use it to answer "who is Grace Hopper's account", "which groups exist", "who is a member of the demo project". Returns the standard list envelope: `it…

  • set_project_favoriteSet project favorite

    Add or remove a project from the authenticated user's favorites (OpenProject 17+). Favorites are per user, not per project: this changes what the account behind OPENPROJECT_API_KEY sees starred on its own overview page, and nothing about the project itself or about anybody else's view. Use it when the user asks to pin, star or favorite a project they work in. Returns ``{id, favorite, message}`` — ``favorite`` is the state now in effect. The call is idempotent: favoriting an already-favorited project succeeds again. Pitfalls: this endpoint only exists from OpenProject 17. When the instance r…

  • set_work_package_reminderSet work package reminder

    Set, change or clear your personal reminder on a work package. Use this when something should resurface later: "remind me about this on Monday", "ping me an hour before the release". Reminders are private — only you see yours, and only you are notified. The tool upserts: it looks for your active reminder on the work package and creates one if there is none, updates it if there is. Returns ``action`` (created/updated/deleted/unchanged) and the resulting reminder. Passing ``remind_at=null`` **deletes** the reminder. That is the documented way to clear it rather than a destructive operation — n…

  • toggle_comment_reactionToggle comment reaction

    React to a work-package comment with an emoji, or take your reaction back. Use this for the lightweight acknowledgement a comment does not deserve: 👍 on a decision, 👀 to say you are looking at it, 🎉 when something shipped. Returns the comment's full reaction state afterwards — every emoji on it with the people who picked it — plus ``reacted``, which says whether you are now among them. Pitfalls. This is a **toggle**, not an add: calling it twice with the same reaction leaves the comment exactly as it started, so it is not safe to retry blindly after a timeout — read ``reacted`` from the r…

  • update_meetingUpdate meeting

    Change a meeting's title, time, place or invite list — or move its lifecycle state. Reschedule ("move Thursday's review to 15:00"), publish a draft (`state='open'`), start/wrap up a running one (`state='in_progress'`/`'closed'`), or fix participants. Only passed parameters are sent; omitted fields stay as they are. Returns the updated meeting in the same shape as `get_meeting`, including the fresh `lock_version` for a follow-up edit. Pitfalls. A closed meeting accepts a state-only patch (reopening it) and nothing else; any other change is rejected with a validation error until it is reopene…

  • update_meeting_agenda_itemUpdate meeting agenda item

    Edit one agenda item: retitle it, rewrite its notes, retime, reorder or re-link it. Use it for "give that item 20 minutes", "move it to the top" (`position=1`), "let Grace present it", or to fix a wrong work-package link. Only the parameters you pass are sent; everything else is left exactly as it is. Returns the updated item in the same shape as `add_meeting_agenda_item`, including the fresh `lock_version` for a follow-up edit. Pitfalls. Once the meeting is CLOSED its agenda is frozen — every write answers a validation error until the meeting is reopened with `update_meeting(state='open')`…

  • update_meeting_outcomeUpdate meeting outcome

    Correct a recorded outcome's kind, text or linked work package. Use it while the meeting still runs: fix a typo in the minutes, upgrade an information note to a decision, or attach the follow-up ticket that was created after the fact. Only the parameters you pass are sent. Returns the updated outcome in the same shape as `add_meeting_outcome`. Pitfalls. The same timing rule as every outcome write: this only works while the meeting state is exactly 'in_progress' — once it is closed, the minutes are what they are, and the write answers a validation error. Outcomes carry no `lock_version` upst…

  • update_membershipChange membership roles

    Replace the roles of an existing membership (admin-gated). Use it to promote or demote somebody inside a project. The project and the principal of a membership cannot be changed: to move access to a different project, delete this membership and create the other one. Runs through the membership form first, so an unknown or non-assignable role comes back with the roles this instance actually offers. Returns the updated membership `{id, project, principal, roles, updated_at}`. Pitfalls. `role_ids` is a **replacement set**, not an addition — read the current roles with `list_memberships` and se…

  • update_newsUpdate news

    Correct or rewrite a published news entry. Use it to fix a headline, refresh a weekly report in place, or clear a stale teaser. Only the parameters you pass are sent, so a concurrent edit to another field survives. Returns the updated entry in the same shape as ``get_news``. Pitfalls: ``summary`` and ``description`` REPLACE the stored text — there is no append. The entry's project and author are fixed at creation and cannot be updated here; publish a new entry instead. News carries no ``lockVersion`` upstream, so there is nothing to echo and no lock parameter: a simultaneous edit by somebod…

  • update_projectUpdate project

    Change a project's name, description, visibility, parent, status or archived state. Use it to record a status change with its explanation ("at_risk because the vendor slipped"), to rename or re-parent a project, to publish it, or to archive it with ``active=false``. The change is validated through ``POST /projects/{id}/form`` first, so rejected values come back as ``violations`` naming the attribute. Only the parameters you pass are sent — omitted fields are never rewritten, so two agents editing different fields do not clobber each other. Projects carry no ``lockVersion`` upstream, so there…

  • update_time_entryUpdate time entry

    Correct an existing time entry. Use it for the everyday fixes: wrong duration, wrong day, wrong activity, a comment that needs to say what actually happened. Only the parameters you pass are written; everything else is left exactly as it is. Returns the updated entry in the same shape ``log_time`` returns. Pitfalls. What can be moved between entries is limited: the work package and the project a time entry belongs to are **not** editable here — delete the entry and log it again where it belongs. Some instances report a ``lock_version`` for time entries and some do not; this tool reads the e…

  • update_versionUpdate version

    Change a version's name, dates, description, status or sharing. Use it to move a sprint's dates, to close a finished release (``status='closed'``), or to widen sharing so a subproject can use the version. The change is validated through ``POST /versions/{id}/form`` first, so rejected values come back as ``violations`` naming the attribute. Only the parameters you pass are sent, so concurrent edits to other fields survive. Versions carry no ``lockVersion`` upstream, so there is nothing to echo and no lock parameter here — a 409 would mean the resource itself changed, not a stale version. Ret…

  • update_work_package_relationUpdate work package relation

    Change an existing relation's type, lag or description. Use it to widen the gap between a predecessor and its successor, to correct a link that was created with the wrong type, or to explain why two work packages are connected. Returns the updated relation. Pitfalls. At least one of type, lag or description must be given. Relations carry no lock version, so this is a plain overwrite with no conflict detection — a concurrent edit is silently replaced; re-read the relation if that matters. The two work packages cannot be changed here: delete the relation and create a new one instead. Raising t…

  • upload_attachmentUpload attachment

    Attach a local file to a work package, wiki page, meeting, document, budget or comment. Use it when a file that already exists on the server's machine should be added to an existing container. The file's existence and its size against this instance's maximumAttachmentFileSize are checked locally first, so an oversized file fails instantly instead of after the transfer. Returns the created attachment row (id, file_name, size_bytes, content_type, description, author, created_at, status) — the id feeds download_attachment. Pitfalls: uploading to a container needs *edit* permission on that cont…

Signals

Stars
5
Forks
1
Open issues
0
Weekly downloads
433
Last commit
Oct 20, 2026 (10 days ago)
Last release
Oct 20, 2026 (10 days ago)
Last package publish
Oct 20, 2026 (10 days ago)

From GitHub (fetched Oct 24, 2026) and the package registry.

Details

Registry name
io.github.kar-thik/openproject-mcp-server
Version
0.4.0
Auth
API key
License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get OpenProject running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying OpenProject?

CallGet help
Cite this page

OpenProject MCP server. Agent Mart. https://agentmart.dev/connectors/kar-thik-openproject-mcp-server (last updated 2026-10-24)