Repository navigation
Troubleshooting
Tool failures never crash the server — every error comes back to the agent as a one-line, actionable message. This page covers the ones people actually hit, plus the host-setup issues that happen before any tool can run.
Work through these in order:
-
Node 18+.
node --versionin the same environment your host runs in. The package declaresengines: node >=18and will not run on older runtimes. -
Run it by hand to see the real error — the same command your host runs:
TWODAI_API_KEY=2dai_sk_... npx -y 2dai-mcp-server
A healthy server prints
[2dai-mcp-server] ready on stdioto stderr and then waits silently. Anything else it prints is your diagnosis. -
Stale npx cache.
npx -y 2dai-mcp-server@latestforces the current version past a cached older one. If npx behaves strangely, clear its cache (npm cache clean --force) and retry. -
Config file validity. A single trailing comma makes some hosts silently ignore the whole
mcpServersblock. Validate the JSON. -
Restart the host. Claude Desktop and most others only read MCP config at startup.
That's a config error, printed to stderr — almost always:
TWODAI_API_KEY is not set. Create a key at https://2dai.io → Dashboard →
Integrations → API keys, then add it to this server's "env" block in your
MCP client config.
Put the key in the server's env block (see
Getting Started). The key is
read from the environment only — it can't be supplied as a tool argument.
On stdio transports, stdout is the JSON-RPC channel. If you wrap the
binary in a shell script, a version manager shim, or a launcher that prints
anything to stdout (an nvm banner, an echo, a greeting), the very first
stray byte corrupts the stream and the host drops the connection with an
unhelpful "server disconnected". The server itself writes all diagnostics to
stderr — keep it that way: launch npx -y 2dai-mcp-server directly, and if
you must wrap it, make the wrapper stdout-silent.
The key in TWODAI_API_KEY is mistyped, truncated, or was revoked
(revocation is instant, and it hits read-only calls like get_account
too). Check for copy/paste damage first — the key is the full
2dai_sk_… string, shown once at creation. If in doubt, mint a fresh key at
2dai.io → Dashboard → Integrations → API keys and swap it into the
config, then restart the host.
Scopes are set per key, at mint time, in Dashboard → Integrations → API keys. The error names the missing scope:
-
generate— the key can read but not create. Mint a key withgenerate(uploads and cancels need it too). -
manage— organising (move/trash/folders/groups) was blocked. -
publish— the agent tried to publish/unpublish. -
finance— the wallet tools. This scope is opt-in and never pre-selected; existing keys don't gain it retroactively, so mint a finance-scoped key if you want wallet reads. See Stats & Wallet.
Keys are create/revoke only — to change scopes, mint a new key, update the config, revoke the old one.
Generations burn the account's USD credit; when it can't cover the next
generation's price the call is refused before any charge, with the
shortfall. Top up in the dashboard's Credit section, then just retry.
The related "spend cap reached" (KEY_SPEND_LIMIT_REACHED) means this key's
own USD ceiling is exhausted while the account may still have credit — raise
or remove the cap in Dashboard → Integrations → API keys.
Almost never a real failure. A generate_* call blocks up to its wait
budget (45 s by default) and then hands back a queueId — video and
high-quality images routinely outlive the budget. Ask the agent to run
check_generation with that queueId; the job kept running server-side and
the charge stands. Two rules of thumb:
-
Collect, don't re-submit — a re-submitted prompt is a new generation
and a new charge. (Accidental rapid duplicates are protected: an
identical submit inside the ~30 s idempotency window is refused as
IDEMPOTENT_RETRYwithout charging.) - Old queueIds don't expire — settled jobs are archived, never deleted, so
check_generationkeeps answering.
If you want longer one-shot calls, raise TWODAI_WAIT_BUDGET_MS; if your
host's own tool timeout is short, lower it and lean on the ticket flow.
cancel_generation only works while the job is still waiting in the queue.
Once a worker has it, there is no abort hook — let it finish and collect it
with check_generation. The race is benign: either you cancelled in time
and were refunded, or you keep the result. A job that fails on its own is
refunded automatically.
get_token_price serves the platform's cached quote and never triggers a
live refresh. If no cache exists yet you get this message — retry in a few
minutes, and never treat it as a zero price.
upload_image and download_creation paths are sandboxed to the server's
working directory — symlinks included. Either keep files inside the project,
or start the server with TWODAI_FILE_ACCESS=any in its env block if you
accept agents touching arbitrary paths. See
Library & Drive.
You are on mcp.2dai.io (or a server started with TWODAI_FILE_ACCESS=none):
its disk is not yours. Upload with base64 instead of path; download by
calling download_creation without savePath and fetching the downloadUrl
it returns, with the same Authorization: Bearer header you send to the
server.
| Message says… | It means |
|---|---|
| "Blocked by content moderation" | The prompt or upload tripped moderation beyond the account's NSFW settings — rephrase, or adjust the account policy on 2dai.io |
| "Your tier does not include this option" | A tier-gated option (a video length, an ultra / ultimate preset, Gen8 Preview images below Holder) — the message names the tier that opens it; nothing was charged — see Dashboard → Tiers |
KEY_POLICY_CHANNEL |
The API key's policy stops at the default model channel: imageModel / videoModel: "next" is refused uncharged — submit on the default model or use a key without a channel policy |
TOO_MANY_REFS |
A tool's strict reference cap (generate_image: 3, or 6 with imageModel: "next") — nothing was charged, drop references |
| "Too many generations already running" | The account's parallel-queue cap — wait for one to land or poll with check_generation
|
| "Rate limited" | Sustained call pressure — space the calls out a few seconds |
| Similar-generation refused | Raw uploads and wallpaper outputs can't be re-derived by generate_similar, by design — generate them fresh instead |
| "Permanent delete only works on a trashed creation" | Deletion is two-step by design: trash first, then delete
|
| "That image is already in the target folder" | Duplicate-upload guard: same pixels, same folder |
Still stuck? Check the underlying client's wiki —
2dai-cloud-sdk —
for the full error catalogue, or open an issue on the
2dai-mcp-server repo.