Skip to main content
Glama

Transfer Fee Estimate (Beta)

transfer_cost
Read-only

BETA. Estimate what a cross-border payment will COST, split by WHO PAYS: the sending bank's published fee (the sender's side), what correspondents deduct in transit and what the beneficiary's own bank charges to credit it (the beneficiary's side), and what actually lands.

This estimator is in BETA. Present every number as a typical case and a high case, never as a quote, and never let a user commit to a contractual amount on it. The payload carries beta=true while this holds.

HOW TO READ THE ANSWER (relay these honestly):

  • answered=false means we REFUSED. The most common reason is that we hold no published tariff rule for the sending bank, in which case there is deliberately no total and no "recipient receives" figure. Say we do not know what that bank charges. Do NOT add up the parts yourself and present a total: treating the unknown fee as zero is the exact defect this tool was built to remove.

  • The correspondent fee is a RANGE (p50 typical, p90 high case), not a point. The spread is real: SWIFT tracking never reveals whether a payment was sent OUR, SHA or BEN, so a single cohort mixes all three.

  • THREE FEES, THREE DIFFERENT PAYERS, AND THEY ARE NOT INTERCHANGEABLE. sending_fee is billed to the SENDER by their own bank. correspondent_fee comes out of the payment in transit, so the BENEFICIARY bears it. beneficiary_fee is what the RECEIVING bank charges its own customer to credit the payment, so the beneficiary bears that too - and it is frequently the largest of the three (measured 2026-08-22 on one live corridor: 35.26 USD of sender-side cost against a 245.68 USD beneficiary bank fee). Never quote one of them as "the cost", and never call the beneficiary bank's fee a correspondent charge. total is the sending fee plus the transit deduction; total_both_sides adds the beneficiary bank's fee and is the all-in figure.

  • WHERE EACH NUMBER COMES FROM. The correspondent fee is OBSERVED, from payments we have tracked. beneficiary_fee.source is tariff (or tariff_fallback, see below) and never observed: a beneficiary bank deducts after the last bank that reports to GPI, so no tracking data can see it, and we read it off that bank's published incoming tariff instead. Say which is which when the user leans on a figure.

  • beneficiary_fee.known=false means WE HOLD NO INCOMING TARIFF for that bank (we hold one for roughly two thirds of beneficiary banks). Its charge is then missing from every figure, total_both_sides is null, and recipient_receives.typical is an UPPER BOUND - recipient_receives.beneficiary_fee_known says so. Do not fill that gap with a zero, a guess or a typical figure; say the receiving bank's own charge is not included and point the user at that bank's tariff.

  • beneficiary_fee.applies=false under OUR / OUR-OUR: the instruction says the sender covers every downstream charge, so the bank claims it back rather than taking it off the credit. The figure is reported but NOT subtracted. Our data ends before the account is credited, so we can neither confirm nor refute that it was honoured on a given payment.

  • beneficiary_fee.segment says which of the bank's incoming price lists was read. segment_fallback=true means the account type asked for had no usable schedule so the other one answered - which can only happen when beneficiary_segment was NOT supplied, i.e. when we were assuming the beneficiary matches the sender. Say that you assumed it.

  • beneficiary_fee.reason='other_segment_only' means you DID supply beneficiary_segment, and that bank publishes an incoming tariff for the other account type only (beneficiary_fee.other_segment names it). We decline to quote it. Do NOT report this as "we hold no tariff for that bank": we hold one, for a different kind of account. Tell the user which, because it is often the useful half of the answer.

  • basis.n is how many observed payments back the correspondent figure and confidence reflects it. At "low", present the range as rough.

  • basis.level says how specific the evidence is: corridor is this correspondent into this destination country, correspondent is that bank overall, and currency or global mean we hold nothing specific and are quoting a pool. Say so when it is a pool.

  • ON A REFUSAL basis IS NULL, and the same two figures are still on each entry of correspondent_fee.legs[] as level and n. Read them there. Do not read a missing basis as corridor-specific evidence: on a measured DE->AM screen the legs said level: "currency", n: 146, a currency-wide pool, and the answer described it as a single well-priced hop because the top-level key was absent.

  • assumptions is a list of plain sentences explaining what shaped the number (SEPA, OUR honoured, PSD2, a modelled BEN uplift, a stale tariff). Relay the ones that matter to the user's question.

  • under OUR the correspondent leg carries our_breach: the measured share of OUR payments that lose a charge in transit anyway, and what that costs. p50 is 0 and p90 is that loss. Quote BOTH - "the beneficiary should receive the full amount, and in about 7% of the OUR payments we can follow end to end they do not" - never the p50 alone as a promise.

  • chain.status = no_chain means the pair settles on local rails (SEPA, domestic, same banking group) with NO correspondent deduction at all.

IMPORTANT ON CHARGE TYPE: charge_type is an INPUT and is never inferred from tracking. OUR is a real instruction and usually holds - of 150 payments whose own MT103 declared OUR and which we could follow from the instructed amount to the settled one, 139 reached the beneficiary intact, against 6 of 52 under SHA. It is NOT a guarantee: the other 11 lost a flat correspondent charge in transit, and we find no evidence that this depends on the destination country or on a US correspondent being in the chain, so do not tell a user that OUR is safe everywhere except the US. BEN is materially more expensive than SHA and our high case models it rather than measuring it. If the user has not said which they will use, ask, or state which one you assumed.

Pass beneficiary_bic whenever the user knows the receiving bank: without it there is no correspondent chain to price and no beneficiary bank to read a tariff from, so the answer is the sending fee alone and no total.

customer_segment selects which side of the SENDING bank's published price list is read. It is not cosmetic: of 30 banks publishing both schedules, 9 of the 17 that answered on both quote a different fee, one of them 220 PLN for a company against free for a person. It defaults to individual here; pass business when the payer is a company, and say which you assumed.

beneficiary_segment does the same for the RECEIVING side, which is a different bank's price list and not a restatement of the sender's. Of 120 banks publishing both schedules, 28 quote a different incoming fee (measured 2026-08-24), and it runs both ways: Hipotekarna banka (HBBAMEPG) credits a 100,000 EUR payment free of charge to a company and takes 0.1% of it from a person, while Nordea charges a person 60 SEK and a company 250. Omit it and we assume the beneficiary matches the sender, which is what this tool did before 2026-08-24 - so if you omit it, say you assumed it. Supply it when the user has told you who is being paid, and prefer asking over guessing when the amount makes the difference material.

Available to any caller with an active subscription.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
amountYesTransfer amount in `currency`, greater than zero.
api_keyNoYour Ohmyfin API key (prod-...). Optional here: it can be sent instead as a KEY header or an Authorization: Bearer header. What the tool requires of the key is in its description.
channelNoSending channel: online | branch | mobile_app | any.
currencyYes3-letter ISO 4217 transfer currency.
bank_swiftYesSending bank's BIC, 8 or 11 characters.
charge_typeNoSHA (default), OUR or BEN. Ask the user rather than guessing.SHA
beneficiary_bicNoReceiving bank's BIC (8 or 11 characters); needed for a total.
customer_segmentNoWho is SENDING: individual | business | financial_institution.
beneficiary_segmentNoWho is being PAID: individual | business | financial_institution. Omitted, it mirrors customer_segment.
customer_sub_segmentNoThe sender's tier at their bank: standard | premium | private_banking | vip.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed10 schema fields changed
    • addedInput schema / properties / amount / description
      Added value: +"Transfer amount in `currency`, greater than zero."
    • addedInput schema / properties / api_key / description
      Added value: +"Your Ohmyfin API key (prod-...). Optional here: it can be sent instead as a KEY header or an Authorization: Bearer header. What the tool requires of the key is in its description."
    • addedInput schema / properties / bank_swift / description
      Added value: +"Sending bank's BIC, 8 or 11 characters."
    • addedInput schema / properties / beneficiary_bic / description
      Added value: +"Receiving bank's BIC (8 or 11 characters); needed for a total."
    • addedInput schema / properties / beneficiary_segment / description
      Added value: +"Who is being PAID: individual | business | financial_institution. Omitted, it mirrors customer_segment."
    • addedInput schema / properties / channel / description
      Added value: +"Sending channel: online | branch | mobile_app | any."
    • addedInput schema / properties / charge_type / description
      Added value: +"SHA (default), OUR or BEN. Ask the user rather than guessing."
    • addedInput schema / properties / currency / description
      Added value: +"3-letter ISO 4217 transfer currency."
    • addedInput schema / properties / customer_segment / description
      Added value: +"Who is SENDING: individual | business | financial_institution."
    • addedInput schema / properties / customer_sub_segment / description
      Added value: +"The sender's tier at their bank: standard | premium | private_banking | vip."
  2. Changed1 schema field changed
    • addedInput schema / properties / beneficiary_segment
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null
      +}
  3. Added

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint/openWorldHint, so the description carries the real burden and does so unusually well: beta status, refusal semantics (answered=false and why there is deliberately no total), range vs point estimates, provenance of each figure (observed vs tariff), upper-bound semantics when a tariff is unknown, and the OUR/SHA/BEN non-guarantee. This is behavior an agent cannot get from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is very long for a tool description, but it is well front-loaded (purpose, then beta caveat, then a structured 'HOW TO READ THE ANSWER' list) and almost every bullet corresponds to a distinct failure mode an agent would otherwise get wrong. Some length is repetition rather than new information, which keeps it out of the top band.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter, high-stakes financial estimator with an output schema, the description covers the input decisions (which segments, which charge type), the refusal paths, and the interpretation of the returned fields. Nothing an agent needs in order to call it correctly or relay it honestly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, but the description adds genuine meaning beyond it: customer_segment is explained as selecting which side of the sending bank's price list is read (with a concrete 220 PLN vs free example), beneficiary_segment as the receiving bank's separate schedule, and beneficiary_bic as the prerequisite for any total at all. This is materially more than the terse schema strings.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states a precise verb ('Estimate') and resource ('what a cross-border payment will COST'), and immediately decomposes it into the three payer-attributed components. This is clearly distinguishable from siblings like fx_rate, payment_method_compare and track_payment, which do not estimate landed cost by payer.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Strong conditional guidance is given for the optional inputs: 'Pass beneficiary_bic whenever the user knows the receiving bank', 'pass business when the payer is a company', 'prefer asking over guessing when the amount makes the difference material', and 'if the user has not said which they will use, ask'. It does not name an alternative sibling tool or state when to reach for a different tool instead, so it stops short of the top band.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources