> ## Documentation Index
> Fetch the complete documentation index at: https://comfyui-mcp.artokun.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Using the tools

> What the tools are, why you never call one yourself, and what to do when one says no. Written for people, not for engineers.

The [Tool Reference](/docs/tools/image-generation) lists everything this project can do, in the form the AI reads it. This page is the version for you.

<Note>
  Nothing here requires you to write code, type JSON, or learn an API. If you have
  ever asked a person to "open my portrait workflow and bump the steps to 30",
  you already know the interface.
</Note>

## A tool is a thing the agent can do, not a thing you type

On its own, a chat model can only produce text. It can describe a workflow; it cannot open one.

A **tool** is a specific, named action we hand the model so it can actually reach your ComfyUI — load a file, queue a render, install a node pack, look at the picture that came out. The model does not get to invent these. It gets a fixed menu, and each item on the menu says exactly what it needs.

**You never pick from that menu.** You say what you want, in whatever words come naturally, and the agent chooses.

| You say                                          | It quietly runs                                                |
| ------------------------------------------------ | -------------------------------------------------------------- |
| "What have I got saved?"                         | `get_workflow` with `action: "list"`                           |
| "Open the portrait one and tell me what it does" | `get_workflow` with `action: "list"`, then `action: "analyze"` |
| "Make me a red fox in the snow"                  | `generate_image` (the `image` job)                             |
| "Is it done yet?"                                | `queue` (the `list` job)                                       |
| "That failed and I don't understand why"         | `get_history` (the `diagnose` job)                             |
| "Half the nodes are red"                         | `list_packs` (the `install_deps` job)                          |
| "I'm out of disk space, what's big?"             | `list_local_models`                                            |

Notice the second row: one sentence, two tools, in an order you did not have to know. That is the point of the whole arrangement. You are not expected to know that finding a file and reading a file are separate operations.

<Tip>
  You can be as vague as you like. "Something's broken" is a perfectly good
  opening — the agent will start with `get_system_stats (action:"health")` and narrow down. Being
  specific gets you there faster, but it is never required.
</Tip>

### So what is all that JSON in the reference pages?

Every tool page shows a block like this:

```json theme={null}
{
  "tool": "generate_image",
  "arguments": {
    "prompt": "a red fox in deep snow, golden hour, sharp focus",
    "steps": 30
  }
}
```

That is a transcript of what the agent sent, not an instruction to you. You said "make me a red fox in the snow, and put a bit more detail into it"; that is what came out the other end.

It is worth being able to read one, for two reasons: when you want to check the agent understood you, and when something goes wrong and you are describing it to someone else. It is not worth memorising.

## Two places tools come from

There are two surfaces, and they exist because they answer different questions.

<CardGroup cols={2}>
  <Card title="The sidebar panel" icon="window-maximize">
    Lives **inside ComfyUI**, in the Agent tab. Its tools (`panel_*`) act on the
    graph you are looking at right now — the actual canvas, with your unsaved
    changes on it.
  </Card>

  <Card title="An outside client" icon="terminal">
    Claude Desktop, Claude Code, an editor, your phone. Its tools act on the
    **server**: files on disk, the job queue, models, node packs, the ComfyUI
    process itself.
  </Card>
</CardGroup>

The split is really about the word "this". When you say "add a LoRA to **this**", the panel knows what "this" is, because it can see your screen. An outside client cannot — it has to be told a filename.

So the panel handles things like:

* reading the graph in front of you (`panel_graph_outline`)
* running it, exactly as if you had hit Queue Prompt yourself (`panel_run`)
* wiring a node in, changing a widget, telling you why a node went red (`panel_add_node`, `panel_set_widget`, `panel_get_errors`)
* loading a whole workflow onto the canvas, or saving what is there (`panel_load_workflow`, `panel_save_workflow`)

And an outside client handles things like generating an image from scratch, managing models and node packs, working through saved files, and restarting ComfyUI.

<Tip>
  **If you are new, use the panel.** It is one install, it is right there next to
  your graph, and it does not need a separate app. See
  [the panel guide](/docs/panel) to set it up. Add an outside client later, when you
  want the agent involved in things that are not a canvas.
</Tip>

