Skip to main content
Glama
SwitchWize MCP

SwitchWize MCP

Official

SwitchWize MCP client

Read-only MCP tools for U.S. rates, savings comparisons, financial indexes, card offers and changes, rewards, CD rollover rules, and downgrade paths.

Connect now

For clients supporting Streamable HTTP, use the hosted endpoint:

https://www.switchwize.com/api/mcp

No SwitchWize account or API key is required. The API is rate-limited. Documentation: SwitchWize Developers.

Related MCP server: @cyanheads/eia-energy-mcp-server

Gemini CLI extension

Install from the public repository:

gemini extensions install https://github.com/switchwize/switchwize-mcp

Restart Gemini CLI, then use /mcp list to confirm that switchwize is connected and exposes all 16 tools. The extension uses Gemini CLI's native Streamable HTTP transport; no separate local MCP process, SwitchWize account, or API key is needed. Gemini CLI itself requires its own supported authentication and runtime setup.

Try: "Use SwitchWize to compare current U.S. high-yield savings observations. Include source URLs and as-of dates, and flag stale or unavailable data."

The extension covers U.S. deposit and card research, excluding mortgages. Review GEMINI.md for source, freshness, and privacy guidance. Installing this extension enables your Gemini CLI to use the tools; it does not enable them for other Gemini users or designate SwitchWize as a Google Search data source.

Google's extension gallery discovers public repositories with a root gemini-extension.json and the gemini-cli-extension GitHub topic. Gallery discovery and installation are separate from consumer usage.

Run the stdio client from source

Use a supported Node.js LTS release and npm:

git clone https://github.com/switchwize/switchwize-mcp.git
cd switchwize-mcp
npm ci --ignore-scripts
npm run build
npm start

For a desktop MCP client, configure command node with the absolute path to dist/index.js as its argument. No environment file or database credentials are needed. SWITCHWIZE_MCP_URL is an optional full MCP endpoint override for developers.

Run from npm

npx -y switchwize-mcp@0.3.0

For a desktop MCP client, configure command npx with arguments ["-y", "switchwize-mcp@0.3.0"]. No API key is required.

The source bridge and package manifest now use 0.3.0, matching the published npm bridge. Building this repository does not republish the existing npm version.

Available tools

  • get_top_rates

  • get_top_hysa_rates

  • get_bank_gap

  • compare_switch_savings

  • get_rate_freshness

  • get_index_dataset

  • get_bank_gap_index

  • get_reality_score

  • get_card_offers

  • get_transfer_bonuses

  • get_card_changes

  • get_reward_valuations

  • best_move_this_week

  • get_cd_rollover_rules

  • get_card_downgrade_path

  • get_fed_hike_pass_through

The hosted server currently discovers 16 tools, three prompts, and four resources. The source-built stdio bridge forwards the hosted tool schemas and annotations, prompts, resources, structured results and tool error status.

The client connects to /api/mcp using Streamable HTTP and exposes that catalog over stdio. It does not initiate financial transactions or request bank credentials. Balance inputs supplied to tools are transmitted to the hosted API; do not include account numbers or other sensitive identifiers.

Validate a source checkout

npm run verify:package checks the build and package contents without publishing. npm run verify:live compares the source bridge's tools, prompts and resources with the public hosted service and performs a hypothetical Bank Gap call. It requires network access and contributes internal acceptance traffic; it does not establish independent user adoption or verify every upstream data source.

npm run verify:gemini -- <report.json> verifies all 16 tools using Gemini CLI 0.66.0's own MCP discovery, input-schema validation, and invocation code. Set GEMINI_CLI_PACKAGE_DIR to an installed @google/gemini-cli@0.66.0 package directory. Optionally set SWITCHWIZE_GEMINI_MANIFEST to the manifest from an installed extension to validate that exact configuration. Keep validation in a separate GEMINI_CLI_HOME so it does not alter your normal Gemini settings.

This check makes live read-only calls with hypothetical inputs, labels its requests as internal probes, records freshness states without treating stale or unavailable data as current, and checks the other three deposit categories. It does not make an LLM request or establish consumer adoption. See the dated Gemini release validation.

Data boundaries

Observations may be aggregator-sourced and may be aging. Preserve each response's source dates and freshness labels. Monthly index data is not a current offer. Confirm product terms directly with the provider before making a decision.

Savings-gap figures are hypothetical estimates. The comparison benchmark is the average of the top three tracked savings rates, not an average across every tracked bank. Card Reality Scores model a consumer segment's assumptions and may carry stale terms; they are not personalized advice or guaranteed benefits.

Attribute data as SwitchWize (switchwize.com). The MIT license covers this client software, not upstream datasets, third-party materials, or trademarks. See data and service terms.

Package verification

npm run verify:package builds the client and checks the npm tarball against an exact allowlist: LICENSE, README.md, dist/index.js, and package.json. npm pack creates a local tarball; neither command publishes it.

License: MIT. Copyright SW Digital Holdings LLC.

Available Tools

16 tools
best_move_this_weekBest Move This WeekA
Read-onlyIdempotent
Inspect

Given the credit cards a user holds, rank this week's dollar-valued actions: which held card to use per spend category, welcome offers at a 12-month high on cards not held, active transfer bonuses, and (optionally) the savings-rate move beside the card move.

NameRequiredDescriptionDefault
walletYesCard ids the user holds, in the form issuer:slug, e.g. ["chase:sapphire-preferred", "amex:gold-card"].
categoriesNoOptional spend categories to rank held cards for; defaults to all nine.
usedBenefitsNoOptional log of period credits already used this month; excluded from picks and counted toward renewal value. Omit to treat every credit as unused.
savingsBalanceNoOptional cash balance, to include the savings-rate move beside the card moves.
currentSavingsApyNoOptional current savings APY, used with savingsBalance.

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
toolYes
errorNo
cardMovesNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
savingsMoveNo
verified_atNo
unheldOffersNo
schemaVersionYes
methodologyUrlNo
freshnessStatusNo
transferBonusesNo

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare a safe, idempotent, open-world read, so the bar is lower. The description still adds real behavioral substance: the 12-month-high threshold for welcome offers, the restriction to cards not held, and that the savings move is contingent/optional. It does not disclose cost, latency, or freshness of 'this week's' data, 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.

Conciseness5/5

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

A single dense sentence that front-loads the input premise and then lists the ranked outputs in priority order. Nothing is wasted; the parenthetical for the optional savings move keeps the conditional out of the main clause.

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

Completeness4/5

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

Because an output schema exists, return values needn't be explained, and the description covers the input premise and the dimensions being ranked. It is slightly thin on how 'this week' is bounded and on what happens when wallet cards have no offers, but nothing critical for invocation is missing.

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

Parameters3/5

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

Schema coverage is 100%, so the schema already documents wallet format, category defaults, usedBenefits semantics, and savings fields, making 3 the baseline. The description adds only light framing — 'per spend category' for categories and '(optionally)... beside the card move' for the savings pair — which is marginal beyond the schema text.

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 description names a specific verb ('rank'), a specific resource ('this week's dollar-valued actions'), and enumerates the four action classes it produces (held-card category picks, 12-month-high welcome offers on unheld cards, transfer bonuses, optional savings move). No sibling tool does this synthesis, so an agent can separate it from get_card_offers or get_transfer_bonuses without opening a schema.

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?

Usage context is clear: it operates 'Given the credit cards a user holds,' which frames the required wallet input and implies a personalized, portfolio-wide aggregation rather than a single-dataset lookup. It stops short of explicit exclusions or naming alternatives (e.g. 'use get_card_offers if you only want offers'), so it is clear context without routing guidance.

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

compare_switch_savingsCompare Savings RatesB
Read-onlyIdempotent
Inspect

Compare a user's current APY with SwitchWize's current top savings APY for a balance.

NameRequiredDescriptionDefault
balanceNo
currentApyYes

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
toolYes
errorNo
balanceNo
annualGapNo
currentApyNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
verified_atNo
comparisonApyNo
schemaVersionYes
methodologyUrlNo
currentInterestNo
freshnessStatusNo
breakEvenFramingNo
comparisonInterestNo
recommendationStatusNo

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is covered. The description adds that the comparison is against a live 'current' top APY for a given balance, but says nothing about rate freshness, data source, or response shape.

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?

A single tight sentence with the comparison target and scoping input front-loaded. No waste, though it is perhaps over-compressed for a tool with two non-obvious parameters.

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

Completeness3/5

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

An output schema exists, so return values need not be explained, and the read-only annotations cover safety. Still missing is any note on which rate source backs the 'top APY' and whether the optional balance changes the result, which the agent needs to invoke confidently in this sibling-heavy cluster.

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

Parameters3/5

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

Schema description coverage is 0%, so the description must carry the burden: it names both parameters implicitly ('current APY', 'balance') and gives each meaning. However, it adds no units or format detail (e.g. APY as a percent number vs decimal, balance currency), which matters given the schema's max of 25 on currentApy.

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

Purpose4/5

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

States a specific verb (compare) and both resources (the user's current APY vs SwitchWize's top savings APY) scoped by balance. An agent can tell what it does, though it does not explicitly distinguish itself from rate-list siblings like get_top_hysa_rates or get_bank_gap.

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

Usage Guidelines2/5

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

No when-to-use guidance, no prerequisites, and no mention of alternatives in a crowded sibling set (get_top_hysa_rates, get_bank_gap, best_move_this_week). Usage must be inferred entirely from the single purpose sentence.

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

get_bank_gapBank Savings GapA
Read-onlyIdempotent
Inspect

Estimate annual savings interest forgone for a supplied balance and optional bank name. comparisonApy is the average of the top three tracked savings rates, not an average across all banks; bankCount is the size of the tracked set. baselineApy is the named bank's APY, or the national savings benchmark when no bank is supplied. Return annualGap, APYs, observation date, freshness and methodology. This is a hypothetical estimate, not guaranteed savings or an account recommendation; verify eligibility, fees and current provider terms.

NameRequiredDescriptionDefault
bankNoOptional bank name for user-facing context.
balanceNo

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
bankNo
toolYes
errorNo
balanceNo
bankApyNo
annualGapNo
bankCountNoNumber of tracked banks in the comparison set, not the number averaged into comparisonApy.
attributionNo
baselineApyNoNamed bank APY, or national savings benchmark when no bank is supplied. Percentage units.
generatedAtYesISO timestamp this response was computed at.
verified_atNo
comparisonApyNoAverage of the top three tracked savings rates (or all available rates if fewer than three). Not an average across bankCount banks. Percentage units.
schemaVersionYes
methodologyUrlNo
freshnessStatusNo

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds genuinely non-structured context: comparisonApy is the average of the top three tracked rates rather than a market-wide average, bankCount bounds that set, and the result is explicitly a hypothetical estimate requiring the user to verify eligibility, fees and provider terms. That methodology disclosure is exactly the kind of value annotations cannot carry.

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?

The purpose is front-loaded in the first clause, followed by methodology and then caveats — a sensible ordering. Four sentences is defensible, but the enumeration of return fields ('annualGap, APYs, observation date, freshness and methodology') duplicates the output schema and is the one sentence that does not earn its place.

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

Completeness4/5

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

With an output schema present, describing return values was optional, and the annotations already carry the safety profile, so the description's remaining job is purpose, metric semantics and caveats — all present. The one real hole is routing: an agent cannot tell from this text when to prefer it over get_bank_gap_index or compare_switch_savings.

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

Parameters4/5

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

Schema description coverage is only 50% — the bank parameter is documented, balance is not. The description compensates by clarifying that bank is optional and, more importantly, that omitting it swaps baselineApy from the named bank's APY to the national savings benchmark, which is real semantic meaning the schema does not convey. It still says nothing about balance units, though the number type plus the 10,000,000 maximum makes dollars the obvious reading.

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

Purpose4/5

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

States a specific verb and resource: 'Estimate annual savings interest forgone for a supplied balance and optional bank name,' which tells the agent exactly what question the tool answers. It defines the headline metric (annual savings interest forgone) concretely enough to separate it from rate-listing siblings like get_top_hysa_rates. It does not, however, address the closely named sibling get_bank_gap_index, so full differentiation is left to inference.

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

Usage Guidelines2/5

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

The description never says when to reach for this tool rather than get_bank_gap_index, compare_switch_savings, or get_top_rates; only a caveat ('hypothetical estimate, not an account recommendation') is given. The 'optional bank name' phrasing implies a no-bank vs named-bank use case, but that is inference rather than stated guidance. No exclusions, prerequisites, or alternatives are named.

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

get_bank_gap_indexBank Gap IndexA
Read-onlyIdempotent
Inspect

Return the current SwitchWize Bank Gap Index headline value, latest release, and methodology URL.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
toolYes
errorNo
labelNo
monthNo
index_idNo
gapPointsNo
topAvgApyNo
datasetUrlNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
verified_atNo
banksTrackedNo
headlineValueNo
schemaVersionYes
methodologyUrlNo
nationalAvgApyNo
freshnessStatusNo
releaseArchiveUrlNo

TDQS

A3.5/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, fully covering the safety profile for a zero-parameter lookup. The description adds only that the result is the headline value plus release and methodology URL, which is modest added context but nothing beyond the annotated read-only, idempotent nature.

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

Conciseness5/5

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

A single front-loaded sentence that names the resource first and enumerates the returned fields without filler. Every clause earns its place.

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

Completeness4/5

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

For a zero-parameter read with an output schema present, the description needs only to frame the resource, which it does. The one real gap is that it never clarifies its relationship to the near-identical sibling get_bank_gap, so an agent could still pick the wrong one.

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

Parameters4/5

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

The tool takes zero parameters, so there is no parameter semantics to convey; per the rubric this is the baseline of 4. Nothing in the schema needs compensating for in the description.

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

Purpose4/5

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

States a specific verb and resource ('Return the current SwitchWize Bank Gap Index headline value, latest release, and methodology URL'), so the agent knows exactly what it produces. It does not, however, distinguish itself from the closely named sibling get_bank_gap, leaving ambiguity about which is the right tool for the gap index.

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

Usage Guidelines2/5

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 reference to alternatives such as get_bank_gap or get_index_dataset. The agent must infer the selection criteria purely from the name.

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

get_card_changesCard ChangesB
Read-onlyIdempotent
Inspect

Return recent verified credit-card fee and APR changes, most recent first. Each event is a diff between two confirmed snapshots of the same card.

NameRequiredDescriptionDefault
limitNo
sinceDaysNoOnly changes observed within this many days.

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
toolYes
countNo
errorNo
changesNo
sinceDaysNo
datasetUrlNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
verified_atNo
schemaVersionYes
methodologyUrlNo
freshnessStatusNo

TDQS

B3.4/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, open world), so the description is not obligated to restate it. Instead it adds genuinely useful behavior: results are 'verified' and ordered 'most recent first', and each event is a diff between two confirmed snapshots, which tells the agent the data model and that entries represent changes rather than current values. It does not mention pagination or coverage limits, keeping it at 4.

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

Conciseness5/5

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

Two dense sentences with no filler; the core purpose is front-loaded and the diff semantics are appended as a clarifying second sentence. Every clause carries information.

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

Completeness4/5

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

An output schema exists, so return values need not be explained, and the description supplies the ordering and diff semantics that matter most for interpreting results. The only gap is the unexplained 'limit' parameter, which is minor given the output schema covers shape.

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

Parameters2/5

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

Schema coverage is only 50%: 'sinceDays' is documented in the schema, but 'limit' has no description beyond its min/max bounds. The description mentions 'recent' but adds no meaning about how limit or sinceDays behave, so it fails to compensate for the uncovered parameter.

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

Purpose4/5

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

The description names a specific verb and resource ('Return recent verified credit-card fee and APR changes'), which is clearly distinct from siblings like get_card_offers or get_rate_freshness. It further sharpens the purpose by defining each event as a diff between two confirmed snapshots, so an agent knows this is a change-feed rather than an offer or rate listing. It stops short of explicitly naming the sibling it displaces, so 4 rather than 5.

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

Usage Guidelines2/5

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

There is no explicit when-to-use, when-not-to-use, or alternative-tool guidance. 'Recent' hints at a recency use case, but the agent must infer when to pick this over get_card_offers, get_rate_freshness, or the rate/offer siblings. No prerequisites or exclusions are stated.

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

get_card_downgrade_pathCard Downgrade PathA
Read-onlyIdempotent
Inspect

Return verified credit-card product-change (downgrade) paths and the issuer's fee-refund window: which no-fee or lower-fee card a given card can be product-changed to, and how long after the annual fee posts a refund is available on cancellation. Optionally filtered to one card id (issuer:slug); returns every verified path and window when omitted.

NameRequiredDescriptionDefault
cardIdNoOptional card id (issuer:slug), e.g. chase:sapphire-reserve or capital-one:venture-x-rewards. Omit to return every verified downgrade path and fee-refund window.

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
toolYes
countNo
errorNo
cardIdNo
datasetUrlNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
verified_atNo
schemaVersionYes
downgradePathsNo
methodologyUrlNo
feeRefundWindowNo
freshnessStatusNo
feeRefundWindowsNo

TDQS

A3.7/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint, so the safety profile is fully covered elsewhere. The description adds the useful qualifier 'verified' (curated data, not raw scrape) and clarifies that the refund window is tied to when the annual fee posts. It says nothing about freshness, pagination, or auth needs, so this is adequate but not rich.

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

Conciseness5/5

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

Two sentences, front-loaded with the return payload and followed by the optional filter. The parenthetical expansion of 'product-change' earns its place by disambiguating the term, and there is no filler.

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?

With an output schema present, the return shape needn't be described, and the tool has only one optional parameter whose schema is complete. The definition covers what is returned, the default behavior when the filter is omitted, and the data's verified nature – nothing an agent needs to call it correctly is missing.

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

Parameters3/5

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

Schema description coverage is 100% and the single cardId parameter is fully documented in the schema, including the issuer:slug format and examples. The description's mention of the same filter and the omit-to-return-all behavior largely restates the schema, so the baseline of 3 applies.

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

Purpose4/5

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

The description uses a specific verb (Return) plus a precisely scoped resource: verified credit-card product-change (downgrade) paths and the issuer's fee-refund window. It even defines the concept inline ('which no-fee or lower-fee card a given card can be product-changed to'), so an agent knows exactly what it gets. It never names the adjacent siblings (get_card_changes, get_card_offers), so it stops short of explicit differentiation.

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

Usage Guidelines3/5

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

The second sentence gives filtering guidance ('Optionally filtered to one card id... returns every verified path and window when omitted'), which tells the agent how to scope the call. However, there is no tool-level when-to-use versus alternatives, and no indication of when get_card_changes would be the better choice.

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

get_card_offersCard OffersA
Read-onlyIdempotent
Inspect

Return current credit-card welcome-bonus offers (non-targeted, confidence-gated), each with a verified timestamp, source URL, and the card's own 12-month best.

NameRequiredDescriptionDefault
cardNoOptional card id (issuer:slug), slug, or name to filter to one card, e.g. chase:sapphire-preferred or Sapphire Preferred.
limitNo

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
toolYes
countNo
errorNo
offersNo
datasetUrlNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
verified_atNo
totalTrackedNo
schemaVersionYes
methodologyUrlNo
freshnessStatusNo

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already cover safety (readOnly, idempotent, openWorld, non-destructive), so the bar is lower; the description still adds real context by disclosing that results are confidence-gated, non-targeted, and carry a verified timestamp plus source URL. This tells the agent about data trustworthiness, which the annotations do not. It does not discuss pagination or staleness limits.

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

Conciseness5/5

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

A single sentence that is front-loaded with the core action and packs scope, filtering behavior, and payload shape without a wasted clause. Nothing here is filler.

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

Completeness4/5

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

For a read-only listing tool with an output schema, the description is nearly sufficient: return values need not be spelled out but are summarized anyway, and scope qualifiers are given. The remaining hole is the undocumented 'limit' parameter, which the description and schema both leave silent.

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

Parameters2/5

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

Schema coverage is only 50%: the 'card' parameter is documented in the schema, but 'limit' has no description anywhere. The description mentions no parameters at all, so it fails to compensate for the coverage gap, particularly the missing semantics of the result cap and its interaction with the 200 maximum.

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

Purpose4/5

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

Specific verb+resource: returning current credit-card welcome-bonus offers, with scoping qualifiers (non-targeted, confidence-gated) and the per-card payload. An agent can distinguish this from siblings like get_transfer_bonuses or get_reward_valuations by resource. It stops short of naming any sibling, so sibling differentiation is inferred rather than stated.

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

Usage Guidelines3/5

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

Usage is implied: fetch it when you need live welcome-bonus offers. The 'non-targeted' qualifier hints at a scope boundary (targeted offers presumably live elsewhere), but there is no explicit when-to-use or when-not-to-use guidance and no alternative tool is named.

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

get_cd_rollover_rulesCD Rollover RulesA
Read-onlyIdempotent
Inspect

Return verified CD rollover rules for one bank, or every bank SwitchWize has verified: what happens automatically at maturity if the customer does nothing, the grace period, how to stop the rollover, and the early-withdrawal penalty. Each fact is sourced directly from the bank's own disclosure; an unverified field is omitted, never guessed.

NameRequiredDescriptionDefault
institutionIdNoOptional institution_registry id, e.g. chase, american-express, wells-fargo. Omit to return every bank SwitchWize has verified.

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
toolYes
countNo
errorNo
sourceUrlNo
datasetUrlNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
verified_atNo
institutionsNo
institutionIdNo
schemaVersionYes
methodologyUrlNo
freshnessStatusNo
gracePeriodDaysNo
autoRenewDefaultNo
autoRenewDescriptionNo
earlyWithdrawalPenaltyNo

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, open world). The description adds genuinely new behavioral context: data provenance from the bank's own disclosure and the rule that unverified fields are omitted rather than guessed, which tells the agent to expect partial objects and not to treat missing fields as errors.

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

Conciseness5/5

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

Two sentences, tightly front-loaded: the first gives the operation and scope, the second gives the data-quality guarantee. No filler, no restatement of the tool name, and the most decision-relevant information (scope) comes first.

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?

An output schema exists, so return-value explanation is unnecessary. Within that constraint the description supplies everything an agent needs: what is returned, for which entity, the sourcing guarantee, and the omission semantics for unverified data.

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

Parameters3/5

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

Schema description coverage is 100% and the single institutionId parameter is fully documented in the schema, including the omit-for-all-banks behavior. The description restates that scope but adds no format, id-validation, or edge-case detail beyond the schema, so the baseline of 3 applies.

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?

States a specific verb and resource ('Return verified CD rollover rules') plus the exact scope: one bank or every verified bank. It also enumerates the returned facts (maturity behavior, grace period, stop-rollover method, early-withdrawal penalty), which cleanly separates it from the rate-, card-, and bonus-oriented siblings.

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?

The scope branch is explicit — pass an institution for one bank, omit it for all verified banks — which tells the agent how to invoke it in either case. It doesn't state when to prefer a sibling tool over this one, but the sibling set covers unrelated domains (rates, cards, bonuses), so ambiguity is low.

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

get_fed_hike_pass_throughFed Hike Pass-ThroughA
Read-onlyIdempotent
Inspect

Return how much of the latest Federal Reserve rate hike each tracked savings account has passed through to savers so far: rate before the hike, rate now, change in basis points, pass-through share, and days until the bank moved. One source per bank; each row carries its source type and observation dates. Optionally filtered to one institution id.

NameRequiredDescriptionDefault
institutionIdNoOptional institution_registry id, e.g. tab, ally, marcus. Omit to return every savings account measured against the latest Fed hike.

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
moveNo
toolYes
countNo
errorNo
summaryNo
excludedNo
datasetUrlNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
institutionNo
verified_atNo
institutionsNo
schemaVersionYes
methodologyUrlNo
freshnessStatusNo
daysSinceAnnouncementNo

TDQS

A4/5.0
Behavior4/5

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

Annotations already carry the safety profile (readOnlyHint=true, idempotentHint=true, openWorldHint=true, destructiveHint=false), lowering the bar. The description still adds real behavioral context beyond them: 'one source per bank,' per-row source type, and observation dates, which tell the agent how to interpret provenance and freshness of each row.

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

Conciseness5/5

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

Two dense sentences: the first front-loads what is computed and the exact output fields, the second covers dataset structure and the optional filter. No filler, no repetition, and the most important information leads.

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

Completeness4/5

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

For a read-only, single-optional-param tool with an output schema and full annotation coverage, the description supplies what's needed: the computation being reported, row granularity, provenance, and the filter. The only marginal gap is that it doesn't touch freshness/staleness expectations, but get_rate_freshness exists as a sibling for that concern.

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

Parameters3/5

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

Schema description coverage is 100% and the single optional institutionId is fully documented in the schema (including example ids like tab, ally, marcus). The description merely restates that the filter is optional and scopes it to 'one institution id,' adding no format or behavior detail beyond the schema, so the baseline 3 applies.

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 description names a specific verb+resource (return Fed-hike pass-through per savings account) and enumerates the exact metrics returned: rate before, rate now, basis-point change, pass-through share, days to move. That framing cleanly separates it from siblings like get_top_hysa_rates or get_bank_gap, which measure levels and gaps rather than pass-through of a specific hike.

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

Usage Guidelines3/5

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

Usage is only implied: the description notes the result can be 'optionally filtered to one institution id,' which hints at the unfiltered-aggregate vs single-bank modes. It never states when to reach for this instead of get_bank_gap, get_reality_score, or best_move_this_week, nor any precondition for calling it.

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

get_index_datasetIndex DatasetC
Read-onlyIdempotent
Inspect

Return a SwitchWize index dataset summary and recent series.

NameRequiredDescriptionDefault
limitNo
indexIdYesIndex id, e.g. bank-gap-index, cd-spread, mma-spread, checking-gap.

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
toolYes
errorNo
labelNo
seriesNo
index_idNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
verified_atNo
schemaVersionYes
methodologyUrlNo
freshnessStatusNo

TDQS

C2.9/5.0
Behavior3/5

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

Annotations declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint, so the safety and idempotency profile is covered. The description adds that it returns a 'summary and recent series,' which hints at output shape but doesn't specify pagination, rate limits, or what 'recent' means. With annotations already conveying core behavior, this is adequate but not rich.

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's a single, efficient sentence with no fluff, though it could be slightly more front-loaded by leading with the action and result. No wasted words.

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

Completeness3/5

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

An output schema exists, so return values needn't be explained. However, for a tool with siblings that serve similar purposes, the description lacks the routing information needed to pick this tool correctly. The parameter gap (undocumented 'limit') also leaves an incompleteness.

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

Parameters3/5

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

Schema coverage is 50%. The indexId parameter has a description with examples in the schema; the limit parameter has no description in the schema or in the description text. The description doesn't compensate for the missing limit documentation. Baseline 3 is appropriate when schema partially covers parameters.

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

Purpose3/5

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

The description states a verb and resource: 'Return a SwitchWize index dataset summary and recent series.' This is clear enough to understand the tool's output, but it doesn't distinguish it from siblings like get_bank_gap_index or get_bank_gap. An agent could confuse this generic 'index dataset' tool with those specific index tools.

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

Usage Guidelines2/5

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

No when-to-use guidance is provided. It doesn't mention alternatives, conditions, or exclusions. With many similar-sounding sibling tools, this omission is significant.

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

get_rate_freshnessData FreshnessA
Read-onlyIdempotent
Inspect

Return public data source freshness status and affected routes. savings is an alias for hysa; money-market is an alias for mma. Also supports cds, checking, macro, bank-gap-index, and indices. Omit category for all supported sources. Unknown categories return an error; a source with no observations is explicitly unavailable. Source collection freshness does not establish that a ranked deposit release is approved or current.

NameRequiredDescriptionDefault
categoryNoOptional freshness category. savings maps to hysa; money-market maps to mma. Also supports cds, checking, macro, bank-gap-index, and indices. Omit for all supported sources. Unknown values return an error; a known source without observations is unavailable.

Output Schema

NameRequiredDescription
toolYes
errorNo
sourcesNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
schemaVersionYes
affectedRoutesNo

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already establish readOnly, idempotent, non-destructive, open-world. The description adds genuine behavioral context beyond them: unknown categories raise an error, sources with no observations are reported as unavailable rather than empty, and freshness is a collection signal not an approval signal. That last caveat is a meaningful semantic distinction the annotations cannot express.

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?

The core purpose and the alias rules are front-loaded, and each sentence carries information. It is slightly padded by re-enumerating categories and aliases that the schema already lists, which is duplication rather than new value.

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

Completeness4/5

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

For a zero-required-parameter read tool with a full output schema, the definition covers purpose, aliasing, error behavior, empty-source semantics, and the approval caveat—enough to call it correctly. 'Affected routes' is mentioned without elaboration, but the output schema carries that detail.

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

Parameters3/5

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

Schema coverage is 100% and the single parameter's enum description already documents the savings→hysa and money-market→mma aliases, the full category list, the omit-for-all behavior, and the error/unavailable semantics. The description largely restates that text, adding little beyond the schema.

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 description opens with a specific verb and resource: 'Return public data source freshness status and affected routes.' No sibling tool covers freshness, so the agent can immediately distinguish this from rate-listing tools like get_top_rates or get_bank_gap.

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?

It gives concrete invocation guidance—omit category for all sources, unknown categories error, known-but-empty sources are explicitly unavailable—plus a boundary caveat that source freshness does not imply an approved/current ranked deposit release. It stops short of naming when to prefer a sibling tool (e.g., call this before trusting get_top_hysa_rates), so it lacks explicit alternatives.

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

get_reality_scoreCard Reality ScoreA
Read-onlyIdempotent
Inspect

Estimate the modeled annual value of a supported premium credit card for a consumer segment. Supply a card slug or name and optionally a segment ID; the default is occasional-traveler. Return segment assumptions, score, rewards, credits, perks, fee, interest, friction, net value, caveats, sources, verification date, freshness and methodology. Gross recovered value is rewards + credits + perks. breakageMultiplier is gross recovered value / advertised value, NOT divided by annual fee. feeRecoveryMultiplier is max(0, gross recovered value - interest drag - rewards friction discount) / annual fee, before subtracting the fee. Friction applies to raw rewards only. Reality Score is 100 * net realized value / advertised value. Ratios are rounded. These are scenario estimates, not personalized advice or guaranteed benefits. Preserve stale or unavailable labels; do not infer that all terms share the observation date. Unknown cards or segments return a structured error with suggestions.

NameRequiredDescriptionDefault
cardYesCard slug or name, e.g. platinum-card or Chase Sapphire Reserve.
segmentNoOptional segment id, e.g. occasional-traveler, small-business-owner, balance-carrier.

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
toolYes
errorNo
resultNo
segmentNo
index_idNo
datasetUrlNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
verified_atNo
schemaVersionYes
methodologyUrlNo
freshnessStatusNo

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), but the description adds real behavioral context: it defines every derived ratio (breakageMultiplier, feeRecoveryMultiplier, friction, Reality Score), warns that these are scenario estimates, and instructs how to handle stale/unavailable labels. It also discloses that unknown cards/segments return a structured error with suggestions. This goes well beyond the annotations, though some overlap with the output schema.

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

Conciseness3/5

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

The purpose and required inputs are front-loaded correctly, but the middle of the description is a dense run of formula definitions (breakageMultiplier, feeRecoveryMultiplier, friction, Reality Score) that partly restates what the output schema can carry. Several sentences do real work, but the block is longer than needed for a 2-parameter read tool.

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 read-only estimation tool with a full output schema and complete annotations, the description covers the remaining gaps: default segment, error behavior, the meaning of every computed ratio, caveats about scenario estimates, and stale-label handling. An agent has everything it needs to call this correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents both parameters (card and segment) with examples. The description adds only the default value for segment (occasional-traveler), which is not in the schema, and restates card-or-name input. Baseline 3 is appropriate.

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

Purpose4/5

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

The opening sentence gives a specific verb+resource+scope: "Estimate the modeled annual value of a supported premium credit card for a consumer segment." It clearly defines the Reality Score concept. However, it never distinguishes itself from the closest siblings (get_reward_valuations, get_card_offers, get_card_downgrade_path), so an agent must infer which card-value tool to pick.

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

Usage Guidelines3/5

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

It states invocation basics ("Supply a card slug or name and optionally a segment ID; the default is occasional-traveler") and notes error behavior for unknown inputs, but gives no when-to-use vs when-not guidance and names no alternative among the many sibling card tools. Usage is implied rather than directed.

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

get_reward_valuationsReward ValuationsB
Read-onlyIdempotent
Inspect

Return SwitchWize points/miles valuations (cents per point) per reward currency, with sample size and provisional/published status.

NameRequiredDescriptionDefault
currencyNoOptional reward currency id or name, e.g. chase-ultimate-rewards or Membership Rewards.

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
toolYes
countNo
errorNo
datasetUrlNo
valuationsNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
verified_atNo
schemaVersionYes
methodologyUrlNo
freshnessStatusNo

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so safety behavior is covered. The description adds useful context beyond the schema by disclosing that results carry sample size and a provisional/published status, but it omits any behavioral notes about freshness, coverage, or defaults.

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?

A single front-loaded sentence with no filler; the core action leads and the detail clauses follow. Slightly dense but every clause carries information.

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

Completeness4/5

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

With an output schema present, return values need not be described, and annotations cover the safety profile. The description covers purpose, unit, and result metadata; the only gap is not stating what happens when 'currency' is omitted (all currencies), which is minor.

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

Parameters3/5

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

Schema description coverage is 100%, so the single optional 'currency' parameter is already fully documented. The phrase 'per reward currency' reinforces that results are currency-scoped, but adds no syntax or format detail beyond the schema, which is the expected baseline.

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

Purpose4/5

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

The description uses a specific verb and resource ('Return SwitchWize points/miles valuations (cents per point) per reward currency') and even names the unit. It is clear what the tool retrieves, though it does not explicitly differentiate itself from siblings like get_transfer_bonuses or get_index_dataset, which an agent must infer from the domain.

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

Usage Guidelines2/5

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

There is no when-to-use guidance, no statement of prerequisites, and no routing to alternative siblings. The agent must infer usage entirely from the tool name and description.

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

get_top_hysa_ratesHigh-Yield Savings RatesA
Read-onlyIdempotent
Inspect

Return top high-yield savings rates with freshness and attribution. Answers only from the editor-approved snapshot; before its first release it returns no ranked rates and says so (approval_status: not_yet_approved). approvedOnly makes the requirement explicit. detail=full adds every listed account marked verified or tracked, best picks, movers, history and a headline summary.

NameRequiredDescriptionDefault
limitNo
detailNosummary (default) adds list_counts. full (savings) adds the complete shared build: accounts (verified and tracked, each marked), best_picks, movers, history and summary. rates stays verified-only either way.
approvedOnlyNoRequire an editor-approved HYSA snapshot. The default tool already answers only from the approved release; before its first release it returns no ranked rates (approval_status: not_yet_approved).

Output Schema

NameRequiredDescription
idNo
asOfNo
toolNo
countNo
errorNo
ratesNo
termsNo
sourceNo
categoryNo
rate_typeNo
releaseIdNo
dataStatusNo
attributionNo
emptyReasonNo
generatedAtYes
releaseSizeNo
releaseStatusNo
schemaVersionYes
sourceDetailsNo
methodologyUrlNo
freshnessStatusNo
attributionDetailsNo
supportedCategoriesNo

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare it read-only, idempotent, and non-destructive, but the description adds real behavioral context beyond them: the sourcing restriction to an editor-approved snapshot and the explicit degraded state (no ranked rates, approval_status: not_yet_approved) before first release. It also enumerates what detail=full surface area includes. Refresh/rate-limit behavior is still unstated.

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?

Three front-loaded sentences that lead with purpose and then qualify behavior; little waste. The approvedOnly sentence is somewhat redundant with the preceding snapshot sentence, costing a point.

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

Completeness4/5

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

An output schema exists so return values need not be explained, yet the description still clarifies the meaningful state (approval_status: not_yet_approved) and the detail modes. Combined with the read-only annotations this is nearly complete; only the undocumented limit parameter remains a gap.

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

Parameters3/5

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

Schema description coverage is 67% and both documented parameters (detail, approvedOnly) are essentially restated rather than clarified — the approvedOnly sentence largely duplicates the schema's own text. The limit parameter has no description in either place, so the description does not compensate for the coverage gap.

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

Purpose4/5

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

The description gives a specific verb+resource ('Return top high-yield savings rates') plus the freshness/attribution wrapper, which is more precise than the bare title. It does not, however, differentiate itself from the close sibling get_top_rates, leaving the agent to infer the HYSA-specific scope.

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

Usage Guidelines3/5

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

It states a meaningful operating condition — answers only from the editor-approved snapshot and returns no ranked rates with approval_status: not_yet_approved before first release. That is output-state guidance rather than when-to-use-this-vs-alternatives guidance; no sibling such as get_top_rates or compare_switch_savings is named as an alternative.

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

get_top_ratesTop RatesA
Read-onlyIdempotent
Inspect

Return top SwitchWize rates with freshness and attribution. Savings, CDs, checking and money market answer only from their editor-approved snapshot. A category with no approved release yet returns no ranked rates and says so (approval_status: not_yet_approved) rather than serving unverified observations; approvedOnly makes that requirement explicit. Approved responses include product terms and field evidence; stale or unavailable releases return no ranked rates. detail=full (savings) adds the complete shared build: every listed account marked verified or tracked, best picks, movers, history and a headline summary.

NameRequiredDescriptionDefault
limitNo
detailNosummary (default) adds list_counts. full (savings) adds the complete shared build: accounts (verified and tracked, each marked), best_picks, movers, history and summary. rates stays verified-only either way.
categoryYesU.S. deposit category: savings (alias hysa), cds, money-market (alias mma), or checking.
approvedOnlyNoRequire an editor-approved deposit snapshot. Savings, CDs, checking and money market always answer from their own approved release; a category with no release yet returns no ranked rates (approval_status: not_yet_approved), as do stale or unavailable releases.

Output Schema

NameRequiredDescription
idNo
asOfNo
toolNo
countNo
errorNo
ratesNo
termsNo
sourceNo
categoryNo
rate_typeNo
releaseIdNo
dataStatusNo
attributionNo
emptyReasonNo
generatedAtYes
releaseSizeNo
releaseStatusNo
schemaVersionYes
sourceDetailsNo
methodologyUrlNo
freshnessStatusNo
attributionDetailsNo
supportedCategoriesNo

TDQS

A3.6/5.0
Behavior4/5

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

Goes well beyond the readOnly/idempotent annotations by disclosing degradation behavior: missing approval returns no ranked rates with approval_status: not_yet_approved, and stale or unavailable releases also return no ranked rates rather than unverified data. It also states that approved payloads carry product terms and field evidence. It does not mention rate limits or payload size, keeping it short of a 5.

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

Conciseness3/5

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

Purpose is front-loaded in the first sentence, but the description then repeats the approval/not_yet_approved story twice (general rule, then again via approvedOnly, then again via stale releases). The final sentence about detail=full duplicates the schema's own detail description almost verbatim.

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

Completeness4/5

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

An output schema exists, so return-value shape need not be explained, and the description covers the important failure modes for a four-parameter read tool. The remaining gap is that it never positions itself against get_top_hysa_rates, leaving potential mis-selection unresolved.

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

Parameters3/5

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

Schema coverage is 75%, so the schema already carries most parameter meaning; the description mainly restates the approvedOnly and detail semantics that the schema also documents. The limit parameter (1-25) is undocumented in both places, and the description adds no formatting or ordering guidance for it.

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

Purpose4/5

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

States a specific verb and resource ('Return top SwitchWize rates') plus the scoping dimensions (freshness, attribution, deposit category). It does not differentiate itself from the overlapping sibling get_top_hysa_rates, which covers the hysa alias of the same category enum, so an agent cannot resolve the overlap from the description alone.

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

Usage Guidelines3/5

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

The description implies usage via its guarantee language ('Savings, CDs, checking and money market answer only from their editor-approved snapshot') and notes when approvedOnly is required, but it never says when to pick this tool over get_top_hysa_rates or get_rate_freshness. Use cases are implied rather than stated.

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

get_transfer_bonusesTransfer BonusesB
Read-onlyIdempotent
Inspect

Return current point-transfer bonuses across tracked bank-to-partner routes, each with a verified timestamp, source URL, and best-ever-for-route when real history exists.

NameRequiredDescriptionDefault
programNoOptional program id or name to filter routes by source or destination, e.g. chase-ultimate-rewards or Flying Blue.

Output Schema

NameRequiredDescription
asOfNoISO timestamp of the underlying data this response reflects.
toolYes
countNo
errorNo
routesNo
datasetUrlNo
attributionNo
generatedAtYesISO timestamp this response was computed at.
verified_atNo
schemaVersionYes
methodologyUrlNo
freshnessStatusNo

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already declare readOnly, idempotent, non-destructive, and open-world, so the safety profile is covered. The description adds one genuinely useful behavioral trait: 'best-ever-for-route when real history exists,' disclosing that a field is conditionally populated. Everything else it mentions (timestamp, source URL) restates return values already covered by the output 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?

A single front-loaded sentence with no filler; the core action leads and the output details follow. Slightly dense and could be split, but nothing is wasted.

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

Completeness4/5

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

For a simple read-only tool with one optional parameter, a full schema, and an output schema, the description covers purpose and return provenance adequately. The only real gap is routing guidance against the many sibling tools in this rate/deal family.

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

Parameters3/5

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

Schema description coverage is 100%, and the single optional 'program' parameter is fully documented as filtering by source or destination with examples. The description adds nothing about filtering semantics, so baseline 3 applies.

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

Purpose4/5

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

States a specific verb and resource ('Return current point-transfer bonuses') and scopes it to 'tracked bank-to-partner routes,' which clearly separates it from rate, card-offer, and valuation siblings. It does not name a sibling, but the domain is unambiguous.

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

Usage Guidelines2/5

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

There is no when-to-use or when-not-to-use guidance, no mention of alternatives (e.g. get_card_offers, best_move_this_week), and no prerequisites. The usage context is only implied by the resource 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.

  1. 3 tool updatesv0.3.1
    • Changedget_rate_freshness2 fields changed
      • addedInput schema / properties / category / description
        Added value: +"Optional freshness category. savings maps to hysa; money-market maps to mma. Also supports cds, checking, macro, bank-gap-index, and indices. Omit for all supported sources. Unknown values return an error; a known source without observations is unavailable."
      • addedInput schema / properties / category / enum
        Added value: +[
        +  "savings",
        +  "hysa",
        +  "cds",
        +  "money-market",
        +  "mma",
        +  "checking",
        +  "macro",
        +  "bank-gap-index",
        +  "indices"
        +]
    • Changedget_top_hysa_rates3 fields changed
      • addedOutput schema / properties / releaseId
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / releaseSize
        Added value: +{
        +  "type": "number"
        +}
      • addedOutput schema / properties / releaseStatus
        Added value: +{
        +  "enum": [
        +    "observed",
        +    "unavailable"
        +  ],
        +  "type": "string"
        +}
    • Changedget_top_rates5 fields changed
      • changedInput schema / properties / category / description
        Previous value: -"Rate category, e.g. savings, cds, money-market, checking, mortgage."New value: +"U.S. deposit category: savings (alias hysa), cds, money-market (alias mma), or checking."
      • addedInput schema / properties / category / enum
        Added value: +[
        +  "savings",
        +  "hysa",
        +  "cds",
        +  "money-market",
        +  "mma",
        +  "checking"
        +]
      • addedOutput schema / properties / releaseId
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / releaseSize
        Added value: +{
        +  "type": "number"
        +}
      • addedOutput schema / properties / releaseStatus
        Added value: +{
        +  "enum": [
        +    "observed",
        +    "unavailable"
        +  ],
        +  "type": "string"
        +}
  2. 16 tool updatesv0.3.0
    • Addedbest_move_this_week
    • Changedcompare_switch_savings1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "annualGap": {
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "asOf": {
        +      "description": "ISO timestamp of the underlying data this response reflects.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "attribution": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "balance": {
        +      "type": "number"
        +    },
        +    "breakEvenFraming": {
        +      "type": "string"
        +    },
        +    "comparisonApy": {
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "comparisonInterest": {
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "currentApy": {
        +      "type": "number"
        +    },
        +    "currentInterest": {
        +      "type": "number"
        +    },
        +    "error": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "code": {
        +          "type": "string"
        +        },
        +        "message": {
        +          "type": "string"
        +        },
        +        "retryable": {
        +          "type": "boolean"
        +        },
        +        "suggestions": {
        +          "items": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "additionalProperties": true,
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "code",
        +        "message"
        +      ],
        +      "type": "object"
        +    },
        +    "freshnessStatus": {
        +      "enum": [
        +        "fresh",
        +        "aging",
        +        "stale",
        +        "unavailable"
        +      ],
        +      "type": "string"
        +    },
        +    "generatedAt": {
        +      "description": "ISO timestamp this response was computed at.",
        +      "type": "string"
        +    },
        +    "methodologyUrl": {
        +      "type": "string"
        +    },
        +    "recommendationStatus": {
        +      "enum": [
        +        "comparison_available",
        +        "data_unavailable"
        +      ],
        +      "type": "string"
        +    },
        +    "schemaVersion": {
        +      "type": "string"
        +    },
        +    "tool": {
        +      "type": "string"
        +    },
        +    "verified_at": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "schemaVersion",
        +    "tool",
        +    "generatedAt"
        +  ],
        +  "type": "object"
        +}
    • Changedget_bank_gap1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "annualGap": {
        +      "type": "number"
        +    },
        +    "asOf": {
        +      "description": "ISO timestamp of the underlying data this response reflects.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "attribution": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "balance": {
        +      "type": "number"
        +    },
        +    "bank": {
        +      "type": [
        +        "object",
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "bankApy": {
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "bankCount": {
        +      "description": "Number of tracked banks in the comparison set, not the number averaged into comparisonApy.",
        +      "type": "number"
        +    },
        +    "baselineApy": {
        +      "description": "Named bank APY, or national savings benchmark when no bank is supplied. Percentage units.",
        +      "type": "number"
        +    },
        +    "comparisonApy": {
        +      "description": "Average of the top three tracked savings rates (or all available rates if fewer than three). Not an average across bankCount banks. Percentage units.",
        +      "type": "number"
        +    },
        +    "error": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "code": {
        +          "type": "string"
        +        },
        +        "message": {
        +          "type": "string"
        +        },
        +        "retryable": {
        +          "type": "boolean"
        +        },
        +        "suggestions": {
        +          "items": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "additionalProperties": true,
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "code",
        +        "message"
        +      ],
        +      "type": "object"
        +    },
        +    "freshnessStatus": {
        +      "enum": [
        +        "fresh",
        +        "aging",
        +        "stale",
        +        "unavailable"
        +      ],
        +      "type": "string"
        +    },
        +    "generatedAt": {
        +      "description": "ISO timestamp this response was computed at.",
        +      "type": "string"
        +    },
        +    "methodologyUrl": {
        +      "type": "string"
        +    },
        +    "schemaVersion": {
        +      "type": "string"
        +    },
        +    "tool": {
        +      "type": "string"
        +    },
        +    "verified_at": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "schemaVersion",
        +    "tool",
        +    "generatedAt"
        +  ],
        +  "type": "object"
        +}
    • Changedget_bank_gap_index1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "asOf": {
        +      "description": "ISO timestamp of the underlying data this response reflects.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "attribution": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "banksTracked": {
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "datasetUrl": {
        +      "type": "string"
        +    },
        +    "error": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "code": {
        +          "type": "string"
        +        },
        +        "message": {
        +          "type": "string"
        +        },
        +        "retryable": {
        +          "type": "boolean"
        +        },
        +        "suggestions": {
        +          "items": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "additionalProperties": true,
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "code",
        +        "message"
        +      ],
        +      "type": "object"
        +    },
        +    "freshnessStatus": {
        +      "enum": [
        +        "fresh",
        +        "aging",
        +        "stale",
        +        "unavailable"
        +      ],
        +      "type": "string"
        +    },
        +    "gapPoints": {
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "generatedAt": {
        +      "description": "ISO timestamp this response was computed at.",
        +      "type": "string"
        +    },
        +    "headlineValue": {
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "index_id": {
        +      "type": "string"
        +    },
        +    "label": {
        +      "type": "string"
        +    },
        +    "methodologyUrl": {
        +      "type": "string"
        +    },
        +    "month": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "nationalAvgApy": {
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "releaseArchiveUrl": {
        +      "type": "string"
        +    },
        +    "schemaVersion": {
        +      "type": "string"
        +    },
        +    "tool": {
        +      "type": "string"
        +    },
        +    "topAvgApy": {
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "verified_at": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "schemaVersion",
        +    "tool",
        +    "generatedAt"
        +  ],
        +  "type": "object"
        +}
    • Addedget_card_changes
    • Addedget_card_downgrade_path
    • Addedget_card_offers
    • Addedget_cd_rollover_rules
    • Addedget_fed_hike_pass_through
    • Changedget_index_dataset1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "asOf": {
        +      "description": "ISO timestamp of the underlying data this response reflects.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "attribution": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "error": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "code": {
        +          "type": "string"
        +        },
        +        "message": {
        +          "type": "string"
        +        },
        +        "retryable": {
        +          "type": "boolean"
        +        },
        +        "suggestions": {
        +          "items": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "additionalProperties": true,
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "code",
        +        "message"
        +      ],
        +      "type": "object"
        +    },
        +    "freshnessStatus": {
        +      "enum": [
        +        "fresh",
        +        "aging",
        +        "stale",
        +        "unavailable"
        +      ],
        +      "type": "string"
        +    },
        +    "generatedAt": {
        +      "description": "ISO timestamp this response was computed at.",
        +      "type": "string"
        +    },
        +    "index_id": {
        +      "type": "string"
        +    },
        +    "label": {
        +      "type": "string"
        +    },
        +    "methodologyUrl": {
        +      "type": "string"
        +    },
        +    "schemaVersion": {
        +      "type": "string"
        +    },
        +    "series": {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "tool": {
        +      "type": "string"
        +    },
        +    "verified_at": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "schemaVersion",
        +    "tool",
        +    "generatedAt"
        +  ],
        +  "type": "object"
        +}
    • Changedget_rate_freshness1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "affectedRoutes": {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "attribution": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "error": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "code": {
        +          "type": "string"
        +        },
        +        "message": {
        +          "type": "string"
        +        },
        +        "retryable": {
        +          "type": "boolean"
        +        },
        +        "suggestions": {
        +          "items": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "additionalProperties": true,
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "code",
        +        "message"
        +      ],
        +      "type": "object"
        +    },
        +    "generatedAt": {
        +      "description": "ISO timestamp this response was computed at.",
        +      "type": "string"
        +    },
        +    "schemaVersion": {
        +      "type": "string"
        +    },
        +    "sources": {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "tool": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "schemaVersion",
        +    "tool",
        +    "generatedAt"
        +  ],
        +  "type": "object"
        +}
    • Changedget_reality_score1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "asOf": {
        +      "description": "ISO timestamp of the underlying data this response reflects.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "attribution": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "datasetUrl": {
        +      "type": "string"
        +    },
        +    "error": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "code": {
        +          "type": "string"
        +        },
        +        "message": {
        +          "type": "string"
        +        },
        +        "retryable": {
        +          "type": "boolean"
        +        },
        +        "suggestions": {
        +          "items": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "additionalProperties": true,
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "code",
        +        "message"
        +      ],
        +      "type": "object"
        +    },
        +    "freshnessStatus": {
        +      "enum": [
        +        "fresh",
        +        "aging",
        +        "stale",
        +        "unavailable"
        +      ],
        +      "type": "string"
        +    },
        +    "generatedAt": {
        +      "description": "ISO timestamp this response was computed at.",
        +      "type": "string"
        +    },
        +    "index_id": {
        +      "type": "string"
        +    },
        +    "methodologyUrl": {
        +      "type": "string"
        +    },
        +    "result": {
        +      "additionalProperties": true,
        +      "properties": {
        +        "advertisedValue": {
        +          "type": "number"
        +        },
        +        "annualFee": {
        +          "type": "number"
        +        },
        +        "breakageMultiplier": {
        +          "description": "Gross recovered value (rewards + credits + perks) / advertised value, rounded to two decimals. Annual fee is not this denominator.",
        +          "type": "number"
        +        },
        +        "feeRecoveryMultiplier": {
        +          "description": "max(0, gross recovered value - interest drag - rewards friction discount) / annual fee, rounded to two decimals; before subtracting the annual fee.",
        +          "type": "number"
        +        },
        +        "interestDrag": {
        +          "type": "number"
        +        },
        +        "realityScore": {
        +          "description": "100 * net realized value / advertised value, rounded to an integer.",
        +          "type": "number"
        +        },
        +        "realizedPerks": {
        +          "type": "number"
        +        },
        +        "realizedRewards": {
        +          "type": "number"
        +        },
        +        "realizedStatementCredits": {
        +          "type": "number"
        +        },
        +        "realizedValue": {
        +          "description": "Rewards + credits + perks minus annual fee, interest drag and rewards friction discount.",
        +          "type": "number"
        +        },
        +        "redemptionFrictionDiscount": {
        +          "description": "Discount applied to raw rewards, not to credits or perks.",
        +          "type": "number"
        +        }
        +      },
        +      "type": [
        +        "object",
        +        "null"
        +      ]
        +    },
        +    "schemaVersion": {
        +      "type": "string"
        +    },
        +    "segment": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "tool": {
        +      "type": "string"
        +    },
        +    "verified_at": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "schemaVersion",
        +    "tool",
        +    "generatedAt"
        +  ],
        +  "type": "object"
        +}
    • Addedget_reward_valuations
    • Changedget_top_hysa_rates3 fields changed
      • addedInput schema / properties / approvedOnly
        Added value: +{
        +  "description": "Require an editor-approved HYSA snapshot. The default tool already answers only from the approved release; before its first release it returns no ranked rates (approval_status: not_yet_approved).",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / detail
        Added value: +{
        +  "description": "summary (default) adds list_counts. full (savings) adds the complete shared build: accounts (verified and tracked, each marked), best_picks, movers, history and summary. rates stays verified-only either way.",
        +  "enum": [
        +    "summary",
        +    "full"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "anyOf": [
        +    {
        +      "properties": {
        +        "attribution": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "category",
        +        "count",
        +        "freshnessStatus",
        +        "rates"
        +      ]
        +    },
        +    {
        +      "properties": {
        +        "attribution": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        }
        +      },
        +      "required": [
        +        "tool",
        +        "error",
        +        "attribution"
        +      ]
        +    }
        +  ],
        +  "properties": {
        +    "asOf": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "attribution": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "additionalProperties": true,
        +          "type": "object"
        +        }
        +      ]
        +    },
        +    "attributionDetails": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "category": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "number"
        +    },
        +    "dataStatus": {
        +      "enum": [
        +        "available",
        +        "no_observations",
        +        "no_eligible_rates",
        +        "source_error",
        +        "unavailable",
        +        "stale",
        +        "conflicted"
        +      ],
        +      "type": "string"
        +    },
        +    "emptyReason": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "error": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "code": {
        +          "type": "string"
        +        },
        +        "message": {
        +          "type": "string"
        +        },
        +        "retryable": {
        +          "type": "boolean"
        +        },
        +        "suggestions": {
        +          "items": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "additionalProperties": true,
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "code",
        +        "message"
        +      ],
        +      "type": "object"
        +    },
        +    "freshnessStatus": {
        +      "enum": [
        +        "fresh",
        +        "aging",
        +        "stale",
        +        "unavailable"
        +      ],
        +      "type": "string"
        +    },
        +    "generatedAt": {
        +      "type": "string"
        +    },
        +    "id": {
        +      "type": "string"
        +    },
        +    "methodologyUrl": {
        +      "type": "string"
        +    },
        +    "rate_type": {
        +      "enum": [
        +        "APY",
        +        "APR"
        +      ],
        +      "type": "string"
        +    },
        +    "rates": {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "schemaVersion": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    },
        +    "sourceDetails": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "supportedCategories": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "terms": {
        +      "type": "string"
        +    },
        +    "tool": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "schemaVersion",
        +    "generatedAt"
        +  ],
        +  "type": "object"
        +}
    • Changedget_top_rates3 fields changed
      • addedInput schema / properties / approvedOnly
        Added value: +{
        +  "description": "Require an editor-approved deposit snapshot. Savings, CDs, checking and money market always answer from their own approved release; a category with no release yet returns no ranked rates (approval_status: not_yet_approved), as do stale or unavailable releases.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / detail
        Added value: +{
        +  "description": "summary (default) adds list_counts. full (savings) adds the complete shared build: accounts (verified and tracked, each marked), best_picks, movers, history and summary. rates stays verified-only either way.",
        +  "enum": [
        +    "summary",
        +    "full"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "anyOf": [
        +    {
        +      "properties": {
        +        "attribution": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "category",
        +        "count",
        +        "freshnessStatus",
        +        "rates"
        +      ]
        +    },
        +    {
        +      "properties": {
        +        "attribution": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        }
        +      },
        +      "required": [
        +        "tool",
        +        "error",
        +        "attribution"
        +      ]
        +    }
        +  ],
        +  "properties": {
        +    "asOf": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "attribution": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "additionalProperties": true,
        +          "type": "object"
        +        }
        +      ]
        +    },
        +    "attributionDetails": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "category": {
        +      "type": "string"
        +    },
        +    "count": {
        +      "type": "number"
        +    },
        +    "dataStatus": {
        +      "enum": [
        +        "available",
        +        "no_observations",
        +        "no_eligible_rates",
        +        "source_error",
        +        "unavailable",
        +        "stale",
        +        "conflicted"
        +      ],
        +      "type": "string"
        +    },
        +    "emptyReason": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "error": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "code": {
        +          "type": "string"
        +        },
        +        "message": {
        +          "type": "string"
        +        },
        +        "retryable": {
        +          "type": "boolean"
        +        },
        +        "suggestions": {
        +          "items": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "additionalProperties": true,
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "code",
        +        "message"
        +      ],
        +      "type": "object"
        +    },
        +    "freshnessStatus": {
        +      "enum": [
        +        "fresh",
        +        "aging",
        +        "stale",
        +        "unavailable"
        +      ],
        +      "type": "string"
        +    },
        +    "generatedAt": {
        +      "type": "string"
        +    },
        +    "id": {
        +      "type": "string"
        +    },
        +    "methodologyUrl": {
        +      "type": "string"
        +    },
        +    "rate_type": {
        +      "enum": [
        +        "APY",
        +        "APR"
        +      ],
        +      "type": "string"
        +    },
        +    "rates": {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "schemaVersion": {
        +      "type": "string"
        +    },
        +    "source": {
        +      "type": "string"
        +    },
        +    "sourceDetails": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "supportedCategories": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "terms": {
        +      "type": "string"
        +    },
        +    "tool": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "schemaVersion",
        +    "generatedAt"
        +  ],
        +  "type": "object"
        +}
    • Addedget_transfer_bonuses
  3. 8 tool updatesv0.1.0
    • First observedcompare_switch_savings
    • First observedget_bank_gap
    • First observedget_bank_gap_index
    • First observedget_index_dataset
    • First observedget_rate_freshness
    • First observedget_reality_score
    • First observedget_top_hysa_rates
    • First observedget_top_rates

TDQS

B3.4/5.0

Scored across 16 tools

Disambiguation3/5

Most tools target distinct datasets, but several savings/rate tools overlap: get_top_rates vs get_top_hysa_rates, and compare_switch_savings vs get_bank_gap both involve comparing a user's APY to top savings rates. best_move_this_week also aggregates actions covered by more specific tools, so boundaries are understandable but not always crisp.

Naming Consistency4/5

Almost all tools use a consistent snake_case get_* convention (e.g., get_card_offers, get_rate_freshness, get_fed_hike_pass_through). The only deviations are best_move_this_week and compare_switch_savings, which are still readable and not chaotic.

Tool Count4/5

Sixteen tools is slightly above the ideal compact range but reasonable for a broad finance-data server covering cards, savings, rates, offers, transfers, and bank behavior. Each tool maps to a recognizable dataset or analysis, though a few could be consolidated.

Completeness4/5

The surface covers a wide range of personal-finance analytics: card value, offers, transfer bonuses, changes, downgrade paths, savings rates, CD rollover rules, bank gaps, and Fed pass-through. Minor gaps remain around explicit card/bank discovery or general product-detail lookup, but core workflows are well supported.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers