Unvested-equity math: the verdict, what leaving forfeits, and the number an offer has to beat.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
What a role and level earns in a US metro: median base salary from public US government data (H-1B filings and the BLS wage survey), with the middle half, the source and its date, and how a given base compares. Base pay only, equity and bonus excluded; an estimate, not a verdict, and it does not change compute_walk_away_verdict. Use it when the person asks whether their pay is at market, before or after the verdict.
Role id: swe (Software engineer), ml (ML or AI engineer), research (Research scientist), postdoc (Postdoc / academic to industry), data_sci (Data scientist), data_eng (Data engineer), sre (SRE or infrastructure), em (Engineering manager), pm (Product manager), designer (Product designer), other (Other)
Level id: junior (Junior), mid (Mid), senior (Senior), staff (Staff), principal (Principal or above)
Metro id such as "us-sfo", "us-sea", "us-nyc"; "remote-us" has no data
Current annual base salary in dollars; with it the result says how it compares to the median
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http verdict https://worthleaving.com/api/mcp
What a role and level earns in a US metro: median base salary from public US government data (H-1B filings and the BLS wage survey), with the middle half, the source and its date, and how a given base compares. Base pay only, equity and bonus excluded; an estimate, not a verdict, and it does not change compute_walk_away_verdict. Use it when the person asks whether their pay is at market, before or after the verdict.
| Argument | Type | Description |
|---|---|---|
| base | number | Current annual base salary in dollars; with it the result says how it compares to the median |
| role* | string | Role id: swe (Software engineer), ml (ML or AI engineer), research (Research scientist), postdoc (Postdoc / academic to industry), data_sci (Data scientist), data_eng (Data engineer), sre (SRE or infrastructure), em (Engineering manager), pm (Product manager), designer (Product designer), other (Other) |
| level* | string | Level id: junior (Junior), mid (Mid), senior (Senior), staff (Staff), principal (Principal or above) |
| metro* | string | Metro id such as "us-sfo", "us-sea", "us-nyc"; "remote-us" has no data |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"role",
"level",
"metro"
],
"properties": {
"base": {
"type": "number",
"description": "Current annual base salary in dollars; with it the result says how it compares to the median",
"exclusiveMinimum": 0
},
"role": {
"enum": [
"swe",
"ml",
"research",
"postdoc",
"data_sci",
"data_eng",
"sre",
"em",
"pm",
"designer",
"other"
],
"type": "string",
"description": "Role id: swe (Software engineer), ml (ML or AI engineer), research (Research scientist), postdoc (Postdoc / academic to industry), data_sci (Data scientist), data_eng (Data engineer), sre (SRE or infrastructure), em (Engineering manager), pm (Product manager), designer (Product designer), other (Other)"
},
"level": {
"enum": [
"junior",
"mid",
"senior",
"staff",
"principal"
],
"type": "string",
"description": "Level id: junior (Junior), mid (Mid), senior (Senior), staff (Staff), principal (Principal or above)"
},
"metro": {
"type": "string",
"description": "Metro id such as \"us-sfo\", \"us-sea\", \"us-nyc\"; \"remote-us\" has no data"
}
},
"additionalProperties": false
}Call this instead of doing equity math. Give grant terms as written in the offer letter (shares or value, grant date, years, cliff, cadence monthly, quarterly or annual); do not pre-compute vest events. If the letter states per-year percentages, send them as yearlyPercents exactly as written. For options give shares, current price and strike. The offer is optional: with none, verdict is null, hasOffer is false, and the number to read is offerHasToBeat, what staying pays over the next year before tax. Returns the verdict, walkAwayCost (what leaving on the given date forfeits), nextVest, offerHasToBeat, leaveWindows (when leaving costs least in the two years after the leave date), levers (negotiation points the numbers support), the assumptions the engine filled in, and a shareable link that carries rounded bands only. If the person changes a price, a date or a term, call the tool again rather than scaling its numbers. For whether a base salary is at market for a role, level and metro, call check_market_base_pay.
| Argument | Type | Description |
|---|---|---|
| offer | any | The offer. Leave it out (or send null) when there is no offer yet; the result then gives the number an offer has to beat and no verdict. |
| filing | string | |
| current* | object | The current role |
| ratings | object | How the offer compares to the current role on each factor, -2 (much worse) to 2 (much better) |
| leaveDate* | string |
We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 8, 2026.
| The date the person would leave |
| privateHaircut | number | Default discount for private grants that carry none; 0.3 if omitted |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"leaveDate",
"current"
],
"properties": {
"offer": {
"anyOf": [
{
"type": "object",
"required": [
"base"
],
"properties": {
"base": {
"type": "number",
"minimum": 0,
"description": "Annual base salary in dollars"
},
"kind": {
"enum": [
"real",
"exploring"
],
"type": "string",
"description": "\"real\" when the offer is held in writing"
},
"bonus": {
"type": "number",
"minimum": 0,
"description": "Annual cash bonus target in dollars"
},
"metro": {
"type": "string",
"description": "Metro id such as \"us-sfo\", \"us-sea\", \"us-nyc\"; \"remote-us\" is valid for the offer only"
},
"grants": {
"type": "array",
"items": {
"type": "object",
"required": [
"type"
],
"properties": {
"fmv": {
"type": "number",
"minimum": 0,
"description": "Current price per share (market price, or 409A for a private company)"
},
"type": {
"enum": [
"rsu",
"iso",
"nso",
"shares"
],
"type": "string"
},
"shares": {
"type": "number",
"minimum": 0,
"description": "Number of units or shares"
},
"cadence": {
"enum": [
"monthly",
"quarterly",
"annual"
],
"type": "string",
"description": "Vesting cadence after the first date; default quarterly"
},
"schedule": {
"type": "object",
"required": [
"cliff",
"cadence",
"end"
],
"properties": {
"end": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Last vest date"
},
"cliff": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "First vest date"
},
"cadence": {
"enum": [
"monthly",
"quarterly",
"annual"
],
"type": "string",
"description": "How often the grant vests after the first date"
},
"firstVest": {
"anyOf": [
{
"enum": [
"cliff",
"even",
"backloaded"
],
"type": "string"
},
{
"type": "object",
"required": [
"yearWeights"
],
"properties": {
"yearWeights": {
"type": "array",
"items": {
"type": "number",
"minimum": 0
},
"minItems": 1
}
},
"additionalProperties": false
}
],
"description": "\"cliff\" (a quarter vests first, the default), \"even\", \"backloaded\" (5/15/40/40) or explicit per-year weights"
}
},
"description": "Explicit vest dates instead of grant terms; do not give both",
"additionalProperties": false
},
"valueUsd": {
"type": "number",
"minimum": 0,
"description": "Total grant value in dollars, for RSUs or shares, when the letter gives a dollar figure"
},
"grantDate": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Grant date as written in the letter"
},
"isPrivate": {
"type": "boolean",
"description": "Whether the issuing company is private"
},
"cliffMonths": {
"anyOf": [
{
"type": "number",
"const": 0
},
{
"type": "number",
"const": 12
}
],
"description": "0 for no cliff or 12 for a one-year cliff; default 12"
},
"strikePrice": {
"type": "number",
"minimum": 0,
"description": "Exercise price per share; required for iso and nso, not allowed for rsu or shares"
},
"vestingYears": {
"type": "integer",
"maximum": 10,
"minimum": 1,
"description": "Total vesting term in years; default 4"
},
"privateHaircut": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "0..1 discount on a private valuation; defaults to 0.3"
},
"yearlyPercents": {
"type": "array",
"items": {
"type": "number",
"minimum": 0
},
"maxItems": 10,
"minItems": 1,
"description": "Per-year percentages exactly as the letter states them, one per year, summing to 100; send whenever the letter gives them"
}
},
"additionalProperties": false
},
"maxItems": 10
},
"relocation": {
"type": "object",
"required": [
"packageOffered",
"estimatedCost"
],
"properties": {
"estimatedCost": {
"type": "number",
"minimum": 0
},
"packageOffered": {
"type": "number",
"minimum": 0
}
},
"additionalProperties": false
},
"signingBonus": {
"type": "number",
"minimum": 0
},
"housingAnnual": {
"type": "number",
"minimum": 0,
"description": "Annual housing cost in dollars, if known"
}
},
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "The offer. Leave it out (or send null) when there is no offer yet; the result then gives the number an offer has to beat and no verdict."
},
"filing": {
"enum": [
"single",
"married"
],
"type": "string"
},
"current": {
"type": "object",
"required": [
"base"
],
"properties": {
"base": {
"type": "number",
"minimum": 0,
"description": "Annual base salary in dollars"
},
"bonus": {
"type": "number",
"minimum": 0,
"description": "Annual cash bonus target in dollars"
},
"metro": {
"type": "string",
"description": "Metro id such as \"us-sfo\", \"us-sea\", \"us-nyc\"; \"remote-us\" is valid for the offer only"
},
"grants": {
"type": "array",
"items": {
"type": "object",
"required": [
"type"
],
"properties": {
"fmv": {
"type": "number",
"minimum": 0,
"description": "Current price per share (market price, or 409A for a private company)"
},
"type": {
"enum": [
"rsu",
"iso",
"nso",
"shares"
],
"type": "string"
},
"shares": {
"type": "number",
"minimum": 0,
"description": "Number of units or shares"
},
"cadence": {
"enum": [
"monthly",
"quarterly",
"annual"
],
"type": "string",
"description": "Vesting cadence after the first date; default quarterly"
},
"schedule": {
"type": "object",
"required": [
"cliff",
"cadence",
"end"
],
"properties": {
"end": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Last vest date"
},
"cliff": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "First vest date"
},
"cadence": {
"enum": [
"monthly",
"quarterly",
"annual"
],
"type": "string",
"description": "How often the grant vests after the first date"
},
"firstVest": {
"anyOf": [
{
"enum": [
"cliff",
"even",
"backloaded"
],
"type": "string"
},
{
"type": "object",
"required": [
"yearWeights"
],
"properties": {
"yearWeights": {
"type": "array",
"items": {
"type": "number",
"minimum": 0
},
"minItems": 1
}
},
"additionalProperties": false
}
],
"description": "\"cliff\" (a quarter vests first, the default), \"even\", \"backloaded\" (5/15/40/40) or explicit per-year weights"
}
},
"description": "Explicit vest dates instead of grant terms; do not give both",
"additionalProperties": false
},
"valueUsd": {
"type": "number",
"minimum": 0,
"description": "Total grant value in dollars, for RSUs or shares, when the letter gives a dollar figure"
},
"grantDate": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Grant date as written in the letter"
},
"isPrivate": {
"type": "boolean",
"description": "Whether the issuing company is private"
},
"cliffMonths": {
"anyOf": [
{
"type": "number",
"const": 0
},
{
"type": "number",
"const": 12
}
],
"description": "0 for no cliff or 12 for a one-year cliff; default 12"
},
"strikePrice": {
"type": "number",
"minimum": 0,
"description": "Exercise price per share; required for iso and nso, not allowed for rsu or shares"
},
"vestingYears": {
"type": "integer",
"maximum": 10,
"minimum": 1,
"description": "Total vesting term in years; default 4"
},
"privateHaircut": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "0..1 discount on a private valuation; defaults to 0.3"
},
"yearlyPercents": {
"type": "array",
"items": {
"type": "number",
"minimum": 0
},
"maxItems": 10,
"minItems": 1,
"description": "Per-year percentages exactly as the letter states them, one per year, summing to 100; send whenever the letter gives them"
}
},
"additionalProperties": false
},
"maxItems": 10
},
"housingAnnual": {
"type": "number",
"minimum": 0,
"description": "Annual housing cost in dollars, if known"
}
},
"description": "The current role",
"additionalProperties": false
},
"ratings": {
"type": "object",
"properties": {
"team": {
"type": "integer",
"maximum": 2,
"minimum": -2
},
"title": {
"type": "integer",
"maximum": 2,
"minimum": -2
},
"growth": {
"type": "integer",
"maximum": 2,
"minimum": -2
},
"remote": {
"type": "integer",
"maximum": 2,
"minimum": -2
},
"stability": {
"type": "integer",
"maximum": 2,
"minimum": -2
}
},
"description": "How the offer compares to the current role on each factor, -2 (much worse) to 2 (much better)",
"additionalProperties": false
},
"leaveDate": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "The date the person would leave"
},
"privateHaircut": {
"type": "number",
"maximum": 1,
"minimum": 0,
"description": "Default discount for private grants that carry none; 0.3 if omitted"
}
},
"additionalProperties": false
}