Skip to content

Commit 2ffcb17

Browse files
committed
feat: initialize project structure with essential files and configurations
1 parent c04d727 commit 2ffcb17

9 files changed

Lines changed: 432 additions & 0 deletions

File tree

.gitignore

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Claude AI files
2+
.claude/
3+
4+
# Binaries
5+
/bin/
6+
/dist/
7+
*.exe
8+
*.exe~
9+
*.dll
10+
*.so
11+
*.dylib
12+
aseprite-mcp
13+
14+
# Test files
15+
*.test
16+
*.out
17+
coverage.txt
18+
coverage.html
19+
20+
# Temporary files
21+
*.tmp
22+
*.aseprite
23+
*.png
24+
*.gif
25+
/tmp/
26+
27+
# IDE
28+
.vscode/
29+
.idea/
30+
*.swp
31+
*.swo
32+
*~
33+
34+
# OS
35+
.DS_Store
36+
Thumbs.db
37+
38+
# Config
39+
config.json
40+
.env

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Added
11+
- Initial project structure
12+
- Go module initialization
13+
- Basic build system with Makefile

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Brandon Williams
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
.PHONY: all build test lint clean install
2+
3+
# Binary name
4+
BINARY_NAME=aseprite-mcp
5+
6+
# Build variables
7+
VERSION?=$(shell git describe --tags --always --dirty)
8+
BUILD_TIME=$(shell date -u '+%Y-%m-%d_%H:%M:%S')
9+
LDFLAGS=-ldflags "-X main.Version=$(VERSION) -X main.BuildTime=$(BUILD_TIME)"
10+
11+
all: lint test build
12+
13+
build:
14+
go build $(LDFLAGS) -o bin/$(BINARY_NAME) ./cmd/aseprite-mcp
15+
16+
test:
17+
go test -v -race -cover ./...
18+
19+
test-coverage:
20+
go test -v -race -coverprofile=coverage.txt -covermode=atomic ./...
21+
go tool cover -html=coverage.txt -o coverage.html
22+
23+
lint:
24+
go vet ./...
25+
go fmt ./...
26+
27+
clean:
28+
rm -rf bin/ dist/ coverage.txt coverage.html
29+
go clean
30+
31+
install:
32+
go install $(LDFLAGS) ./cmd/aseprite-mcp
33+
34+
# Development helpers
35+
run:
36+
go run ./cmd/aseprite-mcp
37+
38+
deps:
39+
go mod download
40+
go mod tidy

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Aseprite MCP Server (Go)
2+
3+
A Model Context Protocol (MCP) server that exposes Aseprite's pixel art and animation capabilities to AI assistants.
4+
5+
## Status
6+
7+
🚧 Under active development - not ready for production use
8+
9+
## Requirements
10+
11+
- Go 1.23+
12+
- Aseprite 1.3.0+
13+
14+
## Installation
15+
16+
Coming soon...
17+
18+
## Usage
19+
20+
Coming soon...
21+
22+
## License
23+
24+
MIT

go.mod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module github.com/willibrandon/aseprite-mcp-go
2+
3+
go 1.24.1
4+
5+
require (
6+
github.com/modelcontextprotocol/go-sdk v0.8.0 // indirect
7+
github.com/willibrandon/mtlog v0.9.0 // indirect
8+
)

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
github.com/modelcontextprotocol/go-sdk v0.8.0 h1:jdsBtGzBLY287WKSIjYovOXAqtJkP+HtFQFKrZd4a6c=
2+
github.com/modelcontextprotocol/go-sdk v0.8.0/go.mod h1:nYtYQroQ2KQiM0/SbyEPUWQ6xs4B95gJjEalc9AQyOs=
3+
github.com/willibrandon/mtlog v0.9.0 h1:DTsi+In254MB1+49OWy5wpLEW++qMkNu5t9TMbQC0PM=
4+
github.com/willibrandon/mtlog v0.9.0/go.mod h1:lgCcScZ+nYWeeSNw+lxYk7paleph8S45lJ24LvdGXS0=

