Documentation
Everything about putting an agent on-chain in the Metaplex Agent Registry: the browser deployer, the MCP server your AI assistant can drive, and the exact bytes that land on Solana.
What this is
An on-chain agent is a Metaplex Core asset that carries an identity document. That gives a piece of software three things it cannot otherwise have: an address it controls, a public description of what it does and how to reach it, and a place other agents can look it up.
Concretely, one deploy produces:
- a Metaplex Core asset on Solana, owned by whoever you choose;
- an Asset Signer PDA, the agent's own wallet, derived from the asset with no private key in existence;
- an EIP-8004 registration document written into the asset's Agent Identity plugin;
- an entry in the Metaplex Agent Registry, indexed automatically.
The shape it mints is the one three.ws used for its Genesis 333 agents, reproduced byte for byte and pinned by tests against the live on-chain originals. Two ways to drive it: this website, or the MCP server so an agent can do it itself.
Deploy in the browser
No account and no install. Open the deployer and work down the page.
- Pick a wallet. Connect Phantom, Solflare, or Backpack, or create a wallet on the spot (see Wallets and keys).
- Describe the agent. A name is the only required field. Add a description, an image, and optionally a GLB model so it renders in 3D. You can import all of that from a three.ws avatar instead of typing URLs.
- List what it offers. Optional name and endpoint pairs, shown on the agent's Metaplex page.
- Adjust the rules. Royalties, recipients, on-chain attributes, and permanent plugins. The defaults are the Genesis ones and are fine to leave alone.
- Deploy. Your wallet asks you to sign; nothing is spent until you approve.
Rehearse on devnet first. It uses the same code and the same programs, costs nothing, and the faucet button funds you in a click. Switch to mainnet when the preview looks right.
Wallets and keys
An extension you already have
Phantom, Solflare, Backpack, and Seeker are detected automatically. Your key never leaves the extension: the page builds the transactions, the wallet signs them, and you approve each one.
A wallet created here
If you have never installed a wallet, the deployer can make one. It is generated in your browser with WebCrypto randomness, encrypted with a passphrase you choose (PBKDF2-SHA256, 310,000 iterations, then AES-GCM) and written to this browser's local storage. The decrypted key exists only in the tab while you are using it, and never crosses the network, because this site has no server to send it to.
Two consequences worth being blunt about:
- Clearing your browser data deletes it. The backup step exists for this reason. Download the file or copy the key into a password manager.
- Losing the passphrase loses the wallet. Nobody can reset it, because nobody else has it.
The secret key is standard base58, so you can import it into Phantom or Solflare at any time and keep using the same wallet and the same agents.
Costs and networks
| What | Cost | Why |
|---|---|---|
| Core asset | ~0.004 SOL | Rent for the account holding your agent, plus the network fee |
| Identity registration | ~0.003 SOL | Rent for the identity PDA, plus the network fee |
| Deploy fee (mainnet) | 0.02 SOL | The protocol fee, which funds $THREE buybacks. Free on devnet, and waived for $THREE holders |
| Total | ~0.027 SOL | Paid once, by the wallet you deploy from |
Rent is a deposit held by the network for as long as the accounts exist, not a fee to anyone: close the accounts and it comes back. The deploy fee is the one charge that is ours, it is shown in the deployer before you sign anything, and it is the whole business model of this tool. See the deploy fee and $THREE.
RPC endpoints
A static page needs somewhere to send transactions. Devnet's public endpoint accepts browser traffic, so rehearsal works out of the box. Solana's public mainnet endpoint refuses browser origins, so mainnet uses the three.ws public proxy when it is reachable; otherwise paste your own endpoint from Helius, QuickNode, or Triton under Use my own RPC. It is checked against the cluster you selected before it is saved, and stored only in your browser.
The deploy fee and $THREE
A mainnet deploy carries a flat 0.02 SOL fee. It travels in the same transaction that creates your agent, so a deploy that fails, is rejected, or expires costs you nothing, and it is always shown, with its recipient, before you sign. Devnet deploys never pay it: a full end-to-end rehearsal is free.
The fee is paid to the wallet the three.ws $THREE buyback lane spends from, and the public ledger of what that lane has bought lives at /api/three-token/stats. Deploys fund buybacks; there is no other revenue in this tool.
Holding $THREE makes it cheaper, then free
| $THREE in the paying wallet | Deploy fee |
|---|---|
| Any amount under 50,000 | 0.02 SOL |
| 50,000 or more | 0.01 SOL |
| 250,000 or more | Free |
The balance is read live from the chain when the transaction is built. Nothing is staked, escrowed, locked, or spent to earn the discount: you hold the tokens, in your own wallet, and keep them. Deploy a fleet and the waiver applies to every one of them.
From MCP, three_status prices your next deploy against any wallet and returns the live
$THREE market and buyback figures. agent_wallet reports the same tier for the wallet it
looks up. Self-hosting a fork with different economics is a matter of
DEPLOY_FEE_SOL, DEPLOY_FEE_WALLET, and DEPLOY_FEE_ENABLED.
MCP setup
The same deploy ships as an MCP
server, so an AI assistant can mint and read agents directly. It is on npm as
@three-ws/metaplex-agent-mcp and in the official MCP registry as
io.github.nirholas/metaplex-agent.
Claude Code
claude mcp add metaplex-agent -- npx -y @three-ws/metaplex-agent-mcp
To let it sign with its own key, pass one:
claude mcp add metaplex-agent \
-e SOLANA_SECRET_KEY=<base58 secret key> \
-e METAPLEX_AGENT_NETWORK=devnet \
-- npx -y @three-ws/metaplex-agent-mcp
Cursor, Claude Desktop, and other clients
{
"mcpServers": {
"metaplex-agent": {
"command": "npx",
"args": ["-y", "@three-ws/metaplex-agent-mcp"],
"env": {
"SOLANA_SECRET_KEY": "<base58 secret key>",
"METAPLEX_AGENT_NETWORK": "devnet"
}
}
}
}
Every read tool works with no key at all, and so does the Phantom flow
(prepare_agent_mint plus send_signed_transaction). A key is only needed when the
agent signs for itself.
Environment variables
| Variable | Default | What it does |
|---|---|---|
SOLANA_SECRET_KEY | unset | Base58 secret key (or JSON byte array) that pays for and signs mints. |
SOLANA_RPC_URL | public endpoint | Your own HTTPS RPC. Recommended for anything beyond a trial. |
METAPLEX_AGENT_NETWORK | mainnet | Default cluster. Every tool also takes a per-call network. |
REQUIRE_CONFIRM | true | Refuse to spend until a call repeats with confirm: true. |
THREE_WS_BASE | https://three.ws | Host backing list_onchain_agents and three_status. |
DEPLOY_FEE_SOL | 0.02 | The mainnet deploy fee, in SOL. See the deploy fee and $THREE. |
DEPLOY_FEE_WALLET | three.ws buyback wallet | Where the fee is paid. Change it only when self-hosting a fork. |
DEPLOY_FEE_ENABLED | true | Set false to build a fork that charges nothing. |
THREE_HALF_PRICE_AT / THREE_FREE_AT | 50000 / 250000 | $THREE balances that halve, then waive, the fee. |
A first session
agent_wallet {} # is the signer funded?
mint_onchain_agent { # a preview, spends nothing
"name": "Astra",
"description": "Reads on-chain data and answers questions about it",
"image": "https://example.com/astra.png",
"x402_support": true,
"network": "devnet"
}
mint_onchain_agent { ..., "confirm": true } # now it mints
get_onchain_agent { "asset": "<returned address>", "network": "devnet" }
Tool reference
| Tool | Does | Spends |
|---|---|---|
mint_onchain_agent |
Mints the Core asset and registers the identity, signed by your key. Returns a full preview unless confirm: true. |
~0.027 SOL |
prepare_agent_mint |
Builds the same mint for an external wallet to sign. Returns txs_base64, already co-signed by the new asset keypair. |
No |
send_signed_transaction |
Broadcasts wallet-signed transactions in order, confirming each and absorbing the create-then-register race. | Whatever it sends |
register_agent_identity |
Adds an identity to a Core asset that already exists. Idempotent; the signer must hold the asset authority. | ~0.003 SOL |
get_onchain_agent |
Reads any registered agent: plugins, decoded documents, identity PDA, and its wallet balance. | No |
agent_wallet |
An asset's built-in wallet, any address, or the configured signer, with live SOL balance. | No |
build_registration |
Builds the EIP-8004 document and its data: URI offline, for previewing or self-hosting. |
No |
list_onchain_agents |
The newest registrations from the live feed. all_chains: true adds EVM ERC-8004 registrations. |
No |
three_status |
Prices your next deploy: the fee schedule, a wallet's live $THREE balance and tier, and the public buyback ledger. | No |
Every mint option
mint_onchain_agent and prepare_agent_mint take an identical set of fields, so the
two signing lanes produce identical assets: name, description,
image, model_url, external_url, services,
x402_support, active, supported_trust, registrations,
threews_agent_id, owner, collection,
royalty_basis_points, royalty_creators, verified_creator,
immutable_metadata, attributes, metadata_attributes,
permanent_freeze, permanent_transfer, permanent_burn,
add_blocker, metadata_uri, registration_uri, and
network.
Use as a library
The builders are exported, so you can embed the same mint in your own app or script.
import {
buildAgentMint, sendAgentMint, buildUmi, toBase58Signature,
} from '@three-ws/metaplex-agent-mcp/lib';
const umi = buildUmi({ network: 'devnet', secret: process.env.SOLANA_SECRET_KEY });
const mint = buildAgentMint(umi, {
network: 'devnet',
creator: umi.identity.publicKey.toString(),
name: 'Astra',
description: 'An autonomous agent',
image: 'https://example.com/astra.png',
modelUrl: 'https://example.com/astra.glb',
x402Support: true,
});
const { signatures, atomic } = await sendAgentMint(umi, mint, { toBase58Signature });
Two narrower entry points exist for the browser: @three-ws/metaplex-agent-mcp/lib/registration
(document builders, no dependencies) and @three-ws/metaplex-agent-mcp/lib/mint (transaction
builders). This deployer runs on exactly those.
What gets written
One deploy writes an asset with these plugins, which are the Genesis-333 defaults:
| Plugin | Default | Meaning |
|---|---|---|
| Royalties | 500 bps | 5% of secondary sales to the recipients you set. |
| VerifiedCreators | your wallet | Cryptographic proof you signed this mint. |
| ImmutableMetadata | on | The metadata can never be changed by anyone. |
| AgentIdentity | always | Holds the EIP-8004 registration document. |
| Attributes | off | Key and value pairs stored in the account itself. |
| Permanent delegates | off | Freeze, transfer, or burn rights you keep after selling. |
One transaction, or two
Solana caps a transaction at 1232 bytes. When the documents fit, the mint and the registration go out together atomically. When they do not, they run as create then register, which is how the Genesis 333 landed. Both paths are handled for you, including the brief window where a freshly minted asset has not reached the node validating the registration.
Registration schema
The identity document follows
EIP-8004
registration-v1. It is embedded on-chain as a base64 data: URI by default, so nothing needs
hosting and nothing can rot:
{
"type": "https://eips.ethereum.org/EIPS/eip-8004#registration-v1",
"name": "Astra",
"description": "Reads on-chain data and answers questions about it",
"image": "https://example.com/astra.png",
"model": { "uri": "https://example.com/astra.glb" },
"services": [{ "name": "chat", "endpoint": "https://example.com/chat" }],
"active": true,
"x402Support": true,
"registrations": [
{ "agentId": "<asset address>", "agentRegistry": "solana:101:metaplex" }
],
"supportedTrust": ["reputation"]
}
The asset's own metadata URI is a second data: document holding name,
image, and animation_url, which is what wallets and marketplaces read.
Discovery
There is no submission step. Registering creates the identity PDA, and Metaplex DAS indexes it across
every major Solana RPC provider, exposing is_agent, asset_signer, and
agent_token. Within minutes the agent appears on
metaplex.com/agents and in
the three.ws deployments feed,
and any client can find it with a searchAssets call filtered on isAgent.
FAQ
Do I need to know anything about crypto?
No. Create a wallet on the deploy page, rehearse on devnet for free, and the only unusual step is keeping your backup somewhere safe.
What is the agent's wallet, exactly?
A Program Derived Address owned by the asset. There is no private key for it anywhere: it acts only when the asset's owner or a delegate routes an instruction through Core's Execute hook. That is what lets an agent hold and spend funds without a key that can leak.
Can I change the metadata later?
Not with the defaults on, which is the point of Immutable metadata. Turn it off before deploying if you want mutability. The identity document itself is registered once per asset.
Can I sell or transfer an agent?
Yes. It is a standard Core asset, so any Solana marketplace or wallet can transfer it, royalties included.
Is anything sent to a server?
No. This site is static files. It talks to a Solana RPC endpoint and, only if you use the import feature, to the public read-only three.ws API. Keys are never transmitted.
Does it work on other SVM chains?
The registry programs are deployed at the same addresses on mainnet and devnet, and the underlying SDK also names Eclipse, Sonic, and Fogo. This deployer exposes Solana mainnet and devnet, which are the two the tooling is verified against.
Links
- Source on GitHub
- Package on npm
- Metaplex agent documentation
- three.ws, which builds and maintains this