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 toHttpResponse
struct -
Extract and store Content-Type
header inprocess_response_with_request()
-
Add is_image()
helper method toHttpResponse
-
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 toHttpResponse
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 toCargo.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)