Aseprite MCP Tools
# Aseprite MCP Tools v2.0
[日本語版はこちら](README_ja.md) | [macOS Setup Guide](SETUP_MACOS.md)
A powerful Python MCP (Model Context Protocol) server for programmatic interaction with Aseprite, featuring enhanced error handling, configuration management, batch processing, and more!
## 🚀 What's New in v2.0
- **🛡️ Comprehensive Error Handling**: Custom exceptions with detailed, actionable error messages
- **🔧 Configuration Management**: Pydantic-based settings with JSON/YAML support
- **📝 Advanced Logging**: Structured logging with performance metrics
- **🎨 Palette Management**: Create, apply, and extract color palettes
- **⚡ Batch Processing**: Process multiple files in parallel
- **🏗️ Lua Script Builder**: Clean, type-safe Lua script generation
- **🔒 Enhanced Security**: Input validation and path traversal protection
- **🧪 Full Test Coverage**: Comprehensive unit tests
## 📋 Features
### Core Drawing Tools
- **Canvas Operations**: Create sprites, add layers and frames
- **Drawing Tools**: Pixels, lines, rectangles, circles, and fill operations
- **Export Tools**: Export to various formats with scaling and layer support
### New Palette Tools (v2.0)
- **Preset Palettes**: GameBoy, NES, PICO-8, CGA, Monochrome, Sepia
- **Custom Palettes**: Create and apply custom color schemes
- **Palette Extraction**: Extract colors from existing images
- **Color Remapping**: Replace colors throughout sprites
### Batch Processing (v2.0)
- **Batch Resize**: Resize multiple sprites maintaining aspect ratio
- **Batch Export**: Convert multiple files to different formats
- **Batch Palette Apply**: Apply palettes to multiple files
- **Custom Scripts**: Run Lua scripts on file sets
## 🔧 Installation
### Requirements
- Python 3.13+
- Aseprite (must be installed separately)
### Claude Desktop Configuration
#### Using UV (Recommended)
```json
{
"mcpServers": {
"aseprite": {
"command": "/opt/homebrew/bin/uv",
"args": [
"--directory",
"/path/to/aseprite-mcp",
"run",
"-m",
"aseprite_mcp"
],
"env": {
"ASEPRITE_PATH": "/path/to/aseprite"
}
}
}
}
```
#### Using Python
```json
{
"mcpServers": {
"aseprite": {
"command": "python",
"args": ["-m", "aseprite_mcp"],
"cwd": "/path/to/aseprite-mcp",
"env": {
"ASEPRITE_PATH": "/path/to/aseprite"
}
}
}
}
```
### Install Dependencies
```bash
pip install -r requirements.txt
```
## ⚙️ Configuration
### Environment Variables
```bash
export ASEPRITE_PATH="/Applications/Aseprite.app/Contents/MacOS/aseprite"
export ASEPRITE_MCP_LOG_LEVEL="INFO"
```
### Configuration File (config.json)
```json
{
"aseprite_path": "/path/to/aseprite",
"canvas": {
"max_width": 10000,
"max_height": 10000
},
"batch": {
"max_parallel_jobs": 4,
"continue_on_error": true
},
"log_level": "INFO",
"security": {
"allowed_directories": ["/home/user/sprites"],
"max_file_size": 104857600
}
}
```
### Configuration File (config.yaml)
```yaml
aseprite_path: /path/to/aseprite
canvas:
max_width: 10000
max_height: 10000
default_color_mode: RGBA
batch:
max_parallel_jobs: 4
continue_on_error: true
log_level: INFO
security:
allowed_directories:
- /home/user/sprites
max_file_size: 104857600
```
## 📖 Usage Examples
### Basic Drawing Operations
```python
# Create a new sprite
await create_canvas(320, 240, "my_sprite.aseprite")
# Draw pixels
await draw_pixels("my_sprite.aseprite", [
{"x": 10, "y": 10, "color": "FF0000"}, # Red
{"x": 11, "y": 10, "color": "00FF00"}, # Green
{"x": 12, "y": 10, "color": "0000FF"} # Blue
])
# Draw shapes
await draw_rectangle("my_sprite.aseprite", 50, 50, 100, 80, "FFFF00", fill=True)
await draw_circle("my_sprite.aseprite", 160, 120, 30, "FF00FF", fill=False)
await draw_line("my_sprite.aseprite", 0, 0, 320, 240, "FFFFFF", thickness=2)
# Fill area
await fill_area("my_sprite.aseprite", 100, 100, "00FFFF", tolerance=10)
```
### Layer and Frame Management
```python
# Add a new layer
await add_layer("my_sprite.aseprite", "Background")
# Add animation frames
await add_frame("my_sprite.aseprite", after_frame=0)
```
### Palette Operations
```python
# Apply preset palette
await apply_preset_palette("my_sprite.aseprite", "gameboy")
# Available presets: gameboy, gameboy-pocket, nes, pico-8, cga, monochrome, sepia
# Create custom palette
await create_palette("my_sprite.aseprite", [
"264653", "2A9D8F", "E9C46A", "F4A261", "E76F51"
])
# Extract palette from image
await extract_palette_from_image("reference.png", max_colors=16)
# Get palette information
await get_palette_info("my_sprite.aseprite")
# Remap colors
await remap_colors("my_sprite.aseprite", {
"FF0000": "00FF00", # Red to Green
"0000FF": "FFFF00" # Blue to Yellow
})
```
### Export Operations
```python
# Export single file
await export_sprite("my_sprite.aseprite", "output.png", scale=2.0)
# Export with frame range
await export_sprite("animation.aseprite", "frames.gif", frame_range="1-10")
# Export each layer separately
await export_layers("my_sprite.aseprite", "layers/", format="png")
```
### Batch Processing
```python
# Resize multiple sprites
await batch_resize(
input_dir="sprites/",
output_dir="sprites_small/",
scale=0.5,
file_pattern="*.aseprite"
)
# Export batch to PNG
await batch_export(
input_dir="sprites/",
output_dir="exports/",
format="png",
scale=2.0
)
# Apply palette to multiple files
await batch_apply_palette(
input_dir="sprites/",
palette_file="my_palette.aseprite",
create_backup=True
)
# Run custom Lua script on multiple files
await batch_process_custom(
input_dir="sprites/",
lua_script="app.activeSprite:flatten()",
output_dir="flattened/"
)
```
## 🏗️ Architecture
### Project Structure
```
aseprite-mcp/
├── aseprite_mcp/
│ ├── core/
│ │ ├── commands.py # Aseprite command execution
│ │ ├── config.py # Configuration management
│ │ ├── exceptions.py # Custom exceptions
│ │ ├── logging.py # Logging system
│ │ ├── lua_builder.py # Lua script builder
│ │ └── validation.py # Input validation
│ └── tools/
│ ├── batch.py # Batch processing
│ ├── canvas.py # Canvas operations
│ ├── drawing.py # Drawing tools
│ ├── export.py # Export functions
│ └── palette.py # Palette management
├── tests/ # Unit tests
├── examples/ # Example scripts
└── config.example.yaml # Configuration example
```
### Error Handling
```python
try:
result = await create_canvas(-100, 200, "test.aseprite")
except ValidationError as e:
print(f"Validation failed: {e}")
except AsepriteError as e:
print(f"Aseprite error: {e}")
```
### Lua Script Builder
```python
from aseprite_mcp.core.lua_builder import LuaBuilder
builder = LuaBuilder()
builder.create_sprite(200, 200)
builder.begin_transaction()
builder.set_color("FF0000")
builder.for_loop("i", 0, 10)
builder.draw_pixel("i * 10", "i * 10")
builder.end_loop()
builder.end_transaction()
builder.save_sprite("output.aseprite")
script = builder.build() # Returns clean Lua code
```
## 🧪 Testing
Run all tests:
```bash
pytest tests/ -v
```
Run specific test:
```bash
pytest tests/test_validation.py -v
```
Run demo script:
```bash
python examples/demo_improvements.py
```
## 📝 Logging
Logs include:
- Operation tracking
- Performance metrics
- Error details with context
- Structured JSON output (optional)
Example log:
```
2024-06-11 10:30:45 - aseprite_mcp - INFO - Operation: create_canvas
2024-06-11 10:30:45 - aseprite_mcp - INFO - Canvas created successfully
2024-06-11 10:30:45 - aseprite_mcp - INFO - Performance: create_canvas took 0.234s
```
## 🤝 Contributing
1. Fork the repository
2. Create a feature branch
3. Follow the coding standards:
- Use type hints
- Add input validation
- Include error handling
- Write unit tests
- Update documentation
4. Submit a pull request
## 📄 License
MIT License - see LICENSE file for details
## 🙏 Credits
- Original implementation: Divyansh Singh
- v2.0 improvements: Enhanced error handling, configuration, batch processing, and more
## 📚 Additional Resources
- [Aseprite API Documentation](https://www.aseprite.org/api/)
- [MCP Documentation](https://modelcontextprotocol.io/)
- [IMPROVEMENTS.md](IMPROVEMENTS.md) - Detailed v2.0 changesTDQS
Scored across 19 tools
Most tools have distinct purposes targeting specific Aseprite operations like drawing shapes, palette management, or batch processing, but some overlap exists between 'export_sprite' and 'batch_export' which could cause confusion in selection. Descriptions help clarify, but the boundary between single-file and batch export is not entirely clear from names alone.
Tool names consistently follow a verb_noun pattern throughout, such as 'add_frame', 'draw_circle', and 'batch_export', with no deviations in style. This predictability makes it easy for agents to understand and navigate the toolset without confusion from mixed conventions.
With 19 tools, the count is slightly high but reasonable for a comprehensive Aseprite manipulation server, covering operations from creation to export and batch processing. It feels well-scoped for the domain, though it borders on being heavy, which could overwhelm agents but is justified by the functionality offered.
The toolset provides complete coverage for Aseprite file manipulation, including CRUD-like operations (e.g., create_canvas, add_frame/layer), drawing functions, palette management, and batch processing. No obvious gaps exist; agents can handle full workflows from sprite creation to export and modification without dead ends.