关于 Atlassian Attachments
Atlassian Attachments 是用于 Jira Cloud 附件文件操作的 MCP 服务,适合需要在 Jira 与本地磁盘间传输文件的团队。它补充官方 Atlassian MCP 服务未覆盖的附件传输,并可解析 ADF 媒体引用。
主要功能
- 01按 ID 下载附件到本地
- 02将本地文件上传到 Jira 问题
- 03解析附件的 ADF mediaId
- 04按 ID 永久删除附件
适用场景
- 01把 Jira 截图或文件保存到本地
- 02将本地报告附加到 Jira 问题
- 03为描述或评论构建媒体引用
- 04清理不再需要的 Jira 附件
MCP 相关
作为 MCP 服务,它向 MCP 客户端提供 Jira Cloud 附件下载、上传、引用解析和删除工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx mcp-atlassian-attachmentsATLASSIAN_SITE_URLAtlassian Cloud site URL, for example https://yourorg.atlassian.net. Must be HTTPS. Can also be set in ~/.config/mcp-atlassian-attachments/config.json.ATLASSIAN_EMAILEmail address used for Atlassian Cloud Basic auth. Can also be set in ~/.config/mcp-atlassian-attachments/config.json.ATLASSIAN_API_TOKEN密钥Atlassian Cloud API token. Used as the password in Basic auth. Can also be set in ~/.config/mcp-atlassian-attachments/config.json.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
4收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| filename | any | 否 | 省略时使用 Jira 元数据中的文件名。 |
| overwrite | boolean | 否 | 为 true 时替换现有文件。为 false 时,如果文件已存在则失败。 |
| output_dir | string | 是 | 保存文件的本地目录。如果目录不存在,则自动创建。 |
| attachment_id | string | 是 | Jira 附件 ID,例如 439535。 |
详细介绍
MCP Jira 附件
一个 Model Context Protocol (MCP) 服务,可按附件 ID 将 Jira Cloud 附件下载到本地磁盘,并将本地文件上传为 Jira 问题的附件。
官方 Atlassian MCP 服务的补充工具。 官方 Atlassian MCP 服务涵盖搜索、问题管理和内容操作,但无法在 Jira 与本地磁盘之间传输附件文件。本服务填补了这一空缺。
要求: Python 3.13+、Atlassian Cloud 账户,以及至少具有 read:jira-work 范围的 API 令牌。上传还需要 write:jira-work。
身份验证
建议使用范围受限的令牌,将访问权限限制在所需的权限范围内。
注意: 细粒度的
read:attachment:jira范围并不足够——Jira 的附件元数据端点(/rest/api/3/attachment/{id})需要read:jira-work才能解析问题级权限。经典(未限定范围的)API 令牌也可使用。
创建 API 令牌
- 前往 id.atlassian.com/manage-profile/security/api-tokens
- 点击 Create API token
- 选择 "Create API token with scopes",并选择
read:jira-work(若要上传,则添加write:jira-work),或选择 "Classic API token" 以获取完整访问权限 - 复制生成的令牌
快速开始
使用 MCP Inspector 是试用此服务最快的方式。设置三个必需的环境变量并运行:
使用已发布的程序包(无需克隆):
ATLASSIAN_SITE_URL=https://yourorg.atlassian.net \
[email protected] \
ATLASSIAN_API_TOKEN=your-api-token \
npx -y @modelcontextprotocol/inspector@latest uvx mcp-atlassian-attachments
使用本地克隆:
ATLASSIAN_SITE_URL=https://yourorg.atlassian.net \
[email protected] \
ATLASSIAN_API_TOKEN=your-api-token \
npx -y @modelcontextprotocol/inspector@latest uv run mcp-atlassian-attachments
配置
设置环境变量或创建配置文件。环境变量优先。
环境变量:
export ATLASSIAN_SITE_URL="https://yourorg.atlassian.net"
export ATLASSIAN_EMAIL="[email protected]"
export ATLASSIAN_API_TOKEN="your-api-token"
配置文件(~/.config/mcp-atlassian-attachments/config.json):
{
"site_url": "https://yourorg.atlassian.net",
"email": "[email protected]",
"api_token": "your-api-token"
}
工具
| 工具 | 说明 | 必需参数 |
|---|---|---|
download_jira_attachment | 按 ID 下载 Jira 附件。 | attachment_id、output_dir |
upload_jira_attachment | 将本地文件上传为 Jira 问题的附件。 | issue_key、file_path |
get_jira_attachment_reference | 将现有附件解析为 ADF 媒体节点。 | attachment_id |
delete_jira_attachment | 按 ID 永久删除附件。 | attachment_id |
download_jira_attachment
| 参数 | 类型 | 说明 |
|---|---|---|
attachment_id | string | Jira 附件 ID |
output_dir | string | 保存文件的本地目录。如果目录不存在,会自动创建。 |
filename | string(可选) | 覆盖文件名。省略时使用元数据中的文件名。 |
overwrite | bool(可选) | 替换现有文件。默认为 false。 |
返回:
{
"product": "jira",
"attachmentId": "439535",
"filename": "screenshot.png",
"mimeType": "image/png",
"size": 496724,
"path": "/your/output/dir/screenshot.png",
"attachmentUrl": "https://yourorg.atlassian.net/rest/api/3/attachment/content/439535"
}
upload_jira_attachment
| 参数 | 类型 | 说明 |
|---|---|---|
issue_key | string | Jira 问题键或 ID,例如 PROJ-123 |
file_path | string | 要上传的本地文件路径。文件必须存在。 |
filename | string(可选) | 在 Jira 中使用的名称。省略时使用本地文件名。 |
返回:
{
"product": "jira",
"issueKey": "PROJ-123",
"attachmentId": "600100",
"filename": "report.png",
"mimeType": "image/png",
"size": 24581,
"path": "/your/local/dir/report.png",
"attachmentUrl": "https://yourorg.atlassian.net/rest/api/3/attachment/content/600100",
"mediaId": "6df94659-caa7-4561-bbe3-6384ec534bba"
}
每次调用都会添加一个新附件;Jira 不会替换同名文件。上传文件超过站点附件大小限制时会失败,并返回 413。
get_jira_attachment_reference
| 参数 | 类型 | 描述 |
|---|---|---|
attachment_id | string | Jira 附件 ID |
只读。返回已附加到某个 issue 的附件的 mediaId:
{
"product": "jira",
"attachmentId": "439535",
"filename": "screenshot.png",
"mimeType": "image/png",
"size": 496724,
"attachmentUrl": "https://yourorg.atlassian.net/rest/api/3/attachment/content/439535",
"mediaId": "6df94659-caa7-4561-bbe3-6384ec534bba"
}
上传后无需调用此工具——upload_jira_attachment 已会返回 mediaId,因此嵌入附件无需额外调用。
delete_jira_attachment
| 参数 | 类型 | 描述 |
|---|---|---|
attachment_id | string | 要永久删除的 Jira 附件 ID |
需要 write:jira-work。删除前会读取元数据,因此结果会报告已删除的内容;若 ID 不存在,则会直接报错,不会尝试执行任何操作:
{
"product": "jira",
"attachmentId": "481718",
"filename": "delete-me.txt",
"mimeType": "text/plain",
"size": 31,
"deleted": true
}
无法撤销。 Jira 会直接删除文件,再次使用同一 ID 调用会失败并返回
404。删除操作不会清理引用。 如果附件嵌入在描述或评论中,ADF 媒体节点会原样保留,变成悬空引用——已在实际运行的 issue 上验证。如果删除了被引用的文件,请自行移除该节点。
在描述或评论中引用附件
上传文件会将其附加到 issue,但不会让文件内嵌显示在描述或评论中。要渲染文件,需要使用 ADF 媒体节点——该节点通过文件的 Media Services UUID 标识文件,而不是数字附件 ID:
{
"type": "mediaSingle",
"attrs": { "layout": "center" },
"content": [
{
"type": "media",
"attrs": {
"type": "file",
"id": "6df94659-caa7-4561-bbe3-6384ec534bba",
"collection": "",
"alt": "report.png"
}
}
]
}
Jira 没有任何附件元数据端点会公开此 UUID,因此本服务会解析它:GET /rest/api/3/attachment/content/{id} 会返回一个 303,指向 https://api.media.atlassian.com/file/{mediaId}/binary。读取 Location 标头而不跟随重定向,即可在不产生下载开销的情况下获取 UUID。文件一经附加,UUID 就会存在,并不取决于附件是否在任何位置被引用。
因此,这两个工具都会返回 mediaId。将节点写入 issue 的操作特意留给 Jira 内容工具(例如官方 Atlassian MCP 服务)处理;该服务的 addCommentToJiraIssue 和 editJiraIssue 接受 contentFormat: "adf"。本服务负责移动文件,不会编辑 issue 内容:
upload_jira_attachment→ 从结果中获取mediaId- 发布评论,其 ADF 正文包含由该值构建的媒体节点:
{
"version": 1,
"type": "doc",
"content": [
{ "type": "paragraph", "content": [{ "type": "text", "text": "Latest run:" }] },
{ "type": "mediaSingle", "attrs": { "layout": "center" }, "content": [ "...the media node..." ] }
]
}
对于描述,请读取现有 ADF,追加节点,然后将整个文档写回——PUT /rest/api/3/issue/{key} 会替换该字段,而不是追加内容。
注意:
- 单独的
media节点不会被渲染;必须将其包装在mediaSingle(单个文件)、mediaGroup(文件卡片列表)或mediaInline(内嵌标签)中。 - 对于 Jira issue 附件,
collection的值为""。 - 媒体节点上的可选
width/height可设置固有像素尺寸,但仅在mediaSingle中生效。 mediaId仅尽力返回:如果无法读取重定向,它会返回null,上传本身仍会成功。
更简单的替代方案:v2 wiki 标记
较旧的 v2 端点仍接受 wiki 标记,并会在服务端将其转换为 ADF,按文件名解析附件,因此不需要媒体 UUID:
POST /rest/api/2/issue/PROJ-123/comment
{ "body": "See attached: !report.png|thumbnail!" }
Jira 会将其存储为规范的 media 节点,并填入正确的 UUID。截至 2026 年 8 月,已确认在 Jira Cloud 上可用。
有两点行为需要了解,均已通过实时 issue 验证:
- 尺寸是固定的占位值,并非图片的实际尺寸。 无论图片尺寸如何,转换过程始终写入
width: 200, height: 183——一个 64x48 的 PNG 和一个 8x8 的 PNG,返回的尺寸都是 200x183。!file|width=300!会设置宽度,但高度仍为 183,因此除非自行编写 ADF,否则宽高比会不正确。 - 同名文件会解析为最早上传的文件。 如果有两个附件都名为
ambiguous.png,!ambiguous.png!会解析到最先上传的那个。使用相同名称重新上传以“更新”图片时,显示的仍会是旧文件。
如果需要明确指定,请优先使用 mediaId:它不会因重名而产生歧义,可设置真实尺寸,适用于 v3/ADF(官方 Atlassian MCP 服务会使用此方式写入),且不依赖 Atlassian 可能最终弃用的旧版路径。
MCP 主机配置
将以下内容添加到 MCP 主机的配置文件中。Cursor(.cursor/mcp.json)、Claude Desktop(claude_desktop_config.json)和 Claude Code(.claude.json)使用的 JSON 相同。
{
"mcpServers": {
"atlassian": {
"command": "uvx",
"args": ["mcp-atlassian-attachments"],
"env": {
"ATLASSIAN_SITE_URL": "https://yourorg.atlassian.net",
"ATLASSIAN_EMAIL": "[email protected]",
"ATLASSIAN_API_TOKEN": "your-api-token"
}
}
}
}
安全性
ATLASSIAN_API_TOKEN永远不会被记录到日志中,也不会包含在错误消息中。- 计算得出的
Authorization标头绝不会暴露在工具输出或错误中。 - 文件写入仅限于提供的
output_dir。 - 文件名会经过清理,以防止路径遍历;下载时和发送给 Jira 时都会进行清理。
- 上传时只读取
file_path指定的文件,不会发送其他内容。
测试
uv run pytest tests/ -v
路线图
download_confluence_attachment_tool— Confluence Cloud 使用不同的 API(/wiki/api/v2/)和不同的标识符模型。计划在未来版本中推出。
许可证
MIT。请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。