专注于Jira的MCP服务器(云)
用于Jira Cloud的MCP服务器,具有受约束的数据抽象,旨在避免用完整的Jira有效载荷淹没LLM上下文。
设计目标
- 业务优先输出:只返回经过策划的字段,而不是完整的Jira有效载荷。
- 上下文安全默认值:注释默认仅为最后3个。
- 低客户端复杂性:将Jira REST API细节隐藏在稳定的工具后面。
它的作用
此服务器公开了十五个工具:
jira_get_issuejira_create_issuejira_update_issuejira_transition_issuejira_get_issue_workflowjira_add_commentjira_list_issue_link_typesjira_link_issuejira_set_issue_parentjira_project_baselinejira_project_assignable_usersjira_list_sprintsjira_assign_issue_to_sprintjira_search_issues_by_jqljira_search_issues
所有工具都有意使用一个焦点问题模型:
url(直接Jira UI链接:/browse/{issueKey})summarydescription(默认纯文本;可选的ADF读/写模式)fixVersionsaffectedVersionslabelsstatuspriorityseverity(通过可配置字段映射)assigneereporterparent/subtasks/linkedIssuescomments(默认值:最后3个仅用于上下文保护)
需求
- Node.js 22+
- Jira云账户+API代币(或预先构建
Authorization头球
支持的Jira API
此服务器仅针对Jira Cloud,并使用:
- Jira云平台REST API
v3 - Jira软件云REST API
agile/1.0用于板和短跑
该实现有意为每个功能使用一个有文档记录的API系列,并且不会悄悄地后退到替代搜索或用户/优先级查找变体。
配置
仅使用MCP客户端配置。
- 尽最大努力
JIRA_*MCP服务器下的变量env块。
获取Jira凭据(一步一步)
- 查找您的Jira基本URL
- 在浏览器中打开Jira并复制网站来源,例如。 https://your-domain.atlassian.net.
- 创建API令牌(Jira Cloud)
- 在以下位置创建令牌 https://id.atlassian.com/manage-profile/security/api-tokens. - 保持私密。把它当作密码。
- 选择电子邮件地址
- 使用您的Atlassian帐户的电子邮件(可以访问Jira网站的同一帐户)。
- 可选:找出严重性自定义字段
- 如果您的项目使用自定义严重性字段,请查找其字段id(通常 customfield_12345). - 快捷方式(需要身份验证):
curl -sS -u "${JIRA_EMAIL}:${JIRA_API_TOKEN}" \
"${JIRA_BASE_URL}/rest/api/3/field" | head- 在输出中搜索一个字段,该字段
name有点像Severity并使用其id. - 如果该字段是选择列表,请使用
JIRA_SEVERITY_VALUE_TYPE=option(默认)。
安装
npm install
npm run build将此服务器添加到MCP客户端(逐步)
这是一个 标准 MCP服务器。大多数MCP客户端都需要相同的4件事:
- 运输:
STDIO - 命令:
node - 参数:绝对路径
dist/index.js - 环境变量:
JIRA_*
步骤0:构建一次(必需)
从repo根目录:
npm install
npm run build你应该 dist/index.js 之后。
重要提示:在MCP客户端中, 使用绝对路径 到 dist/index.js (不是 ./dist/index.js),因为客户端通常使用自己的工作目录启动服务器。
要快速获得绝对路径:
echo "$(pwd)/dist/index.js"MCP客户端设置
使用 JIRA_* 直接在MCP客户端中。
command:nodeargs:["/absolute/path/to/jira-mcp-by-msw/dist/index.js"]env:添加您的JIRA_*变量workingDirectory:可选(可以为空)
如果您的客户端只有一个“命令行”字段,而不是 command + args,使用:
node /absolute/path/to/jira-mcp-by-msw/dist/index.js
Codex应用程序(UI)示例(白痴证明/Idioto Odporne)
在Codex App中,当您添加“自定义MCP”服务器时:
- 选择
STDIO. - 按如下方式填写字段:
- 名字: jira-focused (任何名字都可以) - 启动命令: node - 参数: /absolute/path/to/jira-mcp-by-msw/dist/index.js - 环境变量 (推荐):添加 JIRA_BASE_URL, JIRA_EMAIL, JIRA_API_TOKEN (可选 JIRA_SEVERITY_*) - 工作目录:可选
- 保存。
如何验证它是否真正开始:
- 检查客户端日志;此服务器打印
jira-focused-cloud-mcp is running on stdio成功启动时发送到stderr。
环境变量
必修的:
JIRA_BASE_URL
- 内容:Jira Cloud网站URL,例如。 https://your-domain.atlassian.net (没有尾随斜线)。 - Where:浏览器中的Jira站点地址。
- 身份验证选项A(推荐用于Jira Cloud):
- JIRA_EMAIL - 内容:用于身份验证的Atlassian帐户电子邮件。 - JIRA_API_TOKEN - 什么:在Atlassian生成的API令牌。 - 哪里: https://id.atlassian.com/manage-profile/security/api-tokens
- 身份验证选项B:
- JIRA_AUTH_HEADER - 内容:满 Authorization 标头值。 - 例子: Basic 或 Bearer .
可选:
JIRA_REQUEST_TIMEOUT_MS
- What:请求超时(毫秒)。 - 原因:保护MCP客户端免受挂起的Jira呼叫的影响。 - 违约: 20000
JIRA_SEVERITY_FIELD_ID
- 内容:Jira字段id读/写严重性,例如。 customfield_12345. - 原因:许多Jira项目没有内置的严重性字段;这个命令告诉服务器要使用哪个字段。 - 哪里: /rest/api/3/field 列表(见上面的命令)。
JIRA_SEVERITY_JQL_FIELD
- 内容:JQL筛选器中使用的字段标识符 jira_search_issues. - 违约: JIRA_SEVERITY_FIELD_ID,否则 severity. - 典型值: - customfield_12345 (如果严重性是自定义字段,建议使用) - severity (仅当您的Jira实例支持将其作为JQL字段时)
JIRA_SEVERITY_VALUE_TYPE
- 内容:如何在设置/更新问题时发送严重性。 - 违约: option - 价值观: - option:用于选择列表字段(发送 { value: "..." }) - string:用于自由文本字段(发送 "...") - number:用于数字字段(发送 123)
验证身份(可选)
curl -sS -u "${JIRA_EMAIL}:${JIRA_API_TOKEN}" \
"${JIRA_BASE_URL}/rest/api/3/myself" | head执行身份和密钥权限
重要身份规则:
- MCP服务器没有自己的Jira标识。
- 代理根据提供的凭据以Jira用户的身份执行Jira操作(
JIRA_EMAIL+JIRA_API_TOKEN,或JIRA_AUTH_HEADER). - 权限、问题安全性、工作流规则和审计跟踪都是针对该用户进行评估的。
要验证的关键权限:
- 对于
jira_get_issue,jira_search_issues,jira_search_issues_by_jql,jira_project_baseline
- 浏览项目和问题可见性(包括问题安全级别)。
- 对于
jira_project_assignable_users
- 浏览用户和组(全局Jira权限),以及可分配范围的项目可见性。
- 对于
jira_create_issue
- 在目标项目中创建问题。
- 对于
jira_update_issue
- 编辑问题。
- 对于
jira_transition_issue
- 过渡问题。
- 对于
jira_get_issue_workflow
- 浏览问题的项目和转换可见性。
- 对于
jira_add_comment
- 添加评论。
- 对于
jira_list_issue_link_types
- 浏览与问题链接类型相关的Jira配置。
- 对于
jira_link_issue
- 链接问题。
- 对于
jira_set_issue_parent
- 编辑问题和权限,以更改Jira允许的父层次结构。
- 对于
jira_list_sprints
- 访问Scrum板及其冲刺。
- 对于
jira_assign_issue_to_sprint
- 编辑问题和权限,以管理董事会上的sprint成员资格(通常是管理sprint)。
跑
发展:
npm run dev生产(编译):
npm run build
npm startMCP客户端配置示例(复制/粘贴)
MCP配置示例(stdio):
{
"mcpServers": {
"jira-focused": {
"command": "node",
"args": ["/absolute/path/to/jira-mcp-by-msw/dist/index.js"],
"env": {
"JIRA_BASE_URL": "https://your-domain.atlassian.net",
"JIRA_EMAIL": "you@example.com",
"JIRA_API_TOKEN": "",
"JIRA_SEVERITY_FIELD_ID": "customfield_12345",
"JIRA_SEVERITY_JQL_FIELD": "customfield_12345",
"JIRA_SEVERITY_VALUE_TYPE": "option"
}
}
}
}工具合同(简称)
jira_get_issue
输入:
issueKeyskipComments(可选,默认false)loadOnlyLast3Comments(可选,默认true;忽略时skipComments=true)descriptionFormat(可选:plain_text|adf,默认值plain_text)
输出:
- 一个关注的问题对象包括:
- url (可点击Jira问题链接) - assignee (id, name,可选 email) - reporter (id, name,可选 email) - labels - description 按照要求的格式 - parent, subtasks, linkedIssues (每个都有自己的 url) - comments (纯文本正文) - commentsMeta (mode, total, returned)
- 使用
descriptionFormat=adf仅当需要精确的富格文本结构时
jira_create_issue
输入:
- 必修的:
projectKey,issueType,summary - 可选:
description,descriptionFormat,fixVersions,affectedVersions,labels,priority,severity,assignee,parentIssueKey assignee接受Jira帐户ID、确切的显示名称或确切的电子邮件labels是否设置了要在创建时写入的完整标签parentIssueKey当Jira问题类型和项目配置允许时,创建子任务/子任务关系
描述方式:
- 如果
descriptionFormat省略或设置为plain_text,description必须是字符串 - 如果
descriptionFormat是adf,description必须是ADF JSON文档(或其JSON字符串) - 保持
plain_text作为代币效率的默认值;切换到adf仅用于丰富的格式保存
行为:
- 产生问题
- 状态更改是有意的 不 创造的一部分;使用
jira_transition_issue创建后需要工作流移动时
jira_update_issue
输入:
- 必修的:
issueKey - 可选更新:
summary,description,descriptionFormat,fixVersions,affectedVersions,labels,priority,severity,assignee assignee接受Jira帐户ID、确切的显示名称或确切的电子邮件;使用null清除labels替换当前标签集;使用[]清除- 返回问题的可选标志:
skipComments,loadOnlyLast3Comments
描述方式:
- 如果
descriptionFormat省略或设置为plain_text,description是纯文本字符串 - 如果
descriptionFormat是adf,description必须是ADF JSON文档(或其JSON字符串) - 使用
description: null要清楚描述 - 保持
plain_text作为代币效率的默认值;使用adf只有当必须保留丰富的格式时
行为:
- 通过Jira更新问题字段
Edit issue - 状态更改是有意的 不 部分更新;使用
jira_transition_issue - 冲刺任务是有意的 不 在这里完成(Jira在许多设置中通过问题编辑忽略sprint更新);使用
jira_assign_issue_to_sprint
jira_transition_issue
输入:
- 必修的:
issueKey,toStatus - 返回问题的可选标志:
skipComments,loadOnlyLast3Comments - 可选:
descriptionFormat(plain_text|adf,默认值plain_text)
行为:
- 仅应用工作流转换(专用工具)
- 返回转换结果+焦点问题
- 如果目标转换不可用或Jira拒绝它,则返回MCP工具错误(
isError: true)具有当前状态、时间戳和可用转换
jira_get_issue_workflow
输入:
- 必修的:
issueKey
输出:
- 一个问题的运行时工作流信息:
- 当前状态 - 问题类型 - 父母 - 问题更新时间戳 - 上次检测到的状态更改时间戳 - Jira目前为该问题提供的确切转换
使用此工具之前 jira_transition_issue 当您希望对特定工单上的工作流移动进行精确的预检时。
jira_add_comment
输入:
issueKeybody(纯文本)
行为:
- 添加Jira注释作为ADF(从纯文本转换而来)
- 以焦点形状返回创建的评论
jira_list_issue_link_types
输入:
- 没有输入
输出:
- 此实例的可用Jira问题链接关系:
- name - inward - outward - 可选的 id
使用此工具在调用之前发现有效的关系标签 jira_link_issue.
jira_link_issue
输入:
issueKeytargetIssueKeyrelation(例如blocks,is blocked by,relates to,duplicates)- 可选的
comment
行为:
- 使用业务关系标签创建问题链接
- 返回规范化关系、链接类型、方向和可点击的问题URL(
issueUrl,targetIssueUrl)
jira_set_issue_parent
输入:
- 必修的:
issueKey - 必修的:
parentIssueKey或null - 可选响应控件:
skipComments,loadOnlyLast3Comments,descriptionFormat
行为:
- 当Jira允许时,为问题设置父关系
- 使用
parentIssueKey: null澄清关系 - 返回刷新的焦点问题数据,包括结果
parent
jira_project_baseline
输入:
projectKey
输出:
- 项目信息
- 问题类型(带文本描述)
- 优先级(id+名称+描述)
- 版本(仅未发布且未存档)
- 可分配的顶级用户(15个,仅限活动用户),按过去60天分配的不同问题数量排名:
- id (Jira帐户ID) - name (显示名称) - email (可以是 null 当被Atlassian隐私设置隐藏时) - assignedIssuesLast60Days (排名得分) - 如果在扫描的60天窗口中没有观察到受让人转换事件, integrity.sections 标记 assignableUsers 作为 partial 带有明确的信息(不回退到当前受让人)
- 严重性上下文:
- 是否配置了严重性 - 配置字段id/JQL字段/值类型 - 允许使用带有文本描述的严重性选项(当Jira元数据提供这些选项时)
- 业务字段的字段配置文件(
summary,description,fixVersions,affectedVersions,labels,priority,severity) - Scrum板上的活动冲刺,每个板上都有上下文描述文本(目标/状态/日期/板)
- 每个问题类型的工作流程:
- 紧凑状态列表 - 紧凑的 from -> to 过渡列表(面向业务) - 覆盖率指标(有多少状态有样本问题/转换)
integrity:
- status: complete 或 partial - sections:每节状态 priorities, versions, assignableUsers, severity, fieldProfile, activeSprints, workflowStatuses, workflowTransitions - 每个部分报告 state (ok | partial | unavailable)以及机器可读的消息
notes:
- 仅供参考 - 不用于隐藏丢失的合同数据
工作流转换注意事项:
- Jira不会在不提取大型工作流负载的情况下为项目公开一个小的“权威转换图”。
- 此服务器推断紧凑型
from -> to按状态列出最近更新的问题的采样转换。 - 覆盖率指标可帮助您了解该问题类型的推断图的完整程度。
jira_project_assignable_users
输入:
- 必修的:
projectKey - 必修的:
maxResults(1..200) - 可选:
startAt(默认分页偏移量0)
输出:
- 紧凑型项目的活动可分配用户:
- id (Jira帐户ID) - name (显示名称) - email (可以是 null)
- 元数据:
projectKey,activeOnly,maxResults,startAt - Jira Cloud仅从前1000个用户窗口返回可分配的用户;页面包含的行数可能少于
maxResults - 此工具返回分页列表;当基线前15名不包括您需要的用户时使用它
jira_list_sprints
输入:
- 必修的:
projectKey - 可选:
state(active|future|closed|all,默认值active) - 可选:
boardName(精确的板名过滤器) - 可选:
maxResultsPerBoard(1..50,默认值20)
输出:
- 带有上下文丰富字段的sprint列表:
- id, name, state - description (人性化文本) - goal, startDate, endDate - board (id, name)
jira_assign_issue_to_sprint
输入:
- 必修的:
issueKey - 选择一个目标选择器:
- sprintId (推荐) - sprintName (服务器按名称解析;如果不明确,则出错)
- 可选消歧
sprintName:projectKey,boardName - 可选响应控件:
loadIssueAfterAssign,skipComments,loadOnlyLast3Comments,descriptionFormat
行为:
- 使用Jira敏捷端点分配问题:
POST /rest/agile/1.0/sprint/{sprintId}/issue - 防止无效的目标(缺少选择器、模糊的sprint名称、关闭的sprint)
- 可以在成功分配后返回刷新的焦点问题
ADF快速示例(简短)
仅当您需要保留丰富的格式时才使用这些。否则保留 plain_text 以降低令牌使用率。
在ADF中获取问题:
{
"issueKey": "PROJ-123",
"descriptionFormat": "adf"
}使用ADF描述创建问题:
{
"projectKey": "PROJ",
"issueType": "Task",
"summary": "Formatted note",
"descriptionFormat": "adf",
"description": {
"type": "doc",
"version": 1,
"content": [
{
"type": "paragraph",
"content": [{ "type": "text", "text": "Hello from ADF" }]
}
]
}
}使用ADF描述更新问题:
{
"issueKey": "PROJ-123",
"descriptionFormat": "adf",
"description": {
"type": "doc",
"version": 1,
"content": [
{
"type": "paragraph",
"content": [{ "type": "text", "text": "Updated formatted content" }]
}
]
}
}jira_search_issues
输入:
- 聚焦滤光片(
projectKey,summaryContains,statuses,priorities、版本、严重性等) - 可选原始
jql
输出:
- 仅关注问题列表(没有完整的Jira字段有效载荷),包括
url和parent/subtasks/linkedIssues带有URL nextPageToken
jira_search_issues_by_jql
输入:
- 必修的:
jql(原始JQL)
输出:
- 仅限严格、轻量级的问题列表:
- key - url - summary - fixVersions - sprints - assignee - reporter - priority - status
- 硬安全帽:最多50件退货
- 如果查询返回的值超过50,则响应包括:
- truncated: true - notice: "Results truncated because results exceeded 50!"
为什么?
- 这为代理保持了广泛的JQL发现上下文的安全
- 使用
jira_get_issue检查细节(包括description)针对特定问题密钥
示例输入:
{
"jql": "project = PROJ AND statusCategory != Done ORDER BY updated DESC"
}示例输出(\50个结果):
{
"jql": "project = PROJ ORDER BY updated DESC",
"issues": ["...first 50 issues only..."],
"truncated": true,
"notice": "Results truncated because results exceeded 50!",
"mode": "enhanced"
}如果JQL无效,Jira将返回一个API错误(例如语法错误),该工具将其作为MCP工具错误响应返回,而不是使服务器进程崩溃。
备注
- 吉拉云
description存储为ADF。 - 默认模式为
plain_text(用于低令牌成本和更简单的提示)。 - 您可以选择使用原始ADF
descriptionFormat: "adf"在jira_get_issue,jira_create_issue,以及jira_update_issue当需要保留丰富的格式时。 - Jira评论也是云API中的ADF;服务器在工具边界返回/发送纯文本。
- 默认的注释加载模式是最后3条注释,以保护LLM上下文。
- 在许多项目中,严重性不是Jira系统的标准字段;在env中配置自定义字段映射。
错误处理
此服务器遵循MCP工具错误模型:
- 格式错误的MCP请求和未知工具是协议级错误
- Jira/API失败、验证失败和业务规则失败作为MCP工具执行错误返回,带有
isError: true - 工具执行错误包括客户端或代理可以用来安全重试的可操作有效负载
特别是,工作流转换失败将作为工具执行错误返回,而不是作为带有业务警告的成功工具结果返回。当转换失败时,服务器会返回该问题的最新诊断,包括当前状态、时间戳和当前可用的转换。
故障排除
401 Unauthorized:错误JIRA_EMAIL/JIRA_API_TOKEN,或错误JIRA_BASE_URL.403 Forbidden:令牌用户缺乏权限(浏览项目、转换问题、链接问题等)。- 严重性更新失败:已设置
JIRA_SEVERITY_FIELD_ID并确保JIRA_SEVERITY_VALUE_TYPE与字段类型匹配。 - 链接创建失败,出现“未知链接关系”:请使用Jira实例中存在的关系标签(例如。
blocks,is blocked by,relates to).服务器将这些标签映射到Jira链接类型。 - Sprint不会通过问题更新进行更改:这在许多Jira设置中都是意料之中的。使用
jira_assign_issue_to_sprint(敏捷API),而不是jira_update_issue.