They are not rivals — the panel talks to the same server underneath, and a session can use both. Someone editing a graph on their desktop while a phone drives the same session is a supported thing, not a hack.

## One tool, several jobs

You will notice some tools take an `action`:

```json theme={null}
{ "tool": "workspace", "arguments": { "action": "get" } }
```

This looks cryptic and is not. `workspace` is a topic — *which ComfyUI installation are we talking about* — and `action` says which question you are asking about that topic: read it, change the default, list what is available.

It reads exactly like ordinary speech, where the verb and the object are separate words:

| You say                            | Action        |
| ---------------------------------- | ------------- |
| "Which ComfyUI am I using?"        | `get`         |
| "Always use the one on my D drive" | `set_default` |
| "What installations can you see?"  | `list`        |

### Nothing was removed

This shape is new-ish, and it is easy to read it as capability being cut. It isn't, and the confusion is worth heading off directly, because it has already come up.

There used to be one tool per question — a separate name for reading a workspace, another for setting it, another for listing them. Those names are gone, and if you watch the tool count you will see it falling, sharply.

What actually happened is that related tools were **merged**, not deleted:

| The old name                    | The same thing today                        |
| ------------------------------- | ------------------------------------------- |
| `get_workspace`                 | `workspace` with `action: "get"`            |
| `get_queue`                     | `queue` with `action: "list"`               |
| `apps_run_status`               | `apps` with `action: "run_status"`          |
| `install_workflow_dependencies` | `list_packs` with `action: "install_deps"`  |
| `list_workflows`                | `get_workflow` with `action: "list"`        |
| `analyze_workflow`              | `get_workflow` with `action: "analyze"`     |
| `validate_workflow`             | `create_workflow` with `action: "validate"` |

Same code underneath, same behaviour, same answers. Only the label on the front changed.

The reason is that the menu got long enough to hurt. Every tool's full description has to be handed to the model before it can choose, and past a certain size the choosing itself degrades — smaller models in particular start picking a plausible-looking neighbour instead of the right one. Fewer, broader tools with a clear `action` measurably fixes that. It also means the model spends its attention on your request instead of on reading a catalogue.

You should not notice any of this. You never typed the old name either; you said "which ComfyUI am I on?", and that still works.

<Note>
  If some older guide or a model's own memory reaches for a name that no longer
  exists, you get a specific error naming the replacement rather than a blank
  "unknown tool" — for example: *removed in 0.49.0. Call workspace (action:"get")
  instead.* The agent can usually correct itself and retry without you doing
  anything.
</Note>

## Asking for something different

Every tool page lists parameters — `max_chars`, `limit`, `depth`, `fields`. It is a fair question where you are supposed to type them, and the honest answer is: nowhere. There is no settings box for `max_chars`, because it is not a setting. It is an argument the **agent** fills in, freshly, each time it calls the tool.

That does not leave you out of it. It changes what the control looks like:

<Note>
  You don't set a parameter. You ask for one — in the same sentence you were
  going to write anyway.
</Note>

### Two ways to ask

Both work. They fail differently, which is the only reason to know both.

|              | Sounds like                                                       | Reach for it when                                                         |
| ------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------------- |
| **Plain**    | "Read node 42 in detail — just that node, not the whole graph."   | Always start here. It is what people actually type, and it usually works. |
| **Explicit** | "Use `panel_query_graph` with `ids` \[42] and `max_chars` 20000." | The model already got it wrong once and you want to leave it no room.     |

Naming the tool and the argument is not the *correct* form — it is the *forceful* form. Keep it for the retry.

### When the answer gets cut off

Long reads are capped so that one enormous graph cannot swallow the whole conversation. Two different ceilings can stop the same read — the number of nodes listed (`limit`) and the character budget (`max_chars`) — and raising the one that was not the problem changes nothing, which reads exactly like the retry having failed.

You are not expected to work out which. On a saved file, the note **names the lever that fired and rules out the other one**, in as many words:

> … truncated at 40 of 300 by `limit`=40 — raise `limit` up to 200, or narrow with `types`/`where`/`ids`/`depth`. `max_chars` is not the constraint here.

And when the lever is already at its ceiling it says so instead of sending you to raise it again, because there is nothing left to raise.

