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"]
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?;
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: "llama-3-70b",
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": ["llama-3-70b", "gpt-4"],
"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 capability
Delegation 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 validity
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,trading
List Agents
tenzro-cli identity list --type machine