imprest
imprest is a policy-guarded payment server for AI agents that enables controlled Ethereum/stablecoin spending with audit trails, spend limits, and human approval workflows.
Payment & Spending
request_payment— Send ETH or tokens (e.g., USDC) to a recipient; policy engine enforces per-transaction caps, budgets, allow/deny lists, and rate limits; may require human approval.request_approval— Grant exact ERC-20 token allowances to spender contracts, tracked as liabilities against a global cap; approving 0 revokes the allowance.pay_x402— Purchase HTTP resources via x402 protocol, with one-time EIP-3009 authorization after policy checks.
Operator Controls
list_pending_approvals— View all payments/approvals awaiting human decision (admin-only).resolve_approval— Approve or reject pending requests; hard limits re-checked at execution time.
Observability
get_balance— Check ETH or token balance of any address.get_gas_price— Current gas price in gwei.get_audit_log— Full history of payment attempts and policy verdicts.
Enables AI agents to make controlled payments on the Ethereum blockchain (ETH and ERC-20 stablecoins like USDC) with policy-based spend limits, approval queues, and audit trails.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@imprestpay 10 USDC to 0xabc for data API"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
imprest
Programmable spend limits and audit trails so AI agents can pay for things without risking the wallet.
AI agents are probabilistic — they can be prompt-injected, loop, or simply
choose the wrong tool. The moment an agent can move money, one bad decision is
irreversible. imprest is the guardrail layer between an agent and an
Ethereum wallet: every payment the agent requests is checked against a policy
it cannot override, and every attempt is logged.
Think corporate-card controls (Ramp/Brex) or Stripe Radar — but for agents. The model in one line: give your agent an allowance, not your keys.
Why "imprest"? The imprest system is the centuries-old accounting control behind petty cash: a fixed fund is entrusted to a spender, every draw is documented, and the fund is replenished only after the records are audited. That is precisely what this server implements — for AI agents.
Quick start
pip install imprest
imprest init # the one setup ceremony:
# ✓ policy.yaml — your agent's limits (edit them)
# ✓ a dedicated wallet, generated locally from OS entropy
# → prints the address to fund
imprest status # balances, gas headroom, active limits, sends switchThen point any MCP client (Claude Desktop, Cursor, a LangChain agent — see
examples/) at the server, and the agent gets request_payment and a verdict —
nothing else:
{"imprest": {"transport": "stdio", "command": "imprest"}}Defaults are safe by construction: Base Sepolia testnet, sends OFF until you
explicitly set ENABLE_SENDS=true. On testnets you may even skip init — a
throwaway wallet auto-creates on first use. On mainnet chains imprest
refuses to create a key silently: real-money wallets only come into existence
when a human runs init.
Related MCP server: valta-mcp
The wallet model: a prepaid card
The agent never gets your wallet. init generates a fresh, dedicated wallet
for the agent; you fund it with only what the agent may spend, and top it up
like a prepaid card. That makes the maximum possible loss the card balance —
a physics-level cap that holds even if every software check failed. The policy
engine is the soft limit; the balance is the hard one. Your real wallet
(hardware, exchange, MetaMask) never touches imprest at all.
How it works
agent: "pay 10 USDC to 0xabc… for the data API"
│
│ MCP tool call: request_payment(…, asset="USDC")
▼
┌────────────────────── imprest ──────────────────────┐
│ policy engine: per-tx cap · hourly/daily budgets │
│ allow/denylist · rate limit · approval threshold │
└────────┬───────────────────┬────────────────────┬────────┘
│ │ │
ALLOW NEEDS_APPROVAL DENY
▼ ▼ ▼
preflight, sign, queue for operator: block + log;
broadcast, wait approve → re-check agent gets the
for confirmation limits → execute exact reason
│
▼
tx mined + auditedPayments move stablecoins (USDC) or ETH. Stablecoins are the spending lanes; in the default policy ETH is a gas-only lane with near-zero limits — any real ETH transfer attempt looks anomalous and gets denied or escalated.
The allowance ledger — the part nothing else has. Agents can also
request_approval (a guarded ERC-20 approve()): always an exact amount,
never unlimited — the vector behind most token drains. Granted allowances
outlive every budget window, so imprest tracks them as standing
liabilities: the total live across all spenders is capped
(max_outstanding_allowance), and approve(spender, 0) revokes to free the
cap. Rolling budgets alone can't see this risk; the ledger closes it.
A needs_approval verdict is not a dead end: it queues for a human operator,
who approves or rejects (resolve_approval) — and hard limits are re-checked
at approval time, so a human "yes" can't bust a budget.
x402 — pay-per-request APIs. Agents can also buy paid HTTP resources with
pay_x402(url, max_amount): imprest does the x402
handshake (402 Payment Required → price quote), runs the quoted price through
the same policy pipeline — caps, budgets, allowlist, approval queue — and
only on ALLOW signs an EIP-3009 authorization for exactly the quoted amount
(gasless; the recipient's facilitator settles on-chain). The server's quote is
held to the agent's stated max_amount, the token contract must match the
registry, and if a frozen payment is approved later the terms are re-fetched —
a payee/asset change or a price hike refuses instead of paying.
The MCP server is the product; agents are just clients of it.
Design principles
Non-custodial, blast-radius first. Dedicated per-agent wallet, funded with pocket money. Keys are generated locally, never leave the machine, and never get created as a side effect on mainnet.
The RPC endpoint is untrusted. Gas price is capped by a configurable ceiling (
MAX_FEE_GWEI) and gas limits are fixed, never estimated — a lying RPC can neither overprice nor inflate a transaction. Worst-case gas cost is bounded atgas_limit × ceiling, always.Broadcast is not success. Every send waits for the receipt; reverts and timeouts fail the audit row. "Executed" means mined with status 1.
The policy engine is pure logic (
src/imprest/services/policy.py) — no I/O — so it is exhaustively unit-tested. The code guarding money is the code under the most tests (171 across the engine, auth, audit, ERC-20, approvals, the allowance ledger, x402, the chain rails, and the CLI).Config, not code. Limits live in
policy.yaml. Each asset has its own limits and its own budget — 10 USDC never eats into an ETH ceiling — and a token is payable only if the policy names it.
Deploying it
The wallet owner runs the server; agents connect as clients and set nothing.
Local (stdio) — each MCP client spawns its own server process; identity is
AGENT_ID, the OS is the auth boundary:
{"imprest": {"transport": "stdio", "command": "imprest"}}Hosted (HTTP) — one server for the whole org; developers get a URL and an API key. The server refuses to start without keys (an open endpoint would mean anyone who can reach it can spend the budget):
TRANSPORT=streamable-http \
IMPREST_API_KEYS='sk-supp-…:support-bot,sk-proc-…:procurement' imprest
# or
docker build -t imprest . && docker run -p 8000:8000 \
-e IMPREST_API_KEYS='…' -v $(pwd)/policy.yaml:/app/policy.yaml imprest{"imprest": {"transport": "streamable_http",
"url": "http://payments.internal:8000/mcp",
"headers": {"Authorization": "Bearer sk-supp-…"}}}The API key is the agent's identity: it selects that agent's policy section in
policy.yaml and attributes its audit trail. The same request can be denied
for support-bot and allowed for procurement — identity decides.
Unauthenticated requests get a 401 before any tool runs.
For the approval flow in hosted mode, also set
IMPREST_ADMIN_KEYS='sk-admin-…:ops' — a human with an admin key can
list_pending_approvals / resolve_approval; agents (regular keys) cannot, so
no agent signs off its own payment. Over stdio the local operator is the admin.
Hosted-mode operational notes. Bearer keys travel in headers — terminate TLS at your ingress; never expose the plain HTTP port publicly. Keep API and admin keys disjoint (the server refuses to start otherwise). The server is single-process today: budget checks are atomic within one process, but multiple workers/replicas against one
audit.dbare not yet safe. Run one replica per wallet.
Going to mainnet
Base mainnet (chain 8453) is the recommended target — Circle-native USDC and sub-cent gas. The sequence:
CHAIN_ID=8453 RPC_URL=https://mainnet.base.org imprest initinitprints the funding address. Send it a small USDC float and a few dollars of ETH for gas — withdraw on the Base network, not Ethereum.Edit
policy.yamldown to numbers you'd let an autonomous process spend. Set theallowlistto known recipients. If your agent will legitimately discover new payees (vendors, APIs), setunknown_recipient: ask— an off-allowlist payment then freezes in the approval queue for you to rule on (one payment, one ruling; the address is not remembered) instead of being denied outright. Every other limit still applies first, so an over-cap request to a stranger dies on the cap, never reaching the queue.Check the card:
imprest status.Flip
ENABLE_SENDS=truelast.
Treat the wallet as a hot-wallet float (see limitations below): it should never hold more than you'd load onto a gift card.
Layout
main.py # repo-root shim (python main.py)
src/imprest/
├── main.py # console entrypoint (`imprest`)
├── cli.py # operator CLI: init (the ceremony) + status
├── application.py # app factory: create_application()
├── api/payments.py # MCP tools (transport)
├── services/
│ ├── policy.py # ⭐ the policy engine — pure, tested
│ ├── audit.py # append-only SQLite audit log
│ ├── auth.py # Bearer API-key auth + per-request identity
│ ├── chain.py # web3 wrapper — gas rails, nonce lock, receipts
│ ├── tokens.py # known-token registry (symbol → address/decimals)
│ ├── x402.py # x402 pay-per-request: 402 parsing, EIP-3009 signing
│ └── wallet.py # dedicated wallet: explicit create, mainnet guard
├── schemas/schemas.py # contracts (Decimal money, dataclasses)
└── configs/base.py # pydantic settings
tests/ # 171 tests
examples/demo_agent.py # a LangChain agent that uses the server
examples/agent-shop/ # complete solo-dev setup: agent + operator
# approve/reject CLI (the mainnet-test rig)Developing
git clone https://github.com/theoddalex/imprest && cd imprest
python -m venv .venv && source .venv/bin/activate
pip install -e ".[demo,dev]"
cp .env.example .env
pytest # 171 tests — the policy engine and the rails
python examples/demo_agent.py # watch an agent get allowed / blocked / gatedStatus
Tested live on Base mainnet — an LLM agent running the full verdict ladder
with real USDC: payment allowed and mined, payment frozen for human approval
then executed, over-limit payment denied, an exact-amount allowance granted and
revoked (ledger and on-chain state verified in agreement), and a
non-allowlisted recipient blocked. Every attempt in the audit log with the rule
that fired; total gas for the ceremony ≈ $0.01. The setup used is
examples/agent-shop/.
Working v1, mainnet-hardened chain layer: pure policy engine, per-agent +
per-asset policies, guarded token approve() with the allowance ledger
(total live allowances capped, revoke supported), human approval flow
(admin-gated, re-checked at approval time), Bearer-key auth, append-only audit
log, gas-fee ceiling + fixed gas limits (untrusted RPC), pending-nonce with a
per-wallet lock, receipt-confirmed sends, balance preflight, init/status
operator CLI, USDC on Base + Ethereum (mainnet and testnets), x402
pay-per-request purchases (policy-guarded EIP-3009 signing), stdio + hosted
HTTP transports, and a LangChain demo agent. 171 tests.
Security checks
Every push runs the app-sec pipeline (.github/workflows/ci.yml), mirrored
locally by make security:
bandit — SAST over
src/(the code handling keys, auth, and SQL)Trivy — dependency CVEs (SCA), committed-secret scan (a
wallet.keyor API key in a commit fails the build), Dockerfile misconfig, and the built image (base OS + installed packages)
All findings gate at HIGH/CRITICAL. imprest deploys no custom smart contracts, so the risk surface is the application itself — these checks cover it; an external review is still the gate before serious funds.
Known limitations (read before mainnet)
These are deliberate boundaries of the current design.
The key file is unencrypted (
wallet.key, permissions 0600). This is the prepaid-card trade-off: the wallet is designed to hold a small float, not savings. Anyone with file access to the machine can take the float. An encrypted keystore is on the roadmap; the mitigation today is the funding model itself.The allowance ledger is conservative and off-chain. It assumes the full last-approved amount to each spender is still live (the real liability can only be lower than the cap), and it reconstructs state from imprest's own audit log: allowances granted outside imprest are invisible to it. Start from a wallet with no pre-existing approvals, or revoke them first.
Rate limiting counts only allowed spends. Denied and
needs_approvalattempts don't count towardrate_limit_per_minute, and the pending-approval queue is unbounded — a looping agent can flood the audit log.Single wallet, single process. All agents sign from one keystore. The per-wallet nonce lock serialises concurrent sends within one process, but multiple workers/replicas against one
audit.dbare not safe. Run one replica per wallet.stdio makes the caller its own approver. The "an agent can't approve its own payment" guarantee holds over HTTP (separate admin keys); over stdio the local operator is both. Hard limits are still re-checked at approval time.
Address validation is hex-shape only (no EIP-55 checksum) — a mistyped but well-formed address will send. Use the allowlist for known recipients.
Roadmap
On-chain allowance reconciliation. Cross-check the ledger against live
allowance()reads so spent-down grants free the cap, and out-of-band approvals are detected instead of invisible.Encrypted keystore. Password-protected key at rest (eth_account native), unlocked via env at startup.
Postgres audit backend. Replaces the SQLite file — unlocks multi-replica deployment and cross-process budget atomicity, lifting the single-process limitation. One swap, both wins.
Abuse limits. Count all attempts toward the rate limit; bound, paginate, and expire the pending-approval queue; retain/rotate the audit log.
Non-custodial hosted control plane. Split verdict from signing so a hosted imprest never holds customer keys: policy + audit + dashboard in the cloud, a client-side signer executing only server-issued, single-use vouchers — and, longer term, ERC-4337 session keys / spend permissions so the chain itself enforces the limits.
Deploying agents that spend money?
If your team is putting AI agents in front of real budgets and wants policy-guarded spending — budgets, approvals, audit — I'd like to hear about your use case.
Questions & ideas: GitHub Discussions
Bugs: Issues · security reports via SECURITY.md
Available Tools
7 toolsget_balanceA
Get the balance of an address (read-only).
Args: address: the 0x address to check asset: "ETH" (native, default) or a token symbol such as "USDC"
| Name | Required | Description | Default |
|---|---|---|---|
| asset | No | ETH | |
| address | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. States read-only and explains asset parameter, but lacks details on return format, rate limits, or side effects. Minimal behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise with two clear sentences. Every sentence adds value. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers input parameters well but lacks output description. For a simple read tool with no output schema, missing return format hinders completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaning beyond schema: explains address is a '0x address' and asset is 'ETH' or 'USDC' with default. Compensates for 0% schema description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the action (get balance), the resource (address), and the read-only nature. Distinguishes from sibling tools which involve payments or approvals.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Mentions read-only, implying safe usage. Does not explicitly state when to use vs alternatives, but the context of sibling tools makes it clear this is for querying balances.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_gas_priceA
Get the current gas price in gwei (read-only).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly marks the tool as 'read-only', which is a key behavioral trait. Without annotations, this disclosure is important and sufficient for a simple read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no unnecessary words. Every word contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters, no output schema, and no annotations, the description is adequate but could mention that the gas price is for the current chain. However, it is functionally complete for a simple read.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the baseline score is 4. The description adds the unit 'gwei', providing useful semantic context beyond the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool gets the current gas price in gwei, with a specific verb ('Get') and resource ('current gas price'). It distinguishes from sibling tools like request_payment and pay_x402 which are for payments and approvals.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when the current gas price is needed, but does not explicitly state when to use this tool versus alternatives. No exclusions or alternatives are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_pending_approvalsA
(operator only) List payments/approvals waiting for a human decision.
Requires an admin identity — an agent cannot see or clear its own pending approvals. Over stdio the local operator is the admin.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses important behavioral traits: operator-only, admin requirement, and that agents cannot see their own approvals. It does not mention side effects, but being a read-only list, this is acceptable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, two sentences, no wasted words. The purpose is front-loaded and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and no output schema, the description covers the essential context: what the tool lists, who can use it, and identity requirements. It is adequate for an agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description does not need to add meaning. It still clarifies no parameters are required, which is sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists payments/approvals waiting for human decisions, using a specific verb ('List') and resource ('pending approvals'). It distinguishes from siblings like request_payment and resolve_approval by focusing on the listing function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states operator-only usage and admin identity requirement, providing clear context for when to use. However, it does not directly contrast with alternatives like resolve_approval, though the context suggests it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pay_x402A
Fetch a paid HTTP resource, paying for it over the x402 protocol ("402 Payment Required"). Use this for pay-per-request APIs that quote a price in the 402 response; the spend policy decides whether the quoted price is allowed, blocked, or requires human approval.
The payment is a signed one-time authorization for EXACTLY the quoted amount — never more — and it only happens if the quote passes policy.
Args: url: the resource to fetch (https) max_amount: the most you expect this to cost, in whole token units (e.g. 0.01 for 1 cent of USDC). If the server demands more, the request is refused before policy even runs. reason: what the purchase is for (recorded in the audit log)
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| reason | No | ||
| max_amount | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description details that the payment is a signed one-time authorization for the exact quoted amount, only executed if policy approves. It also explains the max_amount parameter sets a cap. With no annotations, this provides good behavioral insight, though it omits what happens on failure or balance deduction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear introductory paragraph and an Args list. Every sentence provides necessary information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema, annotations, or complex nested objects, the description adequately covers the protocol, policy interaction, and parameters. Minor gap: no mention of return value or error handling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All three parameters (url, max_amount, reason) are explained with their purpose, format, and behavior. This adds significant meaning beyond the bare schema, which lacks descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches a paid HTTP resource via the x402 protocol. It specifies the use case for pay-per-request APIs, differentiating it from sibling tools that handle payments or approvals differently.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use this tool (pay-per-request APIs with 402 responses) and mentions the spend policy. However, it does not explicitly exclude other scenarios or compare with siblings like request_payment.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
request_approvalA
Grant a token spender an allowance so a contract (a marketplace, subscription, or swap) can later pull funds. The policy decides whether it is allowed, blocked, or needs human approval.
imprest approves an EXACT amount only — never an unlimited allowance, the vector behind most token drains. The allowance is capped by, and counts against, the same per-asset limits as a direct payment, and the TOTAL of live allowances across all spenders is itself capped (an allowance outlives budget windows, so it is tracked as a standing liability). Approving 0 revokes the spender's allowance and frees cap.
Args:
spender: the 0x address being granted the allowance
amount: the allowance, in whole units of asset (e.g. 25 for
25 USDC); 0 revokes this spender's existing allowance
asset: the token symbol (e.g. "USDC"); native ETH cannot be approved
reason: what the approval is for (recorded in the audit log)
| Name | Required | Description | Default |
|---|---|---|---|
| asset | Yes | ||
| amount | Yes | ||
| reason | No | ||
| spender | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavioral traits: exact amount only, cap limits, standing liability tracking, revocation via 0, and that native ETH cannot be approved. It provides thorough details on how the allowance is managed and its lifecycle.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a concise overview followed by bullet-pointed args. It is front-loaded with the main action. The 'imprest' paragraph adds valuable context but is slightly verbose; overall efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers inputs and behavior comprehensively but does not mention the return value or outcome (e.g., success status, transaction hash). Given moderate complexity and no output schema, this omission reduces completeness for an agent using the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description fully explains all 4 parameters: spender (address), amount (whole units, 0 revokes), asset (token symbol, no ETH), and reason (audit log). This compensates entirely for the missing schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: 'Grant a token spender an allowance' with a specific verb and resource. It distinguishes from sibling tools by focusing on approvals rather than direct payments, and provides concrete examples of use cases like marketplaces or subscriptions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use this tool (to grant an allowance) and when to revoke (amount=0). It mentions the policy decision and exact amount limitation, but does not explicitly compare to alternatives like request_payment. Context is clear but lacks explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
request_paymentA
Request to pay an address. The spend policy decides whether it is allowed, blocked, or requires human approval. Use this whenever you need to send a payment; do not attempt to move funds any other way.
Args:
recipient: destination 0x address
amount: amount to send, in whole units of asset (e.g. 0.05, 50)
reason: what the payment is for (recorded in the audit log)
asset: what to send — "ETH" (native, the default) or a token symbol
such as "USDC". Each asset has its own policy limits.
| Name | Required | Description | Default |
|---|---|---|---|
| asset | No | ETH | |
| amount | Yes | ||
| reason | No | ||
| recipient | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the transparency burden. It explains that a spend policy determines if the payment is allowed, blocked, or requires human approval, and mentions asset-specific policy limits. However, it does not disclose the exact behavior when blocked (e.g., error type) or the approval flow details. This is adequate but not thorough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is neatly structured: a purpose sentence, a usage directive, then a bullet-like list of arguments. No extraneous words; every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 4 parameters and no output schema. The description covers all parameters and mentions the spend policy and asset limits. It lacks information about the return value (e.g., a payment request ID) and does not clarify how this tool interacts with 'request_approval' (e.g., does it trigger an approval?). Still, it is largely complete for a payment request tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, and the description fully compensates by explaining each parameter: recipient (0x address), amount (in whole units of asset), reason (audit log entry), and asset (ETH default or token symbol with policy limits). This adds critical meaning beyond the schema's bare titles and defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description specifies 'Request to pay an address' and explicitly states 'Use this whenever you need to send a payment; do not attempt to move funds any other way.' This clearly identifies the tool's action and resource, and distinguishes it from any alternative means of moving funds.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear directive: 'Use this whenever you need to send a payment; do not attempt to move funds any other way.' It could be improved by explicitly mentioning when not to use it (e.g., if manual approval is needed elsewhere) or how it relates to sibling tools like 'pay_x402', but it still provides strong guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_approvalA
(operator only) Approve or reject a pending payment and, on approval,
execute it. This is the resume path for needs_approval.
A human approval overrides only the approval threshold — the hard limits (per-transaction cap, budgets, deny/allow list) are RE-CHECKED against the current ledger at approval time, so an approval that would now bust a budget is refused rather than forced through.
Args: payment_id: the audit id of the pending row (from list_pending_approvals) approve: True to approve and execute, False to reject note: optional operator note recorded on the row
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | ||
| approve | No | ||
| payment_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses critical behaviors: approval overrides only the threshold, hard limits are re-checked, and refusal occurs if limits would be busted. It also mentions operator-only access. This provides strong transparency beyond mere safety hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured. It front-loads the purpose, then adds a behavioral note, then lists arguments. Every sentence provides necessary information with no redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 3 parameters, no output schema, and no annotations, the description covers purpose, usage, parameter details, and behavioral implications. It lacks explicit return value or error information, but the overall completeness is high for the stated complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must add meaning. The Args section explains each parameter: payment_id (audit id from list_pending_approvals), approve (True to approve/execute, False to reject), note (optional). This adds valuable context beyond schema names and types, effectively compensating for low coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action: 'Approve or reject a pending payment and, on approval, execute it.' It identifies the resource (pending payment) and distinguishes itself from siblings by noting it is the resume path for 'needs_approval'. The sibling tool list includes request_payment and request_approval, reinforcing differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description specifies that the tool is '(operator only)' and explains it handles pending payments needing approval. It details the behavior on approval (hard limits re-checked). While it does not explicitly state when not to use it or provide direct alternatives, the context is sufficiently clear for an agent to decide.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
7 tool updates
v0.1.0- First observed
get_balance - First observed
get_gas_price - First observed
list_pending_approvals - First observed
pay_x402 - First observed
request_approval - First observed
request_payment - First observed
resolve_approval
TDQS
Each tool has a distinct purpose: sending payments, granting approvals, paying for resources via x402, listing pending approvals, resolving them, and reading balances/gas prices. No overlaps.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., request_payment, get_balance), with clear verb prefixes like 'request', 'list', 'resolve', 'get'.
Seven tools cover the core operations of a payment/approval system without being excessive. Each tool adds necessary functionality.
The tool set covers the main workflows: sending payments, managing token approvals, paying via x402, admin approval flow, and read queries. Minor gaps exist (e.g., no tool to list existing allowances or transaction history), but the core is well-covered.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Give your AI agent a spending limit: approval controls and single-use virtual cards.
AI agent spending controls. Set limits, blocklists, and caps. Approve transactions from your phone.
MCP server for building and testing AI agents with multi-model experimentation and insights.
- gatewayOAuthai.sealgate
MCP gateway with runtime security policy, tool-call-level control, and audit of agent actions.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceMCP server that gives terminal AI agents a guarded USDC wallet with firewall, automatic 402 payment handling, and budget limits.13MIT
- AlicenseAqualityBmaintenanceAn MCP server for Valta that exposes financial governance tools for AI agents, including spend authorization and audit trail via MCP-compatible clients.16721MIT
- FlicenseNot gradedqualityBmaintenanceAn MCP server that enables AI agents to safely interact with a double-entry payments ledger, enforcing idempotency, policy-based access control, and human-in-the-loop approval for high-value actions.-
- AlicenseNot gradedqualityCmaintenanceMCP server that enables AI agents to request human approval before spending money, check approval status, verify signed tokens, and manage API keys.13MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Theoddalex/imprest'
If you have feedback or need assistance with the MCP directory API, please join our Discord server