# Tools reference

Source: https://www.ascii-magic.com/docs/mcp-tools (ASCII Magic documentation)

Seven tools. You never name them in conversation: you ask for what you want and the client picks. This page is for when you need to know exactly what a tool will accept.

_The only branch that matters when you start: an image the agent can reach by URL goes straight into a render, and anything on the user's disk needs create_upload first._

## stylize_image

Renders an image through the engine, uploads the full-resolution PNG, and returns a download link plus a small preview so the agent can look at the result and adjust. This is the only tool that consumes anything.

| Parameter | Type | Required | What it does |
|---|---|---|---|
| `image` | string | yes | An http or https URL, a `data:` URL for a genuinely small image, or the `image` value `create_upload` returned. A file path never works: the server runs in the cloud and cannot see the caller's disk. |
| `style` | string | no | A style id from [the catalog](https://www.ascii-magic.com/docs/styles), for example `halftone`, `risograph` or `glass-crackle`. Omit it and the server picks the best-fitting style for this image, preferring Pro styles on a Pro account. |
| `style_requested_by_user` | boolean | no | Set true only when the person actually named that style. On a Pro account it is required in order to use a free style, which stops an agent quietly handing a Pro subscriber the free tier. |
| `variant` | integer | no | Which curated look to use, 0-based. Default is the first look that suits the image, and the result says how many that style has. |
| `settings` | object | no | Engine settings layered over the dressing, for example `{"contrast":130,"invert":true}`. Keys are the recipe keys that `decode_recipe` shows. An unknown key is rejected rather than ignored, so a typo fails loudly instead of silently rendering the wrong thing. |
| `post_fx` | object | no | Post effects merged over the look's own, for example `{"filmGrain":{"intensity":20},"sharpen":true}`. `true` switches one on at its defaults, `false` switches it off. Pro effects need Pro. |
| `scale` | number | no | Export multiplier over the source, 1 to 4. Default is automatic, chosen so the long edge reaches at least 2560px, and the long edge is capped at 3840px whatever you ask for. |
| `font_size` | integer | no | Cell size in pixels at preview scale, 2 to 64. Smaller means more and finer cells. Default is fitted to the image by the style's look. |
| `palette` | string | no | Dither palette id. Only meaningful for `style: "dither"`. |
| `algo` | string | no | Dither algorithm id. Only meaningful for `style: "dither"`. |
| `enhance` | boolean | no | Default true. Dresses the render for quality: a curated look with its post effects, per-style ground rules, a cell size fitted to the image, exposure rescue for a dark or blown source, and on Pro an automatic Levels grade for a flat render. Set false for the bare engine defaults. |
| `recipe` | string | no | A full `recipe:v1:` code. Rendered exactly as encoded with no dressing, and it overrides every other style setting on the call. |

> **Note:** Download links expire. Hand the user the link the tool returned rather than describing it or trying to re-host it.

## suggest_styles

Ranks the styles that suit a specific image, judged from its brightness, contrast, detail and colour. Every suggestion is one that has a curated look, so anything it returns renders well with `stylize_image`'s defaults, and the results are spread across categories rather than returning six variations of one idea.

| Parameter | Type | Required | What it does |
|---|---|---|---|
| `image` | string | yes | Same forms as `stylize_image`. |
| `count` | integer | no | How many to return. Default 6, maximum 20. |
| `tier` | string | no | One of `pro`, `free` or `any`. Defaults to `pro` on a Pro account and `free` otherwise. |

This is the cheapest way to answer "what would look good here", because ranking an image costs nothing while a render does.

## list_styles

The catalog this build of the engine actually supports, so a call can be made with a valid id rather than a guessed one. Returns every render mode with its id, label, category, tier and how many curated looks it has, followed by the dither palettes and algorithms.

| Parameter | Type | Required | What it does |
|---|---|---|---|
| `query` | string | no | Case-insensitive substring match against style id, label and tags. |
| `category` | string | no | One of `ascii`, `pixel`, `print`, `geometric`, `distort`, `blur`, `glitch`, `light`, `glass`, `material`. |
| `free_only` | boolean | no | Only the styles available on the free tier. |

## create_upload

Takes no arguments. Returns a one-time `upload_url` to PUT a file to, and an `image` value to pass to `stylize_image` or `suggest_styles` afterwards.

`Sending the file`
```bash
curl -sS -f -T "photo.jpg" \
  -H "content-type: image/jpeg" \
  ""
```

Set the content type to the file's real type: `image/jpeg`, `image/png`, `image/webp`, `image/gif`, `image/avif` or `image/bmp`. The link is single-purpose and short-lived, so call this immediately before uploading rather than holding one in reserve.

> **Note:** The `image` value it hands back is only meaningful as an argument to this server's own tools. It resolves inside the renderer and nowhere else, so there is no point curling it or showing it to the user as a link.

> **Warning:** On the current production build, the PUT to the upload URL is caught by the OAuth gate before the signed query string is checked, and returns 401. Until that is fixed, pass a public image URL instead of uploading a local file.

## encode_recipe

Turns a settings object into a `recipe:v1:` code and an editor link, so a look can be shared or handed back to `stylize_image` later.

| Parameter | Type | Required | What it does |
|---|---|---|---|
| `settings` | object | yes | Engine settings, for example `{"renderMode":"dither","ditherPalette":"c64"}`. |

## decode_recipe

Turns a `recipe:v1:` code, or the bare `?r=` payload from an ascii-magic.com link, into the settings it encodes. Useful for reading a look before adjusting it, and the most reliable way to discover a mode's real parameter names.

| Parameter | Type | Required | What it does |
|---|---|---|---|
| `recipe` | string | yes | A `recipe:v1:` code or the bare base64 payload. |

## account_status

Takes no arguments. Says which ASCII Magic account the connection is signed in as and whether Pro styles will render. Worth calling once at the start of a session rather than discovering the tier from a failed render.

## A worked sequence

What a well-behaved agent does with "make this photo look like a risograph print", given a URL:

1. **account_status** Once, to learn whether Pro styles are available.
2. **suggest_styles with the image** Confirms risograph actually suits this image, and offers the near misses if it does not.
3. **stylize_image with style risograph and style_requested_by_user true** The user named the style, so the flag is honest and a free style would be allowed.
4. **Look at the returned preview** If it is not good, try another variant or another suggestion before handing it over.
5. **Give the user the download link** Not a description of it.

## Errors you will actually hit

| What happened | What it means |
|---|---|
| A locked Pro style was requested on a free account | The call errors rather than silently rendering something else. Read the tier from `account_status` or `list_styles` first. |
| An unknown key in `settings` | Rejected, not ignored. Check the key against a `decode_recipe` output. |
| A file path passed as `image` | The server is hosted and has no access to the caller's disk. Use `create_upload`. |
| 401 on the upload PUT | The known gate bug above. Use a public URL for now. |
