A call lacking its one needed argument but carrying one unknown
argument of that type is run with it (open_workflow {name} is
{workflow}), and the AI is told the right name. The timeline names
zoom_image steps; a test makes every tool have a name in both
languages. tool-exam.md records the second exam, all eight tasks
including the repaint one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Gemini 3.8 Flash took seven exam tasks through Antigravity (107 calls, 19
failed, every task done). Nearly all failures were a tool's first use:
empty or guessed arguments. So:
- An argument error lists what the tool takes ("set_prompt takes: prompt
(needed), role, node_id, mode"), and the next call is right.
- One argument name per thing: set_prompt's text is prompt (as in
run_workflow), open_workflow's name is workflow (as in run_workflow).
- A wait over 55 s waits 55 s instead of failing; search_models takes a
model type in the singular too.
- An unread reply older than two hours no longer draws a new chat's calls
into its old task (a two-day-old mark took the first exam task).
The exam doc gets the setup, the Antigravity command line and the results.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- An AI app calling by an older tool list (tool_help or use_tool not offered,
use_tool for a tool offered directly, a tool the list lacks) is told so, and
the task header shows how to reconnect until the app fetches tools/list again.
- add_lora / set_model compare the base models on the model line
(model_advice.py; the page reports the line) and add base_model_note.
- get_model gives author_examples (sampler, steps, CFG, size, a LoRA's weight
from the Civitai record's example pictures) and the version name.
- run_workflow says ComfyUI's refusal as which node, what is wrong and the tool
that fixes it (run_refusal.py; mcp_run.js passes the refusal as data).
- Gates "When I don't answer": wait for me, or go with the recommendation once
the waiting time runs out (choices with a recommended option only), handed to
the AI in the same call and shown on the stage and under Decisions.
- A tool budget test (count, size, description length, required arguments) and
the exam tasks with their scorecard (docs/architecture/tool-exam.md,
tools/tool_exam.mjs). The tool set's text recommends Full for Antigravity.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In the user's real tasks the AI spent many calls finding its way: reading the
canvas, searching node types, looking at combos and the activity log. The
directory gives it what ARCHITECTURE.md gives the code: each tool offered,
under its stage of the work, with its title. The stages are run, canvas,
models, prompts, combos, pictures, voices, the library, and the task and the
user. Seeing it, the AI can go straight to the tool it needs.
The directory is built from action_catalog's stages and the tool specs, so a
new tool shows up by itself, and a test checks that every stage has a heading.
It lists only the tools offered: about 1,100 characters for the daily set and
2,000 for the full one. begin_task's answer carries it, and so does
get_situation's while there is no task. The server's instructions and
begin_task's note point to it.
retext, the helper that rewrites a result's text from its data, moves from
ai_task_runs to mcp_tools, so both modules share it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The descriptions of the daily set are rewritten without the repeats and
roundabout phrasing. Their rules and don'ts stay: no cropping or editing
pictures with code, no reading ComfyUI's folders, ask the user in the
workbench. So do the shared property texts: the query words, node ids, the
task id. tools/list for the daily set drops from about 27,300 to 22,200
characters, and the full one from 46,000 to 40,700. begin_task's note, read at
the start of every task, drops from about 1,900 to 900 characters. The
replacements were made with ast, so each description's adjacent literals
changed as one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In one hour Gemini ran 63 shell commands next to 23 AMB calls: checking files, cropping and
comparing parts of pictures, running OpenPose itself to see a skeleton, and painting pixels
with OpenCV (it overwrote an output picture six times).
- api/mcp_look.py zoom_image: part of a picture in the output, input or temp folder shown
larger, the same part of a second picture beside it; read only.
- get_image_info reads the temp folder too; run_status lists a run's PreviewImage pictures
(ai_task_runs.outputs_of(record, "temp"), kept as the step's previews, not its results).
- begin_task and the repaint note: AMB's tools cover looking; change pictures only by running
workflows, never by editing picture files with code of one's own.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The inpaint picture a repaint mark writes is in the input folder, which get_image_info did not
read, so the AI checked it with a shell command (and the user had to allow it). get_image_info
with folder=input gives such a picture's size and the area LoadImage gives as MASK (where and
how much), optionally attached; the marks message says the picture is in place already.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Antigravity saves a tool result over about 4,000 characters to a file and has Gemini open it;
in one evening 16 of its 32 file reads were AMB results (describe_canvas 9 times). Results are
now compact JSON (mcp_tools.tool_text, also for attached answers and run status), the canvas
leaves out the page's own "$$" widgets, and recent_activity gives the last 10 by default.
begin_task also tells the AI that AMB's tools cover models, pictures, nodes, canvas and runs,
so it need not read ComfyUI's folders, source or routes (each asks the user to allow it).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- model_kind: Anima LLLite, Qwen-Image block-wise and Z-Image Fun ControlNets (and other
ModelPatchLoader files) go to model_patches, not controlnet; import and Tidy follow.
- api/mcp_model_use.py: search_models / get_model say which node types load each model, or
where a misfiled one belongs; move_model moves it there behind a new "files" gate (asks by
default, never overwrites).
- An empty drop-down in add_node says ComfyUI found no file; the task tab switch is no longer
logged as the user's canvas change.
- The folded task list stays while the pointer is in the box around its button and the list.
- The message box's picture button picks gallery pictures; "@" offers the gallery's newest and
searches it as you type.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A task's pictures no longer in the output folder are marked gone when the
task is read and shown as "Picture deleted" (timeline, results strip,
stage panels and picks) instead of a broken picture; "@" no longer offers
them. The AI hears plainly that the user deleted one, and a tool reading a
gone picture says it may have been deleted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Each run keeps its shape read from the prompt ComfyUI queued (ai_run_map.py): boxes by role
with their settings, typed links, plumbing wired through, and what changed since the task's
run before. The run step shows a one-line summary, the changes as chips and the boxes (top
down, fitted to the column, each locating its node); show_run_map puts it on the stage.
- By default the AI works in a tab of the task's own (ai_task_canvas.py, mcp_task_tab.js): the
open workflow is copied before its first change, the tab is brought back (a click on
ComfyUI's tab) before later changes, reads and runs, and the user's tab stays untouched.
Per-task switch in the header, default in the Gates window; the AI is told once.
- Output pictures can be handed to the task an AI is on (gallery card menu, the inspector's
✦), with the user's words: the AI gets them attached with what made them (ai_pictures.py).
search_images(with_pictures) attaches the first six.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A large window: one search over every kind (/ jumps to it), kinds on the
left with picks and matches, a column by source (each custom node pack
with a badge of its own colour, ComfyUI's own, paid API nodes), prompt
origin or model type, a card grid drawn as it scrolls, the card in focus
in full on the right, and the picks below with thumbnails and a prefer /
only switch. A node card is the node in miniature, sockets in ComfyUI's
colours; combos, workflows and models show their covers; prompts their
text, including the prompts inside combos and workflows (combo:<name>,
workflow:<name>), which get_toolbox now resolves. Vector icons, badges
and the empty picture follow the theme.
It opens at once: node types come from the page's own definitions, the
rest in one answer (api/ai_toolbox_catalog.py) read ahead when a task
header is drawn and kept a minute, refreshed behind an open window.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On an AutoDL server every model in the models folder is a link into the
platform's shared, read-only model disk, named like 6b4679... without an
extension. Scans wrote the .info beside the link, but get_metadata
resolved the path and read beside the disk's file: a scanned model
showed as not scanned, under the disk's file name. Delete, edit, open
folder, MCP and saved-workflow lookups resolved the file too, so they
refused it as outside the models folder (or, for a link inside it, would
have acted on the file behind it).
path_utils.model_file_within joins a resolved folder with a bare name
(require_filename, which now refuses "." and ".." too);
model_reference_within resolves the subfolders of a relative path inside
the root, through links as before, and takes the file as named.
get_metadata reads beside the path it is given (abspath). Edits, renames
and deletes act on the link; nothing writes into a model file.
Checked with a link stood in by patching realpath (this computer cannot
make links): the info beside the link is read and the name is the
link's; "..", ".", "a/b" and a relative path leaving the root are refused.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A combo can now hold its own node structure: pick nodes on the canvas and
New -> From the nodes picked on the canvas keeps the model nodes (a
drop-down of model files) and the text nodes (a multiline text box by the
node's definition) with the links between them; other picked nodes and
links to them are left out, their ports stay open on the canvas.
Slots are per box, so a node with several model drop-downs has several; a
box fed by a link is no slot. Each model slot's folder is the one whose
files hold all its drop-down's model-file options (ComfyUI's /models
lists), never guessed from names. Every other box is stored by name and
put back untouched, in order (a count box adds its rows first).
The save dialog shows what is kept and dropped and lets slots be renamed
or unticked. The editor lists the slots: a picker of that folder's models
with covers, filtered by base model, and text boxes. Put on canvas makes
the nodes (missing node types and their packs are named before anything
is placed), fills the slots by name, links by port name and type, as one
Ctrl+Z step; a box or link that cannot be restored is reported, never
guessed. New -> Same structure as ... starts another combo from a saved
structure. The default combo is unchanged. MCP list_combos lists node
combos by slot and place_combo places them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The second batch of MCP tools: they change things, through the same code the UI uses.
- Canvas, done by the open ComfyUI page: describe_canvas, set_prompt, set_model,
add_lora, place_combo, check_workflow_models, fix_workflow_models, run_workflow,
open_in_anomalous. api/mcp_bridge.py sends the action over ComfyUI's websocket and
waits; web/modules/mcp_bridge.js claims it (visible tab first), does it with
Anomalous's canvas code and answers. Each change is one Ctrl+Z step, shows a toast and
is logged as the AI's (activity entries carry via: "mcp", with their undo).
- This server: scan_models (new / look up again / picked models, via /anomalous/scan_all),
list_voices and speak (Anomalous TTS through /prompt and /history).
- graph_splice.js takes the chain's slot types, so a LoRA can go into a model-only (UNet,
Flux) chain as LoraLoaderModelOnly; the default (MODEL and CLIP) is unchanged.
- Nothing deletes or renames files; acting tools are not marked read-only, so AI apps
ask before calling them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An MCP endpoint (Streamable HTTP) inside ComfyUI's server, so Claude, Cursor, Cherry
Studio and other MCP apps can ask about the user's library without anything extra
installed and without memory or VRAM while nobody is connected.
- api/mcp_server.py: one JSON-RPC message per POST, answered with JSON. Serves the
2026-07-28 stateless protocol (headers must match the body) and the earlier
initialize-based versions; no sessions. This computer only: loopback peer, no proxy
headers, loopback Host and Origin (DNS rebinding).
- api/mcp_tools.py: 11 read-only tools: library overview, model search and details
(optional cover), scan status, output-image search and generation settings
(optional thumbnail), combos, workflow recipes, saved prompts, generated audio,
activity log. Ids resolve inside their roots; tool failures come back as isError.
- docs/guides/mcp.md: setup for each app, what can be asked, privacy note.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>