<Note>
  On the live canvas (`panel_query_graph`) the same read is executed by the panel's
  own copy of this engine, which has not caught up with that wording yet. If a note
  there names an argument and raising it changes nothing, try the other one before
  concluding the tool is broken.
</Note>

The agent is meant to read its own note and retry by itself. When it doesn't, you are the fallback, and this is the sentence:

> That got truncated — read the note and retry the same query, raising the limit it names.

### Where the walls are

These are the numbers for the two tools that read a graph on a budget — `panel_query_graph` (the live canvas) and `get_workflow` with `action: "query"` (a saved file):

| Argument               | Default | Most you can ask for |
| ---------------------- | ------- | -------------------- |
| `max_chars`            | 12000   | 60000                |
| `limit` (nodes listed) | 40      | 200                  |

On these two tools, asking past a ceiling is rejected as an invalid argument rather than quietly rounded down, so the agent finds out immediately and can correct itself. The numbers are not universal, either: several other tools take a `max_chars` and set their own ceiling, stated in that tool's own description.

### Scope beats budget

Raising the ceiling is the second thing to try, not the first. On a 600-node workflow, a bigger budget mostly buys you more of the wrong nodes, and burying the answer among hundreds of irrelevant ones degrades the reply even when it technically fits.

Narrow first, in whatever words are natural:

| You say                                   | What it narrows to            |
| ----------------------------------------- | ----------------------------- |
| "Just look at nodes 42 and 43."           | those ids only                |
| "What feeds into the sampler?"            | the upstream side of one node |
| "…only two hops back."                    | a bounded distance from there |
| "How many of each node type are in here?" | counts instead of a listing   |

Then, if it is still cut off, widen.

## When it says no

A tool refusing is not usually a bug. Most refusals are a guard that fired because the call would have done something you did not ask for.

### "It refused and I don't know why"

You will see plain-language text rather than a stack trace — something naming what it would not do and what to do instead. Read it as the agent being careful, not stuck. Common honest refusals:

* **It cannot tell which workflow you mean.** More than one tab is open, or the graph has no saved identity yet. Save it, or say which one.
* **It would overwrite something.** Ask for a new filename and it will proceed.
* **The thing genuinely is not there.** A model file, a node pack, a running server.

If a refusal reads as nonsense rather than caution, that is worth reporting — ask the agent to file it, and it will attach your setup details for you.

### "This panel is too old"

The most common refusal with a real fix. It reads roughly like:

> This ComfyUI-MCP panel is too old for *"…"* — update the ComfyUI-MCP panel, then reconnect.

The sidebar panel and this server are separate pieces that ship separately, so one can lag the other. When the server asks for something the installed panel cannot do safely, it declines rather than guessing — an old panel that cannot confirm *which* workflow a command lands on could apply your edit to the wrong tab, so it is held to reads until it is updated.

The fix is three steps, and **the third is the one people skip**:

<Steps>
  <Step title="Update the panel">
    Ask the agent to update it (`install_comfyui(action:'panel')` with `action: "update"`), or do it
    from ComfyUI-Manager, where it is listed as `comfyui-agent-panel`.
  </Step>

  <Step title="Restart ComfyUI">
    The update does not restart anything on its own. Ask the agent, or restart it
    yourself.
  </Step>

  <Step title="Hard-refresh the ComfyUI browser tab">
    **Ctrl+Shift+R** (**Cmd+Shift+R** on a Mac). Your browser has the old panel
    code cached, and a restart alone will not shake it loose. Skip this and the
    same message comes straight back, which is why it looks like the update
    failed when it did not.
  </Step>
</Steps>

### "No panel connected"

Different problem, similar-looking message. This means the outside agent cannot find your ComfyUI browser tab. Nearly always it is one of:

* ComfyUI is not open in a browser at all — open it and look at the Agent tab in the sidebar.
* ComfyUI was just restarted, or you reloaded the tab. That drops the connection. **Reload the ComfyUI tab** and it comes straight back.
* The Agent tab is open but has never been connected. The panel attaches when you pick a provider and click **Connect**, never on load, so a freshly opened tab showing nothing is the ordinary state rather than a fault.
* The panel is not installed yet. See [the panel guide](/docs/panel).

