Jira Tempo工作日志管理服务器

一个用于通过Tempo API管理Jira工作日志的Model Context Protocol (MCP)服务器,提供时间跟踪、批量操作和分析功能。

  • by ivelin-web
  • TypeScript
  • 混合部署
  • 48 星标
  • 更新于
在 GitHub 查看 ivelin-web/tempo-mcp-server

使用说明

Tempo MCP服务器

用于管理Jira中Tempo工作日志的模型上下文协议(MCP)服务器。该服务器通过Tempo的API提供跟踪时间和管理工作日志的工具,使其可以通过Claude、Cursor和其他兼容MCP的客户端访问。

特性

  • 检索工作日志:获取特定日期范围内的所有工作日志
  • 创建工作日志:记录Jira问题的时间
  • 批量创建:在单个操作中创建多个工作日志
  • 编辑工作日志:修改花费的时间、日期和描述
  • 删除工作日志:删除现有工作日志
  • 失踪天数报告:查找记录低于预期的工作日(使用Tempo的用户日程,因此假期和非工作日会自动跳过)
  • 工作日志分析:按问题、帐户、日、周或月汇总小时数,包括总数和百分比

系统要求

  • Node.js 18+(推荐LTS)——仅适用于本地stdio模式
  • Jira云实例
  • Tempo API代币
  • Jira API令牌(使用OAuth 2.0 PKCE身份验证时不需要)

使用选项

有三种方法可以使用此MCP服务器:

  1. 远程/Cloudflare Workers(无需安装) --主持一次,与你的团队分享。每个用户通过设置页面生成自己的URL,并将其粘贴到Claude.ai或ChatGPT中。适用于网络和移动设备。
  2. NPX:直接运行 npx 在你的笔记本电脑上,不需要克隆。
  3. 本地克隆:克隆存储库以进行开发或自定义。

如果你只想使用服务器,选项1是最简单的,也适用于手机。如果您是为团队部署的维护人员,请参阅 远程部署指南.

选项1:远程(Cloudflare Workers)

面向终端用户

一旦你的团队部署了服务器,流程是:

  1. 打开 https://<your-deployment>.workers.dev/setup.
  2. 粘贴您的Tempo API令牌、Jira基础URL、Jira API令牌和Jira电子邮件。击打 生成MCP URL.
  3. 该页面返回一个个人URL,如下所示 https://<your-deployment>.workers.dev/mcp/u_<random>。复制它。
  4. 在 Claude.ai→ 设置→ 连接器→ 添加自定义连接器,粘贴URL。
  5. 该连接器可在网络、桌面和移动设备(iOS/Android)上同步。

对于ChatGPT:启用设置→ Apps → 高级→ 开发人员模式 (Pro/EPlus/Business+),然后将URL添加为自定义MCP服务器。Plus/Pro帐户可以阅读;编写工具(创建/编辑工作日志)需要每个OpenAI层的Business+。

该URL包含您的凭据——将其视为密码,不要共享或提交。

远程部署(Cloudflare Workers)

Cloudflare Workers上的免费层托管。从克隆到实时URL大约需要5-10分钟。任何人都可以分叉和自托管——不需要上游协调。

先决条件

  • Cloudflare帐户(免费计划就足够了)。
  • Node.js 18+和 npm 本地-仅用于 wrangler CLI;Worker运行时本身不运行Node。

一次性设置

git clone https://github.com/ivelin-web/tempo-mcp-server.git
cd tempo-mcp-server
npm install

# 1. Log in to Cloudflare (opens browser).
npx wrangler login

# 2. Create your own KV namespace for per-user credentials.
npx wrangler kv namespace create USERS

⚠️ 如果你分叉了repo: 承诺 wrangler.jsonc kv_namespaces[0].id 属于上游维护者的Cloudflare帐户。将其替换为刚刚返回的id step 2,否则 wrangler deploy 将失败 KV namespace … is not valid.KV命名空间ID是每个帐户的公共标识符,而不是秘密标识符,但每个帐户都有自己的标识符。

