The Internet connected computers. Blockchain connected value. AI connected intelligence.
What was still missing is an open protocol connecting compute.
Cloudiy is that protocol: any identity can provide computational resources, and any identity
can consume them, through one universal API.
HTTP made the location of a document irrelevant: you ask for a URL, never a server.
cloudiy makes the location of computation irrelevant: you declare a workload and the
capabilities it needs, and the protocol resolves discovery, placement, isolated execution and
settlement. If HTTP standardized exchanging information between computers, cloudiy standardizes
exchanging computational capacity between them.
Cloudiy is not a cloud provider, not a marketplace, not a GPU rental platform.
You describe what you need; the protocol decides how it runs. Docker, VMs,
drivers and networking are implementation details behind swappable interfaces. The end state is
that running code somewhere else feels like calling a function:
# the north star, location-free executionresult = cloudiy.run( function=my_function, cpu=8, memory="32GB", gpu="cuda",)
•Everything is a Resource: CPU, memory, GPU, VRAM, storage, bandwidth, and future hardware, without redesign.
•Everything is an Identity: human, AI agent, company, DAO or another protocol: indistinguishable by design.
•Capabilities are first-class: request cuda:12.8 and pytorch, never "machine X".
•The unit of execution is the Workload: declared, scheduled, isolated, measured, destroyed. Resources return automatically.
Nobody asks which server hosts a website. Soon nobody will ask which machine ran a workload.
cloudiy is not a product at the end of that road, it is the layer other products are built on,
the way HTTP carried far more than websites.
And payment follows proof
Uniquely among compute networks, settlement can be tied to the work itself:
release_verified
releases USDC only after the chain re-verifies the provider's ed25519 signature over the result.
Not "the dashboard says it ran". Proof.
Architecture
cloudiy is layered so that each layer only knows the one below it: the protocol
defines the nouns, the scheduler turns a declaration into a placement, and the
runtime executes it in isolation. Container engines live at the very bottom,
behind a trait, they are implementation, never protocol.
THE EXECUTION STACK
THE DOMAIN MODEL
The four layers
1 · Protocol domain
Resources • Identities • Capabilities • Workloads, pure concepts, zero infrastructure
One trait: prepare / run / destroy in mandatory isolation. Firecracker, Kata, gVisor and WASM slot in without touching schedulers or SDKs. Docker is the first implementation, not part of the protocol.
4 · Settlement
x402 quotes • USDC escrow on Solana • behind interfaces, any chain could implement them
Reference implementation
The reference implementation is a Rust workspace: protocol (pure domain),
scheduler (filter/scorer pipeline), runtime
(Runtime trait), common (wire, keys, signing), sdk,
and the unified cloudiy binary. Transport is P2P QUIC via iroh
(dial-by-NodeID, NAT hole-punching, end-to-end encryption), with an HTTP/WebSocket gateway for browsers.
CloudiyOS
CloudiyOS is the protocol's reference interface, not a separate
product. It consumes the same SDKs and gateway available to everyone, anyone can build a different
UI on top of the protocol.
CloudiyOS is the network rendered as an operating system in the browser. You log in with a Solana
wallet and land on a desktop backed by your own persistent, identity-bound virtual machine, one
Docker container plus a /root volume that survives stop/start — and,
when the operator configures an off-provider store, is restored on whichever node runs your next workload.
•My Virtual Machine: compose CPU / RAM / GPU / storage; specs update as you attach hardware.
Open the gateway origin and everything, model endpoints, the terminal, the wallet-signed escrow
deposit, talks to live providers. Served statically (e.g. on Vercel), the same page runs as an
interactive preview.
Providers
Providers don't rent computers, they contribute resources. Install the node, and it detects your hardware. You choose the slice to share; the rest stays private:
Rather read it before running? curl -fsSL https://cloudiy.cloud/install.sh | less
prints the installer instead of piping it to a shell. It fetches the prebuilt binary from GitHub
Releases (nothing is compiled), verifies its published SHA-256 before installing (a tampered or
truncated download is refused), and runs entirely inside one function so a dropped connection can't
execute half of it.
The Node ID (an ed25519 key) is your address on the network, no port forwarding, no public IP
(QUIC hole-punching via iroh). --share-cpu and
--share-memory-mb default to all detected hardware, the slice you don't
share stays private. On macOS you share CPU and RAM only (Docker can't pass the GPU through), so add
--no-gpu; GPU sharing needs a Linux host with the NVIDIA runtime.
You set the price.--price-usdc is
the per-request price quoted over x402 (default 0.01); --price-usdc-per-hour
is the rate when a consumer leases a whole VM on your node. Payouts land in your Solana keypair, minus
the 4% protocol fee taken at settlement. Add
--require-payment --rpc-url <url> to accept only jobs backed by a
verified on-chain escrow, --directory <id> to get listed for discovery,
and --runtime runsc|kata-runtime for stronger isolation of untrusted workloads.
Consumers & SDKs
Consumers declare workloads: what to run, which resources, which capabilities. Never a machine, never a driver:
$cloudiy run --to 9846…b1ec --image pytorch/pytorch --cap cuda --cpu 8 --memory-mb 32768 -- python app.pySignature verified, result signed by the node you dialed (ed25519)Workload completed · logs returned · settled via x402/escrow
Or from an app / AI agent, via SDK (Rust · Python · JS):
Workloads run in mandatory isolation (namespaces, cgroups, no host execution) and the environment is
destroyed at the end, resources return to the pool. The Python SDK is zero-dependency and exposes
as_tool_schema() so an LLM can call remote compute as a function.
Without payment the node answers Payment Required with its x402 USDC quote.
AI agents & MCP
Cloudiy is agent-native: cloudiy mcp serves the whole network as
MCP tools over stdio.
Any MCP client, Claude Code, IDEs, autonomous agents, can discover providers, get an x402 quote,
lock USDC in escrow, run a workload and release payment against the on-chain signature check.
No API keys, no accounts, no signup.
# give any agent a compute wallet with a hard budget$claude mcp add cloudiy -- cloudiy mcp --max-spend-usdc 0.5
cloudiy_pay_escrowLock USDC on-chain for a provider, inside the server's spend caps.
cloudiy_run_jobRun a kernel and get the ed25519-signed result with its proof.
cloudiy_launchLaunch an OCI container; the client-side scheduler places it.
cloudiy_deployDeploy a template recipe or image with env vars, the agent's own deploy, no dashboard or API key.
cloudiy_release_verifiedPay the provider only after the chain re-verifies its result signature.
cloudiy_refundRecover escrowed funds after the deadline if the job never ran.
Safety rails: devnet by default (--allow-mainnet to opt out),
a per-job cap and a cumulative session cap on escrowed USDC, and a
--read-only mode that removes every transaction-signing tool.
Agents that don't speak MCP can use the zero-dependency Python SDK's
as_tool_schema() instead.
Zero idle, by design.
Centralized serverless GPU forces a trade-off, pay for idle capacity, or accept cold-start latency.
cloudiy does neither: because you pay per request in USDC, there is no idle to bill. Nothing
runs, and nothing is charged, between calls, the scheduler places each call on a live node and settles on-chain.
Point an MCP client at it
Install the binary, then drop this block in
.mcp.json in your project
(or ~/.claude.json for every project) for
Claude Code — the same block goes in
claude_desktop_config.json for
Claude Desktop
(macOS: ~/Library/Application Support/Claude/), then restart the app.
Start read-only: that exposes only the five discovery/run tools, so no transaction-signing tool
reaches the model at all. Drop --read-only once you want the agent to
actually spend, and keep devnet while you do.
Then just ask it: "List cloudiy providers and quote the cheapest one."
Full walkthrough in the
MCP quickstart.
Quickstart: an agent rents compute
The whole arc in one file — discover a provider, let an LLM decide to buy compute, settle the
x402 quote, and refuse the result unless the provider signed it.
Every SDK verifies that ed25519 signature by default: reaching the line after
submit is itself the proof that this provider computed
this output for this input.
Run a node first with cloudiy share.
# pip install cloudiy-sdk · python3 agent_rents_compute.pyfrom cloudiy_sdk import CloudiyClient, PaymentRequired, SignatureError, as_tool_schema
NODE = "127.0.0.1:8080"
client = CloudiyClient(NODE)
# 1. discover — the provider's GPU, price and escrow program
info = client.info()
print(f"{info['gpu_model']}, {info['vram_mb']} MB VRAM, {info['price_usdc']} USDC/job")
# 2+3. the tool the agent callsdef cloudiy_gpu_run(kernel: str, data: str) -> str:
try:
result = client.submit(kernel=kernel, data=data)
except PaymentRequired as quote:
# the node quoted in USDC; a real agent settles the Solana escrow hereprint(f" 402 → paying {quote.price_usdc} USDC to {quote.pay_to[:16]}…")
result = client.submit(kernel=kernel, data=data, payment=quote.demo_payment())
# 4. verify — signature over (job_id, sha256(input), sha256(output))# already checked inside submit(); unsigned output never gets hereprint(f" signature verified — signed by {result.signed_by[:16]}…")
return result.output_text
# 2. decide — hand Claude the tool schema and let it call the tool itself
TOOLS = [as_tool_schema(NODE)]
try:
# … Anthropic function-calling loop; dispatch() routes to cloudiy_gpu_runprint(cloudiy_gpu_run("vector_add", "1,2,3;10,20,30"))
except SignatureError as e:
# the whole point: an agent must not act on unverified compute
sys.exit(f"REFUSED — {e}")
// npm i @cloudiy/sdk · node agent_rents_compute.mjsimport { CloudiyClient, PaymentRequiredError, SignatureError, asToolSchema } from"@cloudiy/sdk";
const NODE = process.argv[2] ?? "127.0.0.1:8080";
const client = new CloudiyClient(NODE);
// 1. discover — the provider's GPU, price and escrow programconst info = await client.info();
console.log(`${info.gpu_model}, ${info.vram_mb} MB VRAM, ${info.price_usdc} USDC/job`);
// 2+3. the tool the agent callsasync function cloudiyGpuRun({ kernel, data }) {
let result;
try {
result = await client.submit({ kernel, data });
} catch (e) {
if (!(e instanceof PaymentRequiredError)) throw e;
// the node quoted in USDC; a real agent settles the Solana escrow here
console.log(` 402 → paying ${e.priceUsdc} USDC to ${e.payTo.slice(0, 16)}…`);
result = await client.submit({ kernel, data, payment: e.demoPayment() });
}
// 4. verify — signature over (job_id, sha256(input), sha256(output))// already checked inside submit(); unsigned output never gets here
console.log(` signature verified — signed by ${result.signedBy.slice(0, 16)}…`);
return result.outputText;
}
// 2. decide — hand Claude the tool schema and let it call the tool itselfconst tools = [asToolSchema(NODE)];
try {
// … Anthropic function-calling loop dispatches tool_use to cloudiyGpuRun
console.log(await cloudiyGpuRun({ kernel: "vector_add", data: "1,2,3;10,20,30" }));
} catch (e) {
if (!(e instanceof SignatureError)) throw e;
// the whole point: an agent must not act on unverified compute
console.error(`REFUSED — ${e.message}`);
}
// go get github.com/cloudiy-cloud/cloudiy/sdk/go · go run .package main
import (
"errors""fmt"
cloudiy "github.com/cloudiy-cloud/cloudiy/sdk/go"
)
const node = "127.0.0.1:8080"var client = cloudiy.NewClient(node)
// 2+3. the tool the agent callsfunc cloudiyGPURun(kernel, data string) (string, error) {
opts := cloudiy.SubmitOptions{Kernel: kernel, Data: []byte(data)}
res, err := client.Submit(opts)
var quote *cloudiy.PaymentRequiredError
if errors.As(err, "e) {
// the node quoted in USDC; a real agent settles the Solana escrow here
fmt.Printf(" 402 → paying %g USDC to %s…\n", quote.PriceUSDC, quote.PayTo[:16])
opts.Payment = quote.DemoPayment()
res, err = client.Submit(opts)
}
if err != nil {
return"", err // *cloudiy.SignatureError if the result was not signed
}
// 4. verify — signature over (job_id, sha256(input), sha256(output))// already checked inside Submit(); unsigned output never gets here
fmt.Printf(" signature verified — signed by %s…\n", res.SignedBy[:16])
return res.OutputText(), nil
}
// 2. decide — AsToolSchema() converts into anthropic.ToolParam for the LLMvar schema = cloudiy.AsToolSchema(node)
// cloudiy-sdk — the typed Rust client. Unlike the HTTP SDKs it speaks the// P2P transport (iroh QUIC), so it dials a provider by NodeID directly.use cloudiy_sdk::{Client, SubmitOptions};
let client = Client::connect("<node-id>").await?;
let result = client
.submit(SubmitOptions::kernel("matrix_mul", "2,2,2;1,2,3,4;5,6,7,8").token("code"))
.await?; // Err(PaymentRequired(quote)) if unpaid// ed25519 proof of which node actually computed this outputassert!(result.signature_verified);
These are condensed for the page — the runnable files, with the full Anthropic
function-calling loop and a mock mode that needs no API key, live in the repo:
Python,
JavaScript,
Go
and the Rust crate.
One caveat worth knowing: the HTTP SDKs talk to one node you already know. Finding nodes
across the network is the CLI's job (cloudiy providers --via <directory>)
or the cloudiy_list_providers MCP tool — discovery rides the P2P transport, not HTTP.
Models
A model on cloudiy is a public inference endpoint: a container from the App Store recipe
catalog, placed on a live provider and reachable over plain HTTP. There is no model registry
to trust and no account to open, the endpoint is just compute that happens to serve a model,
priced per request in USDC.
Ready-to-run runtimes
The catalog ships the runtimes teams actually deploy, each a configurable recipe with its own
version, GPU, disk and environment variables:
vLLM, OllamaOpenAI-compatible LLM serving: chat and completions over HTTP.
SDXL, ComfyUIImage generation, from a single call or a full node graph.
LTX-VideoText and image to video generation.
WhisperSpeech to text transcription.
AxolotlFine-tuning jobs: your dataset in, adapter weights out.
Calling a model
Every endpoint answers Payment Required with its x402 USDC quote,
the caller pays and retries, and the request runs. No key, no idle: nothing is billed between calls.
# call a served model, pay per request in USDC over x402$curl -s https://<endpoint>/v1/chat/completions \ -H "content-type: application/json" \ -d '{"model":"llama-3.1-8b","messages":[{"role":"user","content":"hi"}]}'HTTP/1.1 402 Payment Required x402: 0.0004 USDC on Solana# pay, retry, the provider signs the result and escrow releases on the on-chain check
Deploy your own from the App Store, or let an agent do it with
cloudiy_deploy. Either way the result carries the provider's
ed25519 signature, so payment settles only against a proof of the work.
Payments & Escrow
Settlement is USDC on Solana, behind interfaces. Pricing is quoted over HTTP via the
x402 protocol:
a node answers 402 Payment Required with its USDC price and the client
retries with proof, no accounts, no API keys. For real value transfer, funds are locked in an
on-chain escrow and the provider verifies the deposit before executing.
The escrow flow
1.pay: the consumer funds an escrow (create_job), locking USDC in a program-owned vault.
2.run: the provider verifies the escrow on-chain (right job id, mint, payout, amount) and executes, returning a signed result.
3.release: the consumer releases the escrow, paying the provider minus a 4% protocol fee.
4.refund: after the deadline, unspent funds return to the consumer.
Program and status
The escrow program (Anchor) is live on devnet:
9zMBC7JDA8SJ2mk3ATYqRuJvn14MQyZVg9q3XPnzc1TN.
The full loop is verified end-to-end on devnet. In CloudiyOS, the same
create_job is signed directly by your wallet (Phantom), deposit USDC to
a provider without leaving the browser; keys never leave the wallet.
Every result is signed by the node that produced it, and the escrow can require that proof
on-chain before paying out. This is release_verified: unique among compute networks: payment is cryptographically bound to a
provider-signed result, not to a dashboard's word.
1.The provider signs cloudiy/result/v1 ‖ job-id ‖ sha256(output) with its network identity key (the same ed25519 key behind its Node ID).
2.The escrow stored that node key at create_job time, the consumer chose who to pay before the work started.
3.release_verified(output_hash) makes the Solana Ed25519 precompile re-verify the signature inside the same transaction; the contract checks the signer is the escrow's node key and the message matches.
4.Settlement is permissionless: anyone holding the proof can settle, but the payout addresses are fixed on-chain, a settler can't redirect a cent.
THE SETTLEMENT FLOW
Token-incentive networks verify hardware off-chain and pay on trust. Cloudiy pays in USDC against
an on-chain proof that the provider you chose signed the result: adversarially tested on
devnet (tampered signatures and wrong-signer proofs are rejected by the contract).
Two ways to settle, by trust model.
The proof establishes provenance: which node produced a result, so
release_verified is at its strongest when the output is
independently checkable (a deterministic kernel with run --replicas
quorum, where the signed hash is cross-checked against agreeing providers). For opaque,
single-provider work, the consumer-consent path, plain release,
signed by the consumer only after they verify the result they received, is the protection
against a provider that under-delivers. The CLI's run --release
verifies the result locally before it settles.
The reputation ramp, stake-free
Trust is the collateral, not deposited capital. Providers climb a ramp by passing
canaries: jobs with a known answer, mixed invisibly into real traffic, that catch a swapped model,
an ignored prompt or a canned output (RFC-0006).
A clean canary nudges the score up; one caught cheat multiplies it by 0.25, cratering a veteran back to the
bottom. Honesty is simply the profit-maximizing strategy, with no capital locked.
TIERMAX JOBCANARY AUDITPAYOUT HOLDBACK
New fresh identity$0.011 in 5 · 20%24 h
Building ≥ 5 clean$0.101 in 10 · 10%12 h
Trusted ≥ 25 clean$1.001 in 33 · 3%2 h
Veteran ≥ 100 clean$10.001 in 100 · 1%30 min
A fresh identity is heavily audited, capped to cent-sized jobs and held a full day before payout, so a
hit-and-run earns almost nothing. Veterans reach big jobs, light audit and fast payout, earned over ~100 clean
canaries and lost in one. Sybil identities gain nothing: every new key restarts at the bottom.
Discovery
You can dial a provider directly by Node ID, or discover many through a directory node: a
lightweight bootstrap registry that relays signed provider announcements. Directories can't forge or
alter an entry: every announcement is ed25519-signed by the announcing node, and consumers verify the
signature before trusting a single field.
# run a directory node$cloudiy directory# providers announce onto it, consumers list across one or more$cloudiy share --directory <directory-id>$cloudiy providers --via <directory-id>
The scheduler picks a placement across the discovered pool when you don't name a node. Multiple
directories can be listed and merged; unreachable ones are skipped. Announcements are kept alive by
the provider's own heartbeats, so an entry goes stale and drops shortly after a node goes offline,
the list reflects who is reachable now, not who registered once. A directory is cheap to self-host
(cloudiy directory on any always-on box); share its ID with providers
via --directory and with consumers via --via.
Reads a running network's signed announcements — point it at a gateway with ?gw=<url>, or open it at the gateway's origin. No live network, no mock supply.
CLI reference
shareProvider mode, share this machine's CPU/RAM/GPU with the network.
runConsumer mode, run a workload on a remote node and verify the signed result.
launch / deploy / statusLaunch an OCI container, deploy a full WorkloadSpec (env vars, template kernels), or check a submitted job.
pay / release / refundFund, release (pay provider − 4%), or refund an on-chain USDC escrow.
vm / shell / tunnelManage your persistent VM on a provider, open a PTY shell, or forward a port.
osRun the CloudiyOS gateway, local HTTP/WebSocket bridge to the P2P network.
mcpServe the network as MCP tools, agents discover, pay, run and verify under a spend cap.
directory / providersRun a discovery directory, or list live providers across directories.
info / idPrint a node's info, or your own network identity.
The protocol & RFCs
Cloudiy is a specification first and a program second. The
PROTOCOL.md spec (v0.2, draft) defines an open, transport-
and settlement-agnostic language for allocating computation — a design model
(§§1–9) and a normative wire specification (§§10–17) — with nine RFCs
working out the hard parts. The Rust workspace in this repo is one reference
implementation of that spec — not the spec itself. Anyone can write another.
Protocol ≠ implementation.
The spec is the abstract contract. Some layers ship today, some are interfaces by design, and some are
still planned — the reference map below is candid about which is which.
Which crate implements which layer, and how far along each one is (below).
Part II — the normative wire spec (§§10–17)
This is the strongest thing on the page. New in v0.2: the concrete bytes on the wire
— a verb→endpoint map, message schemas, the /info descriptor, the x402
payment quote, an error taxonomy, frame and size limits, and versioning. Every MUST
is testable, and each cites the reference code so it's auditable. A second team can
build an interoperable node from §§10–17 alone — without reading our code — and prove it by passing the
conformance/ suite.
§10HTTP transport
The verb→endpoint map: which HTTP call each protocol verb lands on.
§11Message schemas
The exact request/response shapes on the wire.
§12Node descriptor
The /info schema a provider advertises: resources, capabilities, escrow, price.
Stable machine-readable error codes, so a client can decide to retry, switch node, or abort.
§15Frame & size limits
The minimum limits every conforming node must honor.
§16Versioning
The compute/0 schema version and how implementations negotiate breaking changes.
§17Kernels & capabilities
The built-in kernels and how capabilities are declared and matched.
Reference implementation map (PROTOCOL.md §9)
The spec is the language; this repo is one implementation of it. The status column is deliberately honest.
Layer
Crate / dir
Status
Protocol domain (pure types)
crates/protocol
v0.1
Scheduler (filters + scorers)
crates/scheduler
v0.1
Runtime abstraction + Docker
crates/runtime
v0.1
Node daemon (P2P, HTTP, wgpu)
crates/cloudiy
shipping
Wire protocol / identity / signing
crates/common
shipping
Consumer SDKs
crates/sdk, sdk/*
shipping
Settlement (Solana/USDC/escrow)
protocol::settlement
interfaces only, by design
Entitlements (quota envelope)
protocol, scheduler
planned — RFC-0004
External storage + volume mounts
protocol, runtime
planned — RFC-0004
Reserved lease vs on-demand float
cloudiy::vm
lease shipping; float via scheduler
The schema is versioned (compute/0); a breaking change bumps the version and implementations negotiate.
RFCs
The design record. Most are drafts; some describe behavior already shipped in the reference implementation. (RFC-0002 is unused — the numbering skips it.)
Prove it, don't take our word.
Any implementation can validate itself against the spec: conformance/ is a zero-dependency, black-box test suite — point it at any node and every check cites the exact spec clause it enforces. A second team's node that passes it can talk to a Cloudiy SDK without being ours. That's the line between a protocol and one program.