From 714ef42a6e270bc10b73b4444ec4bb51374c49f4 Mon Sep 17 00:00:00 2001 From: Caian Ertl Date: Wed, 24 Jun 2026 14:50:03 -0300 Subject: [PATCH] fix(attachments): strip MIME parameters --- internal/mcpserver/server_test.go | 5 +++++ internal/mcpserver/tools_attachments.go | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/internal/mcpserver/server_test.go b/internal/mcpserver/server_test.go index 0a3062e..c4edd1e 100644 --- a/internal/mcpserver/server_test.go +++ b/internal/mcpserver/server_test.go @@ -131,3 +131,8 @@ func TestWorkspaceInfoDoesNotEchoToken(t *testing.T) { require.NotContains(t, text.Text, "X-API-Key") require.Contains(t, text.Text, "ws") } + +func TestAttachmentMimeTypeStripsParameters(t *testing.T) { + require.Equal(t, "text/plain", attachmentMimeType("notes.txt")) + require.Equal(t, "application/octet-stream", attachmentMimeType("archive.unknownext")) +} diff --git a/internal/mcpserver/tools_attachments.go b/internal/mcpserver/tools_attachments.go index 951fac8..9e8142e 100644 --- a/internal/mcpserver/tools_attachments.go +++ b/internal/mcpserver/tools_attachments.go @@ -135,10 +135,7 @@ func (s *Server) handleAttachmentUpload(ctx context.Context, req mcp.CallToolReq } size := info.Size() - mimeType := mime.TypeByExtension(filepath.Ext(path)) - if mimeType == "" { - mimeType = "application/octet-stream" - } + mimeType := attachmentMimeType(path) init, err := s.client.InitAttachmentUpload(ctx, projectID, issueID, displayName, &mimeType, &size) if err != nil { @@ -149,7 +146,7 @@ func (s *Server) handleAttachmentUpload(ctx context.Context, req mcp.CallToolReq return mcp.NewToolResultErrorFromErr("init payload", err), nil } - f, err := os.Open(path) //nolint:gosec // path is supplied by an MCP caller with file-system trust. + f, err := os.Open(path) // #nosec G304 -- path is supplied by an MCP caller with file-system trust. if err != nil { return mcp.NewToolResultErrorf("open file: %v", err), nil } @@ -227,6 +224,18 @@ func (s *Server) handleAttachmentRead(ctx context.Context, req mcp.CallToolReque return asTextResult(out) } +func attachmentMimeType(path string) string { + mimeType := mime.TypeByExtension(filepath.Ext(path)) + if mimeType == "" { + return "application/octet-stream" + } + mediaType, _, err := mime.ParseMediaType(mimeType) + if err != nil || mediaType == "" { + return mimeType + } + return mediaType +} + func parseInitPayload(init map[string]any) (assetID, uploadURL string, fields map[string]string, err error) { if v, ok := init["id"].(string); ok && v != "" { assetID = v