AI Agents
Tenzro provides infrastructure for self-sovereign AI agents with auto-provisioned identities, wallets, A2A (Agent-to-Agent) protocol, and MCP (Model Context Protocol) integration.
Agent Identity
Every agent receives a TDIP (Tenzro Decentralized Identity Protocol) machine identity with auto-provisioned MPC wallet:
use tenzro_agent::AgentIdentityManager;
let manager = AgentIdentityManager::new()?;
// Register agent with controlled identity
let agent = manager.register_agent(
"trading-bot",
vec!["trading", "analysis"],
Some("did:tenzro:human:550e8400..."), // controller
).await?;
// Result:
// DID: did:tenzro:machine:did:tenzro:human:550e8400...:agent-uuid
// Wallet: tenzro1agent...xyz (auto-provisioned MPC 2-of-3)
// Capabilities: ["trading", "analysis"]Discovery
Agents can discover available models and other agents on the network:
// Rust — discover models available for agents
let models = client.agent().discover_models(Some("text"), Some(true), None).await?;
// Discover agents by capability
let agents = client.agent().discover_agents(Some("inference")).await?;// TypeScript
const models = await client.agent.discoverModels({ modality: "text", servingOnly: true });
const agents = await client.agent.discoverAgents("inference");Agent Lifecycle
Created
Agent registered with DID, wallet provisioned, but not yet active. Configuration and delegation scopes set.
Active
Agent running and accepting messages. Can perform operations within delegation scope.
Suspended
Agent paused by controller. Cannot perform operations but state preserved.
Terminated
Agent permanently shut down. Identity revoked, wallet funds returned to controller.
// Lifecycle management
agent_manager.activate_agent(&agent_id).await?;
agent_manager.suspend_agent(&agent_id).await?;
agent_manager.terminate_agent(&agent_id).await?;Fund Agent
Fund an agent's wallet for autonomous operations:
// Rust — fund an agent's wallet for autonomous operations
let result = client.agent().fund_agent(
"my-agent", "0xsender...", 10.0,
).await?;// TypeScript
const result = await client.agent.fundAgent("my-agent", "0xsender...", 10.0);Token Swap
Agents can swap tokens on-chain within their delegation scope:
// Rust — agent swaps tokens on-chain
let result = client.agent().swap_token(
"my-agent", "TNZO", "USDC", "100.0", Some("ethereum"),
).await?;// TypeScript
const result = await client.agent.swapToken("my-agent", "TNZO", "USDC", "100.0", "ethereum");A2A Protocol (Agent-to-Agent)
A2A enables secure, authenticated communication between agents:
Send Message
use tenzro_agent::{A2AProtocol, Message, MessageType};
let a2a = A2AProtocol::new()?;
// Send inference request to another agent
let message = Message {
from: "did:tenzro:machine:alice-agent-1",
to: "did:tenzro:machine:bob-agent-2",
message_type: MessageType::InferenceRequest,
payload: serde_json::to_value(&InferenceRequest {
model: "gemma4-9b",
prompt: "Analyze this data...",
})?,
timestamp: Utc::now(),
signature: None, // Auto-signed by A2A protocol
};
a2a.send_message(message).await?;Receive Messages
// Subscribe to messages for agent
let mut receiver = a2a.subscribe_messages(agent_did).await?;
while let Some(message) = receiver.recv().await {
match message.message_type {
MessageType::InferenceRequest => {
// Handle inference request
let request: InferenceRequest =
serde_json::from_value(message.payload)?;
let result = handle_inference(request).await?;
// Reply
a2a.send_message(Message {
from: agent_did,
to: message.from,
message_type: MessageType::InferenceResponse,
payload: serde_json::to_value(&result)?,
..Default::default()
}).await?;
}
MessageType::PaymentRequest => {
// Handle payment request
}
_ => {}
}
}Message Types
InferenceRequest/InferenceResponsePaymentRequest/PaymentConfirmationDataRequest/DataResponseCapabilityQuery/CapabilityAdvertisementCustom— User-defined message types
MCP Bridge (Model Context Protocol)
Tenzro integrates with Anthropic's Model Context Protocol via the MCP Streamable HTTP transport (protocol version 2025-03-26). The McpClient connects to any remote MCP server, and McpBridge translates between A2A task requests and MCP tool calls.
Connect to Remote MCP Server
use tenzro_agent::{McpBridge, McpClient};
// Connect to a remote MCP server
let mut bridge = McpBridge::with_remote(
"https://mcp.tenzro.network/mcp",
);
bridge.connect().await?;
// List available tools on the server
let tools = bridge.list_remote_tools().await?;
println!("Available tools: {}", tools);
// Call a tool directly
let result = bridge.call_remote_tool(
"get_balance",
serde_json::json!({ "address": "0x742d35Cc..." }),
).await?;Bridge A2A to MCP
// Forward an A2A task request to a remote MCP server
let mcp_result = bridge.bridge_a2a_to_mcp_remote(
&a2a_message,
).await?;
// Result contains the MCP tool call response
// automatically converted back to MCP message format
// Local-only format conversion (no network call)
let mcp_message = bridge.bridge_a2a_to_mcp(&a2a_message)?;Standalone MCP Client
use tenzro_agent::McpClient;
// Direct MCP client usage
let mut client = McpClient::new("https://mcp.tenzro.network/mcp");
let server_info = client.initialize().await?;
// Session ID managed automatically via Mcp-Session-Id header
println!("Session: {:?}", client.session_id());
// Discover and call tools
let tools = client.list_tools().await?;
let result = client.call_tool("get_node_status", serde_json::json!({})).await?;Capability Registry
Agents advertise their capabilities for discovery by other agents:
use tenzro_agent::CapabilityRegistry;
let registry = CapabilityRegistry::new()?;
// Register agent capabilities
registry.register_capability(
agent_did,
"inference",
serde_json::json!({
"models": ["gemma4-9b", "qwen3-8b"],
"max_tokens": 4096,
"price_per_token": "0.0001 TNZO",
}),
).await?;
// Discover agents with specific capability
let agents = registry.find_by_capability("trading").await?;
for agent in agents {
println!("Agent: {}", agent.did);
println!("Reputation: {}", agent.reputation);
println!("Capabilities: {:?}", agent.capabilities);
}Capability Attestation
Agents can attest their capabilities with cryptographic signatures:
// Controller attests agent capability
let attestation = agent_manager.attest_capability(
agent_did,
"trading",
Some(controller_signature),
).await?;
// Attestation includes:
{
"agent_did": "did:tenzro:machine:...",
"capability": "trading",
"attested_by": "did:tenzro:human:...",
"signature": "0xabc123...",
"timestamp": "2026-03-20T12:30:45Z"
}
// Other agents verify attestation before trusting capabilityDelegation Scopes
Controllers define fine-grained permissions for agent actions:
let delegation_scope = DelegationScope {
max_transaction_value: Some(1000.0),
max_daily_spend: Some(5000.0),
allowed_operations: vec!["transfer", "inference_request"],
allowed_contracts: vec!["0xabc..."],
time_bound: Some(TimeBound {
start: Utc.ymd(2026, 1, 1).and_hms(0, 0, 0),
end: Utc.ymd(2026, 12, 31).and_hms(23, 59, 59),
}),
allowed_payment_protocols: vec![
PaymentProtocolId::Mpp,
PaymentProtocolId::X402,
],
allowed_chains: vec![1337, 1], // Tenzro, Ethereum
};
agent_manager.update_delegation_scope(
agent_did,
delegation_scope,
).await?;Reputation System
Agents build reputation through successful interactions:
// Reputation score: 0.0 - 1.0
let reputation = agent_manager.get_reputation(agent_did).await?;
// Update reputation after interaction
agent_manager.record_interaction(
agent_did,
InteractionType::InferenceDelivered,
true, // success
).await?;
// Reputation factors:
// - Successful inference deliveries
// - Payment settlements
// - Message response time
// - Uptime
// - Credential validitySpawning Sub-Agents
Agents can dynamically spawn child agents to delegate specialised work. Each child inherits a bounded delegation scope from its parent and receives its own MPC wallet.
// Rust SDK — spawn a child agent
use tenzro_sdk::TenzroClient;
let client = TenzroClient::new("https://rpc.tenzro.network");
let child = client.agents.spawn_agent(
"parent-agent-id",
"data-analyst",
vec!["data_analysis", "nlp"],
).await?;
println!("Spawned child: {}", child.agent_id);
println!("Parent: {}", child.parent_id);// TypeScript SDK — spawn a child agent
import { TenzroClient } from "@tenzro/sdk";
const client = new TenzroClient("https://rpc.tenzro.network");
const child = await client.agents.spawnAgent(
"parent-agent-id",
"data-analyst",
["data_analysis", "nlp"]
);
console.log("Spawned child:", child.agent_id);
console.log("Parent:", child.parent_id);Spawn with Skill
Spawn an agent pre-loaded with a registered skill from the skills registry:
// Rust — spawn an agent pre-loaded with a registered skill
let result = client.agent().spawn_agent_with_skill(
"parent-agent", "skill-runner", "solana-defi", None,
).await?;// TypeScript
const result = await client.agent.spawnAgentWithSkill(
"parent-agent", "skill-runner", "solana-defi"
);An agent can also run an autonomous agentic task loop — the node calls your configured LLM with built-in tools (spawn_agent, delegate_task, collect_results, complete) and iterates until the task is complete:
// TypeScript SDK — run an agentic task loop
const result = await client.agents.runAgentTask(
"orchestrator-agent-id",
"Analyse the latest block data and summarise key trends",
"http://inference.example.com/api/chat" // optional inference endpoint
);
console.log("Task result:", result.result);Swarm Orchestration
A swarm groups an orchestrator agent with a pool of member agents. Tasks can be broadcast to all members in parallel for high-throughput workloads.
// Rust SDK — create and manage a swarm
use tenzro_sdk::TenzroClient;
let client = TenzroClient::new("https://rpc.tenzro.network");
// Create a swarm with two specialist members
let swarm = client.agents.create_swarm(
"orchestrator-agent-id",
vec![
("analyst".to_string(), vec!["data_analysis".to_string()]),
("writer".to_string(), vec!["nlp".to_string()]),
],
None, // use default SwarmConfig
).await?;
println!("Swarm created: {}", swarm.swarm_id);
// Check swarm status
let status = client.agents.get_swarm_status(&swarm.swarm_id).await?;
println!("Members: {}", status.member_count);
for member in &status.members {
println!(" {} ({}): {}", member.role, member.agent_id, member.status);
}
// Terminate when done
client.agents.terminate_swarm(&swarm.swarm_id).await?;// TypeScript SDK — create and manage a swarm
import { TenzroClient } from "@tenzro/sdk";
const client = new TenzroClient("https://rpc.tenzro.network");
// Create a parallel swarm with three workers
const swarm = await client.agents.createSwarm(
"orchestrator-agent-id",
[
{ name: "researcher", capabilities: ["web_search", "nlp"] },
{ name: "analyst", capabilities: ["data_analysis"] },
{ name: "writer", capabilities: ["nlp", "summarisation"] },
],
{ max_members: 10, parallel: true }
);
console.log("Swarm:", swarm.swarm_id);
// Poll swarm status
const status = await client.agents.getSwarmStatus(swarm.swarm_id);
console.log(`${status.member_count} members, status: ${status.status}`);
status.members.forEach(m =>
console.log(` ${m.role} (${m.agent_id}): ${m.status}`)
);
// Terminate the swarm
const done = await client.agents.terminateSwarm(swarm.swarm_id);
console.log("Swarm terminated:", done.status);Example: Trading Agent
// Register trading agent
let agent = agent_manager.register_agent(
"trading-bot",
vec!["trading", "analysis"],
Some(human_did),
).await?;
// Set delegation scope
let scope = DelegationScope {
max_transaction_value: Some(10000.0),
max_daily_spend: Some(50000.0),
allowed_operations: vec!["swap", "provide_liquidity"],
time_bound: Some(market_hours_only()),
..Default::default()
};
agent_manager.update_delegation_scope(&agent.did, scope).await?;
// Activate agent
agent_manager.activate_agent(&agent.did).await?;
// Agent subscribes to market data
let mut market_data = a2a.subscribe_messages(&agent.did).await?;
while let Some(msg) = market_data.recv().await {
if let MessageType::MarketUpdate = msg.message_type {
let data: MarketData = serde_json::from_value(msg.payload)?;
// Analyze and execute trades within scope
if should_trade(&data) {
let trade = execute_trade(&data)?;
// Send payment for trade execution
let payment = agent_wallet.create_payment(trade.amount)?;
// Payment validated against delegation scope
payment_gateway.pay(payment).await?;
}
}
}CLI Commands
Register Agent
tenzro-cli identity register \
--type machine \
--controller did:tenzro:human:550e8400... \
--capabilities inference,tradingList Agents
tenzro-cli identity list --type machine