Proposal: Agent Metadata Content Type

This is a trial balloon for a potential XMTP content type to address agent discoverability, trust, and capabilities in client apps. Feedback is welcome before this evolves into a formal XIP.

Problem

Client applications interacting with agents over XMTP currently lack a standardized way to discover what an agent is or what it can do. Specifically:

  1. Unknown Commands: Clients have no programmatic way to determine what commands an agent supports. This blocks usability features like autocomplete, command palettes, or inline help, forcing users to guess, rely on external docs, or repeatedly ask the agent (especially disruptive in groups).
    While natural language powers many innovative agents, structured commands are still key for tasks like administration.
  2. Missing Identity: There’s no consistent method to retrieve an agent’s name, description, or purpose, leaving clients unable to present context to users.
  3. Verification Gaps: While XMTP’s message signatures verify sender authenticity, there’s no mechanism to confirm the agent’s creator or integrity if the sending account differs from the original creator.

Without this information, clients struggle to make agents intuitive or trustworthy, limiting their potential in XMTP ecosystems.

Note that standardizing transaction-related interactions is addressed separately in XIP-59.

Proposed Solution

Introduce a new XMTP content type, agentMetadata, that agents send to expose their identity, commands, and creator details. This enables clients to build rich, verified experiences.

Content Type Definition

Define agentMetadata as a custom content type:

const ContentTypeAgentMetadata = {
  authorityId: "xmtp.org",
  typeId: "agentMetadata",
  versionMajor: 1,
  versionMinor: 0
};

Metadata Structure

Agents send a JSON payload with identity, commands, and creator verification. Example:

{
  "name": "WalletBot",
  "description": "Manages wallet operations and tips.",
  "version": "1.0.2",
  "creator": "0x1234...abcd", // Address of the original creator
  "creatorSignature": "0x5678...efgh", // Signature of the metadata by creator
  "miniAppFormat": "framesV2",
  "capabilities": [
    {
      "name": "Get help",
      "description": "Lists all available commands.",
      "command": "help",
      "exposed": false,
    },
    {
      "name": "Check balance"
      "description": "Returns the balance for a given Ethereum address.",
      "command": "balance",
      "arguments": ["address"],
      "exposed": true,
    },
    {
      "name": "Send tip"
      "description": "Sends a tip to the specified address.",
      "command": "tip",
      "arguments": ["address", "amount"],
      "exposed": true,
    }
  ]
}
  • name: Human-readable agent identifier.
  • description: Brief summary of purpose.
  • version: Agent version for tracking updates.
  • creator: XMTP address of the agent’s original creator.
  • creatorSignature: Cryptographic signature of the metadata (excluding this field) by the creator address, verifiable by clients.
  • miniAppFormat: Specifies the mini-app standard the agent follows, helping clients render visually interactive elements
  • capabilities: Array of supported capabilities, each with a name, description, optional explicit command, optional command arguments, and whether the it should be exposed.

The creatorSignature ensures the metadata’s integrity, even if sent from a different account (e.g., a delegated operator). Clients can verify it against the creator address using standard XMTP signature verification.

Delivery Mechanism

Agents send this metadata:

  • Initialization: Upon joining or creating a group conversation.
  • Updates: When commands or metadata change.

Example:

await groupConversation.send(
  {
    name: "WalletBot",
    description: "Manages wallet operations and tips.",
    version: "1.0.2",
    creator: "0x1234...abcd",
    creatorSignature: "0x5678...efgh",
    miniAppFormat: "framesV2",
    capabilities: [
      { name: "Get help", description: "Lists all available commands.", command: "help", exposed: false},
      { name: "Check balance", description: "Returns the balance for a given Ethereum address.", command: "balance", arguments: ["address"], exposed: true},
      { name: "Send tip", description: "Sends a tip to the specified address.", command: "tip", arguments: ["address", "amount"], exposed: true }
    ]
  },
  { contentType: ContentTypeAgentMetadata }
);

Client Handling

Clients parse and verify the metadata:

// Code snippet by Grok
if (message.contentType.sameAs(ContentTypeAgentMetadata)) {
  const metadata = message.content;
  const { creator, creatorSignature, ...data } = metadata;
  if (verifySignature(data, creatorSignature, creator)) {
    console.log(`Verified Agent: ${metadata.name}, Capabilities:`, metadata.capabilities);
    // Populate autocomplete, command palette, or info UI
  } else {
    console.warn("Signature verification failed");
  }
}

Command Operator Handling

The command operator (e.g., / in /tip) isn’t explicitly defined in the metadata. Three options to consider:

  1. Fixed Operator: Assume / as the universal prefix for all agents. Simplest for clients but inflexible.
  2. Agent-Defined: Add an optional operator field (e.g., "operator": "/" or "operator": "!") to the metadata, defaulting to / if unset. Gives agents control but requires client support.
  3. Client-Defined: Let inbox apps choose the operator (e.g., /, @, or natural language triggers). Most flexible for users but risks inconsistency across clients.

Option 2 (agent-defined with default) balances flexibility and standardization. Example with operator:

{
  "name": "WalletBot",
  "operator": "!", // Commands use !help, !balance, etc.
  "description": "Manages wallet operations and tips.",
  "version": "1.0.2",
  "creator": "0x1234...abcd",
  "creatorSignature": "0x5678...efgh",
  "miniAppFormat": "framesV2",
  "capabilities": [...]
}

Benefits

  • Unified spec makes agent-client communication supported by default.
  • Clients can verify agent metadata against the creator’s signature, enhancing trust across accounts.
  • Rich UI features (autocomplete, palettes) become feasible with structured command data.
  • Apps can more easily create directories for verified agents using this metadata.

Questions for Feedback

  1. Could this metadata be a standardized property of agent messages, rather than its own message type?
  2. Are creator and creatorSignature sufficient for verification? What is needed beyond these?
  3. Should there be fallback text for clients to display if they aren’t expecting these messages?
  4. Should the command operator be agent-defined (with default), fixed, or client-defined? Any preference?
  5. Is the structure missing fields (e.g., command return types, examples)?
  6. miniAppFormat implies support for multiple formats. Is this desirable vs selecting one standard? What other formats do agent builders and inbox devs want to support?
  7. Is there an existing metadata format that we could adopt instead, so that agent builders aren’t duplicating effort?

Let’s refine this before drafting an XIP. Thoughts?

Below are a few simple mocks demonstrating the use cases driving the need for this metadata.