# 3. Generate and store the encryption key.
#    Used to AES-GCM-encrypt per-user credentials in KV.
openssl rand -base64 48 | npx wrangler secret put ENCRYPTION_KEY

# 4. (Optional) Pin the CORS origin. Defaults to "*". Set it if you only
#    want browsers from a specific app to call the Worker.
echo "https://claude.ai" | npx wrangler secret put ALLOWED_ORIGIN

# 5. Deploy.
npm run remote:deploy
# → outputs https://tempo-mcp-server.<your-account>.workers.dev

访问 /setup 在部署的URL上加载您的第一个用户。

更新现有部署

从上游拉取新提交后:

npm install              # picks up any new deps
npm run remote:deploy    # ships the new Worker bundle

秘密和KV数据在部署过程中持续存在。 compatibility_date 和 compatibility_flags 在 wrangler.jsonc 因此,当Cloudflare发布运行时更改时,行为不会悄无声息地漂移。

本地开发

cp .dev.vars.example .dev.vars
# edit .dev.vars and put a real ENCRYPTION_KEY (any value works locally)
npm run remote:dev
# → http://localhost:8787 with a mock KV; data is wiped between sessions

其他有用的脚本:

  • npm run remote:typecheck --键入检查Worker捆绑包(使用 tsconfig.worker.json).
  • npm run remote:tail --从部署的Worker流式传输实时日志。

故障排除

  • KV namespace … is not valid — kv_namespaces[0].id 在 wrangler.jsonc 为空(或错误)。跑 npx wrangler kv namespace create USERS 并粘贴新id。
  • ENCRYPTION_KEY is not defined 在运行时,未设置密钥。重新运行步骤3。
  • Rate limit binding … not available -您的帐户计划不包括工人费率限制API。升级或删除 ratelimits 把…的车堵住 wrangler.jsonc 和那个 SETUP_RATE_LIMITER.limit(...) 打电话 src/remote/worker.ts.
  • 404从 /mcp/u_… --用户id未知(或从未存在)。Worker针对无效/缺失的id返回404;让用户重新运行 /setup.
  • 现有用户突然无法连接 --最可能的原因是旋转 ENCRYPTION_KEY;现有的AES-GCM blob无法使用新密钥解密。请参阅下面的警告。

运作原理

凭证存储: 这 /setup POST处理程序AES-GCM使用以下方式加密表单数据 ENCRYPTION_KEY 并将其存储在KV以下 user:u_<random>每个MCP请求读取+解密该记录,构建一个 McpServer 对于该单一请求,并通过Cloudflare的官方发送 createMcpHandler在请求之间,内存中不保存任何凭据;不使用耐用对象。

对待 ENCRYPTION_KEY 作为长寿命。 旋转它会使每个现有的用户记录无效(AES-GCM标签不会根据新密钥进行验证),所有用户都需要重新运行 /setup.从中选择一把钥匙 openssl rand -base64 48 一次,永不改变。

身份验证模型: URL /mcp/u_<id> 是 凭证。22个字符的base64url id包含~128位熵。对于该路径,我们从不返回401(Claude.ai web已经知道401和OAuth流周围的错误),对于未知的id,我们返回404。这与Zapier MCP、Pipedream MCP等使用的URL令牌模式相匹配。

硬化已经到位:

  • 每IP速率限制(5个请求/分钟) POST /setup,通过Cloudflare的本地速率限制绑定。
  • Cache-Control: no-store 上 /setup 响应,因此成功页面(包含MCP URL)和错误重新呈现(回显令牌)永远不会位于任何缓存中。
  • Referrer-Policy: no-referrer 在每个HTML页面上,这样MCP URL就不会通过引用者标头泄漏。

