# earnrate (npm · earnrate)

Which credit card earns the most at a merchant, from your cards or every card, and why.

- Trust score: 82/100 (high trust)
- Change this week: +20
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-06

## Components

- remote · `mcp.earnrate.dev`: 37/100, [markdown](https://verifymcp.io/servers/cwasley-earnrate/mcp.md), [page](https://verifymcp.io/servers/cwasley-earnrate/mcp)
- npm · `earnrate`: 82/100 (this document), [markdown](https://verifymcp.io/servers/cwasley-earnrate/earnrate.md), [page](https://verifymcp.io/servers/cwasley-earnrate/earnrate)

## Channel facts

- Registry: `npm`
- Package: `earnrate`
- Version: `0.2.14`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-06.

- **Supply Chain Security**: 99/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - 3 of 12 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 87/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to cwasley/earnrate).
  - License check failed: the license ((MIT AND CC-BY-NC-4.0)) isn't a recognized OSI-approved license.
  - Actively maintained (last published 0 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 73/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 6809 tokens (~486/item across 14 items; 14 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 30/100
  - Stability observed for 9 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 15 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the earnrate MCP server?

earnrate runs locally as an npm package, launched with npx -y earnrate mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add cwasley-earnrate -- npx -y earnrate mcp
```

### Cursor

```json
{
  "mcpServers": {
    "cwasley-earnrate": {
      "command": "npx",
      "args": [
        "-y",
        "earnrate",
        "mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "cwasley-earnrate": {
      "command": "npx",
      "args": [
        "-y",
        "earnrate",
        "mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add cwasley-earnrate -- npx -y earnrate mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "cwasley-earnrate": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "earnrate",
        "mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add cwasley-earnrate --command npx --arg -y --arg earnrate --arg mcp
```

### Hermes

```yaml
mcp_servers:
  cwasley-earnrate:
    command: "npx"
    args: ["-y", "earnrate", "mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "cwasley-earnrate": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "earnrate",
        "mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add cwasley-earnrate -t stdio -c npx -a -y earnrate mcp
```

### Other

```json
{
  "mcpServers": {
    "cwasley-earnrate": {
      "command": "npx",
      "args": [
        "-y",
        "earnrate",
        "mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-06 (score 82, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-11-05 (score 67, −15)

- [security regression] Malware scan: pass → unverified
- [security regression] Known CVEs: pass → unverified
- [security regression] Tool safety: pass → unverified
- [security regression] Stability: 0.23 → unverified
- [functional regression] Schema quality: 437 → 486
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Schema quality: 100 → unverified
- [functional regression] Dependency health: 0.92 → unverified
- [functional] Package version: 0.2.12 → 0.2.14
- [functional] Package version: 0.2.12 → 0.2.13

### 2026-11-04 (score 82, +18)

- [security regression] Tool safety: pass → unverified
- [security regression] Stability: 0.20 → unverified
- [security improvement] Malware scan: unverified → pass
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional] First check of Schema quality: unverified
- [functional] First check of Schema quality: 100
- [functional] Package version: 0.2.10 → 0.2.12
- [functional] Package version: 0.2.10 → 0.2.11

### 2026-11-03 (score 64, +1)

- [security improvement] Malware scan: unverified → pass
- [functional] Package version: 0.2.8 → 0.2.10
- [functional] Package version: 0.2.8 → 0.2.9

### 2026-11-02 (score 63, −3)

- [security regression] Malware scan: pass → unverified
- [security improvement] Known CVEs: unverified → pass
- [functional improvement] Dependency health: unverified → 0.92
- [functional improvement] Security disclosure: fail → pass
- [functional] Package version: 0.2.5 → 0.2.8
- [functional] Package version: 0.2.5 → 0.2.7
- [functional] Package version: 0.2.5 → 0.2.6

### 2026-11-01 (score 66, +15)

- [security regression] Stability: 0.10 → unverified
- [security regression] Tool safety: pass → unverified
- [security improvement] Known CVEs: unverified → pass
- [security improvement] Malware scan: unverified → pass
- [functional regression] Schema quality: 318 → 358
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional improvement] Dependency health: unverified → 0.92
- [functional] First check of Schema quality: unverified
- [functional] Package version: 0.2.1 → 0.2.5
- [functional] Package version: 0.2.1 → 0.2.4
- [functional] Package version: 0.2.1 → 0.2.3
- [functional] Package version: 0.2.1 → 0.2.2

### 2026-10-31 (score 51, −11)

- [security regression] Known CVEs: pass → unverified
- [security improvement] Malware scan: unverified → pass
- [functional regression] Schema quality: 259 → 318
- [functional regression] Schema quality: 2590 → 3640
- [functional regression] Schema quality: 259 → 292
- [functional regression] Dependency health: 0.92 → unverified
- [functional] Package version: 0.1.2 → 0.2.1
- [functional] Package version: 0.1.2 → 0.2.0
- [functional] Package version: 0.1.2 → 0.1.4
- [functional] Package version: 0.1.2 → 0.1.3

### 2026-10-30 (score 62, −14)

- [security regression] Malware scan: pass → unverified
- [functional improvement] Schema quality: 344 → 259
- [functional improvement] Stability: unverified → 0.07
- [functional] Destructive annotations: pass → 100
- [functional] Package version: 0.1.1 → 0.1.2

## MCP tools (14)

### `best_card_for_purchase` (~1015 tokens)

Best card for a purchase

Which credit card earns the most rewards for a purchase, and why. With no cards given and no saved wallet, it ranks every card earnrate knows (in `allCards`): a complete answer for anyone. With cards named in the conversation (`cards`) or a saved wallet, it picks the best of the user's own: `decision.cardId` is the pick and `decision.checkoutLabel` is how the card appears at checkout, with every usable card ranked with reasons, cards the merchant won't take, assumptions, warnings, and when a different point valuation would change the pick. For a business earnrate may not know, like a local restaurant, pass `category` when you can tell what kind of business it is. When the user is paying outside the U.S. or in another currency, pass `country`: abroad, each card is ranked after its foreign transaction fee. Pass `payment` only when the user says how they're paying, like Apple Pay or PayPal checkout. A merchant statement credit (a card's `credit`, like Amex Platinum's lululemon credit) counts toward the pick only once it's enrolled in the wallet and has dollars left this period, and only when the amount is given; say its dollars apart from the % back. With no cards, `allCards.credits` lists cards with a credit at the store; present those first. Never needs or returns card numbers.

Input parameters:

- `amount` (number): Purchase amount in US dollars. Improves cap math.
- `cards` (array): Cards the user named in this conversation, to answer for just those cards without saving anything. Leave out to use the user's saved wallet if they have one; with neither, the answer covers every car…
- `category` (string): Only for a merchant earnrate may not know, and only if you're confident what kind of business it is: its spending category, e.g. grocery.supermarket for a supermarket, dining for a restaurant, gas fo…
- `channel` (string): How the purchase is made. Omit if unknown; the answer says what it assumed.
- `country` (string): Where the purchase is made, as a two-letter country code (FR, GB, JP). Pass it when the user is paying abroad or in another currency: abroad, cards are ranked after their foreign transaction fees. De…
- `date` (string): Purchase date, YYYY-MM-DD. Defaults to today.
- `memberships` (array): Memberships the user has, such as amazon-prime or costco, when they're named in the conversation rather than saved.
- `merchant` (string, required): Merchant name or web address as the user would say it or see it, e.g. "Whole Foods" or "delta.com", or a kind of place, e.g. "restaurants" or "gas station".
- `payment` (string): How the purchase is paid, only when the user says: card (the card itself or its number), apple-pay, google-pay or paypal (PayPal checkout). Optional; omit it when unknown, and never assume Apple Pay.…
- `valuation` (string): Instead of the user's saved point values (or earnrate's defaults): flat, points at their cash-out value, MR and UR at 1¢; or points-heavy, MR and UR at 1.7¢, for people who transfer points to airline…

Output parameters:

- `allCards`
- `assumptions` (array)
- `bonus`
- `decision`
- `excluded` (array)
- `merchant` (object)
- `notes` (array)
- `ranked` (array)
- `sensitivity` (string|null)
- `warnings` (array)

### `resolve_merchant` (~455 tokens)

Resolve a merchant

Shows how earnrate identifies a merchant: its spend category, likely MCC, which card networks it takes, confidence, and whether that came from curated data, Claude, or nowhere. Use it to explain or double-check a recommendation.

Input parameters:

- `category` (string): Only for a merchant earnrate may not know, and only if you're confident what kind of business it is: its spending category, e.g. grocery.supermarket for a supermarket, dining for a restaurant, gas fo…
- `channel` (string): How the purchase is made. Omit if unknown; the answer says what it assumed.
- `merchant` (string, required): Merchant name or web address as the user would say it or see it, e.g. "Whole Foods" or "delta.com", or a kind of place, e.g. "restaurants" or "gas station".

Output parameters:

- `accepts`
- `ambiguity`
- `bookedVia` (array)
- `category` (string)
- `channel`
- `confidence` (string)
- `inference`
- `input` (string)
- `likelyMcc` (number|null)
- `merchantId` (string|null)
- `resolvedName` (string)
- `source` (string)

### `compare_welcome_offers` (~318 tokens)

Compare welcome offers

Ranks the public welcome (sign-up) offers on cards the user doesn't have by first-year value: the bonus at the user's point values minus the first year's annual fee and any membership the card needs that the user doesn't have. Offers the issuer rules out because of a card in the user's wallet are marked likely not eligible and listed last. Use it when the user asks which new card to get or which has the best sign-up bonus. It covers only the cards earnrate knows, offers vary by person, and each offer's note gives the issuer's eligibility rules; pass those caveats on. It doesn't account for what a card would earn on the user's spending.

Input parameters:

- `business` (boolean): Business cards instead of personal ones.
- `cards` (array): Cards the user named in this conversation, to answer for just those cards without saving anything. Leave out to use the user's saved wallet if they have one; with neither, the answer covers every car…
- `includeHeld` (boolean): Include cards already in the wallet.
- `kind` (string): cash: cash back cards only. points: points and miles cards only.
- `noAnnualFee` (boolean): Only cards with no annual fee.
- `valuation` (string): Instead of the user's saved point values (or earnrate's defaults): flat, points at their cash-out value, MR and UR at 1¢; or points-heavy, MR and UR at 1.7¢, for people who transfer points to airline…

Output parameters:

- `notes` (array)
- `offers` (array)
- `withoutOffer` (array)

### `best_cards_for` (~843 tokens)

Best cards for a purchase

Ranks every card earnrate knows that takes new applicants, not only the user's, for one purchase or category, each set up at its best (the right category pick, activated, cap unused), with its annual fee and what earning the rate takes. Use it for questions like "what's the best card for groceries?" or "which card should I get for Amazon?". It needs no wallet. For which of the user's own cards to use, call best_card_for_purchase instead. Mention the annual fee and any conditions alongside each card. For a store, cards with a statement credit there come first in `credits` ("$75 back each quarter, then 1x Amex Membership Rewards"): present them first, in dollars and never as a percentage, saying when the cardholder must enroll, then the ranking by rate.

Input parameters:

- `amount` (number): Purchase amount in US dollars, if known.
- `business` (boolean): Business cards instead of personal ones.
- `category` (string): A spending category: dining (Restaurants), dining.fast_food (Fast food), grocery.supermarket (Supermarkets), grocery.online (Online grocery and delivery), superstore (Superstores), warehouse_club (Wa…
- `channel` (string): How the purchase is made. Omit if unknown; the answer says what it assumed.
- `country` (string): Where the purchase is made, as a two-letter country code (FR, GB, JP). Pass it when the user is paying abroad or in another currency: abroad, cards are ranked after their foreign transaction fees. De…
- `issuer` (string): Only this issuer's cards.
- `kind` (string): cash: cash back cards only. points: points and miles cards only.
- `memberships` (array): Memberships the user has, such as amazon-prime or costco. Rates that need one they don't have are listed separately; a card that needs one (Costco Anywhere) says so.
- `merchant` (string): Merchant name or web address as the user would say it or see it, e.g. "Whole Foods" or "delta.com", or a kind of place, e.g. "restaurants" or "gas station".
- `noAnnualFee` (boolean): Only cards with no annual fee.
- `payment` (string): How the purchase is paid, only when the user says: card (the card itself or its number), apple-pay, google-pay or paypal (PayPal checkout). Optional; omit it when unknown, and never assume Apple Pay.…
- `valuation` (string): Instead of the user's saved point values (or earnrate's defaults): flat, points at their cash-out value, MR and UR at 1¢; or points-heavy, MR and UR at 1.7¢, for people who transfer points to airline…

Output parameters:

- `assumptions` (array)
- `credits` (array)
- `excluded` (array)
- `merchant` (object)
- `ranked` (array)
- `warnings` (array)

### `simulate_spending` (~429 tokens)

Simulate a year of spending

Spends monthly amounts for a year across every card earnrate knows, and ranks single cards and two-card pairs by rewards minus annual fees, and minus a membership a card needs (a Costco membership) unless the user has it or spends at Costco. Spending is optional: without it, typical U.S. household amounts are used and the answer says so. With `cards` (named in the conversation) or compareToWallet (the saved wallet), it ranks the cards that would add the most to those cards instead. Use it for "which card fits my spending?" or "is it worth adding a card?". It leaves out welcome bonuses.

Input parameters:

- `business` (boolean): Business cards instead of personal ones.
- `cards` (array): Cards the user named in this conversation, to answer for just those cards without saving anything. Leave out to use the user's saved wallet if they have one; with neither, the answer covers every car…
- `compareToWallet` (boolean): Rank the cards that would add the most to the user's saved wallet.
- `issuer` (string): Only this issuer's cards.
- `kind` (string): cash: cash back cards only. points: points and miles cards only.
- `memberships` (array): Memberships the user has, such as amazon-prime or costco. Rates that need one they don't have are listed separately; a card that needs one (Costco Anywhere) says so.
- `noAnnualFee` (boolean): Only cards with no annual fee.
- `spending` (array): Monthly spending lines, each a category (grocery.supermarket, dining, gas, other) or a merchant (Amazon, Costco). Optional: leave out to use typical amounts, and don't press the user for numbers they…
- `valuation` (string): Instead of the user's saved point values (or earnrate's defaults): flat, points at their cash-out value, MR and UR at 1¢; or points-heavy, MR and UR at 1.7¢, for people who transfer points to airline…

Output parameters:

- `additions` (array)
- `current`
- `notes` (array)
- `pairs` (array)
- `singles` (array)

### `cheat_sheet` (~397 tokens)

Cheat sheet

The card to use for each everyday kind of purchase right now: groceries, dining, gas, Amazon, Costco, travel, streaming, drugstores and everything else. With no cards given and no saved wallet, it picks from every card earnrate knows (`scope: all cards`, each row noting the card's fee and conditions). With cards named in the conversation or a saved wallet, it picks from the user's own cards, with caps, picks and activations as they are. The kind, noAnnualFee, business and issuer filters apply only when it picks from every card. For one specific store, call best_card_for_purchase instead. Pass on the notes.

Input parameters:

- `business` (boolean): Business cards instead of personal ones.
- `cards` (array): Cards the user named in this conversation, to answer for just those cards without saving anything. Leave out to use the user's saved wallet if they have one; with neither, the answer covers every car…
- `date` (string): Purchase date, YYYY-MM-DD. Defaults to today.
- `everyCard` (boolean): true to pick from every card earnrate knows even when the user has a saved wallet ("which cards should I get?"); the filters then apply.
- `issuer` (string): Only this issuer's cards.
- `kind` (string): cash: cash back cards only. points: points and miles cards only.
- `memberships` (array): Memberships the user has, such as amazon-prime or costco, when they're named in the conversation rather than saved.
- `noAnnualFee` (boolean): Only cards with no annual fee.
- `valuation` (string): Instead of the user's saved point values (or earnrate's defaults): flat, points at their cash-out value, MR and UR at 1¢; or points-heavy, MR and UR at 1.7¢, for people who transfer points to airline…

Output parameters:

- `assumptions` (array)
- `date` (string)
- `notes` (array)
- `quarter` (string)
- `rows` (array)
- `scope` (string)

### `search_cards` (~108 tokens)

Search cards

Finds credit cards in earnrate's catalog by name or issuer, e.g. "sapphire", "amex gold" or "bofa". Returns each card's id (for add_card), network, annual fee, whether it's already in the wallet, and what it needs set up: category picks and their options, memberships, activations. Leave the query out to list every card. US cards only.

Input parameters:

- `query` (string): Card name or issuer, as the user said it.

Output parameters:

- `cards` (array)
- `exact` (boolean)

### `list_wallet` (~207 tokens)

List wallet

Starts with a to-do list for the user's cards right now (bonuses to activate and their deadlines, categories to pick or confirm, caps nearly used up, welcome bonuses to finish and the weekly pace, yearly spend bonuses at least 75% of the way, merchant credits to enroll in or use before they reset); use it when the user asks what to do with their cards this quarter or what they're forgetting. Then lists the user's cards: checkout label, network, rewards currency and its value, spending caps with how much is left this period, chosen bonus categories (and whether they're current), welcome-bonus progress, progress toward yearly spend bonuses, merchant statement credits (enrolled or not, and what's left this period), which stores a store card works at, when each card's data was last verified, the point values the user saved, and (for the hosted wallet) when it was started. It uses the wallet file on this computer, not the hosted earnrate connector's wallet.

Output parameters:

- `cards` (array)
- `checklist` (array)
- `membershipNames` (array)
- `memberships` (array)
- `pointValues` (array)
- `started` (string|null)

### `record_purchase` (~581 tokens)

Record a purchase

Records a purchase the user has already made, so spending caps, welcome-bonus progress, yearly spend milestones and merchant credits used stay accurate for future recommendations. It updates the user's saved wallet. Only call it after the purchase has happened, and only once per purchase: calling it twice counts the spend twice. Purchases with no cap, no open welcome bonus, no spend milestone and no enrolled merchant credit are acknowledged and nothing is written. For a merchant earnrate doesn't recognize it asks for category first, so caps aren't missed. It uses the wallet file on this computer, not the hosted earnrate connector's wallet.

Input parameters:

- `amount` (number, required): Amount spent in US dollars.
- `cardId` (string, required): The card used, as a cardId from list_wallet or best_card_for_purchase.
- `category` (string): For a merchant earnrate doesn't know, its spending category, e.g. dining for a restaurant: without one the purchase isn't recorded, since its caps can't be told. If nobody knows, other records it tow…
- `channel` (string): How the purchase is made. Omit if unknown; the answer says what it assumed.
- `date` (string): Purchase date, YYYY-MM-DD. Defaults to today.
- `merchant` (string, required): Merchant name or web address as the user would say it or see it, e.g. "Whole Foods" or "delta.com", or a kind of place, e.g. "restaurants" or "gas station".

Output parameters:

- `bonus`
- `booking`
- `credit`
- `message` (string)
- `milestones` (array)
- `recorded` (boolean)

### `add_card` (~630 tokens)

Add a card

Adds a card the user holds to their wallet by its id from search_cards, creating the wallet if there isn't one. The reply says what the card still needs (category picks, memberships, activations); ask the user about those. Stores only the card's product id and settings, never card numbers. It uses the wallet file on this computer, not the hosted earnrate connector's wallet.

Input parameters:

- `activated` (array): Rule ids the user has activated with the issuer, such as rotating categories. Replaces the current list.
- `anniversary` (string): The account's anniversary as MM-DD, for cards whose cap resets on it.
- `bonus`: A welcome bonus the user is working toward, so purchases recorded on this card count toward it and answers can favor it. Ask when they opened the account; spending needed and the deadline default to…
- `capSpent` (object): Dollars already spent this period on a capped bonus, for a card the user starts tracking partway through: cap key (as list_wallet shows it) → dollars, e.g. {"five-percent-quarterly": 400}. Ask; recor…
- `cardId` (string, required): The card id from search_cards, e.g. chase-sapphire-preferred.
- `checkoutLabel`: How the card appears at checkout or in a browser wallet, e.g. "Amex Gold". Optional; null goes back to the card's own name.
- `creditUsed` (object): Dollars of a merchant credit already received this period: credit id → dollars, e.g. {"lululemon": 40}. Ask; recorded purchases add to it from then on.
- `enrolled` (array): Merchant credit ids the user has enrolled in with the issuer (search_cards and list_wallet list each card's credits, e.g. "lululemon" on Amex Platinum). A credit that needs enrolling counts in answer…
- `milestoneSpent` (object): Dollars already spent on the card this year, for its spend milestones (bonuses after a yearly spending total, as search_cards lists them): milestone id → dollars, e.g. {"spend-15k": 9000}. Every purc…
- `opened`: Optional: the day the account opened, YYYY-MM-DD. Only for cards with a first-year rate (search_cards lists it), which applies only while a purchase falls in the window; without a date the card is ra…
- `picks` (object): For cards where the cardholder picks bonus categories: choice id → option ids, from search_cards, e.g. {"five-percent": ["tv-internet-streaming", "fast-food"]}. Saved for the current period. Ask the…

Output parameters:

- `cardIds` (array)
- `created` (boolean)
- `memberships` (array)
- `message` (string)
- `notes` (array)

### `update_card` (~689 tokens)

Update a card

Changes settings on a card already in the wallet: its category picks for this period, checkout label, anniversary, opening date (optional; for first-year rates), activated categories, cap spending so far (capSpent), spending this year toward its spend milestones (milestoneSpent), merchant credits enrolled in (enrolled) and used this period (creditUsed), or a welcome bonus to track. Picks replace the saved ones in each choice group you set (other groups are kept) for the current period. Use it when the user picks new categories, such as each quarter on U.S. Bank Cash+. It uses the wallet file on this computer, not the hosted earnrate connector's wallet.

Input parameters:

- `activated` (array): Rule ids the user has activated with the issuer, such as rotating categories. Replaces the current list.
- `anniversary` (string): The account's anniversary as MM-DD, for cards whose cap resets on it.
- `bonus`: A welcome bonus the user is working toward, so purchases recorded on this card count toward it and answers can favor it. Ask when they opened the account; spending needed and the deadline default to…
- `capSpent` (object): Dollars already spent this period on a capped bonus, for a card the user starts tracking partway through: cap key (as list_wallet shows it) → dollars, e.g. {"five-percent-quarterly": 400}. Ask; recor…
- `cardId` (string, required): The card id from search_cards, e.g. chase-sapphire-preferred.
- `checkoutLabel`: How the card appears at checkout or in a browser wallet, e.g. "Amex Gold". Optional; null goes back to the card's own name.
- `creditUsed` (object): Dollars of a merchant credit already received this period: credit id → dollars, e.g. {"lululemon": 40}. Ask; recorded purchases add to it from then on.
- `enrolled` (array): Merchant credit ids the user has enrolled in with the issuer (search_cards and list_wallet list each card's credits, e.g. "lululemon" on Amex Platinum). A credit that needs enrolling counts in answer…
- `milestoneSpent` (object): Dollars already spent on the card this year, for its spend milestones (bonuses after a yearly spending total, as search_cards lists them): milestone id → dollars, e.g. {"spend-15k": 9000}. Every purc…
- `opened`: Optional: the day the account opened, YYYY-MM-DD. Only for cards with a first-year rate (search_cards lists it), which applies only while a purchase falls in the window; without a date the card is ra…
- `picks` (object): For cards where the cardholder picks bonus categories: choice id → option ids, from search_cards, e.g. {"five-percent": ["tv-internet-streaming", "fast-food"]}. Saved for the current period. Ask the…

Output parameters:

- `cardIds` (array)
- `created` (boolean)
- `memberships` (array)
- `message` (string)
- `notes` (array)

### `remove_card` (~98 tokens)

Remove a card

Removes a card from the wallet, with its tracked cap usage, bonus progress and yearly spending. Memberships and point values stay, even when the last card goes. Only when the user says they no longer have it or don't want it considered. It uses the wallet file on this computer, not the hosted earnrate connector's wallet.

Input parameters:

- `cardId` (string, required): The card id from search_cards, e.g. chase-sapphire-preferred.

Output parameters:

- `cardIds` (array)
- `created` (boolean)
- `memberships` (array)
- `message` (string)
- `notes` (array)

### `set_memberships` (~237 tokens)

Set memberships

Sets the memberships that unlock some cards' rates, such as amazon-prime for Prime Visa's 5% or a Bank of America Preferred Rewards tier, and costco for a Costco membership (so spending answers don't count its cost against Costco Anywhere). Replaces the whole list, so include the ones to keep. It saves them even with no cards saved, and every answer then uses them. It uses the wallet file on this computer, not the hosted earnrate connector's wallet.

Input parameters:

- `memberships` (array, required): Every membership the user has. Known: amazon-prime, bank-of-america-account, bank-of-america-small-business-account, bofa-rewards-member, bofa-rewards-preferred-honors, bofa-rewards-preferred-plus, b…

Output parameters:

- `cardIds` (array)
- `created` (boolean)
- `memberships` (array)
- `message` (string)
- `notes` (array)

### `set_point_values` (~464 tokens)

Set point values

Saves what the user's points are worth to them, in cents per point, in their saved wallet; every answer then compares cards at those values unless a valuation profile is asked for. No saved cards are needed. Use it when the user says what their points are worth ("I value Chase points at 1.5¢") or that they transfer points to airlines and hotels (profile points-heavy). Values change only the currencies given; null goes back to earnrate's default. Currencies by id: cash (Cash back), MR (Amex Membership Rewards), UR (Chase Ultimate Rewards), sofi-rewards (SoFi Member Rewards), bofa-travel-rewards (Bank of America Travel Rewards points), bofa-premium-rewards (Bank of America Premium Rewards points), usbank-altitude (U.S. Bank Altitude points), navy-federal-rewards (Navy Federal Rewards points), rei-rewards (REI Co-op Mastercard rewards), best-buy-rewards (My Best Buy rewards), C1 (Capital One miles), TYP (Citi ThankYou points), WFR (Wells Fargo Rewards), BILT (Bilt points), united-miles (United MileagePlus miles), aadvantage-miles (American Airlines AAdvantage miles), southwest-rapid-rewards (Southwest Rapid Rewards points), aeroplan (Aeroplan points), atmos-points (Atmos Rewards points), trueblue-points (JetBlue TrueBlue points), ihg-points (IHG One Rewards points), delta-skymiles (Delta SkyMiles), hilton-honors (Hilton Honors points), marriott-bonvoy (Marriott Bonvoy points), kohls-rewards (Kohl's Rewards), nordy-club (Nordy Club points). It uses the wallet file on this computer, not the hosted earnrate connector's wallet.

Input parameters:

- `profile` (string): A preset: flat (MR and UR at 1¢) or points-heavy (MR and UR at 1.7¢). Values given too win over it.
- `values` (object): Cents per point by currency id, e.g. {"UR": 1.5, "MR": 1.6}. null goes back to the default.

Output parameters:

- `cardIds` (array)
- `created` (boolean)
- `memberships` (array)
- `message` (string)
- `notes` (array)

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/cwasley-earnrate/earnrate#diagnostics

## Score history

- 2026-11-06: 82
- 2026-11-05: 67
- 2026-11-04: 82
- 2026-11-03: 64
- 2026-11-02: 63
- 2026-11-01: 66
- 2026-10-31: 51
- 2026-10-30: 62
- 2026-10-29: 76
- 2026-10-28: 61

## Common questions

### What is the earnrate MCP server?

earnrate is an MCP server listed in the public MCP registry as io.github.cwasley/earnrate. Which credit card earns the most at a merchant, from your cards or every card, and why. This page covers its npm package (earnrate).

### Is the earnrate MCP server safe to use?

earnrate scores 82 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 6 November 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the earnrate MCP server expose?

earnrate exposes 14 tools: best_card_for_purchase, resolve_merchant, compare_welcome_offers, best_cards_for, simulate_spending, and 9 more. Their descriptions and schemas cost roughly 6,471 tokens of context every time the server is loaded.

### Is the earnrate MCP server still maintained?

earnrate is still listed as active in the MCP registry. We last reached this channel on 6 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What did VerifyMCP test on the earnrate MCP server?

VerifyMCP ran 16 checks on earnrate, covering Malware scan, Known CVEs, Install scripts, Dependency health and 12 more. Endpoint Security and Transport & Reachability do not apply to an npm package, so they were not tested. The score does not measure everything, and the scoring documentation lists what it leaves out.

## Links

- npm package: https://www.npmjs.com/package/earnrate
- Socket report: https://socket.dev/npm/package/earnrate
- Repository: https://github.com/cwasley/earnrate
- Website: https://earnrate.dev/
- Changelog RSS feed: https://verifymcp.io/servers/cwasley-earnrate/earnrate.xml
- Changelog JSON feed: https://verifymcp.io/servers/cwasley-earnrate/earnrate/changelog.json
- Trust report (JSON): https://verifymcp.io/servers/cwasley-earnrate/earnrate.json
- HTML version of this page: https://verifymcp.io/servers/cwasley-earnrate/earnrate
