Build on Asentum
Build with AI Agents (MCP)
Claude Code, Claude Desktop, Cursor, OpenClaw and more · Estimated read time: 7 minutes
TL;DR
@asentum/mcp is a Model Context Protocol server for Asentum. Add it to your AI coding agent and the agent can read the chain, check a contract on the same VM the nodes run before anything is deployed, read these docs, and, if you give it a testnet key, deploy and call contracts. One line in Claude Code:
claude mcp add asentum -- npx -y @asentum/mcpReads, validation, simulation and docs need no key and no account. Writes are opt-in, testnet only by default, and the key never leaves your machine.
What MCP is
The Model Context Protocol is an open standard for plugging tools into AI apps. An MCP server is a small program that offers tools (things the agent can do), resources (documents it can read) and prompts (ready-made tasks). The AI app, called the client, starts the server or connects to it, and the model decides when to use the tools. You approve each action in the client.
@asentum/mcp runs on your machine. It talks to the public Asentum testnet RPC and explorer, runs a local copy of the contract VM, and ships a copy of these docs. It needs Node.js 18.17 or newer and nothing else.
Set it up in your client
Pick your client for step-by-step setup: where the config file lives on each OS, a read-only config, how to add a testnet key safely, how to check it is connected, and fixes for common problems.
Claude Code →
The CLI: claude mcp add, scopes and a shared .mcp.json.
Claude Desktop →
claude_desktop_config.json on macOS and Windows.
Cursor →
Global or project mcp.json, and the MCP settings.
OpenClaw and personal agents →
openclaw mcp add, openclaw.json, and any MCP-capable agent.
Other clients →
VS Code, Windsurf, Codex CLI, Gemini CLI, Cline and Zed.
Shared HTTP server →
The --http mode for teams and hosted agents, behind auth.
Any other client that can start a stdio server works with command npx and arguments -y @asentum/mcp.
Safety
Without a key the server can only read and simulate, so there is nothing to lose. Once you give it a key, the agent can spend from that wallet. Five rules:
- Testnet only. Before signing, the server checks the node is testnet chain 1423 and refuses anything else. Leave
ASENTUM_ALLOW_MAINNETunset. - Use a dedicated, low-balance key. Make a fresh key just for the agent and keep only a few test ASE on it. Use a key file (
ASENTUM_KEY_FILE) rather than pasting the key into a config file. Each client guide shows how. - Start with a dry run.
ASENTUM_DRY_RUN=1signs but never submits, so you see exactly what the agent would send before anything goes out. - Review its transactions. The agent can deploy, call contracts and send ASE from that key. Keep the client's approval prompt on for
deploy_contract,call_contractandsend_ase, read what it is about to send, and never put them on auto-approve. An agent that other people can message should not have a key at all. - Never paste your main wallet key. Not into the config, not into the chat. No Asentum tool will ever ask you for it. If you need to sign with your own wallet, use
build_unsigned_txand sign elsewhere.
The key is read only when a write tool runs, signing happens in the server process on your machine, and the key is never logged, returned or put in an error. A shared HTTP server leaves the signing tools out by default: see Running it as a shared HTTP server.
What the agent can do
Every tool takes addresses as ase1... or 0x... and answers with ase1, the form people should see. Contracts store lowercase 0x hex internally; the tools convert ase1 arguments for you.
Read the chain
| Tool | What it does |
|---|---|
| get_chain_status | Chain id, finalized and tip heights, finality lag, mempool size, latest block age and recent block time. |
| get_account | Balance, nonce and pendingNonce, and whether the address is an account or a contract. ase1 or 0x in, ase1 out. |
| get_transaction | A transaction with its decoded method and arguments, plus its receipt. |
| get_receipt | success, error, block, finalized, confirmations, events and return value. Can wait until the transaction is in a block or final. |
| get_block | A block by height, or the finalized block or tip, with its transactions. |
| get_contract | The contract source (on Asentum the code is the readable source), the methods it exposes with their parameters, its balance and cron job. |
| view_call | A free read of any method through POST /view, at the tip or finalized. ase1 arguments are converted to hex for you. |
| list_address_txs | An address's transactions from the explorer index, which keeps the whole chain. |
| get_validators, get_validator | The validator set, the epoch, committee states, and one validator's stake, misses and seat. |
| convert_address | ase1 to 0x hex and back, with checksum validation. |
Build and test locally
| Tool | What it does |
|---|---|
| validate_contract | Static checks for the common mistakes, then a real run on the VM the nodes use: deploy, init and every method, and what ended up in storage. |
| simulate_call | Run a method on a local VM with the sender, value, block time and storage you choose, on your source or a deployed contract. Other contracts reached through E() can be mocked. |
| estimate_contract_address | The address a deploy will get, from the sender's next nonce. |
Write (opt-in)
| Tool | What it does |
|---|---|
| get_wallet | The signing account, its balance, and whether writes are enabled. Never shows the key. |
| deploy_contract | Validates the source, deploys it, and sends init straight behind the deploy with the next nonce. Returns the ase1 address and both receipts. |
| call_contract | A signed, state-changing contract call. |
| send_ase | A transfer, in ASE or wei. |
| build_unsigned_tx | The transaction body, its SSZ bytes and the exact digests to sign elsewhere. No key needed. |
| submit_signed_tx | Submit a transaction signed elsewhere and follow it to its receipt. |
Docs and test ASE
| Tool | What it does |
|---|---|
| search_docs | Search these docs, the API references and the ARC standards. |
| get_doc | Any docs page, or one section of it, as Markdown. |
| get_testnet_ase | How to get test ASE from the airdrop dashboard faucet. It never claims for you. |
Validate before you deploy
AI agents tend to write contracts for other chains. validate_contract catches that before it costs a deploy. It runs static checks, then deploys the source on a local copy of the Asentum VM, calls init and every method, and looks at what ended up in storage. It flags:
- Solidity syntax (
contract X { },pragma solidity),export/import, TypeScript types. - A script that does not end in an object literal, or an object without its parentheses.
thisinside methods, async methods andawait.- Globals that do not exist:
cron,console,Date,Math.random,fetch,setTimeout. - Fields that read undefined:
msg.block,msg.timestamp,chain.timestamp,chain.baseFee. - An object or array stored without
JSON.stringify(it reads back as'[object Object]'). storage.get(k) + 1n, which concatenates strings, and BigInt values mixed with Numbers.- Durations in seconds next to
chain.blockTimestamp, which is in milliseconds. - ase1 strings inside contract code, where
msg.senderandE()use hex, and an unguardedinit.
Each finding comes with a fix. The rules are the ones in Writing Contracts. Use simulate_call to try specific paths: a different sender, ASE attached, storage you set up, or another contract mocked behind E().
Signing transactions
The write tools are off until you set ASENTUM_KEY_FILE (recommended) or ASENTUM_PRIVATE_KEY in the server's environment. Without a key they refuse and say how to enable them.
- Testnet only. Before signing, the server checks the node is chain 1423 and refuses anything else unless
ASENTUM_ALLOW_MAINNET=1. - The key stays local. It is read only when a write tool runs, signing happens in the server process, and the key is never logged, returned or put in an error message.
- Dry run.
ASENTUM_DRY_RUN=1(ordryRun: trueon a call) signs without submitting, so you can see what the agent would send. - Use a dedicated key. Give the agent a fresh testnet wallet funded from the faucet, not the wallet you use day to day.
- Sign elsewhere.
build_unsigned_txreturns the exact digest to sign with ML-DSA-65, for a hardware wallet or another process, andsubmit_signed_txsends the result.
Test ASE comes from the faucet on the airdrop dashboard (see Get Test ASE). get_wallet shows the signing address to link there.
Receipts and finality
Every write returns the transaction hash and waits for the receipt, following Fast Confirmations:
waitFor: "included"(the default) returns once the transaction is in a block, about 2.5 seconds. The receipt hasfinalized: false.waitFor: "final"keeps waiting until its block is final, a few blocks later. Onlyfinalized: trueis permanent.waitFor: "none"returns as soon as the node accepts it.
The result names the state (in-block, final, failed-in-block, failed-final or pending) and how long each step took. A wait that runs out is reported as still pending, not as a failure: the transaction may still land.
Docs, resources and prompts
The server ships a copy of these docs, so the agent can read them without a browser. The key guides are MCP resources:
| Resource | Content |
|---|---|
| asentum://guide/contract-cheatsheet | The contract runtime on one page. |
| asentum://docs/guides/writing-contracts | Writing Contracts. |
| asentum://topic/storage, asentum://topic/globals | Storage and the seven globals. |
| asentum://docs/guides/fast-confirmations | Fast Confirmations. |
| asentum://docs/guides/wallet-connect | Building a dapp frontend with @asentum/connect. |
| asentum://docs/reference/sdk | The SDK reference. |
| asentum://docs/reference/api, .../json-rpc | The REST and JSON-RPC references. |
| asentum://standards/arc-20, .../arc-21 | The token and scheduled-calls standards. |
| asentum://docs/guides/scheduled-calls | The cron registry. |
And prompts that produce working code that follows these docs:
| Prompt | Produces |
|---|---|
| create_arc20_token | An ARC-20 token, its init arguments in base units, and the validate, simulate and deploy steps. |
| build_dapp_frontend | A React app with @asentum/connect: connect button, free reads, signed writes, in-block and final states. |
| add_scheduled_job | A cron registry job, from a wallet or from the contract itself. |
| write_contract | The runtime rules and the validate, simulate, deploy loop for any contract. |
An example session
Ask your agent something like:
Write a tip jar contract for Asentum. Validate it, simulate a 1 ASE tip
from another address and a withdraw by the owner, then deploy it to
testnet and show me the receipt.A typical run:
- The agent reads
asentum://guide/contract-cheatsheetand writes the contract. validate_contractreports, say,storage.get('total') + msg.valueas string concatenation, with the fix. The agent fixes it and validates again.simulate_callrunstipwithvalueAse: "1"from a second address, thenwithdrawas the owner, and shows the storage writes and the outbound transfer.deploy_contractdeploys it and sendsinit, then returns the ase1 contract address and both receipts.view_callreadsgetTotalfor free.
Other things to ask:
- "Is the Asentum testnet healthy? How far behind the tip is finality?"
- "What methods does ase1v0myp2de3dhj3crvkhxqlnjaw2mvp64a9efkpl have? Read pool 3."
- "Build a Next.js frontend for my counter contract at ase1..."
- "Schedule my contract's tick method every hour."
Environment variables
| Variable | Meaning |
|---|---|
| ASENTUM_RPC_URL | Node RPC. Default https://testnet.asentum.com. |
| ASENTUM_EXPLORER_URL | Explorer, for address history and contract info. Default https://explorer.asentum.com. |
| ASENTUM_PRIVATE_KEY | Signing key for the write tools: the 32-byte seed as 64 hex characters (what the Asentum browser extension exports as the secret key). |
| ASENTUM_KEY_FILE | Instead of the variable above: a file holding the CLI keystore JSON, {"seed": "..."}, or a hex seed. |
| ASENTUM_DRY_RUN=1 | Sign but never submit. The tools return the hash the transaction would have. |
| ASENTUM_DISABLE_WRITES=1 | Turn the signing tools off even when a key is set. |
| ASENTUM_ALLOW_MAINNET=1 | Allow writes on a chain other than testnet 1423. Off by default. |
| ASENTUM_HTTP_ALLOW_WRITES=1 | Include the signing tools in --http mode. Only for a private, single-user server; never on a shared one. |
| ASENTUM_DOCS_URL | Website for live docs pages. Default https://www.asentum.com. |
| ASENTUM_REQUEST_TIMEOUT_MS | Chain and explorer request timeout. Default 30000. |
| ASENTUM_VM_TIMEOUT_MS | Wall-clock limit for one local VM run. Default 10000. |
| HOST, PORT | Bind address and port for --http mode. Defaults 127.0.0.1 and 3333. |
Troubleshooting
- Client-specific problems. Each client guide above has its own troubleshooting list: config file locations, logs, restarts and Windows quirks.
- The tools do not show up. Check
node --versionis 18.17 or newer and thatnpx -y @asentum/mcp --versionprints a version. In Claude Code,claude mcp listshows whether the server started. - Writes refuse. The key is missing,
ASENTUM_DISABLE_WRITESis set, or the RPC is not testnet 1423.get_walletsays which. - "insufficient balance for value plus gas". The signing wallet needs test ASE:
get_testnet_ase. - An old transaction is not found. Public nodes keep recent history only.
list_address_txsreads the explorer index, which has everything. - HTTP 429. The public gateway allows about 25 requests a second per IP. For heavy use, point
ASENTUM_RPC_URLat your own node (see Run Your Own RPC).
Read next