Overview
The resvg-test-triage MCP server provides 8 AI-assisted tools for automated test analysis and feature implementation guidance. It accelerates test triage by automatically detecting SVG features, categorizing failures, suggesting implementation approaches, and tracking progress across the test suite.
Location: tools/mcp-servers/resvg-test-triage/
Architecture
The server is built on three core modules:
- server.py - MCP server with 8 tool implementations
- codebase_helpers.py - File search patterns, ranking, and implementation hints
- test_output_parser.py - Test output parsing, skip file analysis, and feature identification
Dependencies
- mcp>=0.9.0 - MCP server framework
- Pillow>=10.0.0 - Image processing for visual diff analysis
- numpy>=1.24.0 - Numerical analysis for image processing
- pytest>=7.0.0 (dev) - Unit testing
Tool Reference
Core Triage Tools
1. analyze_test_failure
Analyzes a single test failure with comprehensive diagnostics.
Purpose: Detect SVG features, categorize failure type, and generate skip comments.
Input:
{
"test_name": "e-text-023.svg",
"svg_content": "<svg>...</svg>",
"pixel_diff": 8234,
"actual_image_path": "/tmp/actual.png", // Optional
"expected_image_path": "/tmp/expected.png", // Optional
"diff_image_path": "/tmp/diff.png" // Optional
}
Output:
{
"test_name": "e-text-023.svg",
"pixel_diff": 8234,
"features": [
{
"name": "letter_spacing",
"category": "styling",
"description": "letter-spacing attribute"
}
],
"category": "not_implemented",
"severity": "major",
"suggested_skip": "{\"e-text-023.svg\", Params::Skip()}, // Not impl: `letter-spacing`",
"analysis": {
"feature_count": 1,
"primary_feature": "letter-spacing attribute",
"recommendation": "Skip - feature not implemented"
}
}
Implementation: server.py:531-610 Feature Detection: server.py:157-254 (detect_svg_features) Categorization Logic: server.py:287-315 (categorize_failure)
2. batch_triage_tests
Process multiple test failures from bazel output, grouping by feature.
Purpose: Automate triage of 50+ test failures at once.
Input:
{
"test_output": "... complete bazel test output ..."
}
Output:
{
"total_failures": 32,
"failures": [
{
"test": "e-text-002.svg",
"pixel_diff": 13766,
"features": ["multiple_x_values"],
"category": "not_implemented",
"severity": "major",
"suggested_skip": "..."
}
],
"grouped_by_feature": {
"multiple_x_values": ["e-text-002.svg", "e-text-003.svg"],
"dx_attribute": ["e-text-006.svg", "e-text-007.svg"]
},
"summary": {
"not_implemented": 28,
"threshold_needed": 2,
"font_difference": 1,
"bug": 1
}
}
Implementation: server.py:612-688
3. detect_svg_features
Parse SVG content to identify advanced features being tested.
Purpose: Understand what a test validates without running it.
Input:
{
"svg_content": "<svg><text letter-spacing='10'>...</text></svg>"
}
Output:
{
"features": [
{
"name": "letter_spacing",
"category": "styling",
"description": "letter-spacing attribute"
}
]
}
Detected Features:
- Positioning: multiple x/y values, dx/dy attributes, rotate, textLength
- Elements: <tspan>, <textPath>
- Styling: text-anchor, letter-spacing, word-spacing, text-decoration, font-*
- Layout: writing-mode, baseline-shift, alignment-baseline, dominant-baseline
Implementation: server.py:511-529
4. suggest_skip_comment
Generate properly formatted skip comments for resvg_test_suite.cc.
Purpose: Maintain consistent skip comment format across the codebase.
Input:
{
"test_name": "e-text-023.svg",
"features": ["letter_spacing"],
"category": "not_implemented"
}
Output:
{
"skip_comment": "{\"e-text-023.svg\", Params::Skip()}, // Not impl: `letter-spacing`",
"test_name": "e-text-023.svg",
"category": "not_implemented"
}
Comment Conventions:
- Not impl: <feature> - Feature not implemented
- Not impl: <element> - SVG element not supported
- UB: <reason> - Undefined behavior
- Bug: <description> - Known bug
- Larger threshold due to <reason> - Anti-aliasing artifacts
Implementation: server.py:690-712 + server.py:318-363 (format logic)
Implementation Guidance Tools
5. suggest_implementation_approach
Suggests which files to modify and provides implementation hints.
Purpose: Accelerate feature implementation by pointing to relevant code.
Input:
{
"test_name": "e-text-031.svg",
"features": ["writing_mode"],
"category": "text_layout",
"codebase_files": [] // Optional: pre-filtered files from glob/grep
}
Output:
{
"test_name": "e-text-031.svg",
"category": "text_layout",
"primary_feature": "writing_mode",
"likely_files": [
"donner/svg/components/text/ComputedTextStyleComponent.h",
"donner/svg/components/text/TextFlowComponent.h"
],
"file_patterns": [
"**/SVGTextElement.h",
"**/text/*.cc",
"**/ComputedTextStyleComponent.h"
],
"search_keywords": [
"writing-mode",
"WritingMode",
"writingmode"
],
"similar_features": [
{
"name": "text-direction",
"files": ["donner/svg/components/text/..."]
}
],
"implementation_hints": [
"Layout properties often affect how text is measured and positioned.",
"May require changes to text rendering pipeline.",
"Check ComputedTextStyleComponent for text layout state."
]
}
File Ranking Algorithm:
- Category match: +0.3 confidence
- Exact feature name match: +0.5 confidence
- Component files: +0.2 confidence
- Header files: +0.1 confidence
- Test files: -0.3 confidence penalty
Implementation: server.py:714-764 + codebase_helpers.py
6. find_related_tests
Find all tests failing for the same feature.
Purpose: Identify batch implementation opportunities (fix one feature, pass multiple tests).
Input:
{
"feature": "writing-mode",
"skip_file_content": "... content of resvg_test_suite.cc ..."
}
Output:
{
"feature": "writing-mode",
"related_tests": ["e-text-031.svg", "e-text-033.svg"],
"impact": "2 tests affected",
"priority": "medium",
"grouped_by_category": {
"e-text": ["e-text-031.svg", "e-text-033.svg"]
},
"all_missing_features": {
"writing-mode": 2,
"dx attribute": 5,
"textPath": 3
}
}
Priority Calculation:
- 0 tests: none
- 1 test: low
- 2-5 tests: medium
- 6+ tests: high
Implementation: server.py:766-823 + test_output_parser.py:identify_missing_features()
7. generate_feature_report
Generate progress reports by test category.
Purpose: Track feature implementation progress and identify next priorities.
Input:
{
"category": "e-text",
"test_output": "... bazel test output ...",
"skip_file_content": "... resvg_test_suite.cc ..." // Optional
}
Output:
{
"category": "e-text",
"total_tests": 15,
"passing": 3,
"skipped": 12,
"completion_rate": "20%",
"implemented_features": [],
"missing_features": [
"dx attribute",
"dy attribute",
"letter-spacing",
"..."
],
"next_priority": "dx attribute (affects 3 tests)",
"test_details": [
{
"name": "e-text-001.svg",
"status": "PASSED",
"pixel_diff": null
}
]
}
Category Prefixes:
- e-text - Text element tests
- a-transform - Transform attribute tests
- e-path - Path element tests
- etc.
Implementation: server.py:825-888 + test_output_parser.py:group_by_category()
8. analyze_visual_diff
Programmatically analyze diff images to categorize failure types.
Purpose: Understand visual failures without manual image inspection.
Input:
{
"diff_image_path": "/tmp/diff.png",
"actual_image_path": "/tmp/actual.png",
"expected_image_path": "/tmp/expected.png"
}
Output:
{
"difference_type": "positioning",
"visual_analysis": {
"diff_pixels": 3421,
"total_pixels": 65536,
"diff_percentage": "5.22%",
"diff_regions": 1,
"largest_region_pixels": 3421,
"is_uniform_offset": true
},
"likely_cause": "Baseline positioning offset or element placement issue",
"confidence": "high"
}
Difference Types:
- anti_aliasing - <100 pixels, minor rendering artifacts
- `positioning` - Uniform offset detected, element placement issue
- `missing_element` - >30% of image, large missing or incorrect element
- styling - Color, stroke, or fill differences
Image Analysis Algorithm:
- Load images with PIL/Pillow
- Convert to NumPy arrays
- Create diff mask (non-zero pixels)
- Calculate bounding boxes of diff regions
- Detect uniform offsets (concentrated in single region)
- Categorize based on pixel count and distribution
Implementation: server.py:890-977
Usage Examples
Example 1: Triage a Single Failing Test
result = await mcp.call_tool("analyze_test_failure", {
"test_name": "e-text-031.svg",
"svg_content": svg_content,
"pixel_diff": 8234
})
related = await mcp.call_tool("find_related_tests", {
"feature": "writing-mode",
"skip_file_content": skip_file_content
})
guidance = await mcp.call_tool("suggest_implementation_approach", {
"test_name": "e-text-031.svg",
"features": ["writing_mode"],
"category": "text_layout"
})
Example 2: Batch Triage After Test Run
test_output = subprocess.run(
["bazel", "test", "//donner/svg/renderer/tests:resvg_test_suite"],
capture_output=True
).stdout
result = await mcp.call_tool("batch_triage_tests", {
"test_output": test_output.decode()
})
Example 3: Track Progress
report = await mcp.call_tool("generate_feature_report", {
"category": "e-text",
"test_output": test_output,
"skip_file_content": skip_file_content
})
Testing
Unit Tests:
- test_codebase_helpers.py - 98 lines, 6 test cases
- test_test_output_parser.py - 150 lines, 11 test cases
Run Tests:
cd tools/mcp-servers/resvg-test-triage
pip install -e ".[dev]"
pytest -v
Validation:
- Tested against real test failures (e-text-031: writing-mode)
- File ranking validated with actual codebase files
- Skip file parsing tested with resvg_test_suite.cc
Installation & Setup
Install:
cd tools/mcp-servers/resvg-test-triage
pip install -e .
Configure for Claude Code:
{
"mcpServers": {
"resvg-test-triage": {
"command": "python3",
"args": ["/path/to/donner/tools/mcp-servers/resvg-test-triage/server.py"]
}
}
}
Configure for VSCode: See .vscode/mcp.json or mcp-config-example.json for format.
Performance Characteristics
- analyze_test_failure: <100ms for typical SVG (500 lines)
- batch_triage_tests: ~2s for 50 test failures
- detect_svg_features: <50ms per SVG
- suggest_implementation_approach: <10ms (no file I/O if files provided)
- find_related_tests: <100ms for resvg_test_suite.cc (500 skip entries)
- generate_feature_report: <500ms for full test output (1000 tests)
- analyze_visual_diff: ~200ms per image trio (PNG, 500x500)
Security Considerations
- All file paths provided by user (no arbitrary file access)
- Image processing limited to PNG files in temp directories
- No network calls or external data collection
- All analysis performed locally
- Image size limited to 10MB to prevent DoS
- Regex patterns sanitized in test output parsing
- Safe XML parsing (defusedxml not needed - no external input)
Future Enhancements
Potential Additions:
- ML/CV models for better visual diff categorization (70% → 90%+ accuracy)
- Cache analysis results for performance
- Integration with CI/CD for automated reporting
- Support for other test suites beyond resvg
- Real-time progress dashboard
Design Decisions:
- ✅ Simple image processing (no ML) - Fast, deterministic, good enough
- ✅ No caching - Keeps implementation simple, performance acceptable
- ✅ Local-only analysis - Privacy-preserving, no dependencies
See Also
- MCP Server README - User documentation
- AGENTS.md - Workflow examples for AI agents
- README_resvg_test_suite.md - Test triage workflow