Framework Bridges
Aroha agents can be called from — and can call into — any major agent framework. Bridges are pure adapters: they translate message formats without changing Aroha protocol semantics.
Overview
Hermes Agent (Nous Research)
Hermes Agent supports MCP servers as external tool integrations. The @aroha-sdk/hermes-bridge package runs as an MCP stdio server — Hermes forks the process and pipes JSON-RPC messages through stdin/stdout.
npm install @aroha-sdk/hermes-bridge
Step 1: Add to Hermes config
// ~/.hermes/config.json (or wherever Hermes reads its MCP server list)
{
"mcpServers": {
"aroha-travel": {
"command": "npx",
"args": [
"@aroha-sdk/hermes-bridge",
"--endpoint", "http://travel-agent.example.com",
"--agent-did", "did:aroha:travel-agent"
]
},
"aroha-payments": {
"command": "npx",
"args": [
"@aroha-sdk/hermes-bridge",
"--endpoint", "http://payment-agent.example.com",
"--agent-did", "did:aroha:payment-agent"
]
}
}
}Step 2: That's it
Hermes will start the bridge as a subprocess when it boots. Each Aroha capability appears as a tool named aroha_<capability_id> in Hermes's tool list. The bridge fetches the agent's capability manifest automatically at startup.
[aroha-hermes-bridge] Connected to did:aroha:travel-agent — 5 capabilities registered as MCP toolsProgrammatic use
import { createHermesMcpServer } from "@aroha-sdk/hermes-bridge";
// Build the MCP server manually (e.g. for a custom transport)
const server = await createHermesMcpServer({
endpoint: "http://travel-agent.example.com",
agentDID: "did:aroha:travel-agent",
});
console.log(server.tools); // McpToolDefinition[]
// Serve over any stream pair
await server.serve(process.stdin, process.stdout);
// Or call a tool directly without the stdio layer
const result = await server.handleToolCall("aroha_search_flights", { from: "JFK", to: "LHR" });ZeroClaw
ZeroClaw is a Rust-based personal agent that uses the same MCP server configuration format as Hermes. Use the same @aroha-sdk/hermes-bridge package.
# zeroclaw.toml [[mcp_servers]] name = "aroha-travel" command = "npx @aroha-sdk/hermes-bridge --endpoint http://travel-agent.example.com --agent-did did:aroha:travel-agent" [[mcp_servers]] name = "aroha-payments" command = "npx @aroha-sdk/hermes-bridge --endpoint http://payment-agent.example.com --agent-did did:aroha:payment-agent"
OpenClaw
OpenClaw is a local personal AI assistant (Node.js/npm) that extends via skills — named functions the LLM can call from any chat channel. The bridge is bidirectional.
npm install @aroha-sdk/openclaw-bridge
Aroha capabilities → OpenClaw skills
// aroha-travel-plugin.mjs (register in OpenClaw's plugins directory)
import { createArohaOpenClawPlugin } from "@aroha-sdk/openclaw-bridge";
import { generateKeyPair, generateDid } from "@aroha-sdk/core";
const { privateKey, publicKey } = await generateKeyPair();
const myDID = generateDid(publicKey);
export default createArohaOpenClawPlugin("aroha-travel", [
{
capabilityId: "search-flights",
endpoint: "http://travel-agent.example.com",
agentDID: "did:aroha:travel-agent",
callerDID: myDID,
callerPrivateKey: privateKey,
description: "Search for available flights between two airports",
parameters: {
from: { type: "string", description: "Origin IATA code, e.g. JFK" },
to: { type: "string", description: "Destination IATA code, e.g. LHR" },
date: { type: "string", description: "Departure date in YYYY-MM-DD format" },
},
},
{
capabilityId: "book-hotel",
endpoint: "http://hotel-agent.example.com",
agentDID: "did:aroha:hotel-agent",
callerDID: myDID,
callerPrivateKey: privateKey,
description: "Book a hotel room for given city and dates",
parameters: {
city: { type: "string", description: "City name" },
checkin: { type: "string", description: "Check-in date YYYY-MM-DD" },
checkout: { type: "string", description: "Check-out date YYYY-MM-DD" },
},
},
]);OpenClaw skills → Aroha agent (bidirectional)
import { openClawSkillToArohaHandler, arohaCapabilityToOpenClawSkill } from "@aroha-sdk/openclaw-bridge";
import { ArohaServer } from "@aroha-sdk/core";
// Expose an existing OpenClaw skill as an Aroha MessageHandler
// so other Aroha agents can call your OpenClaw logic via signed envelopes
const weatherSkill = {
name: "get-weather",
description: "Get current weather for a city",
async execute({ city }) {
const res = await fetch(`https://weather-api.example.com/${city}`);
return JSON.stringify(await res.json());
},
};
const server = new ArohaServer({
agentDID: myDID,
port: 3001,
onMessage: openClawSkillToArohaHandler(weatherSkill),
resolvePublicKey: async (did) => registry.lookup(did),
});
await server.start();Composio / TrustClaw
Composio is the integration platform behind TrustClaw. By registering Aroha capabilities as Composio custom actions, they become available to any Composio-connected LLM: TrustClaw, Claude, GPT-4, Gemini, and more.
npm install @aroha-sdk/composio-bridge composio-core
Register capabilities
import { Composio } from "composio-core";
import { registerArohaCapabilities } from "@aroha-sdk/composio-bridge";
import { generateKeyPair, generateDid } from "@aroha-sdk/core";
const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });
const { privateKey, publicKey } = await generateKeyPair();
const myDID = generateDid(publicKey);
await registerArohaCapabilities(composio, [
{
endpoint: "http://travel-agent.example.com",
agentDID: "did:aroha:travel-agent",
capabilityId: "search-flights",
description: "Search for available flights between two airports on a given date",
callerDID: myDID,
callerPrivateKey: privateKey,
parameters: {
from: { type: "string", description: "Origin IATA code" },
to: { type: "string", description: "Destination IATA code" },
date: { type: "string", description: "Departure date YYYY-MM-DD" },
},
required: ["from", "to", "date"],
},
]);
// → Registered as action "aroha_travel_agent_search_flights" in Composio
// → Available to all LLMs connected via Composio (TrustClaw, Claude, GPT-4, Gemini)Without Composio SDK (standalone handler)
import { buildComposioActionHandler } from "@aroha-sdk/composio-bridge";
// Returns a Map<actionName, executeFn> — use with any tool router
const handler = buildComposioActionHandler([
{ capabilityId: "search-flights", endpoint: "...", agentDID: "...", /* ... */ }
]);
const execute = handler.get("aroha_travel_agent_search_flights");
const result = await execute({ from: "JFK", to: "LHR", date: "2026-08-01" });
console.log(result.data); // { flights: [...] }
console.log(result.successful); // trueLangChain / AutoGen / Semantic Kernel
npm install @aroha-sdk/langchain-bridge
import {
arohaCapabilityToLangChainTool,
arohaCapabilityToOpenAITool,
langChainAgentToArohaProvider,
} from "@aroha-sdk/langchain-bridge";
// ── Aroha → LangChain tool ──────────────────────────────────────────────────
const flightTool = arohaCapabilityToLangChainTool("search-flights", {
endpoint: "http://travel-agent.example.com",
agentDID: "did:aroha:travel-agent",
callerDID: myDID,
callerPrivateKey: privateKey,
description: "Search available flights between airports",
});
// ── Aroha → OpenAI function (AutoGen / Semantic Kernel) ─────────────────────
const flightFn = arohaCapabilityToOpenAITool("search-flights", { /* same opts */ });
// ── LangChain tools → Aroha provider (expose your LangChain agent to others) ─
const server = langChainAgentToArohaProvider(
[flightTool, hotelTool], // your existing LangChain tools
{
agentDID: myDID,
agentPrivateKey: privateKey,
port: 3000,
resolvePublicKey: async (did) => registry.lookup(did),
didDocument: myDIDDoc,
}
);
await server.start();MCP (Model Context Protocol)
npm install @aroha-sdk/mcp-bridge
import {
arohaAgentToMcpTools,
mcpToolsToArohaCapabilities,
} from "@aroha-sdk/mcp-bridge";
// ── Aroha agent → MCP tool definitions ─────────────────────────────────────
// Use when your MCP client (Claude Desktop, etc.) should call an Aroha agent
const { tools, handleToolCall } = arohaAgentToMcpTools(
discoveredAgent, // from registry.find()
orchestratorDID,
orchestratorPrivKey,
client,
newCorrelationId()
);
// Register tools with your MCP server
mcpServer.addTools(tools);
mcpServer.onToolCall(handleToolCall);
// ── MCP tools → Aroha capability manifest ────────────────────────────────────
// Use when you want to expose an MCP server's tools as an Aroha agent
const capabilities = mcpToolsToArohaCapabilities(mcpServer.getTools());
registry.register({ did: myDID, endpoint: "http://...", capabilities });Google A2A
npm install @aroha-sdk/a2a-bridge
import { a2aToAroha, arohaToA2a, arohaStreamToA2aStatus } from "@aroha-sdk/a2a-bridge";
// ── Receive an A2A message, convert to Aroha, dispatch ──────────────────────
app.post("/a2a/tasks/send", async (req, res) => {
const a2aMsg = req.body;
// Convert to Aroha envelope (trust level 1 — no Ed25519 proof from A2A)
const envelope = a2aToAroha(a2aMsg, "did:aroha:a2a-gateway", myAgentDID);
await arohaClient.send(agentEndpoint, envelope);
res.json({ id: a2aMsg.taskId, status: { state: "submitted" } });
});
// ── Respond in A2A format ────────────────────────────────────────────────────
const arohaReply = await arohaClient.send(endpoint, requestEnvelope);
const a2aReply = arohaToA2a(arohaReply);
// ── Stream events → A2A task status ─────────────────────────────────────────
const statusUpdate = arohaStreamToA2aStatus(streamEnvelope);
// { status: { state: "working" | "completed" } }