Skip to content

edgeandnode/ampersend-hermes

 
 

Repository files navigation

@ampersend/hermes

Integration package that wires ampersend x402 payment capabilities into Hermes Agent across three planes: MCP-based payment proxy, agent identity management via the ampersend dashboard, and client-side spend limit guardrails.

This package is a thin, typed layer over the @ampersend_ai/ampersend-sdk. It provides opinionated defaults for Hermes workflows — automatic agent setup via the approval flow, Hermes config patching for MCP payment proxying, and pre-flight spend validation — while staying composable enough to use in any agent framework.

Quick Start (Bootstrap)

Defaults to Base mainnet and the production ampersend API (https://api.ampersend.ai). No flags needed for production use.

Recommended (Hermes, CI shells, non-TTY): two-step flow — start generates a key and requests approval, finish polls and activates.

git clone https://github.com/edgeandnode/ampersend-hermes.git
cd ampersend-hermes
pnpm install
pnpm bootstrap start --name my-hermes-agent
# Show the user_approve_url to the user — they approve in the ampersend dashboard
pnpm bootstrap finish

If you already have the repo locally, run these commands from the repository root (the folder that contains package.json), not a monorepo packages/ path.

One-shot setup (patches Hermes + starts proxy):

pnpm setup --name my-hermes-agent
# Requests approval, waits for it, patches Hermes config, starts MCP proxy
# Uses Base mainnet + production ampersend by default
# Switch to Hermes and run /reload-mcp

Installation (Manual)

cd ampersend-hermes   # repository root
cp .env.example .env
# Fill in AMPERSEND_AGENT_KEY and AMPERSEND_AGENT_ACCOUNT
pnpm install && pnpm build

Configuration

All environment variables are validated at startup with Zod. The variables required for operation are AMPERSEND_AGENT_KEY and AMPERSEND_AGENT_ACCOUNT — everything else defaults to Base mainnet and the production ampersend API.

Variable Required Default Description
AMPERSEND_AGENT_KEY Yes 0x-prefixed session key private key (66 chars)
AMPERSEND_AGENT_ACCOUNT Yes 0x-prefixed smart account address (42 chars)
AMPERSEND_API_URL No https://api.ampersend.ai ampersend API base URL (production)
AMPERSEND_NETWORK No base Network: base (mainnet) or base-sepolia (testnet)
AMPERSEND_CHAIN_ID No 8453 Chain ID — auto-derived from network
AMPERSEND_MCP_PROXY_PORT No 3000 MCP proxy listen port
AMPERSEND_ENV_FILE No Absolute path to .env when not next to this package
HERMES_CONFIG_DIR No ~/.hermes Path to Hermes config directory

For test isolation, use loadConfig() with partial overrides:

import { loadConfig } from "@ampersend/hermes";
const cfg = loadConfig({ AMPERSEND_AGENT_KEY: "0x..." });

TypeScript examples assume you depend on this package ("@ampersend/hermes" in package.json) or use path mapping to dist/ after pnpm build.

Patch Hermes Config

Register ampersend under mcp_servers.ampersend (tools proxied via x402):

import { patchHermesConfig } from "@ampersend/hermes";
await patchHermesConfig("~/.hermes");

Default (stdio) — recommended: writes a stdio server entry that runs the ampersend MCP proxy via npx with agent credentials in env. The proxy handles SIWE authentication and x402 payments internally.

Optional HTTP (transport: 'http'): connects to an already-running proxy at http://127.0.0.1:<port>/mcp:

await patchHermesConfig("~/.hermes", { transport: "http", proxyPort: 3000 });

Apply in Hermes (no full restart required):

/reload-mcp

One Command Setup (after bootstrap)

pnpm setup --name my-hermes-agent

This does everything (Base mainnet + production ampersend by default):

  1. Reads AMPERSEND_AGENT_KEY / AMPERSEND_AGENT_ACCOUNT from .env (runs bootstrap if missing).
  2. Patches ~/.hermes/config.yamlmcp_servers.ampersend (MCP proxy with x402 payments).
  3. Starts the MCP proxy → waits for ready → prints "ready".
  4. Keeps running (Ctrl+C to stop).

Switch back to Hermes and run /reload-mcp. Done.

Options:

pnpm setup --name my-agent --proxy-port 4000          # custom port
pnpm setup --name my-agent --no-proxy                 # patch only, start proxy yourself
pnpm setup --name my-agent --daily-limit 10000000     # 10 USDC daily limit
pnpm setup --name my-agent --network base-sepolia     # testnet (for development only)
pnpm setup -h                                          # full help

Fetch paid (x402) URLs

Do not use getApiClient() for arbitrary HTTPS URLs. This package’s getApiClient() only exposes authorizePayment, reportPaymentEvent, and related helpers — no .fetch. For paid URLs use getPaidFetch() or ampersend fetch (see below).

Use one of these instead:

Approach When to use
ampersend fetch <url> Shell / quick test (same as SDK’s x402 HTTP stack)
getPaidFetch() from @ampersend/hermes TypeScript: paid fetch with x402 handling
import { getPaidFetch } from "@ampersend/hermes";

async function main() {
  const fetchPaid = getPaidFetch();
  const res = await fetchPaid("https://example.com/x402-endpoint");
  console.log(await res.text());
}
void main();

Inspect cost without paying:

ampersend fetch --inspect https://example.com/x402-endpoint

Authorize Payments

Use the ampersend API to authorize payments with spend limits:

import { authorizePayment, getTreasurer } from "@ampersend/hermes";

// Option 1: Direct API authorization (requirements come from the x402 402 body)
const result = await authorizePayment({
  requirements: [
    {
      scheme: "exact",
      network: "base",
      maxAmountRequired: "1000000",
      resource: "https://api.example.com/resource",
      description: "Example resource",
      mimeType: "application/json",
      payTo: "0x0000000000000000000000000000000000000001",
      maxTimeoutSeconds: 60,
      asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    },
  ],
  context: { method: "tools/call", serverUrl: "https://api.example.com" },
});

// Option 2: Get a pre-configured X402Treasurer for proxy/client use
const treasurer = getTreasurer();

Client-Side Guardrails

Pre-validate payments before they hit the API:

import { validatePayment, buildSpendPolicy } from "@ampersend/hermes";

const policy = buildSpendPolicy({
    perTxLimit: "1000000", // 1 USDC
    dailyLimit: "10000000", // 10 USDC
    networks: ["base"],
});

validatePayment(
    { amount: "500000", network: "base", resource: "/api/data" },
    policy,
); // passes

validatePayment(
    { amount: "2000000", network: "base", resource: "/api/data" },
    policy,
); // throws SpendLimitViolationError (PER_TX_LIMIT_EXCEEDED)

Agent Management

Create and manage agents through the ampersend approval flow:

import {
    requestAgentApproval,
    waitForApproval,
    getAgentStatus,
} from "@ampersend/hermes";

// Request setup approval
const pending = await requestAgentApproval("0xAgentKeyAddress", {
    name: "my-agent",
    dailyLimit: "10000000",
});
console.log("Approve at:", pending.userApproveUrl);

// Wait for user to approve
const result = await waitForApproval(pending.token, {
    timeoutMs: 600_000,
});

// Check status
const status = await getAgentStatus();

Development

pnpm dev          # watch mode
pnpm test         # run all tests
pnpm test:watch   # watch mode
pnpm build        # compile to dist/
pnpm bootstrap start --name agent    # request approval
pnpm bootstrap finish                # poll + activate
pnpm setup --name agent              # all-in-one
pnpm proxy                           # start MCP proxy only

Architecture

src/
  config.ts          — Zod-validated env + runtime config, needsBootstrap() helper
  client.ts          — getApiClient (REST), getPaidFetch (x402 URLs), ApprovalClient, createTreasurer
  dotenv-path.ts     — resolveDotEnvPath (AMPERSEND_ENV_FILE, cwd walk, package .env)
  errors.ts          — Typed error classes (ConfigError, PaymentError, SpendLimitViolationError)
  bootstrap.ts       — Two-phase: start (generate key + request approval) → finish (poll + write .env)
  bootstrap-cli.ts   — CLI: start | finish
  setup.ts           — Unified CLI: bootstrap → patch MCP → start proxy
  mcp/
    index.ts         — buildMcpEntry (proxy URL)
    hermes-config.ts — patchHermesConfig, patchHermesModel, unpatchHermesModel → config.yaml
    proxy-cli.ts     — Standalone MCP proxy runner
  payment/
    index.ts         — Payment authorization and event reporting via ampersend API
    guardrails.ts    — Client-side spend limit validation (network, per-tx)
    history.ts       — Payment record queries (future: API integration)
  agents/
    index.ts         — Agent approval flow: request, check, wait, status
  index.ts           — Public API barrel exports

License

Apache 2.0

About

Hermes Agent integration for Ampersend x402 payment capabilities

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 77.7%
  • JavaScript 20.9%
  • Makefile 1.4%