Skip to content

Add support for image response content in MCP tool calls

Closes #79 (closed)

Summary

This MR implements support for MCP image content responses in rmcp-openapi, allowing OpenAPI endpoints that return images to properly return base64-encoded image data via Content::image() instead of text.

Closes #79 (closed)

Implementation Tasks

  • Phase 1: Detect Content Type (crates/rmcp-openapi/src/http_client.rs)

    • Add content_type: Option<String> field to HttpResponse struct
    • Extract and store Content-Type header in process_response_with_request()
    • Add is_image() helper method to HttpResponse
    • Add is_binary() helper method for general binary content detection
  • Phase 2: Handle Binary Response Data (crates/rmcp-openapi/src/http_client.rs)

    • Add body_bytes: Option<Vec<u8>> field to HttpResponse struct
    • Modify process_response_with_request() to conditionally use .bytes() or .text()
    • Store binary data as bytes for image/audio/video content types
    • Update to_mcp_content() method to handle binary responses appropriately
  • Phase 3: Return Image Content (crates/rmcp-openapi/src/tool/mod.rs)

    • Check response content type in call() method
    • Base64 encode image data when detected
    • Return Content::image(base64_data, mime_type) for image responses
    • Maintain backward compatibility for text responses
    • Handle edge cases (missing content type, empty response, etc.)
  • Phase 4: Add Dependencies

    • Add base64 crate to Cargo.toml
    • Verify dependency versions are compatible
    • Update Cargo.lock if needed
  • Phase 5: Testing

    • Create tests/test_image_responses.rs for integration tests
    • Add test for PNG image responses
    • Add test for JPEG image responses
    • Add test for GIF image responses
    • Add test for WebP image responses
    • Add test for SVG image responses
    • Add test for BMP image responses
    • Verify base64 encoding correctness
    • Test with various content type formats (with charset parameters)
    • Test error handling for 404 responses
    • Test that text/JSON responses are not converted to images
    • Test empty image responses
    • Add unit tests for content type detection helpers
  • Phase 6: Documentation

    • Update README.md Features section with image response support
    • All tests passing (162/162)
    • Documentation committed

Supported MIME Types

Initial implementation supports:

  • image/png
  • image/jpeg
  • image/gif
  • image/webp
  • image/svg+xml
  • image/bmp

Technical Details

Key Changes

HttpResponse struct (http_client.rs):

pub struct HttpResponse {
    pub status_code: u16,
    pub status_text: String,
    pub headers: HashMap<String, String>,
    pub content_type: Option<String>,  // NEW
    pub body: String,
    pub body_bytes: Option<Vec<u8>>,   // NEW
    pub is_success: bool,
    pub request_method: String,
    pub request_url: String,
    pub request_body: String,
}

Tool call method (tool/mod.rs):

// Check if response is an image and return image content
if response.is_image() {
    if let Some(bytes) = &response.body_bytes {
        use base64::{engine::general_purpose::STANDARD, Engine as _};
        let base64_data = STANDARD.encode(bytes);
        
        let mime_type = response
            .content_type
            .as_ref()
            .map(|ct| ct.as_str())
            .unwrap_or("image/png");
        
        return Ok(CallToolResult {
            content: vec![Content::image(base64_data, mime_type)],
            structured_content: None,
            is_error: Some(!response.is_success),
            meta: None,
        });
    }
}

Benefits

  • AI assistants can display images from API endpoints
  • Full compliance with MCP specification
  • Better user experience when working with visual data
  • Foundation for supporting other binary content types (audio, video, PDFs)

Testing Strategy

All tests use mock HTTP servers to simulate image-returning endpoints with various content types and edge cases. Comprehensive test coverage includes:

  • 6 core image format tests (PNG, JPEG, GIF, WebP, SVG, BMP)
  • 6 edge case tests (charset parameters, text/JSON handling, errors, empty responses)
  • All 162 tests passing (100% success rate)

Edited by Wally The Wobot

Merge request reports

Loading