关于 Redmine Fastmcp Server With Oauth
Redmine Fastmcp Server With Oauth 是面向团队的集中部署型 Redmine MCP 服务,用户通过 Redmine OAuth 授权。它将 Redmine 访问令牌保存在服务端,并提供处理问题、项目、工时记录和 Wiki 的工具、提示词与资源。
主要功能
- 01通过 Redmine OAuth 2.0 授权用户
- 02搜索、列出、创建和更新问题
- 03管理项目及项目版本
- 04读取和更新 Wiki 页面
- 05访问工时记录及 Redmine 资源
适用场景
- 01搜索问题并查看详细信息
- 02经用户授权创建或更新问题
- 03查看项目版本和工时记录
- 04获取或修改项目 Wiki 页面
MCP 相关
通过 Streamable HTTP 将 Redmine 操作作为 MCP 工具、提示词和资源提供。客户端获得 FastMCP 签发的 JWT;Redmine OAuth 令牌保留在服务端。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
<<YourServerURL>>claude mcp add --transport http redmine-oauth <<YourServerURL>>{"mcpServers":{"redmine-oauth":{"type":"http","url":"<<YourServerURL>>"}}}在 Cursor 中打开{"servers":{"redmine-oauth":{"type":"http","url":"<<YourServerURL>>"}}}在 VS Code 中打开{"mcpServers":{"redmine-oauth":{"type":"http","url":"<<YourServerURL>>"}}}{"mcpServers":{"redmine-oauth":{"serverUrl":"<<YourServerURL>>"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
mcp-redmine-oauth — 带 OAuth 的 Redmine FastMCP 服务
一个集中部署的 Redmine MCP 服务,使用 OAuth 2.0 进行身份验证。管理员只需部署一次;用户通过 Redmine 授权即可连接,无需 API 密钥或逐个用户设置。使用 FastMCP 3 构建。
工作原理
MCP Client (Claude Desktop, MCP Inspector, …)
│ MCP over Streamable HTTP
│ Authorization: Bearer <fastmcp-jwt>
▼
┌─────────────────────────────┐
│ FastMCP 3 Server │
│ OAuthProxy (port 8000) │──── token exchange ────▶ Redmine OAuth
│ Token store (in-memory) │◀─── access token ────────
│ │
│ Tools │──── REST API ───────────▶ Redmine API
└─────────────────────────────┘
MCP 客户端始终只能看到 FastMCP 签发的 JWT。Redmine OAuth 令牌存储在服务端,绝不会暴露给客户端。
前置条件
- Python 3.11+
- 正在运行的 Redmine 6.1+ 实例,并且已启用 REST API
- 在 Redmine 中注册的 OAuth 应用(见下文)
Redmine 设置
1. 启用 REST API
管理 → 设置 → API → 启用 REST Web 服务(勾选并保存)。
2. 注册 OAuth 应用
管理 → 应用 → 新建应用
| 字段 | 值 |
|---|---|
| 重定向 URI | http://<MCP_BASE_URL>/auth/callback |
| 保密客户端 | 是 |
| 范围 | 启用所有必需范围,以获得完整功能 |
复制生成的客户端 ID和客户端密钥。
设置
git clone https://github.com/tuzumkuru/mcp-redmine-oauth.git
cd mcp-redmine-oauth
cp .env.example .env
填写你的值:
REDMINE_URL=http://your-redmine-host
REDMINE_CLIENT_ID=your-client-id
REDMINE_CLIENT_SECRET=your-client-secret
运行
pip install -e .
mcp-redmine-oauth
MCP 服务将在 http://localhost:8000/mcp 上提供。
要使用 MCP Inspector 进行测试:
npx @modelcontextprotocol/inspector
打开 http://localhost:6274,将传输方式设为 Streamable HTTP,并输入 http://localhost:8000/mcp。
使用 Docker 运行
docker compose up --build
容器会从 .env 读取配置。请确保 MCP_BASE_URL 设置为可从外部访问的服务 URL(如果客户端从其他机器连接,则不要使用 localhost)。
在 .env 中设置 MCP_HOST_PORT 可更改主机侧端口(默认为 8000)。
环境变量
| 变量 | 必需 | 默认值 | 描述 |
|---|---|---|---|
REDMINE_URL | 是 | — | Redmine 实例的基础 URL |
REDMINE_CLIENT_ID | 是 | — | OAuth 应用客户端 ID |
REDMINE_CLIENT_SECRET | 是 | — | OAuth 应用客户端密钥 |
REDMINE_SCOPES | 否 | (全部已声明范围) | 允许列表筛选器:以空格分隔的 Redmine 应用支持的范围(见范围处理) |
MCP_HOST | 否 | 0.0.0.0 | 绑定主机 |
MCP_PORT | 否 | 8000 | 绑定端口 |
MCP_BASE_URL | 否 | http://localhost:MCP_PORT | 用于 OAuth 重定向的公开 URL |
REDMINE_PUBLIC_URL | 否 | REDMINE_URL | 用户在浏览器中访问的 Redmine URL,用于草稿链接。当服务通过内部地址连接 Redmine 时,请设置此项 |
可用工具与资源
| 组件 | 类型 | 所需权限范围 | 描述 |
|---|---|---|---|
get_issue_details | 工具 | view_issues | 按 ID 获取 Redmine 问题,包括描述、自定义字段和日志 |
search_issues | 工具 | view_issues、search_project | 在问题中进行全文搜索,支持分页 |
list_issues | 工具 | view_issues | 使用筛选条件(项目、指派对象、状态、跟踪器、排序)列出问题 |
get_issue_relations | 工具 | view_issues | 获取问题关联关系(阻塞、被阻塞、相关等) |
get_project_details | 工具 | view_project | 获取项目详情,包括跟踪器、类别和已启用模块 |
get_project_versions | 工具 | view_project | 获取项目版本/里程碑及其状态和截止日期 |
list_time_entries | 工具 | view_time_entries | 使用筛选条件(项目、用户、日期范围)列出工时记录 |
create_issue | 工具 | add_issues | 创建问题,包括主题、跟踪器、优先级、指派对象等 |
update_issue | 工具 | edit_issues | 更新现有问题(状态、指派对象、备注等) |
create_project | 工具 | add_project | 创建新的 Redmine 项目 |
update_project | 工具 | edit_project | 更新项目名称、描述、可见性和跟踪器 |
get_wiki_page | 工具 | view_wiki_pages | 获取项目中的 Wiki 页面 |
update_wiki_page | 工具 | edit_wiki_pages | 创建或更新 Wiki 页面 |
rename_wiki_page | 工具 | rename_wiki_pages | 重命名 Wiki 页面,可选择添加重定向 |
draft_new_issue | 工具 | (仅需登录) | 链接到已填入建议值的 Redmine 新建问题表单;用户提交前不会保存任何内容 |
draft_issue_update | 工具 | (仅需登录) | 链接到已填入建议更改和评论的问题编辑表单,并附上问题页面链接 |
draft_new_project | 工具 | (仅需登录) | 链接到已填入内容的 Redmine 新建项目表单;仅适用于获准添加项目的用户,或获准添加父项目的子项目的用户 |
summarize_ticket | 提示词 | view_issues | 生成问题的简明摘要及后续步骤 |
draft_bug_report | 提示词 | view_project | 根据粗略笔记起草结构化的错误报告 |
redmine://projects/active | 资源 | view_project | 列出活跃项目 |
redmine://trackers | 资源 | view_project | 列出可用跟踪器 |
redmine://issue-statuses | 资源 | view_issues | 列出所有问题状态及其 ID 和关闭标记 |
redmine://enumerations/priorities | 资源 | view_issues | 列出问题优先级及其 ID |
redmine://users/me | 资源 | (仅需身份验证) | 当前已验证用户的个人资料 |
计划中:持久化令牌存储、按权限范围动态禁用工具、结构化日志记录。
所需的 Redmine 权限范围
在 Redmine OAuth 应用程序中启用以下权限范围(管理 → 应用程序)。它们按 Redmine 类别分组,与应用程序设置中的分组方式一致。
项目
| Redmine 权限 | 权限范围标识符 | 用于 |
|---|---|---|
| 查看项目 | view_project | get_project_details、get_project_versions、redmine://projects/active、redmine://trackers、draft_bug_report |
| 搜索项目 | search_project | search_issues |
| 创建项目 | add_project | create_project |
| 编辑项目 | edit_project | update_project |
问题跟踪
| Redmine 权限 | 权限范围标识符 | 用于 |
|---|---|---|
| 查看问题 | view_issues | get_issue_details、search_issues、list_issues、get_issue_relations、redmine://issue-statuses、redmine://enumerations/priorities、summarize_ticket |
| 添加问题 | add_issues | create_issue |
| 编辑问题 | edit_issues | update_issue |
工时跟踪
| Redmine 权限 | 权限范围标识符 | 用于 |
|---|---|---|
| 查看已用工时 | view_time_entries | list_time_entries |
Wiki(维基)
| Redmine 权限 | 范围标识符 | 使用方 |
|---|---|---|
| 查看 Wiki | view_wiki_pages | get_wiki_page |
| 编辑 Wiki 页面 | edit_wiki_pages | update_wiki_page |
| 重命名 Wiki 页面 | rename_wiki_pages | rename_wiki_page |
如果未启用某个范围,依赖该范围的工具在调用时会返回描述性错误。
范围处理
每个工具和资源都通过 @requires_scopes 装饰器声明所需的 OAuth 范围。服务会自动收集所有已声明的范围,并在 OAuth 授权期间请求这些范围。
如果你的 Redmine OAuth 应用配置的范围仅为上述范围中的一部分,请设置 REDMINE_SCOPES,以避免出现 “The requested scope is invalid, unknown, or malformed” 错误:
REDMINE_SCOPES=view_issues view_project
设置后,请求的范围仅为工具所声明范围与 REDMINE_SCOPES 的交集。如果工具所需的范围未全部包含在内(例如,search_issues 需要 search_project),该工具会在调用时返回描述性错误,而不会导致整个 OAuth 流程中断。
如果省略此项,则会请求所有工具所声明的范围——当你的 Redmine 应用已启用所有这些范围时,此设置即可正常使用。
架构
有关 OAuth 流程、令牌存储和模块设计的详细信息,请参阅 docs/architecture.md。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。