要了解的限制:

  • 无工人计划:每天10万个请求,每个请求50毫秒CPU(我们受I/O限制,舒适)。
  • KV免费计划:100k读/天,1k写/天。安装程序为每个用户写入一次;每次MCP调用都会进行读取。
  • Worker仅支持Jira 基本的 auth(经典API令牌+电子邮件)。Bearer和OAuth 2.0 PKCE流仅支持stdio——Bearer需要Worker尚未完成的网关URL路由,而PKCE需要Worker无法承载的浏览器回调。

选项2:NPX使用

使用此服务器的最简单方法是通过npx而无需安装:

连接到克劳德桌面(NPX方法)

  1. 打开MCP客户端配置文件:

    • 克劳德桌面(macOS): ~/Library/Application Support/Claude/claude_desktop_config.json
    • 克劳德桌面(Windows): %APPDATA%\Claude\claude_desktop_config.json
  2. 添加以下配置:

{
  "mcpServers": {
    "Jira_Tempo": {
      "command": "npx",
      "args": ["-y", "@ivelin-web/tempo-mcp-server"],
      "env": {
        "TEMPO_API_TOKEN": "your_tempo_api_token_here",
        "JIRA_API_TOKEN": "your_jira_api_token_here",
        "JIRA_EMAIL": "your_email@example.com",
        "JIRA_BASE_URL": "https://your-org.atlassian.net"
      }
    }
  }
}
  1. 重新启动您的Claude Desktop客户端

光标一键安装

选项3:本地存储库克隆

安装

# Clone the repository
git clone https://github.com/ivelin-web/tempo-mcp-server.git
cd tempo-mcp-server

# Install dependencies
npm install

# Build TypeScript files
npm run build

本地运行

有两种方法可以在本地运行服务器:

1.使用MCP检查器(用于开发和调试)

npm run inspect

2.直接使用Node

您可以通过指向构建的JavaScript文件直接使用Node运行服务器:

连接到Claude桌面(本地方法)

  1. 打开MCP客户端配置文件
  2. 添加以下配置:
{
  "mcpServers": {
    "Jira_Tempo": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/tempo-mcp-server/build/index.js"],
      "env": {
        "TEMPO_API_TOKEN": "your_tempo_api_token_here",
        "JIRA_API_TOKEN": "your_jira_api_token_here",
        "JIRA_EMAIL": "your_email@example.com",
        "JIRA_BASE_URL": "https://your-org.atlassian.net"
      }
    }
  }
}
  1. 重新启动您的Claude Desktop客户端

