Skip to main content

Hermes

Use @codespar/hermes to give Hermes Agent (Nous Research) a LATAM commerce rail.

1 min read · updated

Hermes Adapter

Hermes Agent (Nous Research) is an open-source autonomous agent runtime with persistent memory, a tool gateway, credit billing, and a Privy-secured embedded wallet. It ships no commerce or payment tools — and it consumes external tools as plugins and MCP servers. The @codespar/hermes adapter converts CodeSpar session tools into Hermes' MCP-style tool format so a Hermes agent can charge, pay, invoice, ship, and notify across Latin America.

Pick this adapter when you run a Hermes agent that already holds a Privy wallet and credit balance but needs to actually transact with LATAM merchants — who want Pix / BRL / NF-e, not raw stablecoin. CodeSpar is the settlement rail; Hermes is the runtime.

Two ways to connect

Hermes connects external tool servers over the Model Context Protocol. Point it at the CodeSpar MCP server and the meta-tools appear in its tool gateway — no code required.

In the Hermes Portal, open the MCP servers / integrations section.

Add the CodeSpar MCP server:

Hermes MCP config
{
  "mcpServers": {
    "codespar": {
      "command": "npx",
      "args": ["@codespar/mcp", "serve"],
      "env": {
        "CODESPAR_API_KEY": "csk_live_your_key_here"
      }
    }
  }
}

Restart the agent so the tool gateway discovers the meta-tools: codespar_discover, codespar_charge, codespar_pay, codespar_invoice, codespar_ship, codespar_notify, codespar_crypto_pay, codespar_kyc, and codespar_manage_connections.

Ask it to run a commerce flow — for example, "pay a Brazilian supplier R$1.200 via Pix and issue the NF-e."

Use a csk_test_ key to route against sandbox servers with realistic mock data. Switching to live is a single environment-variable change.

If you build a Hermes plugin (Python entry point in ~/.hermes/plugins/) with a JS/TS tool bridge, use the adapter to register CodeSpar tools programmatically.

Installation

npm install @codespar/sdk @codespar/hermes
pnpm add @codespar/sdk @codespar/hermes
yarn add @codespar/sdk @codespar/hermes

@codespar/hermes has a peer dependency on @codespar/sdk@^0.10.0. Make sure it is installed.

API Reference

getTools(session): Promise<HermesTool[]>

Fetches all tools from the session and converts them to Hermes tool format. Each HermesTool mirrors the MCP tool spec — name, description, inputSchema (JSON Schema) — plus an async call that routes execution through the CodeSpar session for billing and audit.

import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/hermes";

const cs = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY! });
const session = await cs.create("user_123", { preset: "brazilian" });

const tools = await getTools(session);

// Register each tool with your Hermes plugin / MCP bridge
for (const tool of tools) {
  plugin.registerTool(tool);
}

toHermesTool(tool, session): HermesTool

Converts a single CodeSpar tool to Hermes format. The call method is bound to the session for execution.

import { toHermesTool } from "@codespar/hermes";

const allTools = await session.tools();
const paymentTools = allTools
  .filter((t) => t.name.includes("pay") || t.name.includes("charge"))
  .map((t) => toHermesTool(t, session));

HermesTool

FieldTypeDescription
namestringTool identifier (e.g. codespar_charge)
descriptionstringHuman-readable description
inputSchemaRecord<string, unknown>JSON Schema for the tool's parameters
call(input) => Promise<string>Executes via the session; returns the JSON-stringified result

Full agent loop

Register CodeSpar tools, then let the Hermes agent call them. Below is a manual execution example; in a real plugin the agent's tool gateway invokes call for you.

hermes-plugin.ts
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/hermes";

const cs = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY! });

async function setup() {
  // 1. Create a session scoped to the providers you need
  const session = await cs.create("user_123", { preset: "brazilian" });

  // 2. Get tools in Hermes format
  const tools = await getTools(session);

  // 3. Register them with the Hermes plugin / MCP bridge
  //    for (const tool of tools) plugin.registerTool(tool);

  // 4. Manual execution (the gateway does this for you in production)
  const charge = tools.find((t) => t.name === "codespar_charge");
  if (charge) {
    const result = await charge.call({
      provider: "asaas",
      amount: 120000,
      currency: "BRL",
      description: "Supplier payment #1234",
      payment_methods: ["pix"],
    });
    console.log("Charge result:", result); // JSON string
  }

  // 5. Clean up
  await session.close();
}

await setup();

Complementary, not competing

Hermes' Privy-secured wallet can hold USDC; CodeSpar settles into LATAM fiat. The natural shape is a Privy-funded agent wallet (USDC) funding a CodeSpar call that settles into Pix / BRL / NF-e — the cross-border meta-tool. Hermes is the agent's runtime and wallet; CodeSpar is the LATAM commerce settlement.

Error handling

call throws if the underlying tool execution fails. Wrap it and return the error so the agent can reason about it:

try {
  const result = await tool.call(input);
  console.log("Success:", result);
} catch (error) {
  console.error(
    `Tool ${tool.name} failed:`,
    error instanceof Error ? error.message : error,
  );
}

Best practices

  1. Scope servers narrowly. Use a preset or explicit servers list so the agent sees only the tools it needs — fewer tools improves selection accuracy.
  2. Close sessions. Use try/finally to ensure session.close() runs even if the plugin throws.
  3. Start in sandbox. Use a csk_test_ key while wiring the plugin, then flip to csk_live_.
  4. Keep custody pluggable. If you bridge the Privy wallet into codespar_crypto_pay, keep the custody backend swappable (Privy vs Turnkey vs Crossmint).

Newer SDK wrappers

getTools(session) is the agent-facing path. From inside (or alongside) the agent you can also call typed wrappers on the session — same routing, no LLM hop:

  • session.discover(query) / session.charge(args) / session.pay(args) / session.ship(args) — typed shortcuts for the meta-tools.
  • session.connectionWizard(serverId) — open a hosted auth flow for a missing connection.
  • session.paymentStatus(toolCallId) and session.paymentStatusStream(toolCallId) — async settlement correlation (poll or SSE).
  • session.verificationStatus(toolCallId) and session.verificationStatusStream(toolCallId) — KYC outcome polling / SSE.

Full reference at /docs/api/sdk.

Next steps

Edit on GitHub

Last updated on