# Sumicat > An infinite whiteboard drawn with a real sumi brush: a fourteen-hair > simulation with an ink reservoir, on paper with a tooth. Boxes, ellipses, > arrows and text like any whiteboard, except an edge is DRAWN by the brush > rather than stroked as a vector. Base URL: `https://sumicat.alcun.dev` ## Pages - [Sumicat](https://sumicat.alcun.dev/): the board itself, which opens ready to draw on. - [MCP endpoint](https://sumicat.alcun.dev/mcp): POST only, streamable HTTP, no signup. ## MCP There is a Model Context Protocol endpoint at `https://sumicat.alcun.dev/mcp` (streamable HTTP, POST only, no signup and no API key). It speaks both protocol eras: a 2026-07-28 client asks `server/discover`, an older one handshakes with `initialize`. Claude Code: ``` claude mcp add --transport http sumicat https://sumicat.alcun.dev/mcp ``` Codex: ``` codex mcp add sumicat --url https://sumicat.alcun.dev/mcp ``` Any client that takes a JSON config: ```json { "mcpServers": { "sumicat": { "type": "http", "url": "https://sumicat.alcun.dev/mcp" } } } ``` ## Tools - `create_board` - make a private board. Returns an owner, an edit and a view link. **Give the person the edit link before you draw**, so they can watch. - `draw_svg_path` - **the easy way to draw**. Give it SVG path data and the board flattens it for you: `d` takes M, L, H, V, C, S, Q, T, A and Z, each M lifts the pen, and `scale`, `x` and `y` place it. Draw in a 0-100 box and scale it up if that is easier to think in. `dry_run: true` measures a path - strokes, points and bounding box - without laying down any ink. - `draw_paths` - the same thing from sampled points, when you already have them. Each path is `[[x,y],...]` in world units; each path lifts the pen. - `draw_shapes` - boxes, ellipses, diamonds and arrows, edges drawn by the brush. - `write_text` - words on the board, in four faces and six sizes. It gives you back the BOX the words came out as, so you can place something beside them; `dry_run` measures without writing. - `read_board` - the elements, plus a separate `versions` map of id to version. **The version is NOT on the element**; take it from `versions`. - `edit_elements` - change or delete marks that are already there. - `snapshot_board` - an immutable JSON copy, revision included. - Optional `frame: "note4"` on `create_board` fixes device output to 400x300 pixels over x -600..600, y -450..450 world units. It accepts up to 32 grey/black brush strokes and 8000 points. `render_board` keeps the whole frame, including its whitespace. Ordinary boards and human Export keep their existing behaviour. - `undo_batch` - undo your own batch, leaving everyone else's marks alone. Every drawing tool takes `preset` (`ink`, `fine` or `dry`), `ink` as a `#rrggbb` colour, and `weight`, the brush size from 0.1 to 3. A vermilion seal is `draw_shapes` plus `write_text` with `ink: "#b3402a"`. A bamboo stem wants `weight: 0.2` beside leaves at the default 0.55 - without it every mark comes out the same width, whatever it is meant to be. `brush` goes under the preset for the five controls the person has in the app: `wetness`, `dryness`, `tooth`, `grain` (path wobble, called jitter in the app) and `seed`, each 0 to 1 except `seed`, which is 0 to 12. A preset is a starting point, so `{"preset": "dry", "brush": {"wetness": 0.45}}` is a rough brush that still reaches the end of a long line. ## Naming your marks `id` names the marks one call makes: `id: "leaf"` draws `leaf_0`, `leaf_1`. It is letters, digits, underscore and hyphen - **no spaces** - and it is optional; leave it out and the board makes one up. **An id that is already on the board is refused, not overwritten.** That is deliberate: a silent overwrite is indistinguishable from a write that worked. To change a mark that exists, use `edit_elements`. To draw it again from scratch, `undo_batch` first - an undone batch hands its ids back. Sending the same id with **identical** content is treated as a retry and changes nothing, so a call you are unsure landed is safe to repeat. ## Changing a mark Read the board, take the element as it came back, change the fields you want, and send the whole thing with its version from the `versions` map (**not** from the element - it is not there): ```json { "board": "...", "token": "...", "author": "...", "batch": "plant", "id": "recolour", "changes": [ { "id": "leaf_0", "version": 3, "value": { "id": "leaf_0", "t": "stroke", "i": "#b3402a", "s": 0.55, "f": "none", "d": "brush", "g": "plant", "p": [[0,0,0],[8,0,1.5],[16,0,3]] } } ] } ``` A partial value is refused: `value` is the complete element. To delete a mark, send `"value": null` - explicitly, because leaving `value` out is a mistake rather than a deletion. `s` is the brush size, 0.1 to 3, and it is the only way to make a stroke thinner or fatter than its preset. ## What a write gives you back A drawing call returns what it did, not the board: ```json { "ok": true, "rev": 14, "batch": "plant", "drew": ["leaf_0", "leaf_1"], "bbox": { "x": -40, "y": -390, "w": 704, "h": 776 } } ``` `read_board` is how you get the elements, and it is the expensive call, because a stroke carries every sampled point. Read when you are about to edit, not after every stroke. ## Drawing well The mechanics above get a mark onto the board. This is how to make it good. All of it comes from drawing on this board and then looking at the result. **Design in a 0-100 box and place it with `scale`, `x` and `y`.** Thinking in a hundred units is easier than thinking in world coordinates, the numbers stay short, and you can move or resize the whole drawing by changing three arguments instead of rewriting every path. `scale: 9` puts a 0-100 design into a comfortable 900-unit drawing. **Say it in few strokes.** This brush rewards one confident sweep over ten careful short ones, because the ink, the taper and the dry break all develop ALONG a stroke. A contour drawn as one curve looks drawn; the same contour in five pieces looks assembled. If you are reaching for a tenth stroke, look for the one stroke it wants to be. **Every stroke tapers in and out.** A path always starts and ends at rest, so a straight line comes out as a long lens, not a bar. Use it: a reed, a tail, a whisker and a blade of grass all want to end in a point, and they get one for free. Do not fight it by chaining segments - that puts a taper in the middle. **Weight is ink, not line thickness, and a short mark needs MORE of it.** The brush reaches about 61.5 x weight units of width only after running 128 units. So the same weight is a band on a long stroke and a hairline on a short one. A 50-unit mark at weight 0.11 comes out about 1.7 wide and is invisible; at 0.45 it is 7 wide and reads. Check the `ink_width` that comes back, and when a short mark is meant to be seen, raise the weight until it is. **Wetness is reach.** A stroke longer than the tank fades to nothing with a perfectly healthy bbox. `dry` is a beautiful brush and it only lasts about 150 units, so it is for accents. For a long stroke that should still look dry, ask for it: `{"preset": "dry", "brush": {"wetness": 0.45}}` is broken ink that reaches the end of the line. Every call tells you `fades_after` when there is a limit. **Vary the weight across the drawing.** A subject drawn at one weight reads flat. Heavy for the mass, light for the detail: a body at 0.3, a limb at 0.1, a whisker at 0.08 of the body's weight. This is the single biggest difference between a drawing that looks like ink and one that looks like a diagram. **Draw back to front.** Marks stack in the order you make them, so background first, subject next, foreground last. Putting two reeds in FRONT of a bird's legs is what makes it stand among them rather than behind them. **Vary the weight WITHIN a form, not just between forms.** One weight held over a long stroke gives a bar with a taper at each end, which is a pencil, not a branch. A branch, a stem, a tail or a trunk wants to be several strokes of DECREASING weight laid end to end - 0.3 at the base, then 0.22, then 0.15, then 0.09 at the tip. The joins are not a defect: they read as knuckles, which is what the subject actually looks like. The first plum branch drawn here was one stroke at one weight and came out as a spear. **A dot needs a very heavy brush.** A petal, an eye or a berry is so short that the brush lands and lifts without ever running, so it barely marks the paper at an ordinary weight. Weight 1.5 on a one-unit path is a small round blob, and the "this will read as a blob rather than a line" warning is the GOAL here rather than a problem. Cluster five of them within about two design units of a centre and they read as a flower; spread them further and they read as confetti. **A circle is much longer than it looks.** Two arcs make one: `M 30 36 A 26 26 0 1 1 82 36 A 26 26 0 1 1 30 36`. But its stroke length is 2*pi*r, so a modest-looking moon can be 1500 world units of travel and will fade away on an ordinary brush. Raise the wetness and check `fades_after` before committing it. **Pale ink recedes.** `ink` takes any `#rrggbb`, so a distant moon at `#9c958a` sits behind a black branch with no layering trick at all, and a muted colour picks out blossom or fruit without shouting. Keep one strong accent - usually the seal - and let everything else be quieter than it. **`dry_run` everything before you commit it.** It costs nothing, uses no id, and tells you the width, the fade and the bounding box. Run the whole drawing as dry runs first, read the warnings, fix the weights, then draw for real. **Keep a board renderable.** `render_board` refuses a board over 128 elements, 20000 stroke points or 1 MiB, and on a busy shared board the ELEMENT count is what runs out first - a real two-person board hit 225 while its points and bytes were both still under. If you are drawing something you want to check, keep it to one subject per board rather than filling one board with everything. **Then look at it.** You cannot see the board, and no number will tell you the composition is wrong. Two or three checkpoints in a drawing is the right rate - after the big shapes, and before the details. Ask the person to look, or render it yourself. Every genuinely bad drawing made through this endpoint was made by an agent that never looked. **Leave space.** Sumi is mostly paper. A drawing filling 60% of its own bounding box with the rest empty reads as confident; one crammed edge to edge reads as anxious. Resist filling the corners. **Size text for the zoom a person will actually see it at.** Sizes run `S` to `XXXL`. A caption beside one mark can be `S` or `M`, but a label meant to be read when the whole board is on screen wants `XXL` or `XXXL` - small text disappears the moment somebody zooms out to look at what was made, which is exactly when a label matters most. **Place words against the drawing, do not guess at them.** `write_text` returns a `bbox`, and `dry_run: true` gets you one without writing anything, so a caption can be centred under a mark or a signature tucked beside it in one extra call. Two caveats it tells you about itself: the width is the sum of the characters and so ignores kerning, which is under 1% on ordinary text and up to 8% on something like "AVATAR Wavy"; and `hand` and `brush` are exact because this board serves those fonts, while `plain` and `mono` are the viewer's own system faces and come back with a note saying the size is close rather than certain. If the placement matters, use `hand` or `brush`. **Sign it if you like.** A vermilion square with a few strokes inside, at `ink: "#b3402a"`, in a bottom corner. The text faces are latin-subset, so a seal is drawn as strokes rather than written as a CJK character. ## Notes for agents - **The links are the access control.** Anyone holding an edit link can draw. Do not post one anywhere public, and do not put one in a commit. - **Invent one author secret** of at least 32 random characters, keep it for the whole session, and reuse it: `undo_batch` can only undo marks made under the same author. - **One batch name per drawing.** Everything sharing a batch undoes in one go, which is what a person expects when they say "no, not that". - Coordinates are world units, x right and **y down**. A comfortable drawing fills about 1200 by 800 around the origin. With `draw_svg_path` the spacing is the board's problem; with `draw_paths` space points 6 to 12 units apart, because closer is wasted and further reads as a straight line. - **Geometry is not ink, and this is the thing that will surprise you.** The brush deposits about **61.5 x weight** world units of width, and it only gets there after the stroke has run **128 units**. So weight 1 on a 200-unit stroke is a band 60 wide; the same weight on a 30-unit stroke is a blob about 7 across; and weight 2.6 on a 7-unit segment is 5 units of ink on 7 units of line, which reads as a splodge whatever the path says. For a mark that reads as a line, keep it at least ten times longer than 61.5 x weight. `dry_run` reports the width before any ink is laid, and every drawing call reports it after, with a warning when a stroke will pool. - **The brush also RUNS OUT, which is the other thing you cannot see.** It carries a tank, and a stroke longer than the tank fades to nothing while its bbox and its width stay perfectly healthy. How far it reaches is set by `wetness` alone, near enough: about 2200 units at the default 0.5, about 460 at 0.3, about 150 at 0.2, and past 0.65 it never runs dry. The `dry` preset sits at 0.2, so it is for short accent strokes - an agent drew a seal with a long dry contour and most of the silhouette came out invisible. Calls report `fades_after` whenever there is a limit, and warn when a stroke exceeds it. - Every stroke also tapers in and out, the way a loaded brush does: a straight line comes out as a long lens, not a bar. - **Look at composition checkpoints.** `render_board` returns the real brushed board as an inline PNG, up to 1024 pixels on either side. Use two to four checkpoints per drawing. The first call says queued and gives an estimated wait and a revision; repeat with that revision to get the image. Omit revision for a new checkpoint after editing. Numbers catch width and fade, but only looking catches "it does not look like a cat". Rendering has its own budget: three new images a minute across the server, one active and two waiting. Polls and cached images do not spend it. Limits: 128 elements, 20000 stroke points and 1 MiB of drawing data. Cache lasts two minutes; old revisions can expire. If rendering is unavailable or the board exceeds the limits, ask the person to look. - Drawing is deliberately paced so a person watching sees the pen move. A batch of many paths takes a few seconds; that is not a stall, it is the show. - Every write is versioned. If an edit returns a conflict, read the board again and retry with the version you just read rather than forcing it. - Errors are a tool result with `isError`, and they name the field and the rule it broke, so read the text and correct the call. A 429 means the per-IP limit; wait a minute. - A view link cannot write, and a revoked link stops working immediately.