Odel
Aura

Aura

@phillypmackPythonMITUpdated 1w ago

Email address, webhook, durable memory and zero-token waiting for agents. Paid in USDC via x402.

Server endpointStreamable HTTPNo authProbed

This is the third-party server itself — Odel doesn't run it. Hitting this URL directly talks straight to the upstream server with no auth or proxying. Connect through Odel to front it with managed auth.

Aura

The persistence layer for ephemeral agents. A real email address, a webhook URL, durable memory, and the ability to wait for an event without burning tokens — sold to autonomous agents that pay in USDC over x402, with no account and no human in the loop.

Service: https://aura.rohnelt.dev · MCP: https://aura.rohnelt.dev/mcp · Docs for models: llms-full.txt

This repository holds the client side: SDKs, framework adapters, and the Claude Skill.


The problem

An autonomous agent is ephemeral. That creates three hard blockers, and none of them is a matter of intelligence:

BlockerWhat normally happens
It has no address.It cannot sign up for anything, because it cannot receive the verification code.
It cannot wait.It polls in a loop, burning tokens on every turn, or it dies and loses the work.
It dies at the end of a run.Everything it learned is gone.

Aura removes all three. An agent proves it controls a wallet with one signature and gets a handle, a real mailbox, a webhook base URL, durable memory, and two ways to wait.

Install

npm install aura-agent     # JavaScript / TypeScript
pip install aura-x402    # Python

Or point any MCP client at the endpoint:

{
  "mcpServers": {
    "aura": {
      "type": "http",
      "url": "https://aura.rohnelt.dev/mcp",
      "headers": { "Authorization": "Bearer aura_sk_..." }
    }
  }
}

Without the header the tools still list, and capabilities and identity_create still work — an agent can evaluate the service before committing to anything.

The thirty-second version

from aura_agent import Aura, LocalSigner

client = Aura.claim(LocalSigner(private_key))   # free, one signature, no signup
address = client.whoami()["email"]              # a real mailbox

sign_up_somewhere(email=address)                # whatever the task actually is
code = client.await_email_code()                # blocks; costs no tokens; refunds on timeout
import { Aura, toSigner } from "aura-agent";
import { privateKeyToAccount } from "viem/accounts";

const { client, identity } = await Aura.claim(toSigner(privateKeyToAccount(key)));
const code = await client.awaitEmailCode({ from: "notifications@example.com" });

What is in here

PathWhat
js/aura-agent on npm — zero-dependency TypeScript client
python/aura-x402 on PyPI (imported as aura_agent) — sync and async clients, plus LangChain and CrewAI adapters
skill/aura/A Claude Skill: drop it in and Claude knows when to reach for Aura
server.jsonThe manifest published to the official MCP Registry

Framework adapters

from aura_agent.langchain import get_tools     # pip install "aura-x402[langchain]"
from aura_agent.crewai import get_tools        # pip install "aura-x402[crewai]"

tools = get_tools(client)

Fourteen tools, each described for a model deciding whether to spend money: what it does, when not to use it, and what it costs.

Pricing

Operations cost fractions of a cent, so they are debited off-chain from a prepaid balance: one on-chain settlement covers hundreds of calls. Claiming an identity is free and grants a small trial credit.

CallPrice
capabilities, whoami, identity.create, forgetfree
recall, list_memory$0.0005
remember$0.0008
inbox, read_mail, create_hook$0.001
search_memory, signal, resume$0.002
await$0.004
park$0.005

Two of these refund themselves: a timed-out await costs nothing, and resume is free when no parked work is ready. So calling resume at the start of every run is safe.

Deposits are paid in USDC on Base: POST /v1/credit/deposit/{1,5,20} answers HTTP 402 with full x402 payment requirements.

Errors carry the fix

An agent has no human to ask, so every error returns what was missing and the corrected call. A 402 carries the exact deposit call; a memory 404 carries the keys that do exist; a 400 carries the schema plus a working example. Both SDKs preserve that rather than flattening it into a string.

try:
    client.remember("k", "v")
except AuraError as err:
    if err.needs_credit:
        print(err.fix)     # the exact deposit call to make

Discovery

Aura is built to be found and evaluated by a machine, without a signup:

GET / returns JSON unless Accept explicitly asks for HTML.

License

MIT