fix(confluence): use v1 REST endpoint for attachment downloads on Cloud#1369
Open
pshiko wants to merge 1 commit into
Open
fix(confluence): use v1 REST endpoint for attachment downloads on Cloud#1369pshiko wants to merge 1 commit into
pshiko wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a Confluence Cloud workaround for Atlassian’s removal of legacy /download/attachments/... links by optionally rewriting attachment download URLs to the v1 REST download endpoint, with config/env/documentation updates and unit tests.
Changes:
- Introduces
ConfluenceConfig.attachment_download_use_v1withCONFLUENCE_ATTACHMENT_DOWNLOAD_USE_V1env support. - Adds
_resolve_attachment_download_url()to rewrite legacy download links to/rest/api/content/{id}/child/attachment/{aid}/download(auto-enabled on Cloud). - Updates server handlers + docs and adds unit tests for the new URL resolution behavior.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/confluence/test_attachments.py | Adds unit tests covering legacy vs v1-rewritten attachment download URLs. |
| src/mcp_atlassian/servers/confluence.py | Switches attachment/image download URL handling to the new resolver method. |
| src/mcp_atlassian/confluence/config.py | Adds config + env var parsing for v1 download rewriting. |
| src/mcp_atlassian/confluence/attachments.py | Implements the download URL resolver and uses it in attachment downloads. |
| docs/troubleshooting.mdx | Documents 401 failures for legacy Cloud download links and the workaround/env var. |
| docs/tools/confluence-attachments.mdx | Notes Cloud download behavior and override env var in tool docs. |
| docs/configuration.mdx | Documents CONFLUENCE_ATTACHMENT_DOWNLOAD_USE_V1. |
| .env.example | Adds example configuration and explanation for the new env var. |
6ab219e to
179e913
Compare
179e913 to
9fa97f5
Compare
Confluence Cloud removed the legacy /download/attachments/{id}/{file} endpoint (CHANGE-2735) that an attachment's _links.download still points to; it now returns 401 for API-token / scoped-token auth while metadata endpoints keep working. This breaks confluence_get_page_images and the attachment download tools (0 downloaded, all "Fetch failed").
Resolve attachment download URLs to the v1 REST endpoint /rest/api/content/{cid}/child/attachment/{aid}/download, which still authenticates correctly. Controlled by CONFLUENCE_ATTACHMENT_DOWNLOAD_USE_V1: unset = auto (v1 on Cloud, legacy link on Server/DC), true = always v1, false = always legacy.
9fa97f5 to
c2bb811
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Attachment/image downloads fail on Confluence Cloud:
confluence_get_page_imagesreturnsdownloaded: 0(every imageFetch failed) andconfluence_download_attachment/confluence_download_content_attachmentsreturn 401.Root cause: these tools follow the attachment's
_links.download(and the v2 attachmentdownloadLink), which points to the legacy/wiki/download/attachments/{id}/{file}path. Atlassian deprecated and removed that endpoint platform-wide on Cloud (changelog CHANGE-2735 — "Deprecation of /download/attachments/ APIs"); it now returns 401 for API-token / scoped-token auth while metadata endpoints keep working. The v2 Attachment API is metadata-only and itsdownloadLinkis the same removed/download/path, so it is not a replacement for the binary.This resolves attachment download URLs to the v1 REST endpoint
/rest/api/content/{cid}/child/attachment/{aid}/download, which is not in the deprecation list and authenticates correctly with the same credentials.Refs: https://community.developer.atlassian.com/t/deprecation-of-download-attachments-apis/94448
Fixes: #1368
Changes
_resolve_attachment_download_url()inconfluence/attachments.pythat resolves an attachment download link, optionally rewriting it to the v1 REST endpoint (parses the content id from the legacy link, or accepts it explicitly).confluence_get_page_images,confluence_download_attachment,confluence_download_content_attachments, and thedownload_content_attachmentsmixin.CONFLUENCE_ATTACHMENT_DOWNLOAD_USE_V1(ConfluenceConfig.attachment_download_use_v1, tri-state): unset = auto (v1 on Cloud, legacy link on Server/DC),true= always v1,false= always the legacy link. Default preserves existing Server/DC behaviour..env.example,docs/configuration.mdx, a troubleshooting entry, and a note on the attachment tools._resolve_attachment_download_url(auto Cloud / auto Server-DC / explicit true / explicit false / explicit content_id / missing attachment_id fallback).Testing
against a real Confluence Cloud page — get_page_images went from 0 downloaded to all images, and the v1 URL returns the image bytesTest result
uv run pytest→ 2584 passed, 161 skipped.pre-commit(ruff-format, ruff, mypy) andpyrightare clean for the changed files.Checklist