Skip to main content
Glama
viktor-haag

scuffed-painter

by viktor-haag
README.md
# Scuffed Painter

An MCP (Model Context Protocol) server that renders drawing
commands into raster images using Pillow. It exposes two tools:

- `draw_image` — render the commands and return the result as an inline PNG
  image.
- `draw_image_to_file` — render the commands and save the result to a file.

Five shapes are supported, each a JSON object discriminated by its `"shape"`
field:

| shape      | parameters                                            |
|------------|-------------------------------------------------------|
| `line`     | `start`, `end`, `color`, `width`                      |
| `rect`     | `box` (left, top, right, bottom), `fill`, `outline`, `width` |
| `circle`   | `center`, `radius`, `fill`, `outline`, `width`        |
| `ellipse`  | `box` (x0, y0, x1, y1), `fill`, `outline`, `width`   |
| `triangle` | `points` (exactly three vertices), `fill`, `outline`, `width` |

Commands run in list order on a fixed-size white canvas; later commands
overpaint earlier ones. Colors are CSS color names or hex codes.

## Installation

```sh
pip install .
```

This provides the `scuffed-painter` console script, which launches the MCP
server over stdio (the default). `python -m scuffed_painter` is an equivalent
alternative. The same command can also serve the server over HTTP
(MCP Streamable HTTP transport):

```sh
scuffed-painter                              # stdio transport (default)
scuffed-painter --transport http             # HTTP on 127.0.0.1:8000
scuffed-painter --transport http --host H --port P
```

`--host` and `--port` only apply to the HTTP transport; the defaults are
`127.0.0.1` and `8000`. You may enable CORS with `--enable-cors` if necessary.

## MCP host configuration

### stdio

Add the server to your MCP host's stdio server configuration:

```json
{
  "mcpServers": {
    "scuffed-painter": {
      "command": "scuffed-painter"
    }
  }
}
```

Note: on a host with a restricted PATH or when running inside a virtualenv,
use the absolute path to the installed `scuffed-painter` script instead (e.g.
the one reported by `which scuffed-painter`).

### Streamable HTTP

Start the server yourself, then point your MCP host at the endpoint
(the path is `/mcp`):

```sh
scuffed-painter --transport http --host 127.0.0.1 --port 8000
```

```json
{
  "mcpServers": {
    "scuffed-painter": {
      "type": "streamable-http",
      "url": "http://127.0.0.1:8000/mcp"
    }
  }
}
```

(Adjust the key names to match your MCP host's configuration format.)

Note: when `draw_image_to_file` is used, `output_path` refers to the machine
the server runs on. Over stdio that is the same host as the MCP client; when
the server is reached over HTTP, it is the server's host instead.

### Example tool call

```json
{
  "width": 200,
  "height": 200,
  "commands": [
    {"shape": "circle", "center": [100, 80], "radius": 50, "fill": "gold", "outline": "orange", "width": 3},
    {"shape": "triangle", "points": [[50, 170], [150, 170], [100, 70]], "fill": "darkgreen"},
    {"shape": "line", "start": [20, 185], "end": [180, 185], "color": "black", "width": 2}
  ]
}
```

## Development

Repository layout:

```
scuffed_painter/          the package
  server.py             server, tools, command models, rendering
  __init__.py           re-exports mcp, defines __version__
  __main__.py           python -m scuffed_painter support
  py.typed              typing marker
tests/                  pytest suite (in-process fastmcp.Client)
```

Setup and running the tests:

```sh
pip install -e ".[dev]"
python -m pytest
```

TDQS

A4.6/5.0

Scored across 2 tools

Disambiguation5/5

The two tools split cleanly by output destination: draw_image_to_file persists to disk, while draw_image returns inline PNG content. Their names and the presence of output_path only in the file variant make misselection unlikely.

Naming Consistency5/5

Both tools follow the same draw_image verb-object prefix, with the file-save variant adding the clear _to_file suffix. The naming is snake_case and consistent across the whole set.

Tool Count4/5

Two tools is slightly below the typical 3-15 range, but the count is reasonable for a narrow painter: one output mode is file saving and the other is inline PNG. It feels minimal rather than excessive.

Completeness4/5

The core draw-and-output workflow is fully covered: all five shapes, validation, coordinate handling, and both file and inline delivery are present. Minor gaps remain, such as only having a fixed white background and no text or image-import tools, though these are workaround-able or outside the narrow scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues