tabula-mcp
Official# tabula-mcp
Credit for AI agents on Robinhood Chain and Base, as an MCP server. Your agent pays x402 (HTTP 402) sellers from a
credit line: Tabula pays the seller at once, the charges go on the agent's tab, and the tab becomes a loan the agent
repays in the chain's dollar (USDG on Robinhood Chain, USDC on Base) with one signature and no ETH.
## What you need
- An agent with an [ERC-8004](https://eips.ethereum.org/EIPS/eip-8004) identity on Robinhood Chain or Base, owned by a key
you hold (an ordinary account, not a contract wallet). If you signed in to Tabula's web app with a passkey, your account is a
Safe: make your agent a sub-key there (below) and repay from the app.
- A credit line. On Robinhood Chain `tabula-mcp join` opens a $1 line while seats are free, for an agent with a repayment
record on the chain's other agent lender (at least three loans repaid and none defaulted). On Base the first $1 lines go
to agents on a list: write to team@tabula.credit. On either chain a line backed by collateral opens from
[Tabula's web app](https://app.tabula.credit).
- The chain's dollar in the owner's wallet when a loan is to be repaid.
- Node 20.19 or later.
## Set it up
Add the server to your MCP client's configuration:
```json
{
"mcpServers": {
"tabula": {
"command": "npx",
"args": ["-y", "tabula-mcp"],
"env": {
"TABULA_GATEWAY_URL": "https://api.tabula.credit",
"TABULA_AGENT_ID": "<your agent's ERC-8004 id>",
"TABULA_AGENT_KEY": "<the key that owns the identity>"
}
}
}
}
```
The gateway names the chain: `https://api.tabula.credit` for Robinhood Chain, `https://api-base.tabula.credit` for Base.
Open the line once, from a terminal with the same variables:
```sh
npx tabula-mcp join
npx tabula-mcp status
```
Then ask the agent to fetch a paid resource from one of the sellers that `list_sellers` shows.
## Agent frameworks
Any framework that runs MCP servers runs this one: the command `npx` with the arguments `-y tabula-mcp`, and the
variables above in its environment. Give a framework a sub-agent's key (`TABULA_SUBKEY`, below) rather than the key
that owns the identity.
**ElizaOS** (`@elizaos/plugin-mcp`), in the character file:
```json
{
"plugins": ["@elizaos/plugin-mcp"],
"settings": {
"mcp": {
"servers": {
"tabula": {
"type": "stdio",
"command": "npx",
"args": ["-y", "tabula-mcp"],
"env": { "TABULA_GATEWAY_URL": "https://api.tabula.credit", "TABULA_SUBKEY": "<the sub-agent's key>" }
}
}
}
}
}
```
**Hermes Agent**, in `~/.hermes/config.yaml` (Hermes hands a server only the variables under `env`):
```yaml
mcp_servers:
tabula:
command: "npx"
args: ["-y", "tabula-mcp"]
env:
TABULA_GATEWAY_URL: "https://api.tabula.credit"
TABULA_SUBKEY: "<the sub-agent's key>"
```
**OpenClaw**: the server goes under `mcp.servers` in `~/.openclaw/openclaw.json` (or `openclaw mcp set`) with the same
command, arguments and variables, and the skill in `skills/tabula-credit` tells the model how to use the tools.
**AgentKit and other LangChain agents**: load the server through LangChain's MCP adapters and give its tools to the
agent beside AgentKit's own.
## Tools
| Tool | What it does |
|---|---|
| `credit_status` | The line: its limit, what is available, the open tab, and each loan with what it owes now and when it is due. |
| `pay_with_credit(url, max_price)` | Pays for an x402 resource from the line, at most `max_price` dollars, and returns the seller's response. Only sellers on Tabula's list can be paid. Send the same `idempotency_key` to retry a call: one key is never paid twice. |
| `list_sellers` | The sellers on the list, with their prices. |
| `repay(loan_id)` | Repays one loan in full from the owner's wallet. |
| `repay_all` | Repays every open loan with one signature. It signs for what the loans will owe an hour from now, and what is not needed comes back at once. |
| `raise_limit` | Waits for $TABULA's launch. Spends the chain's dollar on $TABULA through the bond zap and bonds it behind the agent's line, for a higher limit: `usdg_amount`, and `min_tabula`, the least it must buy after the buy tax. A first bond opens a bond line (the gateway approves it); an agent on a base line keeps it. |
| `autopay_on` / `autopay_off` | While the server runs, repays each loan from 24 hours before it is due, when the wallet holds enough of the chain's dollar. `TABULA_AUTOPAY=on` starts with it on. |
`repay`, `repay_all`, `raise_limit` and autopay need the owner's key. A sub-agent's server (below) has the first three tools only.
## Sub-agents
One line can serve several agents. The owner makes a key for each sub-agent, with its own budget:
```sh
npx tabula-mcp subkey create research 2 0.10 # at most $2 a day (UTC), at most $0.10 a call
npx tabula-mcp subkey list # what each key spent today
npx tabula-mcp subkey revoke 3
```
The key is shown once. The sub-agent runs `tabula-mcp` with `TABULA_GATEWAY_URL` and `TABULA_SUBKEY` and no private
key: it can pay and read the tab, within its budgets, and nothing else. Its charges go on the same tab, and the line's
limit still bounds them all.
## What it costs
- **The fee:** 0.75% of the principal per 30 days, charged for the time used, by the hour, and at least one day. A
loan runs 7 days.
- **The payment fee:** 0.1% of each loan's principal, whatever the term.
- **No gas:** the repayment is an authorization that Tabula's relayer submits.
- **The first loan repaid on time** gets its fee back, up to $0.10.
These are the numbers at launch. `GET /v1/bank` on the gateway shows the current ones, and a loan's fee is fixed when
it opens. A loan not repaid by its due date is late; 3 days later it defaults, the line freezes, and the default
stays on the agent's public credit record.
## What the server signs
The owner's key never leaves the server's environment. With it, the server signs two things only:
- the login to the gateway, which is good for 5 minutes;
- authorizations in the chain's dollar to repay the agent's own loans.
Before it signs a repayment, it checks on the chain itself that:
- the money goes to Tabula's ledger or its batch repayer;
- the token is the dollar of Tabula's ledger, on the right chain;
- every loan belongs to this agent;
- the amount is no more than those loans can owe.
So a gateway that misbehaves still cannot point a signature anywhere else.
The server knows Tabula's contracts on Robinhood Chain (chain 4663) and Base (8453). For any other deployment
`TABULA_LEDGER` and `TABULA_BATCH_REPAYER` name them, and without a trusted ledger the server repays nothing.
A seller's response comes back to the model marked as data from the seller. For an agent that reads content you do
not control, give it a sub-key: a sub-key cannot repay, cannot make keys, and has a daily budget.
## Environment
| Variable | |
|---|---|
| `TABULA_GATEWAY_URL` | Tabula's gateway: `https://api.tabula.credit` for Robinhood Chain, `https://api-base.tabula.credit` for Base. https, or http to this machine only. |
| `TABULA_AGENT_ID`, `TABULA_AGENT_KEY` | The agent's ERC-8004 id and the key that owns it: the identity's owner. |
| `TABULA_SUBKEY` | Instead of the two above: a sub-agent's key. |
| `TABULA_AUTOPAY` | `on` to start with autopay on. |
| `TABULA_RPC_URL` | The chain's RPC, which the owner's server reads to check what it signs. The public RPC by default. |
| `TABULA_LEDGER`, `TABULA_BATCH_REPAYER`, `TABULA_BOND_ZAP` | The contracts to repay to and to bond through, for a deployment the server does not already know. |
## License
MIT
TDQS
Scored across 3 tools
Each tool has a clearly distinct role: checking credit status, paying via credit, and listing available sellers. There is no meaningful overlap between them, so an agent can select the right tool without confusion.
The names use three different structures: noun_noun (credit_status), verb_preposition_noun (pay_with_credit), and verb_noun (list_sellers). They remain readable, but the mixed conventions prevent a predictable pattern.
Three tools is a reasonable minimal surface for a focused credit-payment server. It is slightly thin, but each tool earns its place and the scope is coherent.
The surface supports checking credit, listing sellers, and making a credit payment, but there is no tool to repay or settle the tab despite descriptions saying the charge is repaid later. This creates a significant lifecycle gap and a likely dead end for agents.