mcpField
O
OpenProject

OpenProject

本地服务
github.com生产力61 周前更新

关于 OpenProject

OpenProject MCP Server 将 OpenProject API v3 接入 MCP,面向使用 Community 版实例的团队。它提供涵盖项目管理多类数据的结构化工具,并支持只读和权限控制。

主要功能

  1. 01覆盖工作包、项目、工时等 API
  2. 02工具返回带类型的结构化数据
  3. 03提供报告与工作流提示词
  4. 04支持只读、管理员及分组开关
  5. 05适配 OpenProject 14 至 17.x

适用场景

  1. 01查询并更新工作包及评论
  2. 02管理项目成员、会议和文档
  3. 03查看工时、预算与报告数据

MCP 相关

作为 MCP 服务,向 MCP 客户端开放 91 个 OpenProject API v3 工具、4 个报告/工作流提示词和 3 个资源模板。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"kar-thik-openproject": {
"command": "uvx",
"args": [
"openproject-mcp-server"
],
"env": {
"OPENPROJECT_URL": "<OPENPROJECT_URL>",
"OPENPROJECT_API_KEY": "<OPENPROJECT_API_KEY>",
"OPENPROJECT_OAUTH_TOKEN": "<OPENPROJECT_OAUTH_TOKEN>",
"OPENPROJECT_MCP_READ_ONLY": "<OPENPROJECT_MCP_READ_ONLY>",
"OPENPROJECT_MCP_ADMIN_TOOLS": "<OPENPROJECT_MCP_ADMIN_TOOLS>",
"OPENPROJECT_MCP_DISABLE": "<OPENPROJECT_MCP_DISABLE>",
"OPENPROJECT_MCP_PROFILE": "<OPENPROJECT_MCP_PROFILE>"
}
}
}
}
启动命令uvx openproject-mcp-server
需要配置的环境变量
OPENPROJECT_URLOpenProject instance root URL, e.g. https://openproject.example.com
OPENPROJECT_API_KEY密钥API key from My account -> Access tokens in OpenProject
OPENPROJECT_OAUTH_TOKEN密钥OAuth bearer token used instead of the API key (OAuth deployments)
OPENPROJECT_MCP_READ_ONLYSet to 1 to serve read tools only
OPENPROJECT_MCP_ADMIN_TOOLSSet to 1 to enable the membership-write tools (hidden by default)
OPENPROJECT_MCP_DISABLEComma-separated tool groups to drop, e.g. meetings,budgets
OPENPROJECT_MCP_PROFILEcore (default) or full: core hides the module-backed tool groups at startup

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiopenproject-mcp-server0.4.0

工具

88

收录的工具列表 · 更新于 1 周前

参数类型必填说明
modeenum否“quick”(默认)会匹配主题、ID、项目名称以及类型/状态名称——这与 OpenProject 页眉搜索的行为相同,也是“查找名为 X 的工单”的正确选择。“fulltext”还会匹配描述文本、评论和可搜索的自定义字段;用于查找“提到 Y 的工单”。quick | fulltext
pageinteger否从 1 开始的页码。
querystring是要查找的自由文本。在“quick”模式下,单独的数字也会匹配工作包 ID,因此“1234”会找到 #1234。
page_sizeinteger否每页结果数(最多 100 条)。
project_idany否将搜索范围限制为一个项目:数字 ID 或项目标识符(OpenProject URL 中的 slug)。两者均可通过 list_projects 获取。省略时会搜索用户可见的所有项目。
status_scopeenum否要搜索的状态。默认值为“all”,因为搜索通常是为了查找已关闭的项目;传入“open”可隐藏已完成的工作。始终会发送显式状态筛选器,因此服务器隐式的仅限开放状态的默认值不会生效。open | closed | all

详细介绍

OpenProject MCP 服务

PyPI CI openproject-mcp MCP server

一个用于 OpenProject API v3 的 MCP(Model Context Protocol)服务。它为 Claude 和任何其他 MCP 客户端提供 91 个工具,涵盖工作包、评论和关系、附件、Git/PR 活动、项目、已保存的查询、通知、时间跟踪、版本、人员和成员身份、会议、新闻、文档、预算和报告;此外还提供 4 个报告/工作流提示词和 3 个资源模板。基于 FastMCP 3.x 和 httpx(HTTP/2)构建。

此项目面向 OpenProject Community 版。OpenProject 的 Enterprise 版现已内置 MCP 集成;此服务为可自托管的 Community 实例提供相同的功能。它也能在任何版本上正常运行,只需使用公开的 API v3。

设计原则均已通过代码落实:

  • 一切皆结构化。 每个工具都会返回类型化模型,因此客户端会获得 outputSchema 和机器可读的 structuredContent,而不是散文。错误会以 JSON 信封形式返回,其中包含稳定的 type、上游的 http_status、message,以及说明如何修正调用的 hint。
  • 诚实地处理降级。 OpenProject 实例因版本、已安装的模块和权限而异。工具会以带内注释的形式报告无法读取的内容——模块缺失时会返回附有说明的空页面,而不会伪装成功或只返回原始回溯信息。
  • 默认安全。 提供只读模式、仅限管理员的成员身份写入操作、按组禁用工具、所有破坏性工具均带有 confirm=true 防护、始终验证 TLS,且凭据绝不会出现在日志中。
  • 适配不同版本。 支持 OpenProject 14 LTS 至 17.x;通过延迟执行并缓存的功能探测来检测 API 差异,而非依赖假设(参见支持的 OpenProject 版本)。

效果示例

以下是针对虚构的“网站重新上线”项目进行的两轮交互——下文中的每个 ID、名称和日期都是虚构的。你描述期望结果;模型会选择工具,而返回给模型的是类型化对象,而非需要重新解析的散文。

You         What is still open in Website Relaunch and due by Friday? The checkout
            bug is urgent — raise it and leave a note for whoever owns it.

  →  list_work_packages(project="website-relaunch", status_scope="open",
                        due_before="2026-03-13", sort_by=[["due_date", "asc"]])

     { "items": [
         { "id": 4821, "subject": "Checkout fails on expired coupon codes",
           "type": {"id": 7, "name": "Bug"}, "status": {"id": 7, "name": "In progress"},
           "assignee": {"id": 118, "name": "Dana Okafor"}, "due_date": "2026-03-11" },
         { "id": 4830, "subject": "Move press-kit assets to the new CDN",
           "type": {"id": 1, "name": "Task"}, "status": {"id": 1, "name": "New"},
           "assignee": null, "due_date": "2026-03-13" }],
       "pagination": {"total": 2, "page": 1, "page_size": 20, "has_more": false} }

  →  update_work_package(id=4821, priority="High")
  →  add_work_package_comment(id=4821, comment="Raised to High — it blocks the
                              launch checklist. Dana, can you take a look today?")

Assistant   Two open items are due by Friday. #4821 is High now and the note is on
            its thread; #4830 is due Friday and still has nobody on it.

上面的行经过了简化:每行还包含 priority、project、start_date、percentage_done 和 updated_at;对于会填充这些内容的调用,信封还保留了 groups、sums 和 notes 字段。

提示词模板省去了工具的往返调用:服务会自行读取 OpenProject,并直接返回完整文档,而不是提供指示让你去获取文档。文档开头会附上一条说明,指出其中的数字已计算完成,不应重新计算或润色。

You         /weekly_report project=website-relaunch

            # WEEKLY REPORT - AGILE SCRUM

            _Generated from live OpenProject data_
            ...
            ## B. EXECUTIVE SUMMARY

            **Progress against the sprint goal:** Not assessed — sprint goal and completion dates are not available

            **Currently closed work updated in the window:**
            1. #4802 - Ship the new pricing page
            2. #4795 - Halve the hero image payload
            ...
            ### Data notes

            - open/closed bucketing uses each status's isClosed flag from
              GET /statuses, not status names; a status this instance renamed
              or translated is still bucketed correctly

最后这部分体现了我们的惯例:报告会说明哪些数字是部分数据;工具无法读取某项内容时,会通过注释说明数据缺口,而不是猜测。完整功能请参阅工具和提示词与资源。

要求

  • Python >= 3.12
  • OpenProject 实例,版本为 14 LTS 至 17.x(任何版本均可;面向 Community 版,Enterprise 版自带 MCP 集成)
  • OpenProject API 密钥:在 OpenProject 中前往我的账户 → 访问令牌并生成 API 令牌

安装

分发包名称为 openproject-mcp-server。它会安装两个完全相同的控制台脚本:openproject-mcp-server 和 openproject-mcp;长名称是规范名称(另一个无关的 PyPI 包也会安装一个名为 openproject-mcp 的可执行文件)。

使用 uv 运行一次,无需安装:

uvx openproject-mcp-server

或者进行持久安装:

uv tool install openproject-mcp-server
# or
pip install openproject-mcp-server

最简配置需要两个环境变量:

export OPENPROJECT_URL=https://openproject.example.com
export OPENPROJECT_API_KEY=your-api-key

无需启动服务即可验证配置:

openproject-mcp-server --check

--check 会验证配置并退出;它不会连接到你的实例。通过客户端连接后,调用 get_instance_info 工具进行实时端到端检查。如果配置缺失或无效,服务会将具体问题输出到 stderr,并以代码 2 退出——绝不会输出回溯信息。

Claude Code
claude mcp add openproject \
  --env OPENPROJECT_URL=https://openproject.example.com \
  --env OPENPROJECT_API_KEY=your-api-key \
  -- uvx openproject-mcp-server
Claude Desktop 和其他 MCP 客户端

添加到 claude_desktop_config.json(或客户端对应的 mcpServers 配置):

{
  "mcpServers": {
    "openproject": {
      "command": "uvx",
      "args": ["openproject-mcp-server"],
      "env": {
        "OPENPROJECT_URL": "https://openproject.example.com",
        "OPENPROJECT_API_KEY": "your-api-key"
      }
    }
  }
}
从源码运行
git clone https://github.com/kar-thik/openproject-mcp
cd openproject-mcp
uv sync
uv run openproject-mcp-server

更新或轮换 API 令牌

令牌重新生成、撤销或失效时(OpenProject 重大版本升级可能导致这种情况——其表现为所有工具突然因 authentication_failed / HTTP 401 而失效),请在 OpenProject 的 我的账户 → 访问令牌 下生成新令牌,并在密钥所在的位置更新它:

  • Shell 环境(最便于轮换)。 服务会直接从操作系统环境读取 OPENPROJECT_API_KEY,因此你可以全局导出该变量——例如,在 ~/.zshenv 中——并注册服务,无需任何 --env 标志:

    claude mcp add openproject -- uvx openproject-mcp-server
    

    轮换时只需编辑导出语句、打开一个新终端并重新连接。客户端配置中不会包含密钥。(这不适用于 Claude Desktop 等 GUI 应用,因为它们不会读取你的 shell 配置文件。)

  • 使用 --env 的 Claude Code。 注册信息中会保存密钥,因此需要替换它:

    claude mcp remove openproject
    claude mcp add openproject \
      --env OPENPROJECT_URL=https://openproject.example.com \
      --env OPENPROJECT_API_KEY=new-key \
      -- uvx openproject-mcp-server
    

    然后通过 /mcp 重新连接(正在运行的会话会继续使用旧环境,直到重新连接)。

  • Claude Desktop 和其他使用 JSON 配置的客户端。 编辑客户端配置中的 OPENPROJECT_API_KEY 值,然后重启客户端。

  • .env 文件。 编辑该文件并重启服务。

近期版本的 OpenProject 允许同时使用多个 API 令牌,因此可以实现零停机轮换:创建新令牌,将客户端切换到新令牌,然后撤销旧令牌。

配置

配置完全由环境变量控制。下表是权威参考:服务仅绑定这 26 个名称,不绑定其他名称。未加前缀的名称(如 READ_TIMEOUT 或 API_KEY)会被有意忽略(shell 中意外存在的变量不会更改或破坏服务),其他任何未知变量也会被忽略。服务工作目录中的 .env 文件会使用相同的名称读取;实际环境变量优先级更高。从源码运行的用户可以从 .env.example 开始配置。

变量默认值用途
OPENPROJECT_URL—(必填)实例根 URL,例如 https://openproject.example.com。允许末尾带有 /api/v3,该部分会被移除。
OPENPROJECT_API_KEY—(必填*)从 我的账户 → 访问令牌 获取的 API 密钥。以 HTTP Basic apikey:<token> 形式发送。
OPENPROJECT_OAUTH_TOKEN未设置OAuth bearer token,可替代 API 密钥。*两种凭据必须提供其一。
OPENPROJECT_MCP_ACCEPT_LANGUAGE未设置作为 Accept-Language 标头发送;OpenProject 会据此对验证消息进行本地化。
OPENPROJECT_MCP_CA_BUNDLE系统信任存储为使用私有 CA 的实例指定 CA bundle(PEM)路径。始终验证 TLS;不会提供关闭验证的选项。
OPENPROJECT_MCP_READ_ONLYfalse仅提供读取工具:启动时会移除所有写入、破坏性和管理工具。
OPENPROJECT_MCP_ADMIN_TOOLSfalse提供三个受管理员权限控制的成员资格写入工具(默认隐藏)。
OPENPROJECT_MCP_DISABLE空以逗号分隔的分组标签,用于在启动时移除整个工具组(见下文)。
OPENPROJECT_MCP_PROFILEcorecore 会在启动时隐藏由模块提供的分组;会话可通过 enable_tool_group 重新启用其中某个分组(见下文)。full 会列出所有分组。
OPENPROJECT_MCP_INSECUREfalse允许 --transport http 在没有身份验证令牌的情况下启动。仅用于本地开发。
OPENPROJECT_MCP_DOWNLOAD_DIR./openproject-downloadsdownload_attachment 写入文件的目录(若目录不存在则会创建;默认路径相对于服务的工作目录)。
OPENPROJECT_MCP_UPLOAD_ROOT未设置设置后,upload_attachment 和 create_work_package(attachment_paths) 只会读取此现有目录下的文件;解析到目录外的路径和符号链接会被拒绝。建议与 --transport http 搭配使用。
OPENPROJECT_MCP_DOWNLOAD_ROOT未设置设置后,download_attachment 只会写入此现有目录下,并默认保存到此目录;目录外的 save_dir 会被拒绝。建议与 --transport http 搭配使用。
OPENPROJECT_MCP_MAX_DOWNLOAD_MB100附件下载的大小上限,单位为 MiB。
OPENPROJECT_MCP_MAX_INLINE_MB10openproject://attachment 资源内联返回附件字节内容的大小上限,单位为 MiB(不会超过下载上限)。
OPENPROJECT_MCP_CACHE_TTL300元数据缓存(状态、类型、优先级、架构)的生存时间,单位为秒。
OPENPROJECT_MCP_LOG_LEVELINFODEBUG、INFO、WARNING、ERROR 或 CRITICAL(不区分大小写)。
OPENPROJECT_MCP_LOG_FORMATtexttext 或 json。日志始终写入 stderr(stdout 留给 stdio 传输)。
OPENPROJECT_MCP_LOG_BODIESfalse记录请求/响应正文——仅在 DEBUG 级别下生效,并会隐藏凭据。仅用于开发。
OPENPROJECT_MCP_OTELfalse为 OpenTelemetry 跟踪预留。当前版本会接受此设置,但尚未将其接入任何功能;设置后不会生成跟踪数据。
OPENPROJECT_MCP_HTTP_HOST127.0.0.1--transport http 的绑定地址。
OPENPROJECT_MCP_HTTP_PORT8000--transport http 的端口。
OPENPROJECT_MCP_AUTH_TOKENS未设置--transport http 接受的 bearer token,以逗号分隔(例如,每个客户端一个)。每个请求都必须携带其中一个令牌,即 Authorization: Bearer <token>;其他情况均会返回 401。若未设置此项(且未设置 OPENPROJECT_MCP_INSECURE=1),HTTP 传输将拒绝启动。请参阅传输方式。
OPENPROJECT_MCP_CONNECT_TIMEOUT10等待与 OpenProject 建立 TCP/TLS 连接的秒数。
OPENPROJECT_MCP_READ_TIMEOUT30等待响应数据的秒数。
OPENPROJECT_MCP_WRITE_TIMEOUT60发送请求数据(上传)时的等待秒数。
OPENPROJECT_MCP_POOL_TIMEOUT5等待从连接池中获取空闲连接的秒数。
OPENPROJECT_MCP_MAX_CONNECTIONS10连接到 OpenProject 的连接池大小。
OPENPROJECT_MCP_MAX_RETRIES3幂等请求的重试次数上限。
机密信息(OPENPROJECT_API_KEY、OPENPROJECT_OAUTH_TOKEN、OPENPROJECT_MCP_AUTH_TOKENS)以 Pydantic SecretStr 值的形式保存在内存中,绝不会写入日志;每条日志记录中的 Authorization 标头都会被隐藏。
限制模型的操作

启动时,四项设置会缩减工具范围。此后,工具列表在进程的整个生命周期内保持固定,但有一个例外:enable_tool_group 可以恢复被 core 配置隐藏的工具组,且仅对调用它的会话生效。

  • OPENPROJECT_MCP_READ_ONLY=1 仅提供 40 个读取工具。
  • OPENPROJECT_MCP_ADMIN_TOOLS=1 显示三个成员关系写入工具(create_membership、update_membership、delete_membership);这些工具默认隐藏。
  • OPENPROJECT_MCP_DISABLE 会移除整个工具组,以降低提示词开销,例如 OPENPROJECT_MCP_DISABLE=meetings,news。有效的工具组标签包括:work_packages、wp_collaboration、attachments、git_activity、projects、queries、notifications、time_entries、versions、people、metadata、meetings、wiki、documents、budgets、news、reporting——与下方工具目录各节开头使用的标签相同——以及 meetings 的子标签 meetings_recurring,它只会移除六个定期会议工具(meetings 也会移除这些工具)。
  • OPENPROJECT_MCP_PROFILE 默认为 core(自 0.4.0 起);它会隐藏由模块提供的工具组——meetings、news、documents、wiki、budgets、git_activity 和 reporting,以及两个报告提示词——让会话以较短的工具列表启动。设置为 full 可从一开始就列出所有工具组。模型需要其中某个工具组时,可调用 enable_tool_group;该工具组只会为调用它的会话恢复。随后,服务会向该会话发送 tools/list_changed,因此客户端必须遵循此通知并重新读取工具列表(如果客户端不支持,请设置为 full)。会话规则在空闲 24 小时后过期。enable_tool_group 不会解除 READ_ONLY、管理员限制或 OPENPROJECT_MCP_DISABLE 的限制;它属于 metadata 工具组,因此禁用该组也会将其移除。

无论上述四项设置如何,所有破坏性工具(13 个永久删除工具)在执行操作前都必须显式传入 confirm=true 参数。

传输方式

  • stdio(默认)——Claude Code、Claude Desktop 和大多数本地 MCP 客户端使用此方式。 日志写入 stderr;stdout 仅承载协议内容。

  • Streamable HTTP——openproject-mcp-server --transport http。默认绑定到 127.0.0.1:8000;可通过 --host/--port 或 OPENPROJECT_MCP_HTTP_HOST/ OPENPROJECT_MCP_HTTP_PORT 覆盖。未配置身份验证时,HTTP 传输拒绝启动:将 OPENPROJECT_MCP_AUTH_TOKENS 设置为以逗号分隔的 bearer token 列表,或者——仅限本地开发——设置 OPENPROJECT_MCP_INSECURE=1。

    配置 token 后,发送到 MCP 端点的每个 HTTP 请求都必须携带 Authorization: Bearer <token> 标头,且其中的 token 必须与某个已配置的值匹配(比较采用恒定时间);缺少 token、格式错误或 token 未知的请求都会被拒绝,并返回 401 和 WWW-Authenticate 标头。支持多个 token——例如为每个客户端配置一个,这样便可单独撤销。Token 必须为 ASCII 字符;端点不进行速率限制,因此请使用较长的随机值——例如 python -c "import secrets; print(secrets.token_urlsafe(32))"。 OPENPROJECT_MCP_INSECURE=1 仍是仅供开发使用的应急选项,可让端点在不进行身份验证的情况下开放。

    服务不会终止 TLS,因此 token 否则会以明文形式通过网络传输:请保留默认的 127.0.0.1 绑定;如果必须将 HTTP 传输暴露到 localhost 之外,请将其置于负责终止 TLS 的反向代理之后(例如 nginx 或 Caddy)。

    单一上游身份。 Bearer token 决定谁可以访问端点,而非他们在 OpenProject 中的身份:服务持有单个 OPENPROJECT_API_KEY(或 OAuth token),所有 HTTP 客户端都以该 OpenProject 用户的身份操作,并共用其元数据缓存。仅为你愿意让其使用该账户的客户端部署此服务,并为其创建专用且权限最小化的 OpenProject 用户。

    文件工具会操作服务所在机器的磁盘。 upload_attachment、create_work_package (attachment_paths) 和 download_attachment 会读取和写入运行服务的机器上的路径。通过 HTTP 使用时,这些工具默认关闭,除非你限制其访问范围:upload_attachment 和 attachment_paths 需要 OPENPROJECT_MCP_UPLOAD_ROOT,download_attachment 需要 OPENPROJECT_MCP_DOWNLOAD_ROOT。在此之前,工具会被隐藏(并且 attachment_paths 会被拒绝),服务会在启动警告中指出缺少的变量。

工具

共 91 个工具:42 个读取工具、46 个写入工具和 3 个需管理员权限的写入工具。除非设置 OPENPROJECT_MCP_ADMIN_TOOLS=1,否则管理员工具会保持隐藏;此外,13 个破坏性工具每次调用还都需要 confirm=true。每个小节标题都会标明 OPENPROJECT_MCP_DISABLE 接受的组标签。

工作包(work_packages)
工具类型功能
search_work_packages读取当你不知道工作包 ID 时,通过文本查找工作包。
list_work_packages读取使用结构化筛选条件列出工作包——最常用的读取工具。
get_work_package读取完整读取一个工作包:描述、日期、自定义字段、父级和进度。
create_work_package写入创建工作包,首先通过 OpenProject 自身的表单端点进行验证。
update_work_package写入更改工作包的任何可写字段,并使用乐观锁定。
bulk_update_work_packages写入预览或应用最多 50 项更新,并提供每项的差异、验证和冲突结果。
delete_work_package写入(破坏性)永久删除工作包及其所有关联内容。

批量工作流:调用 bulk_update_work_packages(updates=[{"id": 4821, "changes": {"target_versions": [3, 4]}}]) 进行预览。检查返回的更改, 然后使用 dry_run=false 重复调用,并在 updates 中包含每项返回的 lock_version。任何预检错误都会阻止整个批次写入。之后发生的 冲突可能导致部分成功;请检查每项,且不要重放已成功的更新。unknown 表示响应丢失前写入可能已经提交。

评论、关联、关注者、提醒(wp_collaboration)
工具类型功能
list_work_package_comments读取读取工作包的评论串和更改历史。
add_work_package_comment写入在工作包上发表评论。
edit_work_package_comment写入改写现有工作包评论的文本。
add_work_package_watcher写入订阅用户接收工作包通知。
remove_work_package_watcher写入取消订阅用户接收工作包通知。
create_work_package_relation写入关联两个工作包(阻塞、后续、重复、相关等)。
update_work_package_relation写入更改现有关联的类型、滞后时间或描述。
delete_work_package_relation写入(破坏性)移除两个工作包之间的关联。
toggle_comment_reaction写入使用表情符号回应工作包评论,或撤回应。
set_work_package_reminder写入设置、更改或清除你在工作包上的个人提醒。
list_reminders读取列出你自己的近期工作包提醒。
execute_custom_action写入对工作包运行实例定义的一键操作。
附件和文件链接(attachments)
工具类型功能
list_attachments读取列出一个容器中附加的文件。
download_attachment读取将附件字节下载到运行此服务的机器上的文件中。
upload_attachment写入将本地文件附加到工作包、Wiki 页面、会议、文档、预算或评论。
delete_attachment写入(破坏性)从 OpenProject 永久删除一个附加文件。
list_file_links读取列出链接到工作包的外部存储文件(Nextcloud、OneDrive/SharePoint)。
Git 和拉取请求(git_activity)
工具类型功能
get_work_package_git_activity读取显示工作包背后的代码:提交、拉取/合并请求和 CI 状态。
get_github_pull_request读取完整读取一个已关联的 GitHub 拉取请求,包括其 CI 检查运行。
项目(projects)
工具类型功能说明
list_projects读取列出项目,服务器端筛选,一次返回一页。
get_project读取完整读取一个项目。
create_project写入创建项目,并先通过 OpenProject 自身的表单端点进行验证。
update_project写入更改项目的名称、描述、可见性、父级、状态或归档状态。
delete_project写入(破坏性操作)安排永久删除项目及其所有内容。
copy_project写入将项目复制到新项目中,包括其设置,并可选择是否复制工作包。
get_job_status读取检查后台作业(项目复制或计划删除)是否已完成。
set_project_favorite写入将项目添加到或移出已认证用户的收藏夹(OpenProject 17+)。
list_project_phase_definitions读取列出实例级阶段目录(启动、规划等)及其开始/完成关卡(OpenProject 16.1+)。
get_project_phase读取读取一个项目的阶段记录;其 ID 来自工作包的 project_phase 引用。
已保存的查询(queries)
工具类型功能说明
list_queries读取列出该用户可以打开的已保存工作包视图(查询)。
run_query读取运行已保存的视图,并获取其中当前的工作包。
save_query写入将一组筛选条件保存为可供整个团队打开的 OpenProject 可复用视图。
通知(notifications)
工具类型功能说明
list_notifications读取读取已认证用户的 OpenProject 收件箱。
mark_notifications写入在一次批量请求中将指定通知标记为已读(或未读)。
mark_all_notifications_read写入将符合筛选条件的所有通知标记为已读;默认标记整个收件箱。
时间跟踪(time_entries)
工具类型功能说明
list_time_entries读取列出已记录的时间,在服务器端筛选,并可选择获取准确总计。
log_time写入将时间记录到工作包或项目。
update_time_entry写入更正现有时间记录。
delete_time_entry写入(破坏性操作)永久删除已记录的时间条目。
版本和冲刺(versions)
工具类型功能说明
list_versions读取列出可分配工作包的版本(发布、里程碑、冲刺)。
list_sprints读取列出可用于规划工作包的冲刺(Scrum 时间盒)。
get_sprint读取完整读取一个冲刺:日期、工作区和生命周期状态。
create_version写入在项目中创建版本(发布、里程碑或冲刺)。
update_version写入更改版本的名称、日期、描述、状态或共享设置。
delete_version写入(破坏性操作)永久删除一个版本。
人员和成员资格(people)
工具类型功能说明
search_principals读取查找用户、群组和占位用户,并获取其 ID。
get_user读取读取一个用户的个人资料:姓名、登录名、电子邮件、管理员标记和状态。
list_memberships读取列出谁可以访问哪些项目,以及拥有何种角色。
create_membership管理员写入为主体授予项目中的一个或多个角色。
update_membership管理员写入替换现有成员资格的角色。
delete_membership管理员写入(破坏性操作)撤销主体对项目的访问权限。
list_roles读取列出此实例定义的角色及其 ID。

这三个成员资格写入工具要求设置 OPENPROJECT_MCP_ADMIN_TOOLS=1(并使用拥有 Manage members 权限的 OpenProject 账户)。

实例元数据和架构(metadata)
工具类型功能
get_instance_info读取检查 OpenProject 连接,并报告此实例支持的功能。
get_project_metadata读取列出此实例上实际有效的 ID 和名称(类型、状态、优先级等)。
get_work_package_schema读取显示此项目中此类型的工作包接受哪些字段。
list_permissions读取列出已认证用户获准执行的操作,可查看全局权限或某个项目的权限。
enable_tool_group读取在当前会话中重新启用被 OPENPROJECT_MCP_PROFILE=core 隐藏的工具组;不会调用 OpenProject。
会议(meetings)

这 6 个定期会议工具也带有 meetings_recurring 标签,因此设置 OPENPROJECT_MCP_DISABLE=meetings_recurring 只会停用这些工具(它们需要 OpenProject 17.4+)。

工具类型功能
list_meetings读取列出会议:即将召开的会议和已结束的会议。
get_meeting读取完整读取一场会议:参与者、议程和已记录的结果。
create_meeting写入在项目中安排会议,并可选择邀请参与者。
update_meeting写入更改会议的标题、时间、地点或邀请名单,也可以更改会议的生命周期状态。
delete_meeting写入(破坏性)永久删除一场会议及其议程和已记录的结果。
add_meeting_agenda_item写入向会议议程添加一个条目,也可选择将其关联到工作包。
update_meeting_agenda_item写入编辑议程条目:修改标题、重写备注、调整时间、重新排序或更改关联项。
delete_meeting_agenda_item写入(破坏性)永久删除一个议程条目及其对应的任何已记录结果。
add_meeting_outcome写入在某个议程条目下记录结果,例如决定、备注或后续工单。
update_meeting_outcome写入更正已记录结果的类型、文本或关联的工作包。
delete_meeting_outcome写入(破坏性)从正在进行的会议纪要中永久删除一项已记录结果。
list_recurring_meetings读取列出定期会议系列,即重复规则,而非单场会议。
get_recurring_meeting读取完整读取一个定期会议系列:日程安排及其后续场次。
create_recurring_meeting写入创建定期会议系列:包含日程安排和供后续场次复制的模板。
delete_recurring_meeting写入(破坏性)永久删除一个定期会议系列,包括模板、日程安排和所有场次。
init_recurring_meeting_occurrence写入将系列中的一个场次实例化为真实会议,并从模板复制内容。
cancel_recurring_meeting_occurrence写入(破坏性)取消系列中的一个场次,跳过该时段而不更改日程安排。
Wiki(wiki)
工具类型功能
get_wiki_page读取读取 Wiki 页面的标识信息和所属项目,不读取页面内容(API v3 不提供页面正文)。
文档(documents)
工具类型功能
list_documents读取列出你在所有项目中可见的文档。
get_document读取读取一份文档及其完整描述文本。
预算(budgets)
工具类型功能
list_budgets读取列出项目预算及其 ID 和名称;这是 API v3 提供的全部信息。
新闻(news)
工具类型功能说明
list_news读取列出项目新闻——团队在项目概览中发布的公告。
get_news读取完整读取一条新闻,包括 Markdown 正文。
create_news写入在项目中发布新闻公告。
update_news写入更正或改写已发布的新闻。
delete_news写入(破坏性操作)永久删除一条新闻。
报告(reporting)
工具类型功能说明
get_project_report_data读取汇总单个项目在指定日期范围内的状态报告:精确计数、可通过后续调用深入查看的抽样行,以及每个部分的状态。

提示词和资源

报告数据使用 closed_updated 表示在指定时间范围内更新的当前已关闭工作项。这取代了 v0.3.0 中原有的 closed 字段。它不能确定工作项何时完成;没有相应数据时,仍无法评估冲刺健康状况。

四个提示词模板会将实时 OpenProject 数据渲染为可直接使用的简报:

  • weekly_report — 单个项目的每周状态报告:当前已关闭且已更新/进行中/计划中、工时和阻碍因素。
  • daily_standup — 单个项目的今日站会内容:昨日进展、今日到期事项和受阻事项。
  • triage_inbox — 按原因归类未读通知,并建议采取的行动。
  • groom_backlog — 检查项目未完成的待办事项,找出未分配、长期未更新和未估算的工作。

三个资源模板通过稳定 URI 提供 OpenProject 对象:

  • openproject://work_package/{id} — 单个工作包的 JSON。
  • openproject://project/{identifier} — 单个项目的 JSON(标识符别名或数字 ID)。
  • openproject://attachment/{id} — 附件的字节数据及检测到的 MIME 类型,大小上限为 OPENPROJECT_MCP_MAX_INLINE_MB。

支持的 OpenProject 版本

该服务面向 OpenProject 14 LTS 至 17.x。它不会假定 API 方言一致,而是在首次需要时延迟探测实例,并将结果缓存一小时。与版本有关的功能:

  • 目标版本:所有受支持的实例都会在工作包详情中公开 target_versions。创建/更新操作接受版本 ID 列表([] 表示清除);架构会在 17.8+ 上选择 targetVersions,或使用单个旧版 version。旧版 version 参数仍可作为单值别名;不要同时传入两者。读取时,如果分配了多个版本,该字段为 null。
  • 内部(私有)评论需要 OpenProject >= 16。较旧的服务会静默忽略内部标记,因此在 16 以下,该服务会明确报错,而不是将你要求保密的评论公开发布。
  • 表情回应(toggle_comment_reaction)需要 OpenProject >= 16;该功能根据版本检测,并能容忍调用时返回 404。
  • 项目收藏(set_project_favorite)需要 OpenProject >= 17;同样能容忍相关情况。
  • 时间条目筛选器:会探测工作包筛选器(使用 entityId,若不支持则回退到 15.x 之前的 workPackage 写法)。
  • 权限上下文(list_permissions):会探测上下文前缀(使用 p{id},若不支持则回退到 17.2 引入的 w{id} 写法)。
  • 会议时间筛选器:OpenProject 17.6 更改了线上的方言;list_meetings 会探测实例接受的写法并将其缓存。
  • 故事点数需要启用 Backlogs 模块,且类型必须被 Backlogs 视为故事。17.x 在不满足条件时会拒绝 story_points;14.x 会接受写入但静默丢弃该值,因此结果会附带说明,指出该值未保存(批量预览会在写入前发出警告)。

依赖实例可选模块的功能(会议、新闻、文档、预算、维基、待办列表、GitHub/GitLab 集成、外部存储)在模块缺失时会如实降级:列表工具会返回空页面,并在页面内附上缺失模块的名称;详情工具会返回结构化错误,说明 404 可能表示的两种情况。

安全性

  • API 密钥和 OAuth 令牌以 SecretStr 保存,绝不会写入日志;每条日志记录中的 Authorization 和 Cookie 标头都会被隐藏。请求和响应正文仅在设置 OPENPROJECT_MCP_LOG_BODIES=1 时以 DEBUG 级别记录,供开发使用。
  • 重定向离开 OpenProject 来源时,会移除 Authorization 标头——附件下载会重定向到预签名的对象存储 URL,凭据不得传递到那里。
  • 始终验证 TLS。支持通过 OPENPROJECT_MCP_CA_BUNDLE 使用私有 CA;特意不提供禁用 TLS 验证的开关。
  • 附件下载遵循 OpenProject 的病毒扫描器规则:绝不会获取已隔离的文件,并会产生结构化的 attachment_quarantined 错误。下载大小受 OPENPROJECT_MCP_MAX_DOWNLOAD_MB 限制,文件以经过清理的文件名保存(目录分隔符和路径遍历序列会被处理),并报告文件字节的 SHA-256 值。
  • 具有破坏性的工具需要 confirm=true,并带有注释,以便客户端事先征求用户确认。
  • HTTP 传输在未配置 OPENPROJECT_MCP_AUTH_TOKENS 时拒绝启动,并会在每个请求上验证 Authorization: Bearer 标头——缺失或无效的令牌会被拒绝并返回 401,且令牌比较采用恒定时间算法。服务器不会终止 TLS:请保留默认的 127.0.0.1 绑定;如果端口必须能够从其他位置访问,请在前面放置一个终止 TLS 的反向代理(参见传输)。所有 HTTP 客户端共用服务器的同一个 OpenProject 身份;请使用 OPENPROJECT_MCP_UPLOAD_ROOT / OPENPROJECT_MCP_DOWNLOAD_ROOT 限定文件工具的范围。
  • 下载文件采用独占方式创建(即使并发下载同名文件,也绝不会覆盖现有文件);传输失败或取消时,只会删除本次创建的文件。

故障排除

症状含义及处理方法
服务器退出并显示 "cannot start, configuration is incomplete"运行 openproject-mcp-server --check 并修复其列出的问题;变量说明请参见上文的配置部分。
401 authentication_failedAPI 密钥错误、已撤销,或属于被封禁的账户。请在我的账户 → 访问令牌下生成新令牌。
403 permission_denied账户已通过身份验证,但缺少该项目的角色权限,或项目未启用相关模块。
列表为空,并提示缺少模块该 OpenProject 模块(会议、新闻、文档……)未安装或未在项目中启用——空结果是准确的答复,并非错误。
TLS 证书错误你的实例使用私有 CA:请将 OPENPROJECT_MCP_CA_BUNDLE 指向其 PEM 文件包。没有禁用验证的选项。
--transport http 拒绝启动设置 OPENPROJECT_MCP_AUTH_TOKENS(以逗号分隔的 Bearer 令牌),或仅在本地开发时设置 OPENPROJECT_MCP_INSECURE=1——参见传输。
MCP HTTP 端点本身返回 401请求缺少 Authorization: Bearer <token> 标头,或其值与任何已配置的 OPENPROJECT_MCP_AUTH_TOKENS 条目都不匹配。请检查客户端令牌是否有拼写错误;这与上文提到的上游 401 authentication_failed 不同,后者指的是 OpenProject API 密钥问题。
代理底层 HTTP 客户端会遵循标准的 HTTPS_PROXY / ALL_PROXY / NO_PROXY 变量。

报告问题时,请提供你的 OpenProject 版本、openproject-mcp-server --version 的输出,以及 openproject-mcp-server --check 的输出。

开发

git clone https://github.com/kar-thik/openproject-mcp
cd openproject-mcp
uv sync --group dev
uv run pytest              # entire suite runs offline (respx-mocked HTTP), no instance needed
uv run ruff check .
uv run ruff format --check .
uv run pyright             # strict mode

默认测试套件保持离线。选择加入的兼容性检查会在兼容性工作流中,针对全新的官方 OpenProject 14.6、15.5、16.6 和 17.8 容器运行(包括 17.8 的单版本和多版本模式)。在本地运行其中一项检查(需运行 Docker):

uv run python scripts/live_smoke.py --image openproject/openproject:17.8.0

测试框架会创建一个私有项目、临时用户、自定义字段和版本;通过 MCP 进行测试,然后移除容器及其卷。不会使用现有实例和凭据。直接运行 pytest 时会跳过这些测试,除非提供 --live-openproject 和一个一次性测试夹具文件。 完整的技术规范见 SPEC.md。

发布流程见 CONTRIBUTING.md。

许可和商标

MIT — 详见 LICENSE。

这是一个社区项目,与 OpenProject GmbH 无关,也未获其认可或支持。“OpenProject”是 OpenProject GmbH 的商标,此处仅用于说明互操作性。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。