Give your agent
a tab.
The Opentab MCP server lets any AI agent pay x402 APIs, open a fully backed USDC tab when its wallet is short, settle it on time and read its score, with no human in the loop once the backing is in place. Every tool answers in JSON, and every error comes with the next step to take.
One entry in your MCP client
The server runs on your machine with Node 20 or later, straight from this site. Give it a dedicated agent keypair (a Solana JSON keypair file) holding a little SOL for fees and rent, and the USDC it pays APIs with.
{
"mcpServers": {
"opentab": {
"command": "npx",
"args": ["-y", "https://opentabworld.live/mcp-0.1.1.tgz"],
"env": {
"OPENTAB_KEYPAIR": "/Users/you/.config/solana/agent.json"
}
}
}
}claude mcp add opentab --env OPENTAB_KEYPAIR=$HOME/.config/solana/agent.json -- npx -y https://opentabworld.live/mcp-0.1.1.tgz
OPENTAB_KEYPAIRPath to the agent’s Solana keypair JSON file. Required for anything that signs.OPENTAB_RPCSolana RPC URL. Default the public mainnet RPC.OPENTAB_MAX_PRICEMost pay_x402 pays for one call, in USDC. Default 0.50.OPENTAB_DAILY_CAPMost pay_x402 pays in one UTC day, in USDC. Default 10.OPENTAB_HOST_CAPSPer-API caps, like api.weather.dev:0.05,gpu.render.run:0.50. They override OPENTAB_MAX_PRICE for those hosts.OPENTAB_PAY_HOSTSIf set, the only hosts pay_x402 may pay (comma-separated).OPENTAB_TAB_HOSTSIf set, the only hosts a payment may open a tab for.OPENTAB_ASK_HOSTSHosts that need you: pay_x402 answers needs_approval instead of paying.OPENTAB_TAB_TERM_DAYSTerm of a tab that pay_x402 opens on its own. Default 8.OPENTAB_BACKERBacker wallet to draw on first when the agent has several backings.
17 tools: 7 to read, 10 to act
Amounts are USDC decimal strings like "25.5". Every tool that sends a transaction also takes dry_run: true to check it and preview the exact amounts without sending, except pay_x402 and settle_tabs.
get_protocol_inforeadStart here. How Opentab works, the live parameters (fee, tab and term limits, grace, utilization cap, pause), the addresses, your wallet’s SOL and USDC, your agent and a step-by-step guide.
get_poolreadLender assets, USDC out on tabs, cash available right now, utilization, share price, reserve and the pause flag.
get_agentreadAn agent’s full record: score, level, tabs opened and repaid, late repayments, the open tab with the exact amount due, and every backing behind it.
get_scorereadThe free credit check: score, level, what the next level still needs and a verdict. The same answer as /api/check.
get_credit_limitreadThe biggest tab the agent can open right now for a term, which backing it would draw on, what blocks it, and what to do to raise it. A tab locks its principal plus its fee, so a longer term borrows a little less.
list_tabsreadTabs newest first with fee, amount due, dates and status. Filter by wallet, status or overdue_only to find tabs anyone may mark as defaulted.
get_lender_positionreadYour pool shares, what they are worth in USDC, your share of the pool and how much you can withdraw right now.
register_agentactGive the agent’s wallet an on-chain identity with score 0. One per wallet; costs about 0.002 SOL of rent.
back_agentactLock USDC behind an agent, yours or someone else’s. Backing sets the credit limit and earns 25% of the fee on every tab it covers; if the agent defaults, the locked part is lost.
unback_agentactTake free backing back. Any withdrawal also stops new tabs on that backing; an amount of 0 only stops them, and a top-up reopens it.
open_tabactBorrow USDC against free backing. The fee is fixed now and owed in full even if you repay early. Pass the fee from a dry run as max_fee so a rate change can’t cost you more. One open tab per agent.
repay_tabactRepay the open tab in full from the wallet’s USDC. Anyone may repay for an agent.
settle_tabsactRepay the open tab once it’s time: after 7 days held (so it counts for the score) or from 6 hours before it’s due, whichever is first. force: true repays now. Answers none, repaid, waiting or insufficient_funds.
pay_x402actCall an https API that charges per request and pay the price it asks, in USDC on Solana. If the wallet is short, open the smallest tab that covers it first. Capped per call and per UTC day; what the API answers comes back under untrusted.body.
lendactDeposit USDC into the shared pool for shares. Lenders earn half of every fee. Withdrawals open 24 hours after your latest deposit: a top-up restarts the wait.
withdraw_lendactBurn pool shares for USDC at the current share price, up to the cash that isn’t out on tabs.
mark_defaultactKeeper action: default a tab once it’s past its due date plus 3 days. The locked backing pays the pool back in full and the agent’s score goes to 0 for good.
From nothing to a repaid tab
get_protocol_info {}
register_agent {} // the agent's wallet becomes its identity
back_agent { "amount": "50" } // the owner backs from the agent wallet, a sponsor from theirs
get_credit_limit { "term_days": 8 }
open_tab { "principal": "5", "term_days": 8, "dry_run": true }
open_tab { "principal": "5", "term_days": 8, "max_fee": "0.013334" }
pay_x402 { "url": "https://api.example.com/report" }
settle_tabs {} // after 7 days held, or 6 h before due
get_score {}In practice the agent only calls pay_x402: when the wallet is short it opens the smallest tab that covers the call, and it settles open tabs on its own when they are due. A tab backed by the agent’s own wallet repays normally but doesn’t move the score: the score counts tabs someone else backed.
What an agent can’t do
- Borrow past its backing. A tab locks its principal plus its fee from the backing, so the agent can never owe more than someone locked for it.
- Pay past its caps. Each call is capped (0.50 USDC by default, or per API with
OPENTAB_HOST_CAPS) and each UTC day too (10 USDC). - Pay an API you didn’t allow. With
OPENTAB_PAY_HOSTSset, other hosts are refused; hosts inOPENTAB_ASK_HOSTSreturnneeds_approvalinstead of paying, and only hosts inOPENTAB_TAB_HOSTS(when set) may open a tab. - Follow a stranger’s instructions. What an API answers comes back under
untrusted.body: data, never instructions. Redirects aren’t followed.
Earned on chain, worked out in the open
// on each repayment of a tab backed by someone other than the agent, by its due date + 3 days held = min(now - start, due - start) // capped at the term dollar_seconds += principal × held qualified += 1 if held ≥ 7 days time_pts = min(600, ⌊dollar_seconds / 864_000_000_000⌋) // 1 point per 10 USDC-days count_pts = min(400, 40 × qualified) // 40 per tab held 7+ days score = min(1000, time_pts + count_pts) // a default sets it to 0 for good
Levels are worked out the same way by this site, the check API and the MCP server: Unproven (nothing repaid), Started (one tab repaid), Proven (3 sponsored tabs held 7+ days, 14 days between the first and the latest, never repaid more than 24 h late), Established (Proven, score 500+, 30 days since the first sponsored repayment), and Defaulted. Honest limit: a sponsor is any other wallet, so a second wallet of the same person still counts. It makes a fake record cost money and time; it doesn’t make it impossible.
A free trust check, no key
Before you back, lend to or hire an agent, look it up. One GET returns its score, level, what the next level still needs, and the facts behind them. Any site may call it; answers are cached for 30 seconds.
curl "https://opentabworld.live/api/check?agent=<AGENT_WALLET>"
{
"agent": "<AGENT_WALLET>",
"verdict": "repaid", // "no record" | "no repayments yet" | "repaid" | "defaulted"
"score": 188,
"level": "Started",
"next": [{ "key": "qualified", "have": 1, "need": 3, "met": false }, …],
"tabs_repaid": 2,
"sponsored_repaid": 1,
"late_repayments": 0,
"open_tab": null,
"defaulted": false,
"profile_url": "https://opentabworld.live/agents/<AGENT_WALLET>"
}Every refusal says what to do next
Tools return { code, message, hint }: the program’s error name, a plain sentence and the next step.
- 6000
PausedNew deposits, backing and tabs are switched off for now. Withdrawals, repayments and defaults still work. - 6001
UnauthorizedOnly the right wallet can do this. - 6002
InvalidParamsA value is out of range. Check the inputs. - 6003
ZeroAmountEnter an amount above zero. - 6004
ZeroSharesThat deposit is worth less than one pool share. Deposit a little more. - 6005
InsufficientSharesYou are withdrawing more shares than you hold. - 6006
InsufficientLiquidityMost of the pool is out on tabs. Withdraw less, or wait for repayments. - 6007
PoolInsolventDeposits are halted: the pool has shares but no assets. - 6008
AgentDefaultedThis agent defaulted. Its score is 0 for good and it can’t open tabs or take backing. - 6009
ActiveLoanExistsThe agent already has an open tab. Repay it first. - 6010
LoanOutOfBoundsA tab is 5 to 50 USDC. - 6011
TermOutOfBoundsA term is 1 to 30 days. - 6012
InsufficientBackingFree backing is below the tab plus its fee. Add backing, borrow less or pick a shorter term. - 6013
LoanNotActiveThis tab was already repaid or defaulted. - 6014
LoanNotOverdueA tab can only be defaulted 3 days after its due date. - 6015
InvalidAccountAn account didn’t match what the program expected. Refresh and try again. - 6016
ReserveExceededMore than the reserve holds. - 6017
MathOverflowThe amounts are too large. - 6018
FeeTooHighThe fee is above the quote you approved, so nothing was sent. Review the new quote. - 6019
PoolCapReachedThis deposit would take the pool past its cap. - 6020
UtilizationCapReachedAt most 80% of the pool can be out on tabs at once. - 6021
DepositLockedWithdrawals open 24 hours after your latest deposit. - 6022
BackingClosingThe backer stopped new tabs on this backing. A top-up reopens it. - 6023
WrongMintThat token account isn’t USDC. - 6024
AlreadyInitializedThe program is already set up.
The rules live on chain
One Solana program holds the pool, the backing and every tab. Tab accounts are never closed, so the full history stays readable.
Fee: ceil(principal × 100 × term / (10,000 × 30 days)), so a 5 USDC tab for 7 days costs 0.011667 USDC. Split on repayment: 50% lenders, 25% the backer, 25% reserve. The program is upgradeable until it has been audited; the upgrade key is the admin key, and moving it to a multisig is the next step.
Treat the agent’s key like a hot wallet
- Use a dedicated keypair with only the USDC and SOL the agent needs. Never reuse a wallet that holds anything else.
- The keypair file is read once at startup and is never logged or returned by any tool. Keep it readable only by you.
- Backing is the limit. Lock only what you are comfortable losing if the agent defaults.