scuffed-painter
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@scuffed-painterDraw a green triangle with a gold circle and a black line on a 200x200 canvas."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 |
|
|
|
|
|
|
|
|
|
|
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
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):
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.
Related MCP server: openai-imagegen-mcp
MCP host configuration
stdio
Add the server to your MCP host's stdio server configuration:
{
"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):
scuffed-painter --transport http --host 127.0.0.1 --port 8000{
"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
{
"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:
pip install -e ".[dev]"
python -m pytestAvailable Tools
2 toolsdraw_imageA
Draws a picture with pillow and returns the resulting image as inline PNG image content. This is especially usefull for (chat) applications that can directly display images.
width: canvas width in pixels (positive integer). height: canvas height in pixels (positive integer). commands: list of drawing commands, executed in order; each command is a JSON object with a "shape" field selecting one of: line, rect, circle, ellipse, triangle.
Supported shapes and their fields: line: "shape": "line", fields: start (x, y), end (x, y), color (default black), width (default 1) rect: "shape": "rect", fields: box (left, top, right, bottom), fill (default black, None for none), outline (default None), width (default 1) circle: "shape": "circle", fields: center (x, y), radius, fill (default black, None for none), outline (default None), width (default 1) ellipse: "shape": "ellipse", fields: box (x0, y0, x1, y1), fill (default black, None for none), outline (default None), width (default 1) triangle: "shape": "triangle", fields: points (three (x, y) vertices), fill (default black, None for none), outline (default None), width (default 1)
Commands are validated individually. Invalid commands are skipped, and a warning listing them (1-based positions) is included in the result; the image still contains all valid commands in order. If no command is valid, the call fails with a listing of the per-command errors.
Coordinate system: The coordinate system has its origin at the top-left corner; x increases to the right, y increases downward. All coordinates are in pixels on a fixed-size white background canvas; drawing outside the canvas bounds is clipped (harmless). Commands run in list order, and later commands overpaint earlier ones.
Color format: Color as a CSS color name (e.g. 'red', 'darkorange') or hex code (e.g. '#8b4513'). Values are passed through to Pillow.
Paint semantics: fill=None gives an unfilled shape; outline draws the border; width is the stroke width in pixels for line/rect/circle/ellipse/triangle.
Example (200x200 canvas): { "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} ] }
| Name | Required | Description | Default |
|---|---|---|---|
| width | Yes | ||
| height | Yes | ||
| commands | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it delivers thoroughly. It discloses invalid-command skipping with warnings, total-invalid-command failure behavior, coordinate origin and direction, clipping, overpainting order, color formats, and pass-through to Pillow. This is far beyond what annotations alone would provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although the description is long, the complexity of the tool justifies the length. It is well-structured with clear sections for shapes, coordinate system, colors, paint semantics, and an example, and the core purpose is front-loaded in the first sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, no output schema, and a highly complex nested command format, the description covers everything an agent needs: complete shape schemas, defaults, validation behavior, failure modes, coordinate system details, and a full example. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description fully compensates by explaining width, height, and commands in depth. It documents every supported shape, all their fields, defaults, color formats, coordinate semantics, and provides a working example, so no parameter meaning is left to inference.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Draws a picture with pillow and returns the resulting image as inline PNG image content.' This clearly differentiates the tool from its sibling draw_image_to_file by emphasizing inline PNG output rather than file output, so an agent can select it correctly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use this tool: 'especially useful for (chat) applications that can directly display images.' It does not explicitly name draw_image_to_file as the alternative for file output, but the inline-image framing strongly implies that distinction, leaving little ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_image_to_fileA
Draws a picture with pillow and saves the resulting image to a file.
output_path: absolute file path to save to; the image format is inferred from the extension (e.g. .png, .jpg). Parent directories are NOT created. width: canvas width in pixels (positive integer). height: canvas height in pixels (positive integer). commands: list of drawing commands, executed in order; each command is a JSON object with a "shape" field selecting one of: line, rect, circle, ellipse, triangle.
Supported shapes and their fields: line: "shape": "line", fields: start (x, y), end (x, y), color (default black), width (default 1) rect: "shape": "rect", fields: box (left, top, right, bottom), fill (default black, None for none), outline (default None), width (default 1) circle: "shape": "circle", fields: center (x, y), radius, fill (default black, None for none), outline (default None), width (default 1) ellipse: "shape": "ellipse", fields: box (x0, y0, x1, y1), fill (default black, None for none), outline (default None), width (default 1) triangle: "shape": "triangle", fields: points (three (x, y) vertices), fill (default black, None for none), outline (default None), width (default 1)
Commands are validated individually. Invalid commands are skipped, and a warning listing them (1-based positions) is included in the result; the image still contains all valid commands in order. If no command is valid, the call fails with a listing of the per-command errors.
Coordinate system: The coordinate system has its origin at the top-left corner; x increases to the right, y increases downward. All coordinates are in pixels on a fixed-size white background canvas; drawing outside the canvas bounds is clipped (harmless). Commands run in list order, and later commands overpaint earlier ones.
Color format: Color as a CSS color name (e.g. 'red', 'darkorange') or hex code (e.g. '#8b4513'). Values are passed through to Pillow.
Paint semantics: fill=None gives an unfilled shape; outline draws the border; width is the stroke width in pixels for line/rect/circle/ellipse/triangle.
Example (200x200 canvas): { "output_path": "/home/myuser/documents/picture.png", "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} ] }
| Name | Required | Description | Default |
|---|---|---|---|
| width | Yes | ||
| height | Yes | ||
| commands | Yes | ||
| output_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly. It discloses that parent directories are not created, invalid commands are skipped with warnings, no-valid-command fails, later commands overpaint earlier ones, drawing outside the canvas is clipped, and colors follow specific formats.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but the length is justified by the tool's complexity and the absence of schema-level documentation. It is front-loaded with a one-sentence purpose, then organized into clear labeled sections with a concrete example.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with four required parameters, a free-form commands array, and no annotations, the description covers nearly every decision an agent needs to make: file path rules, canvas size, command shapes, validation behavior, coordinate system, painting order, and colors. The presence of an output schema means return-value details are not required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides only names and basic types, so schema coverage is effectively 0%. The description compensates completely by explaining output_path semantics, width/height meaning, command structure, all supported shape fields, defaults, and coordinate/color conventions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair: it draws a picture and saves it to a file. It also distinguishes itself from the sibling draw_image by emphasizing file output, so an agent can tell the tools apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The saving-to-file behavior implies when this tool is appropriate, but the description never explicitly states when to use it versus draw_image or what conditions would favor one over the other. This is usable but implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
2 tool updates
v0.1.0- First observed
draw_image - First observed
draw_image_to_file
TDQS
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.
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.
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.
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
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
- mcpOAuthcom.slickfast
Render 47 chart types and tiled dashboards as PNG/SVG. Deterministic, no headless browser.
Generate vector art, vectorize images, and return SVG, PNG, and logo kits to AI agents.
Generate and vectorize clean, editable SVG graphics from text, images, or both.
Create, inspect, manage, and render charts and data visualizations as SVG/PNG or interactive embeds.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables creation, management, and export of Excalidraw drawings through natural language. Supports CRUD operations on drawings and export to SVG, PNG, and JSON formats with file-based storage.82,783-
- FlicenseNot gradedqualityDmaintenanceEnables image generation and editing via OpenAI's gpt-image-1 model, with options for saving, format control, and transparency.-
- FlicenseNot gradedqualityDmaintenanceEnables to create, compose, and export SVG documents programmatically using the svgwrite library through tool calls. Supports shapes, groups, gradients, and pattern generators.-
- FlicenseNot gradedqualityBmaintenanceEnables image generation and editing via third-party relay services. Returns local file paths and Markdown display hints.-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/viktor-haag/scuffed-painter'
If you have feedback or need assistance with the MCP directory API, please join our Discord server