The message splits these into two groups for you — it distinguishes "connected earlier and dropped" from "nothing has connected yet". It does not go further than that, and it says so rather than picking a cause it has no way to observe. A tab that connected earlier proves the panel is installed and was working, so reloading the ComfyUI tab is the first thing to try and usually the only thing; if the reload does not bring it back, treat it as the second group and work down the checks above.

## When it says nothing

The harder failure is the one with no error in it at all. The agent does not call a tool, does not refuse, does not complain. It just talks: it describes what your workflow probably contains, or offers to write you a script. It sounds helpful, and it never looked at anything.

Three completely different situations produce that same behaviour, and from where you are sitting they are indistinguishable:

<CardGroup cols={3}>
  <Card title="Absent" icon="circle-minus">
    Your client never got the tools. They are not in the list it hands the model,
    so there is nothing to call.
  </Card>

  <Card title="Blocked" icon="hand">
    Your client has the tools and will not let the model run them. The call is
    stopped inside your client.
  </Card>

  <Card title="Not asked for" icon="eye-slash">
    Everything works. The thing you wanted exists under a name that never came up,
    so nobody reached for it.
  </Card>
</CardGroup>

The remedies point in three different directions, and two of them are actively harmful if you guess wrong: reinstalling what is already installed, or loosening permissions that were never the problem. So the first move is not to fix anything. It is to find out which one you are in.

### Two questions that separate them

Ask the agent, in plain words:

<Steps>
  <Step title="Ask what it can see">
    > What tools do you have from comfyui-mcp? Just list the names.

    A list of a few dozen names is normal and healthy — that is the direct
    surface, which has been the default since 0.50.0.

    **Three names** — `list_tools`, `describe_tool`, `call_tool` — is *also*
    normal and healthy. That is [compact mode](#if-you-run-a-small-local-model),
    which you get by passing `--compact`, and which small local models still
    select automatically. The rest of the catalogue is one `list_tools` call
    away, so ask it to run that and you will see the real list. Neither answer
    means anything is held back.

    **No names at all**, or "I don't have any tools for ComfyUI", rules out the
    third case and nothing else. It does **not** mean absent. A permission policy
    can withhold tools from the list the model is shown, so a server that is
    installed, connected and working produces this exact answer. Absent and blocked
    are indistinguishable at this step, and this is the branch that cost a user days
    — being sure it was the wiring.

    One check narrows it, and it is not something the agent can see: **open your
    client's own list of MCP servers** — the place it shows which servers it
    connected to, which is a different list from the tools it hands the model.

    * **comfyui-mcp is not there, or shows as failed** → **absent**. A client-side
      wiring problem, not a panel or server fault. It splits again into two — never
      wired up, or a host that cannot hold them at all — and the list
      [below](#where-each-answer-usually-comes-from) tells those apart.
    * **It is there and connected, and the model still lists nothing** → the tools
      reached your client. Where they stopped after that is still open: they may be
      withheld from the model by a permission rule, or the model may simply have
      failed or declined to list them, which looks exactly the same from here. Do
      **not** start loosening permissions on this alone.

      If that server list also shows **which tools it took from comfyui-mcp**, it
      settles it: tools listed there but not by the model means the model is the
      problem, not your permissions; none listed there means they are being filtered
      before the model ever sees them. If your client does not show that — and many
      do not — nothing available to you distinguishes the two here, and step 2 is
      the better chance, because a denial comes back in words.
  </Step>

  <Step title="Ask it to try, and to report back verbatim">
    > Now call the one you'd use for the thing that isn't working, and paste
    > exactly what comes back — including any error. Don't work around it.

    Two details in that sentence are doing the work.

    **The tool you'd use for the thing that isn't working**, specifically. Permission
    rules are usually written per tool, so a different tool succeeding proves nothing
    about the one you care about — that is precisely how a block hides. If the canvas
    is what is not being read, the test has to be a canvas read.

    **Don't work around it.** The whole failure mode is an agent quietly routing
    around an obstacle instead of naming it, and left to itself it will do that again.

    * **A real result** — that tool works. You are in the third case.
    * **"That was denied" / "not permitted" / "I need permission"** — **blocked**,
      inside your client. This one is conclusive: the agent asked and was refused.
    * **"I don't have that tool"** — absent *or* blocked, still. A withheld tool and
      a missing one look identical from the model's seat, so do not act on this by
      itself: take it back to step 1's server list, and if that list does not show
      per-server tools either, then nothing you can reach separates the two and the
      honest next move is to ask in the issue tracker rather than to start changing
      settings.
    * **More prose, still no call** — ask flatly: *"Did you call a tool? If not, why
      not?"* An agent that dodges twice is usually working around something it has
      not mentioned.
  </Step>
</Steps>

### What we can see from here, and what we cannot

<Warning>
  When your client refuses a tool call, that call never leaves your client. Nothing
  reaches this server, so nothing appears in its log and no error is produced
  anywhere we can reach. We cannot detect a block, and we will not pretend to: any
  page or message claiming to tell you "your client blocked this" would be guessing.
</Warning>

The same fact cuts the other way, and it is the part that misleads people: a quiet log is not evidence that nothing was attempted. Absent, blocked, and never-asked-for all look like silence from here.

Which is why the two questions above are the real diagnostic. They work because they ask the one participant who *was* in the room — your agent — to say what it tried, and refuse it the option of routing around the answer.

### Where each answer usually comes from

**Blocked — your client's own permission rules.** In Claude Code that is the `permissions` block of `settings.json` (`~/.claude/settings.json`, or the project's `.claude/settings.json`); MCP tools appear there under their namespaced names, `mcp__comfyui__<tool>`. A strict `allow` list that never mentions them stops every call before it is sent. This is the case that cost one user several days: the tools looked like they were working, precisely because the errors he was hunting could never appear.

**Absent, and fixable — never wired up.** The client speaks MCP but was never told about this server, or was told and the entry is wrong. This is the common one and it is a config edit; see [Quickstart](/docs/quickstart) for the entry your client expects.

**Absent, and not fixable — a host with no MCP client at all.** Some agents do not speak MCP, and no amount of configuration changes that. `pi` is one: it has its own built-in shell-and-editor tools and no MCP client, so it cannot be handed ours whatever else is installed. The panel says so outright when you pick it — *"pi has no ComfyUI tools (no MCP)"*. That line is the answer, not a symptom to debug; the fix is to pick a different backend.

**Either — something sitting in between.** A gateway, proxy, or router carrying your MCP traffic may pass along only part of the surface. If the catalogue and what actually runs disagree with each other, suspect the middle.

### If it turns out to be the third case

Then nothing was broken and nobody misconfigured anything: a capability existed and you had no way to find out. That is our failure rather than yours, and it is worth telling us — ask the agent to file it and it will attach your setup for you. A feature nobody can find is, from where you sit, a feature we did not ship.

## If you run a small local model

Handing the entire menu to a model costs a lot of reading before it says a word. On a large hosted model that is fine. On a small model running on your own machine it is often the difference between working and not.

So by default the agent gets **three** tools instead of the full set: one to browse the catalogue, one to look up a single tool in detail, and one to run it. It fetches what it needs, when it needs it, rather than reading everything up front.

You do not have to do anything to get this — it is the default. The controls exist if you want them:

```bash theme={null}
# force the small three-tool mode
npx -y comfyui-mcp --compact

# or hand the model everything at once
npx -y comfyui-mcp --full
```

Either can also be set with `COMFYUI_MCP_TOOL_MODE=compact` or `COMFYUI_MCP_TOOL_MODE=full`.

The trade is a couple of extra round-trips before the first real action, in exchange for a model that has room left to think. Big models are usually happier with `--full`. See [local LLMs](/docs/local-llms) for which models cope with which.

## Where to go next

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/docs/quickstart">
    Install it and generate your first image.
  </Card>

  <Card title="The sidebar panel" icon="window-maximize" href="/docs/panel">
    The in-ComfyUI agent, and what it can do to your canvas.
  </Card>

  <Card title="Tool Reference" icon="book" href="/docs/tools/image-generation">
    Every tool, with worked examples of what a real call looks like.
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/docs/troubleshooting">
    When it is not a refusal and something is actually broken.
  </Card>
</CardGroup>
