ASCII & SVG Art Studio
README.md
```
. * . * . *
* ┌──────────────────────────┐ .
. │ A S C I I & S V G │ *
. │ A R T S T U D I O│ .
* └──────────────────────────┘ .
. * . * . *
```
# ASCII & SVG Art Studio
English | [简体中文](README.zh-CN.md)
An MCP server that gives an AI a drawing hand made of text. Build a character canvas, watch it render as a real PNG you can look at, iterate, export to PNG / JPG / PDF / SVG / TXT, or shoot a stop-motion animation and composite it into an MP4/GIF — with an optional voice-over synthesized from text.
It exposes itself to any MCP client as `ASCII & SVG Art Studio`.
## What it looks like
<table>
<tr>
<td align="center"><img src="gallery/moonlit_bay/moonlit_bay.png" alt="Moonlit Bay — a night scene of a mountain silhouette, a full moon, scattered stars, and rippling water, drawn entirely in ASCII shading and framed in a double-line box" width="420"></td>
<td align="center"><img src="gallery/daybreak_bay/daybreak_bay.png" alt="Daybreak Bay — the same bay at dawn: a backlit mountain silhouette, a half-risen sun with its shimmering reflection, fading stars, two birds, and a small sailboat heading out" width="420"></td>
</tr>
<tr>
<td align="center"><em>"Moonlit Bay" — Claude Opus 4.6</em></td>
<td align="center"><em>"Daybreak Bay" — Claude Fable 5</em></td>
</tr>
</table>
*The same bay, by night and at dawn — a diptych drawn start to finish through this MCP's tools by two different Claude models: canvas drawing, shaded fills, box frames, rendered to PNG for preview, then exported to `gallery/` in PNG, JPG, TXT (editable source), and print-ready PDF. Nothing was hand-edited outside the tool calls.*
## Tools
| Tool | What it does |
|---|---|
| `create_canvas` | Create a character canvas to draw on (up to 10M cells) |
| `canvas_draw` | Batch-draw onto a canvas: `text`, `box`, `hline`/`vline`/`line`, `fill` (shaded palettes), `stamp`, `circle`, `ellipse`, `clear`, `char` |
| `canvas_get` | Read a canvas back as text; supports reading just a region for large canvases |
| `canvas_resize` | Resize a canvas, keeping existing content where it still fits |
| `canvas_list` / `canvas_delete` | List / remove canvases |
| `preview` | Render text, a canvas, or SVG to a PNG and hand it back inline so the model can actually see it |
| `save` | Write to disk as PNG / JPG / PDF / SVG / TXT — quality and print-friendly (white bg) options included |
| `create_table` | Build a formatted ASCII table |
| `export` | One call to `gallery/<name>/`: editable source, metadata, and every requested format, organized |
| `animation_frame` | Stop-motion style: snapshot a canvas (or raw text) as one frame, with a `hold` (repeat count) |
| `animation_render` | Composite frames into MP4/GIF with ffmpeg; MP4 can be muxed with an audio track |
| `animation_list` / `animation_delete` | List / remove in-memory animations |
| `speak` | Text-to-speech via espeak-ng with an effects chain (`robot` / `radio` / `echo` / `cave` / `deep`) — feed the output straight into `animation_render` as a voice-over |
| `list_styles` | Reference sheet: available box-drawing styles and shading palettes |
The typical loop is **draw → preview → tweak → preview again → save/export** — the model gets to actually look at its own work before committing to a file.
## Installation
Requires **Python >= 3.10**.
```bash
git clone https://github.com/SolenmeChiara/ASCII_ART_MCP.git
cd ASCII_ART_MCP
pip install -r requirements.txt
```
That gets you canvases, PNG/JPG/PDF/TXT export, and animation rendering. Two things are optional or external:
- **SVG rendering** (the `svg=` input/output paths) needs `cairosvg`, which isn't in `requirements.txt` by default:
```bash
pip install cairosvg
```
On Windows, cairosvg also needs the GTK runtime installed separately.
- **Animation rendering** (`animation_render`, `export` with `mp4`/`gif`) needs **ffmpeg** on your `PATH`.
- **Voice synthesis** (`speak`) needs **espeak-ng**. It's looked up on `PATH` first, then at `C:/Program Files/eSpeak NG/`.
### Known limitation: font handling is Windows-first
Text rendering (`preview` / `save` / `export` when the source isn't already an image) picks fonts from built-in candidate lists. On Windows that's `C:/Windows/Fonts` — `seguisym.ttf`, `msgothic.ttc`, `simsun.ttc`, `consola.ttf`, `cour.ttf` — covering monospace + symbols + CJK. Linux/macOS have their own fallback chain (DejaVu Sans Mono, Menlo, Monaco, Apple Symbols, PingFang — see `server.py:288-335`, `server.py:505-507`), but it has only been tested on Windows, and the Linux list currently has no CJK entry, so Chinese/Japanese/Korean glyphs may render as boxes there. The `speak` tool finds espeak-ng via `PATH` first and only falls back to the Windows install location (`server.py:1440-1443`), so a normally installed espeak-ng on Linux/macOS should just work. If your platform's fonts live elsewhere, point `_find_font`/`_FALLBACK_FONT_PATHS` at them. PRs welcome.
## Running it
### Mode A — stdio (local, the usual case)
Run it directly:
```bash
python server.py
```
**Claude Desktop** — add to your MCP config:
```json
{
"mcpServers": {
"ascii-art-studio": {
"command": "python",
"args": ["/path/to/ASCII_ART_MCP/server.py"]
}
}
}
```
**Claude Code**:
```bash
claude mcp add ascii-art-studio -- python /path/to/ASCII_ART_MCP/server.py
```
### Mode B — Streamable HTTP (remote / from your phone)
```bash
cp .env.example .env
python -c "import secrets; print(secrets.token_urlsafe(32))"
# paste the output into MCP_PATH_SECRET in .env
start_http.bat
```
This serves on port `8767`. The MCP endpoint is at:
```
http://<host>:8767/mcp/<MCP_PATH_SECRET>/
```
with a plain health check at `/health`. To expose it to the internet without port-forwarding, `start_tunnel.bat` opens a Cloudflare quick tunnel (`cloudflared`) and prints a random `*.trycloudflare.com` URL.
> **Security note.** The path secret is the *only* authentication this server has. Keep `.env` out of version control (it already is — see `.gitignore`) and don't share the URL casually. The HTTP transport also disables MCP's DNS-rebinding protection (`server.py:611-613`) so it works behind a tunnel or bare IP — which means you should never run it publicly without a secret set. If `MCP_PATH_SECRET` is empty, `http_server.py` refuses to mount the MCP endpoint at all.
## A quick example
```
create_canvas(width=60, height=20, name="scene")
canvas_draw("scene", [
{"op": "box", "x": 0, "y": 0, "w": 60, "h": 20, "style": "double", "title": "Hello"},
{"op": "fill", "x": 1, "y": 1, "w": 58, "h": 18, "palette": "blocks", "direction": "radial"},
{"op": "text", "x": 22, "y": 10, "text": "Hello, world!"}
])
preview(canvas="scene") # look at it
save(path="D:/art/hello.png", canvas="scene") # happy with it, keep it
```
## Credits
Inspiration and reference drawn from [ascii-art-mcp](https://github.com/dmarsters/ascii-art-mcp) by dmarsters and [nakkas](https://github.com/arikusi/nakkas) by arikusi. Thanks for showing what this space could look like.
## License
MIT — see [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues