Naira Offramp MCP
This server exposes wallet-balance, default-bank, and payout tools for preparing, approving, executing, tracking, and reviewing Nigerian bank payouts.
Check the Arc USDC balance for cashouts.
Get the saved default recipient bank account and masked account ending.
Verify and save a default Nigerian bank account, requiring human approval.
Prepare a payout quote in NGN or USDC without moving funds, optionally using a one-off bank account.
Execute a prepared payout at most once after human approval.
Inspect an existing payout’s status without sending funds.
List the ten most recent payouts with bank account numbers masked.
Targets USDC on Arc as the source asset for an NGN offramp, supporting quotes and simulated payouts from Arc USDC to Nigerian bank accounts.
Integrates with Circle Agent Wallet through the Circle CLI, scaffolded for future wallet signing and live USDC settlement; the current demo does not access a wallet or move real funds.
Click on "Deploy 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., "@Naira Offramp MCPQuote NGN 15,000 to my saved bank from my USDC on Arc."
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.
Agent Fiat MCP
Pay for irl services or businesses in naira from the Circle Agent Wallet your agent already uses. Fund that same wallet with naira.
Your agent can pay for APIs and other agents' services in USDC. But a freelancer, supplier or local business may need naira in a bank account.
Agent Fiat MCP connects the two. Your agent verifies the recipient, prepares the payment and asks for your approval. Circle sends USDC from your existing wallet on Arc, and PAJ converts it into a naira bank payment. The recipient receives naira in their account.
Funding works in the other direction: request bank details, transfer naira from your banking app, and PAJ delivers USDC to that same agent wallet.
Watch the demo

