Gno build
Author, build, test, and deploy a Gno realm or pure package. Use whenever the user wants to write a new realm or `/p/` package, add or change a function in one, scaffold a Gno project, or deploy/publish `.gno` code to a chain — even when they only describe the on-chain behavior they want ("make a realm that stores notes", "deploy a counter I can bump", "add a withdraw function") without ever saying "build". This skill owns writing Gno source; reasoning about existing code stays with gno, security audits with gno-audit, failed transactions with gno-debug.From its SKILL.md
npx -y skills add gnoverse/gno-mcp --skill gno-buildAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
5.5 KB, as published. Nobody here has run it
Building a Gno realm or package
Gno reads like Go but its semantics and API are its own — author from the references, not from Go memory. "This function is simple enough to write as plain Go" is exactly the thought that ships a realm that only works by luck.
The shape of the work is: author and test locally first, decide where it runs only when it's ready to go on-chain. Don't ask "local devnet or testnet?" up front — that is friction before there is anything to deploy. A realm can be written and made correct with zero chain and zero keys.
-
Load the knowledge. Read
../gno/SKILL.md(the source index), then../gno/references/build.md(project layout,gnomod.toml, thegnobinary, test flavors) and../gno/references/patterns.md(realm idioms — globals,init, crossing-function discipline, state shape). Pullinterrealm.mdforcur realm/ crossing / caller-identity semantics,stdlib.mdfor the chain API,render.mdif it exposesRender(),security.mdto avoid known footguns. Load what the realm needs, not all of them. If the realm interacts with a system realm (registers a name viar/sys/users, reads chain params, touches the validator set), pull../gno/references/sysrealms.md— and query the target chain for the sys realm's live API rather than coding against remembered signatures. -
Pin what to build — not where. If the on-chain behavior is ambiguous (who may call it, what persists across transactions, what it returns), ask one sharp question now. A wrong state shape is expensive to migrate later. The deploy target is a separate question for step 5; raising it here is premature.
-
Ground the code in real examples. Before inventing structure,
gno_readan existing on-chain realm of a similar shape and match its crossing-function signatures and state layout (outline mode surveys the API;full=truereads a file verbatim). Then write it. -
Test locally — no chain, no keys. Run
gno testand filetests against the source on disk. This loop is friction-free and is where a realm becomes correct; stay in it until tests pass. A realm that compiles is not a realm that works. (Ifgnois missing from PATH, or the realm imports on-chain packages that must come from a specific chain,../gno/references/toolchain.mdcovers installing a chain-matched binary and fetching deps from the target; fall back to a cheap on-chain check withgno_eval/simulate=trueonly when a local toolchain truly can't be had.) -
Now pick the target. Only when the realm is ready to go on-chain, ask where it should run: a local devnet (
gnodev— fast, throwaway) or a testnet (via a gnomcp profile). This is the right moment for that question; before this point there was nothing to place. Once a named chain is chosen,../gno/references/networks.mdcarries its per-chain facts (gas price, gate states, faucet, toolchain tag) and what differs between the live testnets — a package that resolves on one may not exist on the other. -
Never touch keys. Do not run
gnokeydirectly, and never read, ask for, or import a keystore or private key. gnomcp signs for you — agent-key writes viagno_addpkg/gno_call/gno_run, user-attributed writes via a session (gno_session_propose, which the user authorizes with their own key). Reaching for rawgnokeyor a key file means you took a wrong turn. Prefer gnomcp for deploying and calling throughout — it is strongly encouraged here. (For why gnomcp signs, what a deploy/call actually costs — the--gas-wanted/--gas-fee/--max-depositmodel and the gnomcp↔gnokey mapping — see../gno/references/gnokey.md; understanding gnokey is fine, shelling out to it for a write is not.) -
Security pass before deploy. Self-check against
security.md's bug classes — designation-forgery (caller-identity guards), payment guards, impl-substitution. For anything non-trivial or fund-handling, run thegno-auditskill rather than trusting the self-check. -
Clear the deploy gates, then deploy and prove. On a public network a deploy must clear the gates that chain currently enforces — always namespace authorization, and the CLA when it is switched on (it is off on both live testnets today, so check rather than assume either way). Don't discover them by a failed broadcast: pre-check for the agent address and resolve them first (
../gno/references/sysrealms.md, "Deploying through the sys gates"). In short — deploy under the agent's own-address namespace (r/<agent-g1address>/*) or a registered name, and if the CLA gate is enforced andgno.land/r/sys/cla.HasValidSignature(addr)is false, clear it with the MCP'sgno_cla_info+gno_cla_signpair (fetch the agreement URL and hash, the user confirms, then sign) from the same key. On a fresh local chain these gates are usually off — skip straight to deploying. Then deploy via gnomcp, prove it with a real call that returns the expected state, and report which identity signed. Done means deployed, proven, and signer named.