nanoodle-mcp
OfficialEnables keyless x402 payments for API calls using Nano cryptocurrency, with automatic signing and broadcasting of Nano send blocks through a Nano RPC node, plus proof-of-work handling and wallet management.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@nanoodle-mcprun my video-to-gif graph on clip.mp4"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
nanoodle-mcp
Build a multi-model media pipeline visually at nanoodle.com — then hand the whole pipeline to your agent as ONE typed tool.
Skill or MCP? Running (or designing) a single workflow? The nanoodle skill is one command and no setup. This server is for when you've built up a folder of saved graphs and want each one exposed to your agent as its own tool.
Point this MCP server at a folder of noodle-graph.json saves from the
nanoodle editor and every graph becomes a callable tool with a derived input
schema — in Claude Code, Grok, Claude Desktop, Cursor, VS Code, Windsurf, or
anything else that speaks the Model Context Protocol.
It speaks stdio to your own agent by default, or HTTP to everyone with
serve mode — including
charging per call in Nano, so strangers'
agents can pay to run your noodles with no account anywhere.
No middleman server, no telemetry — and with wallet mode,
no account either. The MCP implementation here is hand-rolled (stdio +
streamable HTTP, JSON-RPC 2.0 — small enough to read). Two runtime dependencies:
nanoodle (MIT), the zero-dep
workflow executor that does all the heavy lifting, and
nanocurrency (GPL-3.0) for
signing Nano blocks — loaded only on the x402 paths, see
Licensing. Your NanoGPT API key goes straight from your
machine to nano-gpt.com; it is never logged and never
appears on stdout.
Install
You need: Node 20+, a folder of saved graphs (say ~/noodles — see
Making graphs), and a nano-gpt.com
API key in NANOGPT_API_KEY (or passed via --key / --env-file) — or no
key at all with a Nano wallet, see
wallet mode.
Optional: ffmpeg on PATH. Tools whose graphs include a local-media node
(resize, video frames, combine, audio trim/extract) use a pure-JS path for the
common case but fall back to ffmpeg/ffprobe for formats it can't handle —
JPEG/WebP resize, reading video frames, compressed audio. Without ffmpeg those
runs fail (and auto-refund in charge mode); the server prints a warning at
startup naming the affected tools. Pure image/LLM/vision tools don't need it.
Install with apt install ffmpeg (Debian/Ubuntu) / brew install ffmpeg.
Claude Code
claude mcp add nanoodle --env NANOGPT_API_KEY=your-key-here -- npx -y nanoodle-mcp --graphs ~/noodlesOr install it as a plugin — Claude Code prompts for your noodles folder and API key, and also learns what a noodle is (this repo doubles as a plugin marketplace):
/plugin marketplace add nanoodlecom/nanoodle-mcp
/plugin install nanoodle@nanoodleGrok
grok mcp add nanoodle -e NANOGPT_API_KEY=your-key-here -- npx -y nanoodle-mcp --graphs ~/noodlesOr, for a remote/serve endpoint (no local process, no API key on your machine):
grok mcp add --transport http noodles https://mcp.nanoodle.com/mcpThat writes [mcp_servers.noodles] into ~/.grok/config.toml (or
.grok/config.toml with --scope project). Same shape by hand:
[mcp_servers.noodles]
url = "https://mcp.nanoodle.com/mcp"
enabled = trueCursor
Install in Cursor
(then edit the graphs path and key), or add to .cursor/mcp.json yourself:
{
"mcpServers": {
"nanoodle": {
"command": "npx",
"args": ["-y", "nanoodle-mcp", "--graphs", "/absolute/path/to/noodles"],
"env": { "NANOGPT_API_KEY": "your-key-here" }
}
}
}VS Code
.vscode/mcp.json — note VS Code's root key is servers, not mcpServers:
{
"servers": {
"nanoodle": {
"type": "stdio",
"command": "npx",
"args": ["-y", "nanoodle-mcp", "--graphs", "/absolute/path/to/noodles"],
"env": { "NANOGPT_API_KEY": "your-key-here" }
}
}
}Windsurf
~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"nanoodle": {
"command": "npx",
"args": ["-y", "nanoodle-mcp", "--graphs", "/absolute/path/to/noodles"],
"env": { "NANOGPT_API_KEY": "your-key-here" }
}
}
}Claude Desktop
Same shape as Cursor/Windsurf, in claude_desktop_config.json under
mcpServers.
ChatGPT
Not reachable: ChatGPT only connects to remote HTTPS MCP servers, and this is a local stdio server by design. A hosted endpoint would put a middleman between your API key and NanoGPT, which is the opposite of the point — so none is planned.
Related MCP server: AgentTasker MCP Server
⚠️ This spends real money
The server runs on your money — either a nano-gpt.com API key (BYOK) or,
keyless, your own Nano wallet via
x402. Every tools/call
executes a workflow against the NanoGPT API and spends from that balance —
and the caller is usually an AI agent deciding on its own when to call. Point
it only at graphs you're happy to have run, and keep an eye on your balance.
Each result ends with a cost: $X.XXXX line so the agent (and you) can see
what a call cost.
Wallet mode — no account, no API key (x402)
NanoGPT supports x402 accountless payments:
a keyless API call answers HTTP 402 with a Nano invoice, you pay it, the
call completes. Give the server a wallet and it does this automatically —
no NanoGPT account, no API key, no signup anywhere:
export NANO_SEED=<64-hex seed> # account 0 pays; or NANO_PRIVATE_KEY=<64-hex key>
nanoodle-mcp --graphs ~/noodles --max-usd 0.50Per call, the server: sees the 402 invoice → signs a Nano send block locally →
broadcasts it through a Nano RPC node (--nano-rpc / NANO_RPC_URL, default
rpc.nano.to) → NanoGPT detects the deposit and returns
the result. The seed/private key never leaves the process: only the signed
block goes to the RPC node, and neither secret is ever logged. An API key,
if present, always wins — the wallet is only used keyless.
Proof-of-work reliability. Every send block needs Nano proof-of-work. The
server asks the RPC node's work_generate first, but public nodes routinely
refuse or throttle it (no GPU, key required); the fallback is local
single-threaded CPU work, which can take a minute. Two fast options, both via
--work-rpc / NANO_WORK_URL:
Hosted GPU work API — sub-second work, no hardware. E.g. nano.to's PoW API (
--work-rpc https://rpc.nano.to) or Nanswap Nodes (--work-rpc https://nodes.nanswap.com/XNO— the fast work server is on their paid plan; the free one queues for minutes). Put the API key inNANO_WORK_KEY(env or--env-file, never a flag) — it's sent as both akeybody field (nano.to style) and anodes-api-keyheader (Nanswap style).Your own nano-work-server on the same machine (
nano-work-server --cpu-threads 8 -l 127.0.0.1:7076→ work in a few seconds, free forever).
Order: --work-rpc (2-minute timeout, so a hung server can't stall a payment)
→ --nano-rpc node → local CPU. The wallet also precomputes work for the
next block the moment one publishes, and serve mode prewarms at boot — with
any healthy work source, callers effectively never wait on proof-of-work.
The local-CPU last resort runs on the Node main thread: in --serve mode a
send-difficulty grind (minutes) freezes the whole HTTP server while it runs.
If your remote work sources are dependable, pass --no-local-work — the send
then fails cleanly instead (an unpayable invoice is refused up front, and a
failed refund/payout send leaves the balance in the wallet for the next
settle to move).
This is a hot wallet. Use a dedicated wallet holding pocket money, not
your savings: its balance is a natural spend ceiling, and --max-usd adds a
per-call one on top. NanoGPT auto-refunds overpayments and failed generations
on its side.
Prefer prepay? Wallet mode settles on-chain per call. If you'd rather pay once and draw down a balance, that's exactly what a NanoGPT account is: deposit crypto (Nano included) into an account, take its API key, and run the server in normal BYOK mode — same tools, one payment instead of many.
Serve mode — host your noodles as a service (--serve)
Everything above speaks MCP over stdio to your own agent. --serve speaks
MCP over streamable HTTP instead, turning a directory of noodles into a
service anyone's agent can connect to:
nanoodle-mcp --graphs ~/noodles --serve 8402Callers connect with one command — no key, no signup:
claude mcp add --transport http noodles https://your-host/mcp
# or
grok mcp add --transport http noodles https://your-host/mcpGET / serves a landing page with the tool list and that exact command (Claude
and Grok behind a one-click toggle — same endpoint, same flags), so sharing
your server's bare URL is the onboarding. Every workflow on it links to its
source: an open in editor link (a share link minted from the exact graph
file being served — it loads the workflow in the
nanoodle editor to inspect, remix, or run on your own
key) and its raw graph JSON at /graph/<tool>.json. The page also spells
out the economics (deposits settle at metered cost + 20%; the markup is the
author's cut on graphs that name a payout address, and the operator's on the
rest, and the page says which of yours do) and how to self-host — this server, the editor, and the
executor are MIT (licensing). Generated media is served
back under unguessable /out/… URLs (small images also ride inline in the
tool result). Runs themselves are not logged: free serve mode keeps no
record of who called what, and charge mode keeps only a payments ledger (money
events, never run telemetry — see below).
Generated media is deleted after --out-ttl hours — a privacy backstop so
a hosted server doesn't hoard every caller's generations on disk forever. In
--serve mode it defaults to 24h; pass --out-ttl <hours> to change it
(fractions like 0.5 are fine) or --out-ttl 0 to keep everything. Stdio mode
defaults to off — files you generated locally are yours to keep — but honors
the flag if you pass it. The sweep only ever removes media artifacts (images,
video, audio); the operator's own costs.json, gate-state.json, and
usage.jsonl are never touched. Note the 24h default matches the charge gate's
replay window: a paid result stays replayable for 24h and references its /out/
URL, so lowering --out-ttl below 24h in charge mode means a replayed result
can point at a file that's already been swept.
Privacy — what your server keeps
Run with the defaults and the same promise the hosted server makes holds on your box, every line checkable in this repo:
No accounts, no API keys, no sign-ins. In charge mode, paying is the only thing that authorizes a call.
Prompts and inputs are never written to disk or logs. Input media rides in memory only — it is never stored. In charge mode the gate keeps only a short hash binding a payment to its call (
hashArgs), never the arguments.Generated media auto-deletes after
--out-ttlhours (default 24h in--serve, off for local stdio), served at unguessable/out/…URLs until then. Set--out-ttl 0to keep everything.Results are held in memory for delivery, not stored — the restart-state file carries no result text or error detail.
No analytics, no trackers, no IP logs — the app keeps no request logs. In charge mode the one thing it writes is
usage.jsonl, a payments ledger of money-lifecycle events that mirror the public Nano ledger — no run telemetry, no error text. Free serve mode writes no ledger at all.
gate-state.json itself never holds customer content. It exists to keep
in-flight money safe across the restart a deploy causes — quotes and owed sends
survive — but a paid tool's text output and any upstream error detail are
never written to disk. Media results persist only their /out/ pointer and a
receipt; a text result persists as nothing, so a restart between a run and the
caller's retry simply re-runs the tool (charged once, delivered once — the
operator eats one duplicate model call) rather than replaying content from disk,
and a failed run replays a fixed placeholder plus its refund status, never the
original error message.
One caveat, stated plainly: generation runs on NanoGPT's API, so prompt content in flight is governed by their privacy policy.
Free serve mode runs on your balance — fine on a trusted network, ruinous on the open internet. For that, charge for calls:
Charging per call (--charge-usd)
nanoodle-mcp --graphs ~/noodles --env-file wallet.env \
--serve 0.0.0.0:8402 --public-url https://noodles.example.com --charge-usd 0.05Now every tool call is paid in Nano (XNO) by the caller, with no accounts
on either side. The flow their agent walks through (the server's MCP
instructions teach it automatically):
On each PAYMENT REQUIRED quote the tools/call hangs up with payUrl,
watchUrl, and a next imperative ( blocking: false ):
Pay. Show the user ONLY
payUrl(QR for the exact amount); any Nano wallet scans it. Never show themwatchUrlor the wallet address.Watch — immediately, on that same payment link. The agent opens
watchUrl(GET /x402/watch/<id>, agent-only SSE) the moment it has the quote. Onestatusevent per state change; when payment lands the stream closes withdone: trueand anextfield for phase 3. (The pay page uses the same stream; pollGET /x402/status/<id>?wait=1as a fallback.) Detection is RPC polling or push via--nano-ws— about a second.Results. ONLY after the watch closes paid: re-call the tool with the same arguments plus
_payment_id. Thattools/callis the results stream — it runs the workflow (progress heartbeats on a streaming transport) and returns the result with a receipt. Do not open it while still watching for payment. Re-calls with the same_payment_idreplay the cached result free.
What they paid is a deposit, not the price: the call settles at the run's actual metered model cost + 20%, and everything above that is sent back to the paying wallet as change — the same deposit→meter→refund model NanoGPT itself uses, one layer up. Nobody ever pays off an estimate.
Nano has no payment memo, so each quote's amount carries a few raw of random
dust — the amount is the memo. Quotes expire after 15 minutes; a payment
that arrives late is bounced straight back, and a run that fails after
payment is refunded automatically. Arguments are validated before a quote
is issued (nobody pays for a typo), and run_noodle is withdrawn in charge
mode — an arbitrary share link's cost can't be priced up front.
Pricing: --charge-usd sets the ceiling deposit, and the opening quote
for a tool that has never run. Once a tool has run, its deposit tracks its
real cost automatically: quotes become twice the settle price (worst observed
metered cost + 20%, from the costs.json sidecar), ceiled to a whole cent
with a 1¢ floor — a tool that meters $0.004 quotes a $0.01 deposit, not the
flat ceiling. Size the ceiling generously; over-covering costs callers
nothing since the difference comes back as change, while an under-sized
deposit means runs can cost more than was collected and you eat the
difference (the gate warns at startup when a graph's deposit is below its
last observed cost + 20%). The XNO conversion comes from NanoGPT itself:
the gate fires a keyless x-x402 probe and keeps the invoice's exact
raw-XNO/USD pair — the same rate your downstream payments settle at, so
quotes and costs can never drift apart on FX, and no market-data service is
involved (probe invoices are never paid; they just expire). Cached 60s, stale
cache rides out probe outages, and --xno-usd forces a static rate if you
ever need one. Per-graph overrides are a hand-added top-level block in the
graph JSON:
"x402": { "usd": 0.10, "author": "nano_1abc…" }usd overrides the deposit. author routes the 20% markup of every
successful call to that address — computed on what the run actually cost,
never on the deposit, and capped by whatever the deposit has left once the cost
is taken out (a deposit too small to cover cost + 20% pays the author only the
remainder). Nano has no network fees and this server takes no cut of the
markup, so creators keep 100% of what does get routed. With no author
field the markup stays with the wallet running the server — it is opt-in per
graph, not the default. In exact raw, per settled call:
cost = metered model cost, converted at the deposit's own oracle pair, rounded up
markup = cost / 5 (20%, integer floor)
take = min(markup, deposit − cost) → author (or kept, if no author field)
change = deposit − cost − take → back to the payerA run costing more than its deposit keeps the whole deposit and the operator absorbs the excess; a run whose model reports no cost settles at $0 and the whole deposit is returned (the caller is never billed off a number the meter didn't produce). The math is integer-exact end to end: USD decimals parse by string into nano-dollars, the rate is the oracle invoice's literal raw/USD pair, every conversion is BigInt ratio arithmetic with an explicit floor or ceil, and floats never touch an on-chain value.
The wallet (NANO_SEED / NANO_PRIVATE_KEY, via --env-file) receives
payments, sends refunds and author payouts, and — if you don't set an API
key — also pays NanoGPT per call via x402, making the whole service
nano-in/nano-out. With an API key, runs spend from the key and the wallet only
handles the customer side.
Payment detection
Polling receivable on your Nano RPC node (1s while quotes are pending) is
the always-on default. Add --nano-ws wss://… to subscribe to a Nano node
websocket for push detection — settlement is then effectively instant and
polling relaxes to a safety net. Public websockets exist (e.g.
wss://nanoslo.0x.no/websocket worked at the time of writing); your own node
is the dependable option. Either way the poller also checks account_history,
so payments pocketed by a concurrently-running wallet are still found.
Payments ledger
In charge mode <out>/usage.jsonl is a payments ledger: one line per money
event only — quote, paid, refund, change, author_payout — your
server's own record of money moving, nothing client-side. It is deliberately
not a usage log: there are no run events, no run timing, no
success/failure telemetry, and no upstream error strings (which can quote user
content). A money event does carry .tool — the tool name is the subject of
the payment, not a record of a run — so you can see what earns, but not who
ran what when or whether it failed. Refunds record a fixed category
(run_failed, late_payment), never the underlying error text — the full
error still reaches the caller and the operator's stderr. Free serve mode
writes no ledger at all. Some starters:
jq -r 'select(.event=="paid") | .tool' usage.jsonl | sort | uniq -c | sort -rn # paid calls per tool
jq 'select(.event=="paid") | .settleMs' usage.jsonl # quote→settle latency
jq 'select(.event=="paid") | .usd' usage.jsonl | jq -s add # gross deposits taken
jq -r 'select(.event=="refund") | .reason' usage.jsonl | sort | uniq -c # refunds by categoryHosting checklist
Reverse proxy / tunnel: bind localhost, put Caddy/nginx/cloudflared in front for HTTPS, and set
--public-urlto the outside URL (it's what pay links and media links are built from).systemd (adjust paths):
[Unit] Description=nanoodle-mcp serve After=network-online.target [Service] ExecStart=/usr/bin/npx nanoodle-mcp --graphs /srv/noodles --out /srv/noodle-out \ --env-file /srv/wallet.env --serve 8402 --public-url https://noodles.example.com \ --charge-usd 0.05 --work-rpc http://127.0.0.1:7076 Restart=on-failure [Install] WantedBy=multi-user.targetKeep the float small: the wallet is hot. Sweep revenue to cold storage regularly; if you run with an API key, cap that account's balance too.
Work server: refunds and payouts are Nano sends and need proof-of-work — use a hosted GPU work API (nano.to, Nanswap — key in
NANO_WORK_KEYin the env file), or pointNANO_WORK_URLat anano-work-server --gpuon any box you own over a tailnet (work requests carry only block hashes — nothing secret). Pair either with--no-local-workso a work outage can't freeze the server on CPU work. Wallet-material and key env vars all belong in the--env-file, which also takesNANO_WS_URLfor a key-bearing websocket URL (e.g. Nanswap'swss://nodes.nanswap.com/ws/?ticker=XNO&api_key=…).There is intentionally no auth: on a charged server, payment is the authorization. Don't serve graphs you wouldn't want strangers running.
How it works
~/noodles/
generate-hero-image.json → tool "generate-hero-image"
make-jingle.json → tool "make-jingle"Every readable *.json graph in --graphs becomes one MCP tool:
Tool field | Derived from the graph |
| filename minus |
| the graph's first comment (if any), its node chain in dependency order with node names (e.g. |
| one string property per unwired field, exactly like the nanoodle CLI's |
media inputs | image / audio / video inputs take a file path or https URL — local files ride inline as base64 |
result | text outputs as text blocks; media outputs saved into |
When the run does not use your prompt verbatim, the result says so. Many
image and video models reject an over-long prompt outright, and in a graph the
prompt is usually written by an upstream LLM — nobody typed it, so nobody can
shorten it. nanoodle (0.8.0+) trims it to the model's cap at a sentence
boundary instead of losing the run to a certain 400. That is only defensible if
the caller is told, so the trim leads the tool result:
note: prompt trimmed for "Poster" (qwen-image-3) — the prompt was 1320 characters
and this model accepts at most 800, so nanoodle cut it to 791 characters at a
sentence boundary. The run used the shortened prompt.It matters most in charge mode, where that run is already paid for. The library
also emits a process warning, but stderr belongs to whoever started the server,
not to the agent that paid.
Protocol behavior worth knowing: malformed calls (unknown tool, unknown /
missing / non-string argument) are rejected as JSON-RPC -32602 before any
money is spent; a run that fails (network, model error, missing key) comes
back as a normal tool result with isError: true.
usage: nanoodle-mcp --graphs <dir> [--graphs <dir> …] [--out dir] [--key K] [--env-file path] [--nano-rpc url] [--work-rpc url] [--max-usd n]
--graphs dir directory of noodle-graph.json saves (required; repeat to serve
several dirs — scanned in order, so an earlier dir wins name clashes)
--out dir where media outputs are saved (default ./nanoodle-out)
--key K NanoGPT API key (defaults to NANOGPT_API_KEY)
--env-file p read NANOGPT_API_KEY / NANO_SEED / NANO_PRIVATE_KEY / NANO_WORK_URL /
NANO_WORK_KEY / NANO_WS_URL from a .env-style file
--nano-rpc u Nano RPC node for wallet mode (default https://rpc.nano.to; NANO_RPC_URL)
--work-rpc u dedicated work_generate endpoint — a local nano-work-server or a hosted
GPU work API (NANO_WORK_URL; NANO_WORK_KEY carries its API key;
falls back to --nano-rpc, then local CPU work)
--max-usd n wallet mode: refuse any single x402 invoice above $nKey precedence matches the nanoodle CLI: --key > --env-file >
NANOGPT_API_KEY; wallet secrets come only from the environment or
--env-file, never argv. The server refuses to start if no directory holds a
runnable graph, and says why per file on stderr; stdout is protocol only.
Per-project graphs + a shared library
--graphs is repeatable, so one server can merge several folders. The pattern:
commit a noodles/ dir to a repo for that project's own tools, then list your
global library after it as a fallback:
nanoodle-mcp --graphs ./noodles --graphs ~/noodlesDirs are scanned in the order given, and the earlier dir wins a name clash:
if both folders have a changelog.json, the project's becomes changelog and
the shared one becomes changelog-2. So a project can override a shared tool
just by dropping a same-named graph in ./noodles, while everything else in
~/noodles stays available. An unreadable dir (a typo, a folder that isn't
there) is a hard startup error naming the offender — no silent half-load.
Wiring it into your editor
MCP config is per-project in most clients, so the two-dir pattern lives in the
repo, right next to the graphs it serves. For Claude Code that's a .mcp.json
at the project root — commit it along with noodles/ and everyone who clones
gets the same tools:
{
"mcpServers": {
"nanoodle": {
"type": "stdio",
"command": "npx",
"args": ["-y", "nanoodle-mcp", "--graphs", "./noodles", "--graphs", "/home/you/noodles"]
}
}
}Relative paths resolve from the project root. A project-scoped server named
nanoodle shadows a user-scoped one of the same name, so repos with a
.mcp.json get their own graphs and every other directory falls back to your
global install untouched.
Two things to keep out of a committed config: your API key (leave env
out and let NANOGPT_API_KEY come from the environment, or point
--env-file at a file outside the repo — never commit a key) and, for team
repos, your personal library path (the second --graphs above is an
absolute path on your machine; drop it from a shared repo's config and keep
just ./noodles, since ~ is not expanded in MCP args). Cursor
(.cursor/mcp.json) and VS Code (.vscode/mcp.json) take the same args in
the config shapes shown under Install.
Run any share link
Every nanoodle share link is an executable tool. Alongside your saved graphs the
server always exposes one more tool, run_noodle, that takes any share link
and runs it — no file needed:
run_noodle("https://nanoodle.com/#g=…", { "Text": "a lighthouse at dawn" })Pass the link as url and any workflow inputs as inputs (the same friendly
keys the graph's own tool would take; media inputs take a file path or https
URL). It accepts #g=/#j= workflow links, #a= app links, and short links
to one. Direct links decode locally; only fragment-less short links trigger a
network read, and it carries no credentials. Like every other tool, a run
spends real money and ends with a cost: $X.XXXX line.
Making graphs
Build and test workflows in the nanoodle editor, hit
💾, and drop the downloaded noodle-graph.json into your --graphs folder
(rename it — the filename becomes the tool name). Restart the server (or your
MCP client) to pick up new files.
Describing your tools
The first comment node in a graph doubles as the MCP tool's description: its text leads the auto-derived node chain, so the calling agent reads your words first. Keep it to one sentence saying what the tool produces from what inputs — e.g. "Renders a product mockup image from a one-line feature description." Long text is truncated to 200 characters and whitespace is collapsed, so write for one line. Graphs without a comment just get the node chain, as before.
After each successful run the tool's real cost is recorded in
<out>/costs.json (a small {tool: {usd, at}} sidecar next to your media
outputs) and folded into the description as last run $X — observed, not
estimated. The server announces the change with a
notifications/tools/list_changed notification, so MCP clients that honor it
show updated prices mid-session; others catch up on restart.
Limitations
Honest list — most of these are inherited from the executor:
Feed-forward DAGs only. nanoodle graphs are stateless pipelines; there are no loops, no conversations, no memory between calls.
One run per call, no streaming. A
tools/callblocks until the whole workflow finishes — video graphs can take minutes. No MCP progress notifications yet.Graphs load once at startup. Adding or editing files in
--graphsneeds a restart; the tool list doesn't change mid-session (nolistChangednotifications).Local media nodes need nanoodle ≥ 0.4 (this package's dependency). Graphs using resize, combine, trim, extract-audio, video-frames, or soundtrack run headlessly — pure JS where possible, ffmpeg on
PATHfor the rest (see the supported-nodes table). A graph with a node type the library doesn't know is still skipped at startup with a stderr note.Media rides inline. NanoGPT has no upload endpoint, so media inputs are sent as base64 in the request body (~4 MB max, checked before spending).
No cost cap in key mode. The server won't stop a client from calling an expensive graph repeatedly. Your NanoGPT balance is the only brake. (Wallet mode is better here:
--max-usdcaps each call, and the wallet's balance caps the total.)
No telemetry, no analytics; the API key and wallet secrets are never logged and never appear on stdout.
Testing
Fully offline — the suite spawns the real server against a canned local NanoGPT stub and drives the MCP handshake over stdio:
npm testIt also carries release guards: the three release manifests must agree on the
version, the landing page's chip table may only name node types the nanoodle
library still has, and no startup path may statically import the GPL-3.0
dependency.
Those guards are offline, so they compare repo files to each other and cannot
see npm. One more guard needs the network and therefore runs in the publish
workflow, not in npm test: scripts/assert-npm-version.mjs fails the registry
publish unless server.json's version is really on npm. See
PUBLISHING.md.
Registry
server.json is the official MCP registry
manifest (io.github.nanoodlecom/nanoodle-mcp); see PUBLISHING.md
for the release checklist.
Which repo do I want?
This server exposes saved workflows as typed MCP tools. If your agent supports Agent Skills rather than MCP servers, nanoodle-skill (teaches your agent to build any graph) and noodle-skills (prebuilt one-task workflows) cover similar ground without running a server. Running graphs in GitHub CI? → run-noodle-action.
Licensing
MIT: this server (see LICENSE), the
nanoodle editor, and the
nanoodle executor this server
runs graphs on. The sibling projects — nanoodle-py,
nanoodle-skill,
noodle-skills — are MIT too.
Graphs are not covered by any of that. A noodle-graph.json is its
author's work. Serving one as a tool, or downloading one from /graph/<tool>.json,
does not place it under this repo's licence. The public library this project
maintains, awesome-noodles, is
MIT because that repo says so; the graphs on any other server carry whatever
licence their authors give them.
GPL-3.0: one runtime dependency,
nanocurrency. It derives
Nano keys, builds and signs blocks, and computes proof-of-work. It is used only
by the optional x402 Nano wallet: wallet mode
(NANO_SEED / NANO_PRIVATE_KEY) and charge mode
(--charge-usd).
Be clear about what that means for you. Every installer receives it.
npm install nanoodle-mcp and npx -y nanoodle-mcp both download and unpack
nanocurrency onto your disk, whether or not you ever touch x402. Your
dependency tree contains GPL-3.0 code from the moment you install, and it is
redistributed with any bundle or image you build from this package.
What the on-demand load changes is narrower, and only that: which runs
execute it. src/wallet.mjs and src/gate.mjs are the only modules that
touch nanocurrency, and bin/nanoodle-mcp.mjs reaches them through
await import() inside the branches that already gate x402. So a BYOK
(API-key) run never loads or runs GPL-3.0 code — it still has it installed.
tests/gpl-boundary.test.mjs holds that line.
We keep it a normal dependency on purpose. npm installs optionalDependencies
by default, so that would change nothing; the only way to skip it is an
optional peerDependency, and then npx -y nanoodle-mcp — the documented
one-command install — could no longer run wallet or charge mode at all. Correct
labelling beats a broken accountless install.
Not affiliated with NanoGPT or Anthropic. Build workflows at nanoodle.com; run them from code with nanoodle-js / nanoodle-py.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityDmaintenanceA dual-transport MCP server that exposes your API as tools to LLM clients, supporting both stdio transport for local clients like Claude Desktop and HTTP/SSE transport for remote clients like OpenAI's Responses API.Last updated
- AlicenseBqualityDmaintenanceA lightweight stdio-only MCP server that allows AI agents to run multiple tasks (e.g., Python code, HTTP requests, shell commands) in parallel or with dependencies, returning structured results in a single call.Last updated2MIT
- Alicense-qualityBmaintenanceModel Context Protocol server exposing MiniMax's image, speech, music, and video generation APIs as MCP tools for use with any MCP-aware host.Last updated3,604MIT
- FlicenseAqualityCmaintenanceMCP server that wraps MiniMax platform APIs (speech, video, image, music, and file management) as tools over stdio, enabling natural language interaction with MiniMax's AI services.Last updated16
Related MCP Connectors
MCP server for NanoBanana AI image generation and editing
MCP server exposing the Backtest360 engine API as tools for AI agents.
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/nanoodlecom/nanoodle-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server