OpenProject
io.github.kar-thik由 GitHub 账号 kar-thik 发布v0.5.0更新于 Oct 29, 2026
91 tools for the OpenProject API v3, with read-only, admin-gate, profile and per-group switches.
概览
通过 91 个 OpenProject API v3 工具,让助手查询和修改工作包、项目、工时、会议等数据,并支持只读与分组开关。
- 可以做什么
- 搜索、列出、读取、创建、更新、批量更新和删除工作包,以及评论、关联、关注者和提醒
- 列出、读取、创建、更新、复制和删除项目、已保存查询、版本与冲刺
- 读取和管理通知、工时记录、会议与周期性会议、新闻、文档和预算
- 列出、下载、上传和删除附件,并列出外部文件链接
- 查询人员、角色和成员关系,读取实例元数据、字段结构和权限
- 生成周报、站会、收件箱分诊和待办梳理提示,并把工作包、项目和附件作为资源提供
- 适用场景
- 当团队用 OpenProject 管理项目、希望助手在对话中查询和更新工作包、登记工时、生成状态报告或站会材料、整理通知时适用。
- 运行要求
- 需要本机 Python 3.12 以上运行环境,通过 uvx 或 pip 安装 openproject-mcp-server 包。需要一个 OpenProject 实例(14 LTS 至 17.x),并在 OPENPROJECT_API_KEY 中提供 API 密钥或在 OPENPROJECT_OAUTH_TOKEN 中提供 OAuth 令牌,同时在 OPENPROJECT_URL 中填写实例根地址。需要能访问该实例的网络。
安装
在 SourceWeft 中
- 打开 控制台中的 OpenProject,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
OpenProject MCP Server
[PyPI] [CI] [openproject-mcp MCP server]
An MCP (Model Context Protocol) server for the OpenProject API v3. It gives Claude and any other MCP client 91 tools covering work packages, comments and relations, attachments, git/PR activity, projects, saved queries, notifications, time tracking, versions, people and memberships, meetings, news, documents, budgets and reporting — plus 4 report/workflow prompts and 3 resource templates. Built on FastMCP 4.x and httpx (HTTP/2); speaks MCP 2026-07-28 and the earlier handshake versions.
This project is aimed at the OpenProject Community edition. OpenProject's Enterprise edition now ships with its own built-in MCP integration; this server brings the same capability to self-hosted Community instances. It runs fine against any edition — it only needs the public API v3.
Design principles, all enforced in code:
- Structured everything. Every tool returns a typed model, so clients get an
outputSchemaand machine-readablestructuredContent, not prose. Errors come back as a JSON envelope with a stabletype, the upstreamhttp_status, amessageand ahintdescribing how to correct the call. - Honest degradation. OpenProject instances differ by version, installed modules and permissions. Tools report what they could not see as in-band notes — a missing module yields an empty page with an explanation, never a fake success or a bare traceback.
- Safe by default. A read-only mode, admin-gated membership writes, per-group tool
disabling, a
confirm=trueguard on every destructive tool, TLS always verified, and credentials that never appear in logs. - Version-adaptive. Targets OpenProject 14 LTS through 17.x; API differences are detected by a lazy, cached feature probe instead of assumptions (see Supported OpenProject versions).
What it looks like
Two exchanges against a fictional "Website Relaunch" project — every id, name and date below is invented. You describe the outcome; the model picks the tools, and what comes back to it is a typed object rather than prose to re-parse.
The rows above are abridged: each one also carries priority, project, start_date,
percentage_done and updated_at, and the envelope keeps groups, sums and notes slots
for the calls that fill them.
The prompt templates cut out the tool round trips: the server reads OpenProject itself and hands back a finished document rather than instructions to go and fetch one. It arrives prefaced with a note that the numbers are already computed and must not be recomputed or embellished.
That last block is the house style: a report says which of its numbers are partial, and a tool that could not read something returns the gap as a note instead of guessing. The whole surface is in Tools and Prompts and resources.
Requirements
- Python >= 3.12
- An OpenProject instance, version 14 LTS through 17.x (any edition; aimed at Community — Enterprise ships its own MCP integration)
- An OpenProject API key: in OpenProject, go to My account → Access tokens and generate an API token
Installation
The distribution name is openproject-mcp-server. It installs two identical console scripts,
openproject-mcp-server and openproject-mcp; the long form is canonical (an unrelated PyPI
package also installs a bin named openproject-mcp).
Run one-shot with uv, no install step:
Or install persistently:
The minimal configuration is two environment variables:
Validate the configuration without starting the server:
--check verifies the configuration and exits; it does not contact your instance. Once
connected through a client, call the get_instance_info tool for a live end-to-end check.
When configuration is missing or invalid, the server prints the specific problems to stderr
and exits with code 2 — never a traceback.
Claude Code
Claude Desktop and other MCP clients
Add to claude_desktop_config.json (or your client's equivalent mcpServers config):
From source
Updating or rotating your API token
When a token is regenerated, revoked or invalidated (OpenProject major upgrades can do this —
the symptom is every tool suddenly failing with authentication_failed / HTTP 401), generate
a fresh one in OpenProject under My account → Access tokens and update it wherever your
key lives:
-
Shell environment (easiest to rotate). The server reads
OPENPROJECT_API_KEYstraight from the OS environment, so you can export it globally — e.g. in~/.zshenv— and register the server with no--envflags at all:Rotation is then: edit the export, open a fresh terminal, reconnect. The client config never contains a secret. (This does not work for GUI apps like Claude Desktop, which don't read your shell profile.)
-
Claude Code with
--env. The registration stores the key, so replace it:Then reconnect via
/mcp(a running session keeps the old environment until it does). -
Claude Desktop and other JSON-configured clients. Edit the
OPENPROJECT_API_KEYvalue in the client config and restart the client. -
.envfile. Edit the file and restart the server.
Recent OpenProject versions allow several API tokens in parallel, so you can rotate with zero downtime: create the new token, switch your clients over, then revoke the old one.
Configuration
Configuration is entirely environment-driven. The table below is the authoritative reference:
the server binds exactly these 26 names and no others. Bare, unprefixed names such as
READ_TIMEOUT or API_KEY are deliberately ignored (a stray variable in your shell cannot
change or break the server), as is any other unknown variable. A .env file in the server's
working directory is read with the same names; real environment variables take precedence.
From-source users can start from
.env.example.
Secrets (OPENPROJECT_API_KEY, OPENPROJECT_OAUTH_TOKEN, OPENPROJECT_MCP_AUTH_TOKENS) are
held in memory as Pydantic SecretStr values and are never written to logs; the
Authorization header is redacted in every log record.
Limiting what the model can do
Four settings shrink the tool surface at startup. The tool list is then fixed for the lifetime
of the process, with one exception: enable_tool_group can bring back a group hidden by the
core profile, for the calling client (see below for what that means per protocol version).
-
OPENPROJECT_MCP_READ_ONLY=1serves only the 40 read tools. -
OPENPROJECT_MCP_ADMIN_TOOLS=1reveals the three membership write tools (create_membership,update_membership,delete_membership); they are hidden by default. -
OPENPROJECT_MCP_DISABLEdrops whole groups to cut prompt cost, e.g.OPENPROJECT_MCP_DISABLE=meetings,news. The valid group tags are:work_packages,wp_collaboration,attachments,git_activity,projects,queries,notifications,time_entries,versions,people,metadata,meetings,wiki,documents,budgets,news,reporting— the same tags that head each section of the tool catalog below — plusmeetings_recurring, a sub-tag ofmeetingsthat drops only the six recurring-meeting tools (meetingsdrops them too). -
OPENPROJECT_MCP_PROFILEdefaults tocore(since 0.4.0), which hides the module-backed groups —meetings,news,documents,wiki,budgets,git_activityandreporting, plus the two reporting prompts — so a session starts with a smaller tool list. Set it tofullto list every group from the start. When the model needs one of them it callsenable_tool_group, which restores that group and tells the client to re-read its tool list (if yours never does, setfull). Who sees the restored group depends on the client's protocol version, and the result'sscopefield names it:session— clients on theinitializehandshake (MCP 2025-11-25 and earlier): that MCP session only. Over HTTP a session ends after 30 minutes idle.token— MCP 2026-07-28 clients over HTTP, which have no session: every connection presenting the same bearer token. Give each user their own token inOPENPROJECT_MCP_AUTH_TOKENSif they should not share a tool list. WithOPENPROJECT_MCP_INSECUREnothing identifies the client, so the call is refused; runfullthere (the server warns at startup).process— MCP 2026-07-28 clients over stdio: the whole server process, which serves one client anyway.
Enabled groups are forgotten after 24 hours idle.
enable_tool_groupnever liftsREAD_ONLY, the admin gate orOPENPROJECT_MCP_DISABLE; it lives in themetadatagroup, so disabling that group removes it.
Independent of all four, every destructive tool (the 13 permanent deletes) requires an
explicit confirm=true argument before it acts.
Transports
-
stdio (default) — what Claude Code, Claude Desktop and most local MCP clients use. Logs go to stderr; stdout carries only the protocol.
-
Streamable HTTP —
openproject-mcp-server --transport http. Binds127.0.0.1:8000by default; override with--host/--portorOPENPROJECT_MCP_HTTP_HOST/OPENPROJECT_MCP_HTTP_PORT. The HTTP transport refuses to start without authentication configured: setOPENPROJECT_MCP_AUTH_TOKENSto a comma-separated list of bearer tokens, or — for local development only — setOPENPROJECT_MCP_INSECURE=1.With tokens configured, every HTTP request to the MCP endpoint must carry an
Authorization: Bearer <token>header whose token matches one of the configured values (compared in constant time); requests with a missing, malformed or unknown token are rejected with a 401 and aWWW-Authenticateheader. Multiple tokens are supported — for example one per client, so each can be revoked independently. Tokens must be ASCII, and the endpoint applies no rate limiting, so use long random values — for examplepython -c "import secrets; print(secrets.token_urlsafe(32))".OPENPROJECT_MCP_INSECURE=1remains a development-only escape hatch that leaves the endpoint open without authentication.The server does not terminate TLS, so tokens would otherwise cross the network in plaintext: keep the default
127.0.0.1bind, and if you must expose the HTTP transport beyond localhost, put it behind a TLS-terminating reverse proxy (for example nginx or Caddy).One upstream identity. Bearer tokens decide who may reach the endpoint, not who they are in OpenProject: the server holds a single
OPENPROJECT_API_KEY(or OAuth token), and every HTTP client acts as that OpenProject user and shares its metadata cache. Deploy it for clients you would trust with that account, and issue a dedicated, least-privileged OpenProject user for it.File tools touch the server's disk.
upload_attachment,create_work_package (attachment_paths)anddownload_attachmentread and write paths on the machine running the server. Over HTTP they are off until you confine them:upload_attachmentandattachment_pathsneedOPENPROJECT_MCP_UPLOAD_ROOT,download_attachmentneedsOPENPROJECT_MCP_DOWNLOAD_ROOT. Until then the tool is hidden (andattachment_pathsis refused), and the server names the missing variable in a startup warning.
Tools
91 tools: 42 read, 46 write and 3 admin-gated writes. The admin tools stay hidden unless
OPENPROJECT_MCP_ADMIN_TOOLS=1; the 13 destructive tools additionally require confirm=true
on every call. Each section heading names the group tag accepted by
OPENPROJECT_MCP_DISABLE.
Work packages (work_packages)
Batch workflow: call bulk_update_work_packages(updates=[{"id": 4821, "changes": {"target_versions": [3, 4]}}]) to preview. Review the returned changes,
then repeat with dry_run=false and each item's returned lock_version included
in updates. Any preflight error prevents the whole batch from writing. A later
conflict can produce partial success; inspect every item and never replay successful
updates. unknown means the write may have committed before the response was lost.
Comments, relations, watchers, reminders (wp_collaboration)
Attachments and file links (attachments)
Git and pull requests (git_activity)
Projects (projects)
Saved queries (queries)
Notifications (notifications)
Time tracking (time_entries)
Versions and sprints (versions)
People and memberships (people)
The three membership write tools require OPENPROJECT_MCP_ADMIN_TOOLS=1 (and an OpenProject
account with the Manage members permission).
Instance metadata and schemas (metadata)
Meetings (meetings)
The six recurring-meeting tools also carry the meetings_recurring tag, so
OPENPROJECT_MCP_DISABLE=meetings_recurring drops just them (they need OpenProject 17.4+).
Wiki (wiki)
Documents (documents)
Budgets (budgets)
News (news)
Reporting (reporting)
Prompts and resources
Report data uses closed_updated for currently closed work updated in the requested
window. This replaces the former closed field in v0.3.0. It does not establish when
work was completed; sprint health remains unassessed without supporting data.
Four prompt templates render live OpenProject data into ready-to-use briefings:
- weekly_report — a weekly status report for one project: currently closed and updated / in progress / planned, hours and impediments.
- daily_standup — today's standup for one project: yesterday's movement, what is due today, and what is blocked.
- triage_inbox — groups your unread notifications by reason and suggests actions.
- groom_backlog — sweeps a project's open backlog for unassigned, stale and unestimated work.
Three resource templates expose OpenProject objects at stable URIs:
openproject://work_package/{id}— one work package as JSON.openproject://project/{identifier}— one project as JSON (identifier slug or numeric id).openproject://attachment/{id}— the attachment's bytes with the detected MIME type, up toOPENPROJECT_MCP_MAX_INLINE_MB.
Clients that support argument completion get suggestions while typing: project
identifiers for the project argument of weekly_report, daily_standup and
groom_backlog and for the project resource, and the available locales for
weekly_report.
Supported OpenProject versions
The server targets OpenProject 14 LTS through 17.x. Instead of assuming one API dialect, it probes the instance lazily on first need and caches the result for an hour. The version-dependent surfaces:
- Target versions: work-package details expose
target_versionson every supported instance. Create/update accept a list of version ids ([]clears); the schema selectstargetVersionson 17.8+ or a single legacyversion. The oldversionargument remains a single-value alias; do not pass both. On reads it is null for multiple assignments. - Internal (private) comments need OpenProject >= 16. Older servers silently ignore the internal flag, so below 16 the server refuses with a clear error rather than posting a comment publicly that you asked to keep internal.
- Emoji reactions (
toggle_comment_reaction) need OpenProject >= 16; detected from the version, tolerant of a 404 at call time. - Project favorites (
set_project_favorite) need OpenProject >= 17; same tolerance. - Time-entry filters: the work-package filter is probed (
entityId, falling back to the pre-15.xworkPackagespelling). - Permission contexts (
list_permissions): the context prefix is probed (p{id}, falling back to thew{id}spelling introduced in 17.2). - Meetings time filter: OpenProject 17.6 changed the wire dialect;
list_meetingsdiscovers which spelling the instance accepts and caches it. - Story points need the Backlogs module and a type Backlogs treats as a story. 17.x
refuses
story_pointsotherwise; 14.x accepts the write and silently drops the value, so the result carries a note saying it was not saved (bulk previews warn before writing).
Features that depend on optional instance modules (meetings, news, documents, budgets, wiki, backlogs, GitHub/GitLab integration, external storages) degrade honestly when the module is absent: list tools return an empty page with an in-band note naming the missing module, and detail tools return a structured error explaining both possible readings of the 404.
Security
- The API key and OAuth token are held as
SecretStrand never logged;Authorizationand cookie headers are redacted from every log record. Request/response bodies are only logged at DEBUG level withOPENPROJECT_MCP_LOG_BODIES=1, for development. - The
Authorizationheader is stripped whenever a redirect leaves the OpenProject origin — attachment downloads redirect to presigned object-storage URLs, and the credential must not travel there. - TLS is always verified. Private CAs are supported via
OPENPROJECT_MCP_CA_BUNDLE; an insecure-TLS switch deliberately does not exist. - Attachment downloads respect OpenProject's virus scanner: quarantined files are never
fetched and produce a structured
attachment_quarantinederror. Downloads are capped byOPENPROJECT_MCP_MAX_DOWNLOAD_MB, stored under sanitized file names (directory separators and traversal sequences are neutralized), and reported with a SHA-256 of the bytes. - Destructive tools require
confirm=trueand are annotated so clients can ask the user first. - The HTTP transport refuses to start without
OPENPROJECT_MCP_AUTH_TOKENSconfigured and verifies theAuthorization: Bearerheader on every request — missing or invalid tokens are rejected with a 401, and token comparison is constant-time. The server does not terminate TLS: keep the default127.0.0.1bind, and put a TLS-terminating reverse proxy in front if the port must be reachable from anywhere else (see Transports). All HTTP clients share the server's one OpenProject identity; confine the file tools withOPENPROJECT_MCP_UPLOAD_ROOT/OPENPROJECT_MCP_DOWNLOAD_ROOT. - Downloads are created exclusively (never overwriting an existing file, even under concurrent downloads of the same name), and a failed or cancelled transfer removes only the file it created.
Troubleshooting
When reporting an issue, please include your OpenProject version, the output of
openproject-mcp-server --version, and the output of openproject-mcp-server --check.
Development
The default suite stays offline. Opt-in compatibility checks run against fresh official OpenProject 14.6, 15.5, 16.6 and 17.8 containers in the Compatibility workflow (including both single- and multiple-version modes on 17.8). To run one locally with Docker running:
The harness seeds a private project, temporary users, custom fields and versions; it tests
through MCP, then removes the container and its volumes. Existing instances and credentials
are not used. Direct pytest runs skip these tests unless --live-openproject is supplied
with a disposable fixture file. The
full technical specification lives in
SPEC.md.
Releasing is documented in CONTRIBUTING.md.
License and trademark
MIT — see LICENSE.
This is a community project. It is not affiliated with, endorsed by, or supported by OpenProject GmbH. "OpenProject" is a trademark of OpenProject GmbH and is used here only to indicate interoperability.
来源:README.md,提交 7733e01
工具
0版本历史
6- v0.5.0最新Oct 29, 2026
- v0.4.0Oct 20, 2026
- v0.3.4Oct 20, 2026
- v0.3.3Oct 2, 2026
- v0.3.1Sep 23, 2026
- v0.3.0Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分