github.com/anthropics/anthropic-sdk-go@v1.70.1/mcp/mcp_test.go (about) 1 package mcp_test 2 3 import ( 4 "errors" 5 "testing" 6 7 "github.com/anthropics/anthropic-sdk-go/mcp" 8 mcpsdk "github.com/modelcontextprotocol/go-sdk/mcp" 9 ) 10 11 func TestToBlock_Text(t *testing.T) { 12 block, err := mcp.ToBlock(&mcpsdk.TextContent{Text: "hello world"}) 13 if err != nil { 14 t.Fatalf("unexpected error: %v", err) 15 } 16 if block.OfText == nil || block.OfText.Text != "hello world" { 17 t.Fatalf("expected text block with %q", "hello world") 18 } 19 } 20 21 func TestToBlock_Image(t *testing.T) { 22 for _, mimeType := range []string{"image/jpeg", "image/png", "image/gif", "image/webp"} { 23 t.Run(mimeType, func(t *testing.T) { 24 block, err := mcp.ToBlock(&mcpsdk.ImageContent{ 25 Data: []byte("raw bytes"), 26 MIMEType: mimeType, 27 }) 28 if err != nil { 29 t.Fatalf("unexpected error: %v", err) 30 } 31 if block.OfImage == nil || block.OfImage.Source.OfBase64 == nil { 32 t.Fatal("expected base64 image block") 33 } 34 if string(block.OfImage.Source.OfBase64.MediaType) != mimeType { 35 t.Fatalf("expected media_type %q, got %q", mimeType, block.OfImage.Source.OfBase64.MediaType) 36 } 37 }) 38 } 39 } 40 41 func TestToBlock_ImageUnsupportedMimeType(t *testing.T) { 42 _, err := mcp.ToBlock(&mcpsdk.ImageContent{MIMEType: "image/bmp"}) 43 var mcpErr *mcp.UnsupportedValueError 44 if !errors.As(err, &mcpErr) { 45 t.Fatalf("expected UnsupportedValueError, got %T: %v", err, err) 46 } 47 } 48 49 func TestToBlock_EmbeddedResource_Text(t *testing.T) { 50 block, err := mcp.ToBlock(&mcpsdk.EmbeddedResource{ 51 Resource: &mcpsdk.ResourceContents{URI: "file:///hello.txt", MIMEType: "text/plain", Text: "hello"}, 52 }) 53 if err != nil { 54 t.Fatalf("unexpected error: %v", err) 55 } 56 if block.OfDocument == nil || block.OfDocument.Source.OfText == nil { 57 t.Fatal("expected text document block") 58 } 59 if block.OfDocument.Source.OfText.Data != "hello" { 60 t.Fatalf("expected %q, got %q", "hello", block.OfDocument.Source.OfText.Data) 61 } 62 } 63 64 func TestToBlock_EmbeddedResource_Image(t *testing.T) { 65 block, err := mcp.ToBlock(&mcpsdk.EmbeddedResource{ 66 Resource: &mcpsdk.ResourceContents{URI: "file:///img.png", MIMEType: "image/png", Blob: []byte("binary")}, 67 }) 68 if err != nil { 69 t.Fatalf("unexpected error: %v", err) 70 } 71 if block.OfImage == nil { 72 t.Fatal("expected image block") 73 } 74 } 75 76 func TestToBlock_EmbeddedResource_PDF(t *testing.T) { 77 block, err := mcp.ToBlock(&mcpsdk.EmbeddedResource{ 78 Resource: &mcpsdk.ResourceContents{URI: "file:///doc.pdf", MIMEType: "application/pdf", Blob: []byte("%PDF")}, 79 }) 80 if err != nil { 81 t.Fatalf("unexpected error: %v", err) 82 } 83 if block.OfDocument == nil || block.OfDocument.Source.OfBase64 == nil { 84 t.Fatal("expected base64 document block") 85 } 86 } 87 88 func TestToBlock_Audio_Unsupported(t *testing.T) { 89 _, err := mcp.ToBlock(&mcpsdk.AudioContent{}) 90 var mcpErr *mcp.UnsupportedValueError 91 if !errors.As(err, &mcpErr) { 92 t.Fatalf("expected UnsupportedValueError, got %T", err) 93 } 94 } 95 96 func TestToBlock_ResourceLink_Unsupported(t *testing.T) { 97 _, err := mcp.ToBlock(&mcpsdk.ResourceLink{}) 98 var mcpErr *mcp.UnsupportedValueError 99 if !errors.As(err, &mcpErr) { 100 t.Fatalf("expected UnsupportedValueError, got %T", err) 101 } 102 } 103 104 func TestToBlock_NilResource(t *testing.T) { 105 _, err := mcp.ToBlock(&mcpsdk.EmbeddedResource{Resource: nil}) 106 if err == nil { 107 t.Fatal("expected error for nil resource") 108 } 109 } 110 111 func TestToMessage_User(t *testing.T) { 112 msg, err := mcp.ToMessage(&mcpsdk.PromptMessage{ 113 Role: "user", 114 Content: &mcpsdk.TextContent{Text: "hello"}, 115 }) 116 if err != nil { 117 t.Fatalf("unexpected error: %v", err) 118 } 119 if msg.Role != "user" { 120 t.Fatalf("expected role %q, got %q", "user", msg.Role) 121 } 122 if len(msg.Content) != 1 || msg.Content[0].OfText == nil { 123 t.Fatal("expected single text content block") 124 } 125 } 126 127 func TestToMessage_Assistant(t *testing.T) { 128 msg, err := mcp.ToMessage(&mcpsdk.PromptMessage{ 129 Role: "assistant", 130 Content: &mcpsdk.TextContent{Text: "reply"}, 131 }) 132 if err != nil { 133 t.Fatalf("unexpected error: %v", err) 134 } 135 if msg.Role != "assistant" { 136 t.Fatalf("expected role %q, got %q", "assistant", msg.Role) 137 } 138 } 139 140 func TestToMessage_UnsupportedContent(t *testing.T) { 141 _, err := mcp.ToMessage(&mcpsdk.PromptMessage{ 142 Role: "user", 143 Content: &mcpsdk.AudioContent{}, 144 }) 145 if err == nil { 146 t.Fatal("expected error for unsupported content") 147 } 148 } 149 150 func TestResourceToBlock_Text(t *testing.T) { 151 block, err := mcp.ResourceToBlock(&mcpsdk.ReadResourceResult{ 152 Contents: []*mcpsdk.ResourceContents{ 153 {URI: "file:///hello.txt", MIMEType: "text/plain", Text: "hello world"}, 154 }, 155 }) 156 if err != nil { 157 t.Fatalf("unexpected error: %v", err) 158 } 159 if block.OfDocument == nil || block.OfDocument.Source.OfText == nil { 160 t.Fatal("expected text document block") 161 } 162 if block.OfDocument.Source.OfText.Data != "hello world" { 163 t.Fatalf("expected %q, got %q", "hello world", block.OfDocument.Source.OfText.Data) 164 } 165 } 166 167 func TestResourceToBlock_NoMimeType(t *testing.T) { 168 block, err := mcp.ResourceToBlock(&mcpsdk.ReadResourceResult{ 169 Contents: []*mcpsdk.ResourceContents{{URI: "file:///data", Text: "plain data"}}, 170 }) 171 if err != nil { 172 t.Fatalf("unexpected error: %v", err) 173 } 174 if block.OfDocument == nil || block.OfDocument.Source.OfText == nil { 175 t.Fatal("expected text document block") 176 } 177 } 178 179 func TestResourceToBlock_SkipsUnsupportedSelectsSupported(t *testing.T) { 180 block, err := mcp.ResourceToBlock(&mcpsdk.ReadResourceResult{ 181 Contents: []*mcpsdk.ResourceContents{ 182 {URI: "file:///audio.mp3", MIMEType: "audio/mpeg"}, 183 {URI: "file:///notes.txt", MIMEType: "text/plain", Text: "notes"}, 184 }, 185 }) 186 if err != nil { 187 t.Fatalf("unexpected error: %v", err) 188 } 189 if block.OfDocument == nil || block.OfDocument.Source.OfText == nil || block.OfDocument.Source.OfText.Data != "notes" { 190 t.Fatal("expected text from second item") 191 } 192 } 193 194 func TestResourceToBlock_EmptyContents(t *testing.T) { 195 _, err := mcp.ResourceToBlock(&mcpsdk.ReadResourceResult{}) 196 var mcpErr *mcp.UnsupportedValueError 197 if !errors.As(err, &mcpErr) { 198 t.Fatalf("expected UnsupportedValueError, got %T", err) 199 } 200 } 201 202 func TestResourceToBlock_NoSupportedMimeType(t *testing.T) { 203 _, err := mcp.ResourceToBlock(&mcpsdk.ReadResourceResult{ 204 Contents: []*mcpsdk.ResourceContents{{URI: "file:///video.mp4", MIMEType: "video/mp4"}}, 205 }) 206 var mcpErr *mcp.UnsupportedValueError 207 if !errors.As(err, &mcpErr) { 208 t.Fatalf("expected UnsupportedValueError, got %T", err) 209 } 210 } 211 212 func TestResourceToBlock_ImageWithTextData_Error(t *testing.T) { 213 _, err := mcp.ResourceToBlock(&mcpsdk.ReadResourceResult{ 214 Contents: []*mcpsdk.ResourceContents{ 215 {URI: "file:///img.png", MIMEType: "image/png", Text: "not binary"}, 216 }, 217 }) 218 if err == nil { 219 t.Fatal("expected error for image resource with text data") 220 } 221 } 222 223 func TestResourceToBlock_BlobIsRawBytes(t *testing.T) { 224 // Blob is []byte (already decoded) — no base64 required from the caller. 225 block, err := mcp.ResourceToBlock(&mcpsdk.ReadResourceResult{ 226 Contents: []*mcpsdk.ResourceContents{ 227 {URI: "file:///file.txt", MIMEType: "text/plain", Blob: []byte("decoded text")}, 228 }, 229 }) 230 if err != nil { 231 t.Fatalf("unexpected error: %v", err) 232 } 233 if block.OfDocument == nil || block.OfDocument.Source.OfText == nil { 234 t.Fatal("expected text document") 235 } 236 if block.OfDocument.Source.OfText.Data != "decoded text" { 237 t.Fatalf("expected %q, got %q", "decoded text", block.OfDocument.Source.OfText.Data) 238 } 239 } 240 241 func TestResourceToFile_Text(t *testing.T) { 242 r, err := mcp.ResourceToFile(&mcpsdk.ReadResourceResult{ 243 Contents: []*mcpsdk.ResourceContents{ 244 {URI: "file:///hello.txt", MIMEType: "text/plain", Text: "hello"}, 245 }, 246 }) 247 if err != nil { 248 t.Fatalf("unexpected error: %v", err) 249 } 250 if r == nil { 251 t.Fatal("expected non-nil reader") 252 } 253 } 254 255 func TestResourceToFile_EmptyContents(t *testing.T) { 256 _, err := mcp.ResourceToFile(&mcpsdk.ReadResourceResult{}) 257 var mcpErr *mcp.UnsupportedValueError 258 if !errors.As(err, &mcpErr) { 259 t.Fatalf("expected UnsupportedValueError, got %T", err) 260 } 261 }