pkg/aseprite/types.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Package aseprite provides types and utilities for interacting with Aseprite.
2+
package aseprite
3+
4+
import (
5+
"fmt"
6+
"regexp"
7+
"strconv"
8+
"strings"
9+
)
10+
11+
// Color represents an RGBA color value.
12+
type Color struct {
13+
R uint8 `json:"r"`
14+
G uint8 `json:"g"`
15+
B uint8 `json:"b"`
16+
A uint8 `json:"a"`
17+
}
18+
19+
var hexColorPattern = regexp.MustCompile(`^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$`)
20+
21+
// NewColor creates a new Color with the specified RGBA values.
22+
func NewColor(r, g, b, a uint8) Color {
23+
return Color{R: r, G: g, B: b, A: a}
24+
}
25+
26+
// NewColorRGB creates a new opaque Color with the specified RGB values.
27+
func NewColorRGB(r, g, b uint8) Color {
28+
return Color{R: r, G: g, B: b, A: 255}
29+
}
30+
31+
// FromHex parses a hex color string in the format "#RRGGBB" or "#RRGGBBAA".
32+
// The "#" prefix is optional.
33+
func (c *Color) FromHex(hex string) error {
34+
hex = strings.TrimPrefix(hex, "#")
35+
36+
if !hexColorPattern.MatchString("#" + hex) {
37+
return fmt.Errorf("invalid hex color format: %q (expected #RRGGBB or #RRGGBBAA)", hex)
38+
}
39+
40+
// Parse RGB
41+
r, _ := strconv.ParseUint(hex[0:2], 16, 8)
42+
g, _ := strconv.ParseUint(hex[2:4], 16, 8)
43+
b, _ := strconv.ParseUint(hex[4:6], 16, 8)
44+
45+
c.R = uint8(r)
46+
c.G = uint8(g)
47+
c.B = uint8(b)
48+
49+
// Parse alpha if present
50+
if len(hex) == 8 {
51+
a, _ := strconv.ParseUint(hex[6:8], 16, 8)
52+
c.A = uint8(a)
53+
} else {
54+
c.A = 255 // Opaque by default
55+
}
56+
57+
return nil
58+
}
59+
60+
// ToHex converts the color to a hex string in the format "#RRGGBBAA".
61+
func (c Color) ToHex() string {
62+
return fmt.Sprintf("#%02X%02X%02X%02X", c.R, c.G, c.B, c.A)
63+
}
64+
65+
// ToHexRGB converts the color to a hex string in the format "#RRGGBB" (ignoring alpha).
66+
func (c Color) ToHexRGB() string {
67+
return fmt.Sprintf("#%02X%02X%02X", c.R, c.G, c.B)
68+
}
69+
70+
// Point represents a 2D coordinate.
71+
type Point struct {
72+
X int `json:"x"`
73+
Y int `json:"y"`
74+
}
75+
76+
// Rectangle represents a rectangular region.
77+
type Rectangle struct {
78+
X int `json:"x"`
79+
Y int `json:"y"`
80+
Width int `json:"width"`
81+
Height int `json:"height"`
82+
}
83+
84+
// Pixel represents a single pixel with color and position.
85+
type Pixel struct {
86+
Point
87+
Color Color `json:"color"`
88+
}
89+
90+
// SpriteInfo contains metadata about a sprite.
91+
type SpriteInfo struct {
92+
Width int `json:"width"`
93+
Height int `json:"height"`
94+
ColorMode string `json:"color_mode"`
95+
FrameCount int `json:"frame_count"`
96+
LayerCount int `json:"layer_count"`
97+
Layers []string `json:"layers"`
98+
}
99+
100+
// ColorMode represents the color mode of a sprite.
101+
type ColorMode string
102+
103+
const (
104+
ColorModeRGB ColorMode = "rgb"
105+
ColorModeGrayscale ColorMode = "grayscale"
106+
ColorModeIndexed ColorMode = "indexed"
107+
)
108+
109+
// String returns the string representation of the color mode.
110+
func (cm ColorMode) String() string {
111+
return string(cm)
112+
}
113+
114+
// ToLua returns the Lua constant for the color mode.
115+
func (cm ColorMode) ToLua() string {
116+
switch cm {
117+
case ColorModeRGB:
118+
return "ColorMode.RGB"
119+
case ColorModeGrayscale:
120+
return "ColorMode.GRAYSCALE"
121+
case ColorModeIndexed:
122+
return "ColorMode.INDEXED"
123+
default:
124+
return "ColorMode.RGB"
125+
}
126+
}

0 commit comments

Comments
 (0)