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

import { Callout } from "fumadocs-ui/components/callout";
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
import { Steps, Step } from "fumadocs-ui/components/steps";

# Hermes Adapter

<VersionBadge pkg="@codespar/hermes" />

<Callout type="warn">
**Coming soon.** The `@codespar/hermes` package is not yet published to npm, so the install and import snippets below will not resolve yet. The MCP-server path on this page works today with the published `@codespar/mcp` package.
</Callout>

[Hermes Agent](https://hermes-agent.nousresearch.com/) (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.

<Callout type="info">
**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.
</Callout>

## Two ways to connect

<Tabs items={["MCP server (no code)", "Plugin adapter"]}>

<Tab value="MCP server (no code)">
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.

<Steps>
<Step>
In the Hermes Portal, open the **MCP servers / integrations** section.
</Step>
<Step>
Add the CodeSpar MCP server:

```json title="Hermes MCP config"
{
  "mcpServers": {
    "codespar": {
      "command": "npx",
      "args": ["@codespar/mcp", "serve"],
      "env": {
        "CODESPAR_API_KEY": "csk_live_your_key_here"
      }
    }
  }
}
```
</Step>
<Step>
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`.
</Step>
<Step>
Ask it to run a commerce flow — for example, _"pay a Brazilian supplier R$1.200 via Pix and issue the NF-e."_
</Step>
</Steps>

<Callout type="info">
Use a `csk_test_` key to route against sandbox servers with realistic mock data. Switching to live is a single environment-variable change.
</Callout>
</Tab>

<Tab value="Plugin adapter">
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

<Tabs items={["npm", "pnpm", "yarn"]}>
<Tab value="npm">
```bash
npm install @codespar/sdk @codespar/hermes
```
</Tab>
<Tab value="pnpm">
```bash
pnpm add @codespar/sdk @codespar/hermes
```
</Tab>
<Tab value="yarn">
```bash
yarn add @codespar/sdk @codespar/hermes
```
</Tab>
</Tabs>

<Callout type="info">
`@codespar/hermes` has a peer dependency on `@codespar/sdk@^0.10.0`. Make sure it is installed.
</Callout>
</Tab>

</Tabs>

## 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.

```typescript
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.

```typescript
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`

| Field | Type | Description |
|-------|------|-------------|
| `name` | `string` | Tool identifier (e.g. `codespar_charge`) |
| `description` | `string` | Human-readable description |
| `inputSchema` | `Record<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.

```typescript title="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:

```typescript
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](/docs/api/sdk).

## Next steps

<NextStepsGrid items={[
  { label: "PROVIDER", title: "MCP Adapter", description: "Connect any MCP-compatible client, not just Hermes.", href: "/docs/providers/mcp" },
  { label: "CONCEPT", title: "Sessions", description: "Session lifecycle, presets, and server scoping.", href: "/docs/concepts/sessions" },
  { label: "CONCEPT", title: "Tools & Meta-Tools", description: "The meta-tool layer and how routing works.", href: "/docs/concepts/tools" },
  { label: "PROVIDER", title: "Claude Adapter", description: "Programmatic integration with the Anthropic SDK.", href: "/docs/providers/claude" },
  { label: "QUICKSTART", title: "Quickstart", description: "End-to-end setup in under 5 minutes.", href: "/docs/quickstart" },
]} />
