Skip to main content
Glama

MCP-JIRA-Python Server

by Kallows
get_issue_attachment.py6.04 kB
from typing import List from mcp.types import Tool, TextContent from .base import BaseTool import os class GetIssueAttachmentTool(BaseTool): def get_tool_definition(self) -> Tool: return Tool( name="get_issue_attachment", description="Download an attachment from a Jira issue to a local file. If neither attachmentId nor filename is provided, all attachments will be downloaded. Original filenames preserved.", inputSchema={ "type": "object", "properties": { "issueKey": { "type": "string", "description": "Key of the issue containing the attachment" }, "attachmentId": { "type": "string", "description": "ID of the attachment to download (optional if filename is provided)" }, "filename": { "type": "string", "description": "Name of the attachment file to download (optional if attachmentId is provided)" }, "outputPath": { "type": "string", "description": "Local path where to save the downloaded file (optional, defaults to current directory with original filename)" } }, "required": ["issueKey"] } ) async def execute(self, arguments: dict) -> List[TextContent]: issue_key = arguments.get("issueKey") attachment_id = arguments.get("attachmentId") filename = arguments.get("filename") output_path = arguments.get("outputPath", ".") if not issue_key: raise ValueError("issueKey is required") # If neither attachment_id nor filename is provided, download all attachments download_all = not attachment_id and not filename # If no output path specified, use current directory but maintain original filename if not output_path: output_path = "." try: # Create output directory if it doesn't exist os.makedirs(os.path.abspath(output_path), exist_ok=True) # If attachment_id is provided, download directly if attachment_id: attachment = self.jira.attachment(attachment_id) file_path = os.path.join(output_path, attachment.filename) # Download the content attachment_data = attachment.get() # Write to file with open(file_path, 'wb') as f: f.write(attachment_data) return [TextContent( type="text", text=str({ "message": "Attachment downloaded successfully", "filename": attachment.filename, "path": file_path, "size": attachment.size }) )] # Get issue with attachments issue = self.jira.issue(issue_key, expand='attachments') if not hasattr(issue.fields, 'attachment') or not issue.fields.attachment: raise ValueError(f"No attachments found in issue {issue_key}") # If download_all is True, download all attachments if download_all: downloaded_files = [] for attachment in issue.fields.attachment: file_path = os.path.join(output_path, attachment.filename) # Download the content attachment_data = attachment.get() # Write to file with open(file_path, 'wb') as f: f.write(attachment_data) downloaded_files.append({ "filename": attachment.filename, "path": file_path, "size": attachment.size, "id": attachment.id }) return [TextContent( type="text", text=str({ "message": f"Downloaded {len(downloaded_files)} attachments successfully", "files": downloaded_files, "outputPath": output_path }) )] # If filename is provided, find the specific attachment found = False for attachment in issue.fields.attachment: if attachment.filename == filename: file_path = os.path.join(output_path, attachment.filename) # Download the content attachment_data = attachment.get() # Write to file with open(file_path, 'wb') as f: f.write(attachment_data) found = True return [TextContent( type="text", text=str({ "message": "Attachment downloaded successfully", "filename": attachment.filename, "path": file_path, "size": attachment.size, "id": attachment.id }) )] if not found: raise ValueError(f"Attachment '{filename}' not found in issue {issue_key}") except Exception as e: raise Exception(f"Failed to download attachment: {str(e)}")

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Kallows/mcp-jira-python'

If you have feedback or need assistance with the MCP directory API, please join our Discord server