Related MCP server: Peer Cash MCP
What you can do
flowchart LR
Wallet[Circle Agent Wallet on Arc] --> Payout[PAJ payout order]
Payout --> Bank[Nigerian bank account]
Bank --> Funding[PAJ funding order]
Funding --> WalletAction | Money flow | Current status |
Pay someone | Agent wallet USDC on Arc → PAJ → Nigerian bank account | Tested live; the recipient confirmed bank receipt. |
Fund your wallet | Naira bank transfer → PAJ → USDC in your existing Arc agent wallet | Tested live; 1 USDC credited to the existing wallet on 25 October 2026. |
Both directions have now been tested end to end with real funds on Arc mainnet. The latest funding test converted ₦1,391.68 into 1 USDC, confirmed through PAJ, the wallet balance and the Arc transaction receipt. See the verification record and observed timing for the test scope and measurements.
Once connected to a local agent, you can ask:
“Pay this freelancer ₦5,000 from my agent wallet. Here are their bank details.”
Review the verified recipient and estimated costs, then approve before the agent sends USDC. You can pay a one-off recipient or save a default.
“Prepare bank details to add ₦5,000 to my agent wallet.”
The agent returns the bank account, exact naira amount, estimated USDC, receiving wallet and expiry. You review the details and make the transfer yourself in your banking app.
What you need
This is a local developer tool for Nigerian naira ↔ USDC on Arc mainnet. Run it on a computer or terminal environment that can reach Circle and PAJ.
Requirement | What to provide |
Node.js and npm | Node.js 22.13+ and npm. |
Your own wallet on Arc mainnet, already logged in through Circle CLI 1.2.1+, and its Arc address. | |
PAJ access | Your own production Business API key from the PAJ developer dashboard. |
AI client, for MCP use | A client that can launch local stdio MCP servers. You can also use the CLI directly without an AI client. |
To pay someone, you need USDC in the Arc wallet to cover the payment and network fees, plus the recipient's Nigerian bank name/code, ten-digit account number and full account holder name.
To fund the wallet, you need naira in your bank account. The tool returns bank instructions; you make the transfer yourself in your banking app.
Payout approval: your MCP client must support human approval forms (MCP form elicitation). Otherwise, review and approve the payout in an interactive terminal.
Credentials: configure the PAJ key privately in your local .env; do not paste it into chat or commit it. Wallet access uses the Circle CLI session. No Circle API key or Entity Secret is required. The tool needs no LLM API key; your AI client handles its own model access.
Web/mobile browser connectors are unsupported. A normal web chat alone cannot run this server or access your local wallet session.
Setup prompt
Copy this into a local coding agent with terminal access and access to the repository:
Set up Agent Fiat MCP for this local AI client:
https://github.com/Adeyemir/agent-fiat-mcp
Read the README. Reuse an existing checkout or clone and build the source.
Check the required Node.js and Circle CLI versions; report missing prerequisites.
Reuse my existing Circle CLI, login and Arc mainnet agent wallet. Do not
reinstall or upgrade Circle, log out, restart login or create a wallet.
Preserve existing .env files, MCP servers, recipients and payment history.
Help me configure my own PAJ_API_KEY privately in the local .env file.
Never ask me to paste credentials into chat or print their values.
Verify that CIRCLE_ARC_ADDRESS belongs to my authenticated Arc agent wallet.
Run the documented read-only doctor and provider checks. If this client
supports local stdio MCP, register the server using its documented settings
and absolute paths. Confirm that all 13 tools actually load. If a reload is
needed, report "configured; reload required", not "connected". If local MCP
is unsupported, report CLI readiness and any blockers.
Report payment approval support separately: supported, unsupported or
unverified. If MCP approval forms are unavailable, explain terminal approval.
Do not register bank accounts, create payout or funding orders, transfer
money, or use simulated results to claim live readiness during setup.Get started
Reuse your existing Circle installation, login and wallet. This tool uses that session; it does not manage wallet login or creation.
1. Build the project
git clone https://github.com/Adeyemir/agent-fiat-mcp.git
cd agent-fiat-mcp
npm ci
npm run build
cp -n .env.example .env
chmod 600 .envThe copy command preserves an existing .env. Use this source checkout for both payment and funding tools; the renamed package has not yet been published to npm.
2. Configure your wallet and PAJ access
Set these values privately in .env:
CIRCLE_ARC_ADDRESS=your_existing_arc_agent_wallet_address
PAJ_API_KEY=your_private_paj_business_api_key
CIRCLE_BIN=circle
ARC_NETWORK=mainnet
PAJ_ENVIRONMENT=production
OFFRAMP_MODE=liveCIRCLE_ARC_ADDRESS and PAJ_API_KEY are required for the live flows. Use an absolute CIRCLE_BIN path if your agent cannot find the authenticated executable on its PATH.
PAJ uses the Business API key directly; PAJ email/OTP login is not needed.
3. Check the connection
npm run doctor
npm run provider:checkThese read-only checks inspect configuration, wallet access, PAJ rates, banks and Arc availability. They create no orders and move no money. Gateway balance is an optional diagnostic; this route needs no Gateway deposit.
4. Connect your local agent
Use your client's documented local stdio MCP configuration. For clients using mcpServers, merge this entry with existing servers and replace the absolute paths:
{
"mcpServers": {
"agent-fiat": {
"command": "node",
"args": [
"--env-file=/absolute/path/agent-fiat-mcp/.env",
"/absolute/path/agent-fiat-mcp/dist/cli.js",
"serve"
]
}
}
}Reload the client and confirm that the tools appear. Ask the agent to check readiness and your Arc USDC balance, then check payment approval support separately. A saved configuration alone does not confirm a working connection.
The underlying server command is:
node --env-file=/absolute/path/agent-fiat-mcp/.env /absolute/path/agent-fiat-mcp/dist/cli.js serveIt communicates through stdio and waits for the MCP client. There is no browser URL to open.
The live server exposes 13 tools:
Purpose | Tools |
Wallet and readiness |
|
Bank accounts |
|
Pay someone |
|
Fund your wallet |
|
Get a receipt |
|
Use the terminal
Run these commands from the checkout with the same .env and data directory throughout. quote and fund create real, initially unfunded PAJ orders.
Pay a Nigerian bank account
Verify and save a recipient, then prepare an estimated ₦5,000 payment:
npm start -- set-bank
npm start -- quote 5000 NGNThe CLI uses the saved recipient. MCP also supports a one-off recipient without changing your default. Preparation sends no USDC.
Review the recipient, estimated naira payout, USDC transfer, network fee, reserve and expiry. To proceed with that prepared payment:
npm start -- approve YOUR_PREPARED_PAYOUT_IDRead the displayed terms and type APPROVE yourself. The terminal must be interactive; piped input and agent-supplied approval flags are refused.
Fund the existing wallet
npm start -- fund 5000Review the bank instructions, exact amount, receiving wallet and expiry, then pay from your banking app. The receiving address is checked against your authenticated Arc agent wallet. Track the returned funding ID:
npm start -- funding-status YOUR_FUNDING_ID
npm start -- funding-historyPreparation reuses an active funding order for the same amount. A different amount is blocked while an order is active. Pay only the current instructions returned by the tool; never reuse an expired account.
Get a receipt
Completed funding_status and payout_status results automatically include a text receipt and the path to a local SVG receipt card. You can retrieve either receipt again:
npm start -- receipt YOUR_LOCAL_FUNDING_OR_PAYOUT_IDFor MCP, call get_receipt with { "id": "YOUR_LOCAL_FUNDING_OR_PAYOUT_ID" }. The SVG is saved to receipts/<id>.svg inside OFFRAMP_DATA_DIR (default: ~/.local/share/naira-offramp-mcp). Open that file to view or share the card; it contains payment details, with bank account numbers limited to their last four digits.
Receipts show the final NGN and USDC amounts, PAJ status, wallet credit status, Arc confirmation, wallet address, timestamp, full transaction hash and an explorer link. Arc verification checks the expected USDC transfer against the chain. Balance changes appear only when both observations were recorded; older orders may show Not recorded. PAJ completion remains a provider report of bank settlement, not independent proof that a recipient's bank credited the account.
Amounts, settlement and interrupted requests
Amounts are estimates. PAJ applies its rate when the deposit arrives. Circle estimates gas without a hard gas cap. Approval does not lock rates or guarantee the final received amount or total wallet debit.
Approval belongs to the person. Saving a recipient and executing a payout require MCP forms or an interactive terminal. A tool argument cannot grant approval.
Delivery needs confirmation. Receipts separate PAJ's settlement report from independently checked Arc transfers. Missing evidence stays unverified; bank credit is not independently checked. See the live payment and funding evidence.
Keep uncertain requests for investigation. Check the existing ID with
payout_statusorfunding_status. Do not send again, create a replacement or delete the database to retry. Errors do not establish refunds.
See usage and recovery and PAJ setup and settlement for the detailed behavior.
Configuration and existing installations
Optional settings for the data directory, payout budget and gas reserve are in the configuration reference.
The rename preserves OFFRAMP_* settings and the default ~/.local/share/naira-offramp-mcp data directory. Keep your existing recipients, history and private profile files. Configuration comes from the process environment and the .env passed to Node; older provider.env files are not loaded automatically.
The existing npm release, naira-offramp-mcp@0.3.0, contains the earlier payout-only implementation. It does not include the funding or receipt tools in this checkout.
Development
npm run check
npm run build
npm testTests use fake wallet/provider responses and temporary databases; they move no funds. npm run demo runs the payout simulator in an isolated temporary profile. Normal startup uses live mode.
Available Tools
7 toolsexecute_payoutADestructiveIdempotent
Request human approval for the exact prepared quote, then execute it at most once. Never claims bank credit from a chain receipt alone. Repeated calls inspect the existing payout; uncertain submissions require reconciliation and must not be resent.
| Name | Required | Description | Default |
|---|---|---|---|
| payoutId | Yes | The ID returned by prepare_payout; never create a replacement to retry a payment. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructive=true, idempotent=true, openWorld=true, but the description adds substantial non-structured context: human approval gating, at-most-once execution, the rule that a chain receipt alone never proves bank credit, and the reconciliation requirement for uncertain submissions. It is consistent with idempotentHint rather than contradicting it.
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?
Three dense sentences, front-loaded with the core action and approval requirement, followed by safety constraints. Every sentence earns its place, though the wording is terse to the point of being clipped.
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 destructive, open-world mutation tool with no output schema and a single fully-documented parameter, the description covers approval, at-most-once execution, retry/reconciliation, and credit-claiming semantics. It does not describe failure/error behavior or what an agent should report back after execution, leaving a small gap.
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 description coverage is 100% and the payoutId description already carries the key guidance ('never create a replacement to retry'). The description adds no parameter-level syntax or constraints beyond what the schema states, so the baseline 3 applies.
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?
States a specific verb+resource (execute a prepared payout) with the crucial qualifier 'at most once' and the approval step. An agent can immediately distinguish it from prepare_payout (which produces the quote) and from payout_status (which only inspects).
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?
Explicitly defines the retry/repeat semantics ('Repeated calls inspect the existing payout'), the reconciliation requirement for uncertain submissions, and the prohibition on resending. It does not explicitly name payout_status or payout_history as alternatives for pure inspection, but the context is clear enough to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_balanceARead-onlyIdempotent
Inspect the USDC balance for Arc cashouts. Demo values are simulated; this does not move funds.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly, idempotent, non-destructive and closed-world, so the bar is lower, and the description still adds meaningful context the annotations cannot express: the values are simulated demo data and no funds move. That is exactly the kind of caveat an agent needs before reporting a balance as real.
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?
Two short sentences with no filler; the resource and the demo-value caveat are both front-loaded. Every clause earns its place.
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 zero-parameter read tool whose annotations already declare the safety profile and with no output schema required, the description is nearly complete. Only the return shape (a balance figure) is left implicit, which is a minor gap.
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 takes zero parameters, so per the rubric the baseline is 4. There is nothing for the description to clarify about inputs, and it does not need to.
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?
Names a specific verb and resource (inspect the USDC balance) and scopes it to Arc cashouts, which separates it from the payout/bank siblings. It stops short of explicitly contrasting with any named sibling, but the intent is unambiguous.
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 phrase 'for Arc cashouts' hints at context, but the description never says when to call this versus alternatives like payout_status or payout_history, nor that it should precede prepare_payout/execute_payout. No exclusions or prerequisites are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_default_bankARead-onlyIdempotent
Get the saved recipient's bank, name, and masked account ending. No bank is chosen automatically.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile is covered. The description usefully adds that no bank is auto-selected and that the account ending is masked, which is genuine behavioral context beyond the annotations.
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?
Two compact sentences, front-loaded with the action and return payload, neither of which is padding. Every sentence earns its place.
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?
With no parameters and no output schema, the description carries the burden of conveying the return shape, which it does (bank, name, masked ending). It stops short of stating what happens when no saved bank exists, a minor gap for such a simple read 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?
The tool takes zero parameters, so the baseline is 4; there are no arguments whose meaning could be clarified. Nothing in the description misrepresents the parameterless contract.
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 uses a specific verb (Get) and resource (saved recipient's bank) and names the returned fields (bank, name, masked account ending), which lets an agent distinguish it from set_default_bank. It never explicitly names siblings, but the get-vs-set contrast is clear from the naming.
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?
There is no explicit when-to-use or when-not-to-use statement relative to prepare_payout, execute_payout, or set_default_bank. The clue that 'no bank is chosen automatically' implies behavior rather than routing guidance, so the agent is left to infer usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
payout_historyARead-onlyIdempotent
List the ten most recent payouts in this local mode/profile. Bank account numbers are masked.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and non-open-world, so safety is covered. The description adds useful behavior beyond that: results are capped at ten entries, scoped to the local mode/profile, and bank account numbers are masked — the masking note is genuinely valuable context not derivable from annotations.
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?
Two short sentences, front-loaded with the core action and scope. No filler; every clause (cap of ten, local profile, masking) earns its place.
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 no-parameter, read-only list tool with full annotation coverage and no output schema, the description is nearly sufficient. It could mention ordering or an empty-history case, but nothing essential for correct invocation is missing.
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 takes zero parameters (schema coverage 100%), so the baseline is 4. Nothing about the description conflicts with the empty schema, and no parameter meaning needs to be added.
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?
States a specific verb (List) and resource (payouts) with a clear scope: the ten most recent in the local profile. It doesn't explicitly contrast itself with payout_status, though the 'history/list' framing versus a single-status lookup is reasonably inferable.
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?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as payout_status or get_balance. The agent must infer the use case entirely from the tool name and 'ten most recent' scope.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
payout_statusARead-onlyIdempotent
Inspect an existing payout. Reports completed only after the payout provider confirms completion. A demo completion is simulated and always has bankPaid=false. Never sends funds.
| Name | Required | Description | Default |
|---|---|---|---|
| payoutId | Yes | The ID returned by prepare_payout; never create a replacement to retry a payment. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive, open-world behavior, so the bar is lower. The description still adds genuine value beyond them: completion is only reported after the provider confirms, demo completions are simulated with bankPaid=false, and no funds are ever sent. It stops short of describing latency, polling expectations, or error states.
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?
Three short sentences, front-loaded with the core action and scoping constraint, followed by return-value caveats. No filler and nothing buried.
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?
There is no output schema, so the description reasonably covers the most load-bearing return semantics (completion only on provider confirmation, demo bankPaid=false). It leaves the overall response shape unspecified, but for a one-parameter read tool with full safety annotations, the agent has what it needs.
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 description coverage is 100% and the single payoutId parameter is fully documented in the schema (including the "never create a replacement to retry" warning). The description adds nothing about the parameter, so the baseline 3 applies.
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?
States a specific verb and resource ("Inspect an existing payout") and immediately separates itself from the write siblings with "Never sends funds," so an agent can distinguish it from execute_payout and prepare_payout without opening any schema.
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 the tool is for checking status of an already-created payout (vs. creating/executing one), but it never explicitly names when to use this instead of payout_history or execute_payout. Usage is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepare_payoutA
Prepare a quote; no funds move. NGN means exact naira to receive; USDC means maximum total spend including all fees. Defaults to the saved bank. Supply a bank only when the user explicitly requests another destination. Repeated calls create separate quotes.
| Name | Required | Description | Default |
|---|---|---|---|
| bank | No | ||
| amount | Yes | Positive decimal text, e.g. 15000 or 10. Never use floating point numbers. | |
| currency | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real context beyond the annotations: it clarifies that despite readOnlyHint=false nothing moves funds, and 'repeated calls create separate quotes' explains the non-idempotent behavior in practical terms. Currency semantics (NGN = exact receive, USDC = max total spend incl. fees) is behavior an agent cannot get from structured fields.
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?
Four short sentences, each carrying distinct information, with the safety-critical 'no funds move' claim front-loaded. 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 the essential behaviors for a quote tool (no fund movement, currency meaning, bank defaults, non-idempotency). It stops short of describing the quote's lifecycle or expiry, which matters given there is no output schema.
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?
With only 33% schema coverage, the description carries needed weight: it defines currency semantics precisely and explains when to omit bank (defaults to saved). Amount format is left to the schema, which already covers it well.
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?
States a specific action ('Prepare a quote') and immediately scopes it ('no funds move'), which cleanly separates it from execute_payout among the siblings. An agent can tell this is a quote-creation step, not a transfer.
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?
Gives concrete routing rules: default to the saved bank, supply a bank only when the user explicitly asks for another destination, and warns that repeated calls make separate quotes. It never explicitly names execute_payout as the follow-up step, which is the one missing link.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_default_bankADestructive
Verify and save a default Nigerian bank account once. Requires human approval through the MCP client. Demo accepts only Demo Bank / 0000000000 / DEMO USER.
| Name | Required | Description | Default |
|---|---|---|---|
| bank | Yes | Nigerian bank name. In demo mode: Demo Bank. | |
| expectedName | Yes | Expected full account holder name. In demo mode: DEMO USER. | |
| accountNumber | Yes | Ten-digit bank account. In demo mode: 0000000000. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, openWorldHint=true, idempotentHint=false and destructiveHint=true. The description adds genuinely new behavior: human approval is required, the account is verified before saving, and it happens only once. It does not explain why destructiveHint is true or what happens to a previously saved default account, which is the remaining gap.
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?
Two tight sentences with zero filler; the core action is front-loaded and the approval prerequisite and demo constraints follow in priority order.
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 three-required-parameter mutation with no output schema and full schema coverage, the description covers the essential non-schema facts: verification, human approval, one-time nature, and demo constraints. It is nearly complete, lacking only what happens to a pre-existing default.
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 description coverage is 100%, so the schema already defines each field, including min/max lengths and the 10-digit pattern. The description only repeats demo values, adding no format or validation meaning beyond what the schema documents. Baseline 3 applies.
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 states a concrete verb+resource: verify and save a default Nigerian bank account. It implies a one-time operation ('once'), which distinguishes it implicitly from the sibling get_default_bank. It does not explicitly name or contrast with that sibling, keeping it just short of a 5.
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?
It gives a prerequisite ('requires human approval through the MCP client') and demo-mode values, which is useful context, but it never states when to use this tool versus get_default_bank or when not to (e.g., if a default already exists). The set-vs-get distinction must be inferred from the name.
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.
7 tool updates
v0.1.0- First observed
execute_payout - First observed
get_balance - First observed
get_default_bank - First observed
payout_history - First observed
payout_status - First observed
prepare_payout - First observed
set_default_bank
TDQS
Scored across 7 tools
Each tool targets a distinct action in the payout lifecycle: reading balance, managing the saved bank, listing history, inspecting a single payout, and the prepare/execute two-phase flow. prepare_payout vs execute_payout and payout_history vs payout_status are clearly delineated by descriptions that emphasize quote-vs-move and list-vs-inspect.
All names use consistent snake_case, and the verb_noun pattern (get_balance, set_default_bank, prepare_payout, execute_payout) is clear. The two noun-only names (payout_history, payout_status) are a minor deviation but remain readable and unambiguous.
Seven tools is well-scoped for an offramp flow: balance, bank config, quote, execution, status, and history. Every tool maps to a needed step, with no redundant or filler operations.
The surface covers the full payout lifecycle from bank setup through quoting, execution, status, and history, including a safety-oriented reconciliation path. Minor gaps exist around cancellation/refund or explicit fee-preview, but core workflows are covered.
Maintenance
Related MCP Connectors
Human-governed Arc agent services, live demand signals, quotes, feedback, and USDC commerce.
Spend USDC in the real world: prepaid cards, gift cards, push-to-card, and bank payouts.
Nigeria payments for AI agents — bank transfer / USSD via Paystack. Never holds funds.
Non-custodial stablecoin bill-pay rails on Celo & Base for AI agents, settled on-chain via MCP.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceEnables agents to vet merchants, create and verify USDC charges and invoices, assess trust and tokenized-asset authenticity, and manage provable books on Base, all non-custodially.30 npm-

Peer Cash MCPofficial
AlicenseAqualityFmaintenancePrepare custody-separated Base USDC cash-out plans, list supported fiat rails, and track settlement state through Peer Cash.922 npmMIT- AlicenseNot gradedqualityBmaintenanceEnables agents to accept and spend payments via Rill's network, including pay links, wallets, and Connect onboarding.MIT
- AlicenseAqualityCmaintenanceNon-custodial stablecoin bill payments (airtime, data, electricity, cable, education) on Celo mainnet, reachable via x402 (zero setup, EIP-3009), a linked wallet's PIN-gated MCP/A2A tool catalog, or plain natural language on Telegram/WhatsApp/X.101MIT