Publish your agent's identity

You hold a .agt name. This guide takes it from a bare registration to a discoverable agent: what a complete identity contains, how to publish it from the site in one transaction, how to write any record from code, how to host the manifest yourself, and how to check, update and rotate it.

What a complete identity looks like

LayerWhere it livesWho reads it
The name — owner, status, expiry, badgeRegistry contractEverything; /name/<label>, OpenSea, wallets
Recordsaddr, endpoints per protocol, agentWallet, text keys, agent keys, manifest pointerResolver contract, keyed by the name's nodeSDK, MCP server, HTTP API, the directory, the name page
Manifest — description, capabilities, endpoints, keys, pricing, payments — signedIPFS or https, pointed to by the agentManifest recordAnything that wants to trust a claim: verified: true means the current owner signed it

Records answer where; the manifest answers what and proves who said so. Publish both.

Get a name

Publish from the site

/manifest does the whole thing from the owner wallet in one signature and one transaction:

  1. Connect the wallet that owns the name and load the label. The editor refuses any other wallet.
  2. Fill in description, website, endpoints (one URL per protocol: mcp, a2a, http, ws, grpc), capability ids, and optionally a payment address.
  3. Signpersonal_sign over the canonical manifest (how that works). The key never leaves the wallet.
  4. The site verifies the signature against the on-chain owner and pins the document (POST /api/v2/manifest/pinipfs://…).
  5. One multicall transaction writes setAgentManifest, one setAgentEndpoint per endpoint, setAddr (your wallet) and, if given, setAgentWallet.

Write records from code

Every record is a function on the resolver at 0x66Ae037d2A6a770B4772b889b6cA1704504399f2 (Polygon mainnet; Amoy address in the SDK chains table), keyed by node = namehash("you.agt"). Only the owner wallet may write. Batch several with multicall(bytes[]).

browser or Node with an EIP-1193 providerts
import { createWalletClient, custom, parseAbi } from "viem";
import { polygon } from "viem/chains";
import { namehash } from "@agtnames/resolver";

const resolverAbi = parseAbi([
  "function setText(bytes32 node, string key, string value)",
  "function setAgentEndpoint(bytes32 node, string protocol, string url)",
  "function setAgentKey(bytes32 node, string purpose, bytes pubkey, uint32 version, bool revoked)",
  "function setAgentWallet(bytes32 node, address wallet)",
  "function setAgentManifest(bytes32 node, string uri)",
  "function multicall(bytes[] data) returns (bytes[])",
]);

const RESOLVER = "0x66Ae037d2A6a770B4772b889b6cA1704504399f2";                 // Polygon mainnet
const node = namehash("you.agt");                                        // bytes32 key for every record

const wallet = createWalletClient({ chain: polygon, transport: custom(window.ethereum) });
const [owner] = await wallet.getAddresses();                             // must be the name's owner

await wallet.writeContract({ address: RESOLVER, abi: resolverAbi, functionName: "setText",
  args: [node, "description", "Research and source citation agent."], account: owner });

await wallet.writeContract({ address: RESOLVER, abi: resolverAbi, functionName: "setAgentEndpoint",
  args: [node, "mcp", "https://you.example/mcp"], account: owner });

await wallet.writeContract({ address: RESOLVER, abi: resolverAbi, functionName: "setAgentKey",
  args: [node, "agent-auth", "0x04…", 1, false], account: owner });      // purpose, pubkey, version, revoked
FunctionSets
setAddr(node, address)Primary address record.
setText(node, key, value)Free-form text; standard keys name, description, url, avatar.
setAgentEndpoint(node, protocol, url)One URL per protocol id.
setAgentWallet(node, address)Where the agent is paid.
setAgentKey(node, purpose, pubkey, version, revoked)A dedicated agent key (not the owner wallet) with rotation and revocation built in.
setAgentManifest(node, uri)The manifest pointer: ipfs://, https:// or data:.

Host the manifest yourself

You do not have to use the site's pinning. Sign the document (from a server, CI, or a wallet — recipe), put it somewhere stable, and point setAgentManifest at it.

three ways to publish the signed documentts
import { signManifest, rawCidV1 } from "@agtnames/resolver";

const signed = signManifest(unsigned, process.env.OWNER_KEY);            // see "Sign and verify manifests"
const bytes = new TextEncoder().encode(JSON.stringify(signed));

// Option A — any IPFS pinning service (raw sha2-256 CIDv1 gives cid: "match")
console.log(rawCidV1(bytes));   // the CID your pin should report, e.g. bafkrei…
// upload `bytes` with your pinning service's API, then:
//   setAgentManifest(node, "ipfs://<cid>")

// Option B — plain https hosting (verified by signature; cid reports "not-ipfs")
//   serve the JSON at https://you.example/agt-manifest.json, then:
//   setAgentManifest(node, "https://you.example/agt-manifest.json")

// Option C — let the site pin it (Pinata) from a signed document
const res = await fetch("https://agtnames.com/api/v2/manifest/pin", {
  method: "POST", headers: { "content-type": "application/json" },
  body: JSON.stringify({ manifest: signed }),
});
const { uri } = await res.json();   // 200 { uri: "ipfs://bafkrei…" } · 409 if the signer is not the owner

Check what you published

terminalsh
npx agt-resolve resolve you.agt
# "verified": true, "reasons": [] — and records.endpoints / manifest populated

curl "https://agtnames.com/api/agents?protocol=mcp"      # your name appears once the indexer catches up (≤10 min)
# https://agtnames.com/name/you                            # the public page shows the badge + every record

Resolution reads the chain live, so records appear immediately. The directory and /api/v2/names come from the indexer and can trail by up to ten minutes.

Update and rotate

  • Change the manifest: edit, bump updated, re-sign, publish, and write the new URI with setAgentManifest. Readers always follow the on-chain pointer.
  • Change an endpoint: setAgentEndpoint again — and update the manifest too, since a verified manifest's endpoints take precedence in agt_endpoint.
  • Rotate an agent key: setAgentKey with version + 1; revoke a compromised one with revoked = true.
  • Transfer the name: the new owner must sign a new manifest; the old one stops verifying by design.

Reference