获取API令牌

  1. Tempo API代币:

    • 前往Tempo>设置>API集成
    • 使用创建新的API令牌 自定义访问 并至少选择:
      • 工作日志 (查看+管理)--适用于所有工作日志工具
      • 方案 (视图)--必需 getMissingWorklogDays (阅读用户日程表)
      • 账户 (查看)--仅当您的工作日志使用Tempo帐户时
      • 团队 (查看)--仅当您使用 program / team 筛选器(包括团队和程序)
    • Tempo不允许编辑现有令牌的范围;如果以后需要添加作用域,请创建一个新的作用域。
  2. Jira API代币:

    • 首选 Atlassian API代币
    • 点击 “创建API令牌” (经典的、无范围的流程)。这是有效的 basic 开箱即用的身份验证。
    • 不要使用“创建具有作用域的API令牌” --这些令牌必须通过Atlassian的网关URL发送(https://api.atlassian.com/ex/jira/{cloudId}/...)使用此服务器的云ID basic auth路径当前未路由到。它们将失败,对您的网站URL为401。如果您只有一个可用的作用域令牌(例如,您的组织禁用了经典令牌),请使用 OAuth 2.0 PKCE流程 相反,它会自动通过网关路由。

环境变量

服务器需要以下环境变量:

TEMPO_API_TOKEN           # Your Tempo API token
JIRA_API_TOKEN            # Your Jira API token (required for basic and bearer auth)
JIRA_EMAIL                # Your Jira account email (required for basic auth)
JIRA_BASE_URL             # Your Jira instance URL (e.g., https://your-org.atlassian.net)
JIRA_AUTH_TYPE            # Optional: 'basic' (default), 'bearer', or 'oauth'
JIRA_OAUTH_CLIENT_ID      # OAuth 2.0 client ID (required for oauth auth)
JIRA_OAUTH_CLIENT_SECRET  # OAuth 2.0 client secret (required for oauth auth)
JIRA_TEMPO_ACCOUNT_CUSTOM_FIELD_ID     # Optional: Custom field ID for Tempo accounts

您可以在您的环境中设置这些,也可以在MCP客户端配置中提供它们。

身份验证类型

服务器支持Jira API的三种身份验证方法:

基本身份验证(默认)

使用电子邮件和API令牌。这是传统的方法:

{
  "env": {
    "JIRA_API_TOKEN": "your_api_token",
    "JIRA_EMAIL": "your_email@example.com",
    "JIRA_AUTH_TYPE": "basic"
  }
}

承载令牌身份验证(OAuth 2.0)

对于希望使用OAuth 2.0范围内的令牌来增强安全性的用户:

{
  "env": {
    "JIRA_API_TOKEN": "your_oauth_access_token",
    "JIRA_AUTH_TYPE": "bearer"
  }
}

注意:使用时 bearer auth, JIRA_EMAIL 不需要,因为用户是从令牌中识别出来的。

OAuth 2.0 PKCE身份验证

一些Atlassian组织通过管理策略限制API令牌访问,这会导致基本和承载身份验证失败。这 oauth 类型使用PKCE实现了完整的OAuth 2.0授权代码流,并且在不受API令牌限制的情况下工作-令牌是短暂的,并且在没有任何手动管理的情况下自动刷新。

首次使用时,会打开一个浏览器窗口供您授权访问。代币存储在本地 ~/.tempo-mcp-server/tokens.json 并自动刷新。

  1. 在中创建OAuth 2.0应用程序 Atlassian开发人员控制台 随着 read:jira-user 和 read:jira-work 范围和 http://localhost:7788/callback 作为回调URL。

  2. 配置服务器:

{
  "env": {
    "JIRA_BASE_URL": "https://your-org.atlassian.net",
    "JIRA_AUTH_TYPE": "oauth",
    "JIRA_OAUTH_CLIENT_ID": "your_client_id",
    "JIRA_OAUTH_CLIENT_SECRET": "your_client_secret"
  }
}

注: JIRA_API_TOKEN 和 JIRA_EMAIL 使用时不需要 oauth auth。

Tempo帐户配置

如果Tempo实例要求将工作日志链接到帐户,请设置包含帐户信息的自定义字段ID:

JIRA_TEMPO_ACCOUNT_CUSTOM_FIELD_ID=10234

要查找您的自定义字段ID:

  1. 转到Jira设置→ 问题→ 自定义字段
  2. 找到您的Tempo帐户字段,并记下URL或字段配置中的ID

查看其他用户的工作日志

阅读工具(retrieveWorklogs, getWorklogAnalytics, getMissingWorklogDays)默认为令牌所有者自己的工作日志,但接受针对其他人的可选过滤器——对管理员、项目经理和团队负责人很有用:

  • users --电子邮件、显示名称或Jira帐户ID的数组(例如。 ["ivan@company.com", "Maria Petrova"])
  • program --Tempo程序名称或id;扩展到项目团队的所有现有成员
  • team --Tempo团队名称或id;扩展到所有当前团队成员

过滤器组合成一个接头。Tempo强制执行权限 服务器端:API静默地忽略了令牌所有者不允许看到的工作日志(不返回错误)。要查看其他用户,您需要:

  1. 一个Tempo 权限角色 随着 查看工作日志 授予令牌所有者(Tempo>设置>权限角色)——每个人都是“完全”,或“受限”+选定团队
  2. Jira 浏览项目 相关项目的许可
  3. 这 团队 如果使用 program / team 过滤器

getWorklogAnalytics 还支持 groupBy: "user" --结合 program,它在一次通话中生成每人小时报告。 getMissingWorklogDays 使用过滤器返回缺少时间的每用户报告(查看其他用户的日程也是权限门控的)。

可用工具

检索工作日志

在开始日期和结束日期之间获取已配置用户(或通过筛选器获取其他用户)的工作日志。

Parameters:
- startDate: String (YYYY-MM-DD)
- endDate: String (YYYY-MM-DD)
- users: String[] (optional) — emails, display names, or accountIds
- program: String (optional) — Tempo Program name or id
- team: String (optional) — Tempo Team name or id

创建工作日志

为特定的Jira问题创建新的工作日志。

Parameters:
- issueKey: String (e.g., "PROJECT-123")
- timeSpentHours: Number (positive)
- date: String (YYYY-MM-DD)
- description: String (optional)
- startTime: String (HH:MM format, optional)

bulkCreateWorklogs

在单个操作中创建多个工作日志。

Parameters:
- worklogEntries: Array of {
    issueKey: String
    timeSpentHours: Number
    date: String (YYYY-MM-DD)
    description: String (optional)
    startTime: String (HH:MM format, optional)
  }

editWorklog

修改现有工作日志。

Parameters:
- worklogId: String
- timeSpentHours: Number (positive)
- description: String (optional)
- date: String (YYYY-MM-DD, optional)
- startTime: String (HH:MM format, optional)

删除工作日志

删除现有工作日志。

Parameters:
- worklogId: String

getMissingWorklogDays

报告用户记录的时间少于预期的日期范围内的工作日。每天的预期小时数来自用户的Tempo时间表,因此假期、非工作日和兼职时间表都会自动执行。随着 users / program / team 它检查其他人并返回每个用户的报告(按最缺少的时间排序)。

Parameters:
- startDate: String (YYYY-MM-DD)
- endDate: String (YYYY-MM-DD)
- minHoursPerDay: Number (optional) — override the per-day threshold;
                                      non-working days are still skipped
- users: String[] (optional) — emails, display names, or accountIds
- program: String (optional) — Tempo Program name or id
- team: String (optional) — Tempo Team name or id

所需温度范围: 这 TEMPO_API_TOKEN 必须包括 方案 范围(包括工作量方案、假期方案、用户计划) 工作日志.Tempo不允许修改现有令牌上的作用域-如果当前令牌只有Worklogs,请在Tempo>Settings>API Integration创建一个新令牌。

getWorklogAnalytics

聚合某个日期范围内的工作日志,并返回按小时降序排列的每个组的小时数、工作日志计数和百分比。合并 groupBy: "user" 随着 program / team / users 对于每个人的报告。

Parameters:
- startDate: String (YYYY-MM-DD)
- endDate: String (YYYY-MM-DD)
- groupBy: "issue" | "account" | "user" | "day" | "week" | "month" (optional, default "issue")
- users: String[] (optional) — emails, display names, or accountIds
- program: String (optional) — Tempo Program name or id
- team: String (optional) — Tempo Team name or id

项目结构

tempo-mcp-server/
├── src/                  # Source code
│   ├── authors.ts        # Author filter resolution (users/program/team → accountIds)
│   ├── config.ts         # Configuration management
│   ├── index.ts          # MCP server implementation
│   ├── jira.ts           # Jira API integration
│   ├── oauth.ts          # OAuth 2.0 PKCE flow and token management
│   ├── tools.ts          # Tool implementations
│   ├── types.ts          # TypeScript types and schemas
│   └── utils.ts          # Utility functions
├── build/                # Compiled JavaScript (generated)
├── tsconfig.json         # TypeScript configuration
└── package.json          # Project metadata and scripts

故障排除

如果您遇到问题:

  1. 检查所有环境变量是否设置正确
  2. 验证您的Jira和Tempo API令牌是否具有正确的权限
  3. 检查控制台输出是否有错误消息
  4. 尝试与检查员一起运行: npm run inspect

许可证

麻省理工学院

学分

此服务器实现 模型上下文协议 由Anthropic创建的规范。