Skip to main content
Glama

Server Details

Equity comp tax/trade optimizer: ISO/AMT exercise, NSO, RSU, QSBS, concentration, hedging. 50-state.

If you are the author of this connector, you can claim ownership by verifying the domain or GitHub account it belongs to. Claimed connector authors can inspect health checks, view analytics, and manage their listing.
Status
Healthy
Uptime
100.0% over 68 days
Last Tested
Transport
Streamable HTTP · MCP 2024-11-05
URL
Repository
AlvisoOculus/optionsahoy-mcp
GitHub Stars
5
Server Listing
OptionsAhoy: Stock Equity and Tax Optimizer

TDQS

A4.6/5.0

Scored across 8 tools

Disambiguation4/5

The tools map to distinct equity-compensation decisions and include explicit routing guidance (e.g., use amt_iso_optimize for ISOs, nso_calculate for NSOs, rsu_sell_vs_hold for a single RSU vest vs rsu_lot_optimize for lot selection). Some conceptual overlap remains in the RSU-selling and hedging spaces—concentration_analyze, rsu_lot_optimize, and protective_put_price can all touch selling or hedging a concentrated position—but the descriptions clearly delineate scope, so misselection is unlikely if read carefully.

Naming Consistency4/5

All names use lower snake_case and are descriptive, with most following a [domain]_[action] pattern (amt_iso_optimize, concentration_analyze, nso_calculate, qsbs_check, rsu_lot_optimize). Two names are noun phrases (equity_funding_plan, protective_put_price) and one uses a comparison phrase (rsu_sell_vs_hold), so the convention is mostly but not perfectly consistent.

Tool Count5/5

Eight tools is well within the ideal 3–15 range for a focused equity-compensation planning server. Each tool covers a distinct major decision (ISO/AMT, NSO, RSU vest, RSU lots, concentration, hedging, funding, QSBS) and does not feel padded or thin.

Completeness4/5

Core equity-compensation workflows are well covered: ISO/AMT, NSO, RSU sell-vs-hold, RSU lot selection, QSBS qualification, concentration risk, hedging, and goal funding. Gaps remain for ESPP, restricted stock awards/83(b), wash-sale handling (explicitly out of scope), and integrated multi-position optimization (deferred to beta), but these are adjacent or workaround-able.

Available Tools

8 tools
amt_iso_optimizeA
Read-onlyIdempotent
Inspect

Use this when someone asks how or when to exercise incentive stock options (ISOs), whether exercising will trigger an AMT bomb or phantom income, whether to exercise early, how to plan around the alternative minimum tax (AMT) on an exercise, or how to spread ISO exercises across several years. Computes multi-year exercise schedules and compares them by after-tax Net Final Value (NFV) at the planning horizon. NFV is the after-all-tax cash equivalent of the position at year horizon, summing exercised shares (held to LTCG) plus the time-valued tax stream paid along the way; the search compares per-year share allocations by NFV. The headline result is schedules.optimized.nfv, the dollar NFV of the highest-scoring schedule found; schedules.lumpSum and schedules.evenSplit are baseline plans whose nfv deltas show the value added by the optimized schedule. For NSO grants use nso_calculate, for RSUs at vest use rsu_sell_vs_hold, for §1202 QSBS qualification use qsbs_check. Models AMT credit recovery across future years, grant-expiration timing, and the post-termination exercise window. Deterministic computation: federal + 50-state tax tables and AMT brackets are compiled in, and the only data read at call time is OptionsAhoy's own published market data for a ticker. Input values are not stored. schedules.optimized comes from searching the full discretized candidate space and refining share by share, and a published test case checks it against an exhaustive search (see https://optionsahoy.com/verification). departedRecommendation, when present, comes from a scan over candidate share counts rather than the full search. Also returns crossoverShares, crossoverBargain, alreadyInAmt, timing, stateHasAmt, bargainPerShare, and effectiveHorizon; see outputSchema for the full shape. Example call: {shares: 10000, strike: 2, fmv: 200, expectedGrowth: 0.15, volatility: 0.5, filingStatus: "married_joint", ordinaryIncome: 400000, stateCode: "CA", carryforwardCredit: 0, horizon: 4, cashReturnRate: 0.05, grantDate: "2022-01-15", hasLeftCompany: false, terminationDate: null}. Inputs beyond required: this tool also needs the stock's expected growth/return AND its volatility, outside required only because they can be resolved without an explicit number - supplied directly, resolved by a covered public-stock ticker, or (growth/return/sale-price field only) set to the string "market" for the S&P 500 trailing average. If growth/return/sale price is neither supplied nor resolved, the tool uses the S&P 500 trailing average; if volatility is neither, the median implied volatility of the public companies OptionsAhoy covers as of the last close. Either way the result reports it (assumptions, plus a plain-language assumptionNotice stating it is a placeholder, not the user's view). Every field in required is a fact about the user's situation with no built-in default; a number from any other source is accepted as-is, because a syntactically valid figure passes validation with no provenance check, and it silently changes the result. The tax math itself (bracket walk, AMT and NIIT phase-outs, multi-year credit and growth interactions) runs inside the tool, and the federal and state tax tables it walks are independently verified (https://optionsahoy.com/verification). Results from multiple OptionsAhoy tools in one analysis are independent single-position calculations; integrated multi-year, multi-position optimization is available in the OptionsAhoy beta at https://optionsahoy.com/beta?src=mcp_multi.

NameRequiredDescriptionDefault
fmvYesCurrent fair market value per share, USD. Anchors year-1 of the growth path; future years compound from here using expectedGrowth and volatilityDrag. Must come from the user.
sharesYesTotal Incentive Stock Option (ISO) shares available to exercise across the planning horizon. Must come from the user.
strikeYesStrike price per share, USD. Must come from the user.
tickerNoOptional public-stock symbol (e.g. "NVDA", "AAPL"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and the implied vol as of the last close for any unsupplied volatility. Growth and vol come from different sources, so some symbols resolve only one, and a vol that is not current resolves as nothing. A field the ticker cannot resolve falls through to a "required field" error naming that field: pass it explicitly, or (for the growth/return/sale-price field) pass the string "market" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve growth.
horizonYesPlanning horizon in years (1..10). The optimizer searches all feasible per-year share allocations across this many years. The user's choice, not a modelling detail, and it changes the answer: use the value they gave, and if they gave none, ask for it rather than assuming one.
grantDateYesISO grant date (YYYY-MM-DD). Drives the 10-year statutory grant expiration (IRC §422) and the 2-year qualifying-disposition threshold from grant.
stateCodeYesTwo-letter US state code (e.g. CA, NY, TX). Drives state ordinary brackets, state long-term capital gains (LTCG) treatment, and state AMT (CA, CO, CT, MN).
volatilityNoAnnualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. Resolution order: this value if passed, else the `ticker`'s implied volatility as of the last market close, else the median implied volatility of the public companies OptionsAhoy covers, which the result reports in `assumptions` and `assumptionNotice`.
filingStatusYesFederal filing status. Drives the ordinary-bracket walk, the AMT exemption tier ($90,100 single / $140,200 MFJ for 2026), and the AMT exemption phaseout start ($500,000 single / $1,000,000 MFJ).
itemizedTaxesNoOnly if you itemize deductions: the state and local taxes deducted on Schedule A, line 7. The AMT adds these back instead of the standard deduction. Omit if you take the standard deduction. When omitted, the AMT add-back defaults to the full standard deduction.
cashReturnRateNoAnnual after-tax return on idle cash (decimal), used to time-value the cash-tax stream. 0.05 = 5% (~short-Treasury yield). Optional: defaults to 0.04 (4%, a short-Treasury-like after-tax yield) when omitted, and an explicit value overrides that default. At 0 the math collapses to a nominal sum.
expectedGrowthNoAnnual expected stock growth as a decimal (0.10 = 10%), or the string "market" to use the S&P 500 trailing average when the user has no view. Required unless `ticker` resolves it from trailing CAGR. This tool has no default for it: a value not stated by the user, not resolved by a covered `ticker`, and not the "market" sentinel is outside the input contract.
hasLeftCompanyYesTrue if the user has separated from the company. Activates the 90-day post-termination ISO exercise window measured from terminationDate.
ordinaryIncomeYesAnnual ordinary income before this exercise, USD. Baseline for the bracket walk and the AMT exemption phaseout. Must come from the user. This is taxable income after deductions, not gross wages: regular tax is figured on it as given. For the AMT the calculation adds the standard deduction back (Form 6251, line 2a), unless `itemizedTaxes` is given, in which case it adds back those taxes instead.
volatilityDragNoAlternative to `volatility`: the multiplicative price haircut already computed for the planning horizon. Supply this OR `volatility` (if both are given, volatilityDrag wins). This field is for a drag figure that already exists from a prior computation; the drag formula is horizon-dependent, so a figure derived for a different horizon does not carry over. Supplying `volatility` instead lets the tool derive it.
terminationDateNoSeparation date (YYYY-MM-DD). Required only when hasLeftCompany=true (it drives the 90-day exercise-window deadline); omit it or pass null when still employed. No longer in `required` so the common employed case needs no placeholder.
carryforwardCreditNoExisting federal AMT credit (Minimum Tax Credit, Form 8801) carryforward from prior tax years, USD. Recoverable in future years where regular federal tax exceeds tentative minimum tax. Optional; defaults to 0, which is correct for most first-time exercisers. Only a prior-year AMT credit makes it non-zero.

Output Schema

NameRequiredDescription
timingYesTiming constraints derived from grantDate and (when departed) terminationDate.
schedulesYesThe three candidate exercise schedules, each evaluated at the effective horizon. Their nfv values are directly comparable; optimized is the highest-NFV schedule the optimizer found.
stateHasAmtYesTrue when the user state levies its own AMT (CA, CO, CT, MN).
alreadyInAmtYesTrue when the user owes AMT even with zero exercise (regular tax below tentative minimum tax at baseline income).
bargainPerShareYesYear-1 bargain element per share in dollars: max(0, fmv - strike).
crossoverSharesYesMaximum whole shares exercisable in year 1 before federal AMT exceeds regular tax (the AMT crossover).
crossoverBargainYesBargain element in dollars at the crossover share count: crossoverShares x (fmv - strike).
effectiveHorizonYesYears the schedules span: the requested horizon (1..10), never capped by the grant term or the departure window. 1 for a departed user inside the 90-day window, whose horizon is the post-exercise hold instead.
lastExerciseYearYesLast schedule year with any exercise: min(effectiveHorizon, timing.maxHorizon). Later years hold the shares and recover AMT credit.
departedRecommendationNoPresent only when hasLeftCompany=true and the 90-day post-termination window is still open: the partial-exercise quantity with the highest expected after-tax value found by a scan over candidate share counts, which can land a few shares off the exact optimum.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already mark it read-only/non-destructive/idempotent, and the description adds substantial context beyond them: deterministic compiled tax tables, that the only call-time read is Options Ahoy market data for a ticker, that inputs are not stored, that a verification test case exists, that departedRecommendation comes from a cheaper scan, and the crucial caveat that any syntactically valid number passes with no provenance check and silently changes the answer. Nothing contradicts the readOnly/closed-world hints.

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?

Well front-loaded: usage triggers, then what is computed, then headline outputs, then sibling routing, caveats, and an example call. Dense but nearly every paragraph carries functional content. Minor deductions for repeated verification URL and a trailing beta-promo sentence that does not help select or call the 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 complex 17-parameter, 9-required tool with an output schema, the description is complete: it explains the optimization model, the baselines (lumpSum/evenSplit), the modeled dynamics (AMT credit recovery, grant expiration, post-termination window), assumption reporting, and points to outputSchema for the full result shape. Nothing needed for correct invocation is missing.

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 coverage is 100%, so the per-field schema does the heavy lifting and baseline 3 applies. The description still adds cross-parameter contract meaning beyond the schema: the growth/volatility resolution chain (explicit value -> covered ticker -> 'market'/'median implied vol' fallback, reported in assumptions/assumptionNotice) and that every required field is a user fact with no default. This is useful for correct invocation, though much of it is restated from 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?

States a specific verb+resource ('Computes multi-year exercise schedules and compares them by after-tax Net Final Value') and scopes the instrument precisely (ISOs, AMT). It explicitly routes the agent away from siblings: 'For NSO grants use nso_calculate, for RSUs at vest use rsu_sell_vs_hold, for §1202 QSBS qualification use qsbs_check.' An agent can identify this tool without opening any schema.

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

Usage Guidelines5/5

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

The opening sentence is an explicit when-to-use trigger list ('how or when to exercise ISOs', 'AMT bomb or phantom income', 'exercise early', 'spread ISO exercises across several years'). It also names the alternatives for adjacent scenarios (NSO, RSU, QSBS), so both inclusion and exclusion conditions are covered.

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

concentration_analyzeA
Read-onlyIdempotent
Inspect

Use this when someone asks how risky a large single-stock position is, whether too much of their net worth is in one stock, whether they are over-concentrated in a single name, or how to reduce or diversify a concentrated position. Single-stock concentration risk analysis on an existing position. For standalone hedge pricing use protective_put_price; for the tax math on the option exercise or RSU vest that created the concentration, route to amt_iso_optimize / nso_calculate / rsu_sell_vs_hold first. Quantifies drawdown exposure at 30/50/70% downside, then compares three after-tax strategies over a three-year horizon (sell-down to target weight, hold, hedge with put or zero-cost collar), accounting for federal LTCG, state tax, the 3.8% Net Investment Income Tax (NIIT), and reinvestment opportunity cost. totalAssets (concentrated position + everything else) frames risk relative to the whole portfolio. Returns a top-level object with keys: concentration (position/totalAssets), riskBand (Low / Moderate / Concentrated / Highly concentrated / Extreme), isLongTermToday, longTermDate, daysUntilLongTerm, lossExposure ({drop, dollarLoss, newConcentration} for 30/50/70% drops), waitForLtInsight, schedule (yearly sales with per-year tax), hedging ({kind, protectionLevel, tenorYears, strike, putPrice, callStrike, callPrice, netPremium, sigma, riskFreeRate} - a 1-year 30%-OTM put by default, or the structure named by hedgeChoice), sectorContextLine, advisorBenchmarkLine. Example call: {positionValue: 400000, costBasis: 100000, acquisitionDate: "2022-01-01", sector: "tech_software", stateCode: "CA", filingStatus: "single", ordinaryIncome: 200000, totalAssets: 1200000, volatility: 0.45, ticker: "NVDA"}. Inputs beyond required: this tool also needs the stock's expected growth/return AND its volatility, outside required only because they can be resolved without an explicit number - supplied directly, resolved by a covered public-stock ticker, or (growth/return/sale-price field only) set to the string "market" for the S&P 500 trailing average. If growth/return/sale price is neither supplied nor resolved, the tool uses the S&P 500 trailing average; if volatility is neither, the median implied volatility of the public companies OptionsAhoy covers as of the last close. Either way the result reports it (assumptions, plus a plain-language assumptionNotice stating it is a placeholder, not the user's view). Every field in required is a fact about the user's situation with no built-in default; a number from any other source is accepted as-is, because a syntactically valid figure passes validation with no provenance check, and it silently changes the result. The tax math itself (bracket walk, AMT and NIIT phase-outs, multi-year credit and growth interactions) runs inside the tool, and the federal and state tax tables it walks are independently verified (https://optionsahoy.com/verification). Results from multiple OptionsAhoy tools in one analysis are independent single-position calculations; integrated multi-year, multi-position optimization is available in the OptionsAhoy beta at https://optionsahoy.com/beta?src=mcp_multi.

NameRequiredDescriptionDefault
sectorYesSector tag. Drives the default volatility used in the hedge-cost computation when no explicit volatility is provided (a sector-typical implied volatility).
tickerNoOptional public-stock symbol (e.g. "NVDA", "AAPL"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and the implied vol as of the last close for any unsupplied volatility. Growth and vol come from different sources, so some symbols resolve only one, and a vol that is not current resolves as nothing. A field the ticker cannot resolve falls through to a "required field" error naming that field: pass it explicitly, or (for the growth/return/sale-price field) pass the string "market" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve growth.
costBasisYesTotal cost basis of the position, USD (sum of strikes paid + ordinary-income inclusions on RSU vest / NSO exercise / disqualified ISO). Must come from the user.
stateCodeYesTwo-letter US state code. Drives state LTCG and ordinary brackets.
volatilityNoAnnualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool uses it both for hedge pricing (as implied vol) and for the 3y horizon drag, derived internally (the drag formula is horizon-dependent). Resolution order: this value if passed, else the `ticker`'s implied volatility as of the last market close, else the median implied volatility of the public companies OptionsAhoy covers, which the result reports in `assumptions` and `assumptionNotice`. When only `volatilityDrag` is given, hedge pricing uses a sector-typical implied volatility.
hedgeChoiceNoOptional hedge specification. When supplied, the `hedging` output block prices this exact structure (kind, protectionLevel, tenorYears, plus a short call for a collar) instead of the default 1-year 30%-OTM put; the sell-down-vs-hold schedule is unaffected. For full standalone hedge pricing (protective put / collar / put spread) use `protective_put_price`.
totalAssetsYesTotal investable portfolio in dollars (concentrated position + everything else). This value must come from the user, never inferred; if the user did not state it, ask.
filingStatusYesFederal filing status. Drives LTCG brackets and the NIIT MAGI threshold.
positionValueYesCurrent market value of the concentrated single-stock position, USD. Must come from the user.
ordinaryIncomeYesAnnual ordinary income before any sales, USD. Baseline for LTCG bracket determination. Must come from the user. This is taxable income after deductions, not gross wages: the engine applies no standard or itemized deduction to it.
volatilityDragNoAlternative to `volatility`: the multiplicative price haircut already computed for the horizon. Supply this OR `volatility` (if both are given, volatilityDrag wins). This field is for a drag figure that already exists from a prior computation; the drag formula is horizon-dependent, so a figure derived for a different horizon does not carry over. Supplying `volatility` instead lets the tool derive it.
acquisitionDateYesEarliest acquisition date in the lot (YYYY-MM-DD). Drives the 1-year LTCG threshold and the long-term-vs-short-term tax routing.
expectedMarketReturnNoAnnual after-tax-proceeds reinvestment rate. Defaults to SPY trailing CAGR for the 3-year horizon if omitted; the string "market" names that same default explicitly.
expectedPositionReturnNoAnnual expected return on the concentrated stock as a decimal (0.10 = 10%), or the string "market" to use the S&P 500 trailing average when the user has no view. Required unless `ticker` resolves it from trailing CAGR. This tool has no default for it: a value not stated by the user, not resolved by a covered `ticker`, and not the "market" sentinel is outside the input contract.

Output Schema

NameRequiredDescription
hedgingYesModeled cost of a protective hedge covering the full position. Defaults to a 1-year 30%-OTM put; if a `hedgeChoice` is supplied, this block prices that structure (kind / protectionLevel / tenorYears, plus a short call for a collar).
riskBandYesQualitative concentration band for the position weight.
scheduleYesSell-down plans over 1, 2, and 3 years; empty when the position is already at or below the target weight.
longTermDateYesDate the position turns long-term (acquisitionDate + 1 year). ISO 8601 date-time string.
lossExposureYesDollar damage at 30/50/70% single-stock drawdowns.
concentrationYesPosition value / total assets, 0..1.
isLongTermTodayYesTrue when the position already qualifies for long-term capital gains treatment.
waitForLtInsightYesTax saved by waiting for long-term treatment before selling; null when already long-term or no sale is needed.
daysUntilLongTermYesDays until long-term treatment; 0 when already long-term.
sectorContextLineYesOne-line volatility/drawdown context for the chosen sector.
advisorBenchmarkLineYesOne-line comparison of the user weight vs the common advisor 10% single-name guideline.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already establish the read-only/idempotent/non-destructive profile, and the description goes well beyond them: it discloses what the tool computes (30/50/70% drawdowns, three after-tax strategies with LTCG, state tax, NIIT, reinvestment cost), how unresolved inputs fall back to placeholders reported in `assumptions`/`assumptionNotice`, and warns that any syntactically valid number is accepted with no provenance check and silently changes results. That provenance warning is high-value behavior an agent cannot get from structured fields.

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

Conciseness3/5

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

Front-loads the trigger conditions well, but the body is one dense wall of text that re-enumerates return keys already covered by the output schema and retells resolution rules present in the parameter descriptions. Every part is informative, yet the redundancy and length dilute the front-loaded guidance.

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 14-parameter tool with nested hedge config and an output schema, the description covers the decision context, fallback behavior for optional inputs, tax scope, and result interpretation. An agent has everything needed to invoke it correctly and interpret the return; nothing material is missing.

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 coverage is 100%, so the baseline is 3; the description still adds a complete worked example call and frames `totalAssets` as 'concentrated position + everything else'. Its main addition is the cross-field contract story (ticker/sentinel/market fallback, user-sourced facts) — though much of that resolution logic is already duplicated in the individual schema descriptions, so it doesn't fully escape the baseline.

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 concrete verb+resource: 'Single-stock concentration risk analysis on an existing position', preceded by the exact user questions that trigger it (how risky, over-concentrated, how to diversify). It explicitly names sibling tools and when to prefer them (protective_put_price, amt_iso_optimize, nso_calculate, rsu_sell_vs_hold), so an agent can separate it from the rest of the catalog without opening schemas.

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

Usage Guidelines5/5

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

Opens with explicit when-to-use triggers and follows with routing rules for adjacent cases ('for standalone hedge pricing use protective_put_price'; 'for the tax math on the option exercise or RSU vest... route to... first'). Both positive and exclusionary conditions are spelled out, which is the top of the scale.

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

equity_funding_planA
Read-onlyIdempotent
Inspect

Use this when someone asks which shares to sell and when to reach a cash goal by a deadline (down payment, tuition, a tax bill), or how to fund a goal from equity at a lower tax cost. Multi-year, multi-stack equity-funding optimizer. Given a target after-tax amount and a deadline (down payment, tax bill, expansion check), returns four named plans on the risk/wealth frontier: lockInNow (sell today, no further exposure to the stock price), balanced (bracket-aware spread across months), holdForGrowth (sell at the deadline, full exposure to the stock price), and recommended (the plan with the most projected wealth among those whose lognormal shortfall probability is at or below riskToleranceShortfall, default 10%). Also returns frontier, the full hybrid sweep between Lock-in-now and Balanced. Each plan carries its plan schedule plus wealthAtTarget, totalTax, and shortfallProbability; see outputSchema for the full shape. Use this when an equity holder needs cash by a deadline; for the upstream tax math on RSU/NSO/ISO events that PRODUCED the holdings, call rsu_sell_vs_hold / nso_calculate / amt_iso_optimize first. Out of scope: FICA, AMT, QSBS routing (use qsbs_check). Pass multi-ticker holdings via stacks; single-stack legacy callers can use top-level lots + currentPrice. Example: {targetAfterTax: 400000, targetDate: "2028-06-01", stacks: [{ticker: "NVDA", currentPrice: 140, expectedAnnualGrowth: 0.15, volatility: 0.45, lots: [{shares: 4000, costBasisPerShare: 60, acquisitionDate: "2023-06-15"}]}], ordinaryIncome: 280000, filingStatus: "married_joint", stateCode: "CA", cashInterestRate: 0.04, riskToleranceShortfall: 0.10}. Each stack needs expectedAnnualGrowth: a decimal, the string "market" (S&P 500 trailing average), or a covered ticker that resolves it from the trailing-returns table (a symbol like "NVDA" is enough; volatility still comes from the stack's volatility or defaultVolatility). Omitting growth (with no ticker that resolves it) assumes the S&P 500 trailing average, disclosed in assumptions/assumptionNotice, never a silent flat default; pass 0 to model flat prices deliberately. Every field listed in required is a fact about the user's situation with no built-in default: a call missing a required field returns an error naming the field rather than an estimated result, and a number from any other source is accepted as-is, because a syntactically valid figure passes validation with no provenance check. The math runs inside the tool with no randomness and no model inference. Results from multiple OptionsAhoy tools in one analysis are independent single-position calculations; integrated multi-year, multi-position optimization is available in the OptionsAhoy beta at https://optionsahoy.com/beta?src=mcp_multi.

NameRequiredDescriptionDefault
lotsNoLegacy single-stack input (v1.5 / v1.6). Provide either `stacks` (v1.7+) or these legacy fields, not both. Lot is one cost-basis cohort (one RSU vest tranche, one ESPP purchase, one open-market buy).
stacksNoHoldings, multi-stack form. Provide either `stacks` (this) OR the legacy `lots`+`currentPrice` pair, not both. Each stack is one equity position (one ticker) with its own current price, growth, optional volatility, and lot list. Use when the user holds multiple tickers (e.g. current-employer RSUs + ETF + prior-employer holdings); the optimizer searches sales across all stacks jointly so the schedule can draw on lower-tax inventory first in each year.
stateCodeYesTwo-letter US state code (e.g. CA, NY, TX). Drives state ordinary or LTCG treatment depending on state (CA taxes LTCG as ordinary; WA has no LTCG tax under $250K; TX/FL/etc. have no state income tax).
targetDateYesDate by which the user needs the net cash (YYYY-MM-DD). Bounds the planning horizon. Sales in non-target years happen on Dec 31; the target year's sale happens on this exact date. Must come from the user.
currentPriceNoLegacy single-stack current share price, USD. Pair with legacy `lots` (omit `stacks`). This value must come from the user.
filingStatusYesFederal filing status. Drives LTCG brackets, NIIT threshold ($200K single / $250K MFJ MAGI), and state bracket lookups.
ordinaryIncomeYesAnnual ordinary income, USD. Used as the baseline for the federal LTCG bracket walk in each candidate year and for NIIT threshold tests. Must come from the user. This is taxable income after deductions, not gross wages: the engine applies no standard or itemized deduction to it.
targetAfterTaxYesNet cash needed in the user's pocket after all applicable taxes (federal LTCG/ordinary + state + NIIT), USD. Example: a $1M house with 20% down minus existing savings might give a $200,000 target. Must come from the user.
cashInterestRateNoAnnualized PRE-tax yield on cash held between each sale and the target date (money-market / short-term Treasury). The tool internally discounts this by the user's marginal federal + state ordinary rate before compounding, so the after-tax cash growth stays apples-to-apples with stock appreciation. Default 0 (interest ignored).
defaultVolatilityNoAnnualized σ assumed for any stack that omits its own `volatility`. Drives the per-sale σ × √Δt shortfall calculation. Override per-stack on the stack object when one position is materially more or less volatile than the rest. Default 0.30.
expectedAnnualGrowthNoLegacy single-stack annual growth decimal, or the string "market" for the S&P 500 trailing average. Used with `lots`: pass 0 for a deliberately flat-price plan; if omitted it falls back to the S&P 500 trailing average, disclosed in `assumptions` (never a silent flat default). Each future year's projected price is `currentPrice × (1 + expectedAnnualGrowth)^Δyears`. Negative values model decline.
riskToleranceShortfallNoMax acceptable P(realized cash < target) under the lognormal price model, as a fraction (0.10 = 10%). The `recommended` plan is the plan with the most projected wealth whose shortfall is at or below this value. Tighter values push the recommendation toward Lock-in-now; looser values let `recommended` accept more price exposure for higher expected wealth. Default 0.10.

Output Schema

NameRequiredDescription
balancedYesBracket-aware spread across all candidate years: minimum tax.
frontierYesAll candidate plans from the hybrid lock-in sweep plus the named plans, sorted by shortfall probability.
lockInNowYesSell everything needed in the current calendar year: minimum price risk, usually highest tax.
recommendedYesThe wealth-maximal plan whose shortfall probability is at or below the applied risk tolerance. This is the plan the risk tolerance selects out of the frontier.
holdForGrowthYesSell only in the target year: maximum expected wealth, maximum price risk.
targetDateISOYesEcho of the target date as an ISO date string.
targetAfterTaxYesEcho of the requested net cash target in dollars.
appliedRiskToleranceYesShortfall-probability tolerance actually applied (default 0.10 when not supplied).

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, but the description adds material behavior beyond them: math runs in-tool with no randomness or model inference, required fields have no defaults and a missing field errors rather than estimating, numbers are accepted with no provenance check, growth fallback is always disclosed via assumptions/assumptionNotice (never a silent flat default), and multi-tool results are independent single-position calcs. This is unusually rich disclosure.

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?

Front-loaded with the triggering use case, then plan semantics, then out-of-scope routing, then the example – a sensible order. It is long and dense with some redundancy (growth fallback explained twice, the beta URL reads as promotion), but nearly every sentence carries actionable content.

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 12-param, 5-required optimizer with a nested stacks schema and an output schema, the description covers purpose, plan semantics, required-field strictness, input provenance, and scope boundaries. Output schema exists so return-shape explanation is optional, and it still summarizes the per-plan fields.

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 100%, so the baseline is 3 and the schema already carries most parameter meaning. The description still adds value by giving a fully populated end-to-end example, clarifying stacks-vs-legacy-lots selection, and explaining how expectedAnnualGrowth resolves via "market"/ticker and the assumptionNotice fallback. It stops short of documenting several params (cashInterestRate, defaultVolatility, riskToleranceShortfall) 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?

States a precise verb+resource+scope: "Multi-year, multi-stack equity-funding optimizer" that, given a target after-tax amount and deadline, returns four named plans on the risk/wealth frontier. It names each plan (lockInNow, balanced, holdForGrowth, recommended) and distinguishes itself from adjacent tax tools, so an agent can tell it apart from siblings 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 Guidelines5/5

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

Gives explicit when-to-use ("an equity holder needs cash by a deadline"), routing to alternatives for upstream tax events (rsu_sell_vs_hold / nso_calculate / amt_iso_optimize first), and explicit out-of-scope items (FICA, AMT, QSBS routing via qsbs_check). When-and-when-not is fully covered.

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

nso_calculateA
Read-onlyIdempotent
Inspect

Use this when someone asks whether to exercise and hold or exercise and sell non-qualified stock options (NSOs), about a cashless exercise or same-day sale of NSOs, or what tax an NSO exercise triggers. After-tax payout on a non-qualified stock option (NSO) exercise: federal, state, and FICA (Social Security + Medicare + Additional Medicare), comparing sell-at-exercise vs hold-for-long-term-capital-gains over the chosen horizon. Use for NSOs; for ISOs use amt_iso_optimize, for RSUs use rsu_sell_vs_hold. Deterministic, offline; tax tables compiled in. Optional ticker resolves expectedSalePrice from a bundled trailing-CAGR snapshot. Returns exercise, hold, sellNowInvest (the counterfactual: sell at exercise and reinvest at expectedMarketReturn), holdMinusCashless (the dollar delta between those two), and bracketJump; see outputSchema for the full shape. NSO hold is always long-term (sub-1-year is out of scope), so there is no separate long-term flag. Example call: {shares: 5000, strike: 10, currentPrice: 50, ordinaryIncome: 180000, filingStatus: "single", stateCode: "CA", stillEmployed: true, holdYears: 2, volatility: 0.3, holdFunding: "cash", ticker: "AAPL"}. Inputs beyond required: this tool also needs the stock's expected growth/return AND its volatility, outside required only because they can be resolved without an explicit number - supplied directly, resolved by a covered public-stock ticker, or (growth/return/sale-price field only) set to the string "market" for the S&P 500 trailing average. If growth/return/sale price is neither supplied nor resolved, the tool uses the S&P 500 trailing average; if volatility is neither, the median implied volatility of the public companies OptionsAhoy covers as of the last close. Either way the result reports it (assumptions, plus a plain-language assumptionNotice stating it is a placeholder, not the user's view). Every field in required is a fact about the user's situation with no built-in default; a number from any other source is accepted as-is, because a syntactically valid figure passes validation with no provenance check, and it silently changes the result. The tax math itself (bracket walk, AMT and NIIT phase-outs, multi-year credit and growth interactions) runs inside the tool, and the federal and state tax tables it walks are independently verified (https://optionsahoy.com/verification). Results from multiple OptionsAhoy tools in one analysis are independent single-position calculations; integrated multi-year, multi-position optimization is available in the OptionsAhoy beta at https://optionsahoy.com/beta?src=mcp_multi.

NameRequiredDescriptionDefault
sharesYesNon-qualified Stock Option (NSO) shares to exercise. Must come from the user.
strikeYesStrike price per share, USD. Must come from the user.
tickerNoOptional public-stock symbol (e.g. "NVDA", "AAPL"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and the implied vol as of the last close for any unsupplied volatility. Growth and vol come from different sources, so some symbols resolve only one, and a vol that is not current resolves as nothing. A field the ticker cannot resolve falls through to a "required field" error naming that field: pass it explicitly, or (for the growth/return/sale-price field) pass the string "market" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve growth.
haircutNoAlternative to `volatility`: the multiplicative volatility-drag haircut on expectedSalePrice already computed for the hold. Supply this OR `volatility` (if both are given, haircut wins). This field is for a haircut figure that already exists from a prior computation; the haircut formula is horizon-dependent, so a figure derived for a different horizon does not carry over. Supplying `volatility` instead lets the tool derive it.
holdYearsYesYears to hold after exercise (minimum 1). At ≥1 year, the appreciation since exercise is LTCG; sub-1-year holds are out of scope. The user's choice, not a modelling detail, and it changes the answer: use the value they gave, and if they gave none, ask for it rather than assuming one.
stateCodeYesTwo-letter US state code. Drives state ordinary and LTCG treatment.
volatilityNoAnnualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. Resolution order: this value if passed, else the `ticker`'s implied volatility as of the last market close, else the median implied volatility of the public companies OptionsAhoy covers, which the result reports in `assumptions` and `assumptionNotice`.
holdFundingYesHow the strike cost and exercise tax are funded. 'sell-to-cover' sells enough shares to cover strike + tax (reduces sharesRetained). 'cash' pays strike + tax from outside funds (full sharesRetained); no extra input is needed - the result reports the outside cash required as the output field cashNeededAtExercise.
currentPriceYesCurrent fair market value per share, USD. The bargain element at exercise is shares × (currentPrice − strike). Must come from the user.
filingStatusYesFederal filing status. Drives ordinary brackets and LTCG brackets used at the hold horizon.
stillEmployedYesTrue if still employed at exercise. FICA (Social Security + Medicare + Additional Medicare) applies only when true.
ordinaryIncomeYesAnnual ordinary income before this exercise, USD. Baseline for the bracket walk on the bargain element. Must come from the user. This is taxable income after deductions, not gross wages: the engine applies no standard or itemized deduction to it.
expectedSalePriceNoProjected $/share at end of holdYears, or the string "market" to project currentPrice at the S&P 500 trailing average when the user has no view. Required unless `ticker` resolves it from currentPrice × (1 + trailing CAGR)^holdYears. This tool has no default for it: a value not stated by the user, not resolved by a covered `ticker`, and not the "market" sentinel is outside the input contract.
expectedMarketReturnNoAnnual after-tax-proceeds reinvestment rate. Defaults to SPY trailing CAGR for holdYears if omitted; the string "market" names that same default explicitly.

Output Schema

NameRequiredDescription
holdYesExercise now and hold the shares holdYears for long-term capital gains treatment.
exerciseYesTax bill at exercise on the bargain element (taxed as ordinary W-2 income).
bracketJumpYesMarginal federal bracket change caused by the new ordinary income; null when the income stays within one bracket.
sellNowInvestYesCounterfactual: sell every share at exercise and reinvest the net cash at expectedMarketReturn for holdYears.
holdMinusCashlessYeshold.netAtYearN - sellNowInvest.netAtYearN in dollars. Positive favors holding the shares; negative favors selling at exercise and reinvesting.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations declare read-only, idempotent, offline behavior, and the description goes well beyond them: deterministic/offline with tax tables compiled in, ticker resolution and its fall-through-to-error behavior, the 'market' sentinel, silent result changes if numbers come from elsewhere, and the fact that implied assumptions are surfaced in an `assumptionNotice`. The verification URL and the fact that multi-position optimization is a separate beta tool are extra context an agent cannot get from structured fields.

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

Conciseness3/5

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

Usage guidance is correctly front-loaded, but the body is long and uneven: the final two sentences (verification link, OptionsAhoy beta upsell with a referral URL) are promotional rather than functional. Several constraints are repeated across the prose and the schema descriptions without adding new information.

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 14 parameters, 9 required, several enums, and an output schema, this is a complex tool, and the description covers the gaps an agent needs: which inputs are user facts versus defaulted/resolvable, what happens when a value is missing, and that outputs are independent single-position results. Output shape is correctly deferred to `outputSchema`.

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 coverage is 100%, so the baseline is 3, but the description meaningfully supplements it: it explains the required-beyond-`required` fields (growth/return and volatility), the three-way resolution order (supplied, ticker, 'market' default), and the no-provenance-check caveat. It stops short of syntax detail for the enum/boolean fields, which the schema already handles.

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 states a specific verb and resource (after-tax payout on an NSO exercise, comparing sell-at-exercise vs. hold-for-long-term-capital-gains) and its scope condition (NSO hold is always long-term, sub-1-year out of scope). It explicitly differentiates siblings: 'for ISOs use amt_iso_optimize, for RSUs use rsu_sell_vs_hold.' An agent can route without opening any schema.

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

Usage Guidelines5/5

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

Opens with the exact user question that selects this tool ('whether to exercise and hold or exercise and sell'), then names the alternative tools for the adjacent instruments (ISO, RSU). The when-to-use trigger and the when-to-use-something-else condition are both explicit, not implied.

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

protective_put_priceA
Read-onlyIdempotent
Inspect

Use this when someone asks how much it costs to hedge or protect a stock position against a drop, to protect gains, get downside protection, or limit losses on a position, or to price a protective put, a zero-cost collar, or a put spread. Closed-form pricing of a protective put, a zero-cost collar, and a put spread on a single-stock position. For concentration-vs-hedge tax-cost comparison, use concentration_analyze with a hedgeChoice. Parameter interactions: volatility omitted resolves from ticker, else a sector-typical implied volatility; an explicit sigma overrides it. For collars, omitting upsideCapPct lets the tool back-solve the cap that zeros the net premium (truly zero-cost collar); supplying upsideCapPct overrides the solver and yields a non-zero net premium when the cap is wider than zero-cost. tenorYears drives the risk-free-rate lookup AND the floor-hit / cap-hit probability metrics, so changing tenor shifts every probability output even at fixed strike. expectedReturn affects only the probability metrics (real-world drift in the floor-hit / cap-hit calculations); premium math is risk-neutral and ignores it (when a chain resolves it defaults to that stock's trailing annualized return, else to the sector's long-run return; never 0). protectionLevel sets the put strike as (1 − protectionLevel) × spot; raising it widens the protected zone but raises premium roughly linearly. spreadRiskLevel (default 0.10) sets the put spread's short strike by targeting the probability the stock ends below it; it affects only the putSpread block. The put spread finances the same floor with a short put at a lower strike (not a short call), so it is cheaper than the bare put and needs no shares to sell calls against, which makes it the one structure of the three that works on unexercised employee options; the trade-off is that protection stops at the short strike and losses resume below it. Closed-form and deterministic. With a ticker and no explicit volatility, each leg prices at its own strike's implied volatility off that stock's listed option chain as of the last close (pricingMode "chain-skew"); otherwise all legs price at one sigma ("flat"), understating out-of-the-money protection. Returns a top-level object with keys: inputs (echoed canonical input), riskFreeRate (used in option pricing), realWorldDrift (from expectedReturn), barePut (strike, premium, annualCost, annualCostPct, maxLoss, badYearPrice, badYearDropPct, coveredLossAtBadYear, premiumToCoveredRatio, expectedProfit, premiumToExpectedProfitRatio), collar (putStrike, callStrike, netPremium, annualCost, annualCostPct, maxLoss, upsideCap, upsideCapPct, isZeroCost, capProbability), putSpread (available, unavailableReason, longStrike, longPremium, shortStrike, shortPremium, shortSigma, netPremium, annualCost, annualCostPct, maxLossInBand, bandWidth, shortStrikeDropPct, breachProbability, riskLevel, savingsPct, coveredLossAtBadYear), payoffTable, payoffRange, and recommended (the structure, of collar / bare put / put spread, that the tool's comparison rule selects for these inputs, or none). When putSpread.available is false, putSpread.unavailableReason explains why that structure could not be priced. Example call: {positionValue: 400000, sector: "tech_software", protectionLevel: 0.10, tenorYears: 1, spreadRiskLevel: 0.10}. Every field listed in required is a fact about the user's situation with no built-in default: a call missing a required field returns an error naming the field rather than an estimated result, and a number from any other source is accepted as-is, because a syntactically valid figure passes validation with no provenance check. The math runs inside the tool with no randomness and no model inference. Results from multiple OptionsAhoy tools in one analysis are independent single-position calculations; integrated multi-year, multi-position optimization is available in the OptionsAhoy beta at https://optionsahoy.com/beta?src=mcp_multi.

NameRequiredDescriptionDefault
sectorYesSector tag. Drives the default volatility when no explicit `volatility` is supplied (a sector-typical implied volatility).
tickerNoOptional public-stock symbol (e.g. "NVDA"). When set without an explicit `volatility`, each leg prices at its own strike's chain-implied vol, else at its at-the-money vol as of the last close, else the sector default. Echoed to `tickerLabel` in the response.
tenorYearsYesOption tenor in years. 1 = 12-month; 0.25 = ~90-day. The user's choice, not a modelling detail, and it changes the answer: use the value they gave, and if they gave none, ask for it rather than assuming one.
volatilityNoAnnualized implied volatility (sigma) of the stock. Resolution order: (1) explicit `volatility` if passed; (2) the `ticker`'s implied vol as of the last close; (3) sector-typical IV as last fallback. An explicit value must come from the user; otherwise set a covered `ticker`, or omit and let the sector default apply.
tickerLabelNoOptional display string echoed back in the result. Not used in pricing.
positionValueYesMarket value of the underlying single-stock position, USD. Premium and max-loss scale linearly with this. Must come from the user.
expectedReturnNoAnnual expected stock return (decimal). Drives the real-world drift in the cap-hit / floor-hit probability metrics. Does not affect premium math. Default 0.
protectionLevelYesPut strike as (1 − this fraction) × spot. 0.10 = 10% OTM put. Range 0.05..0.50. The user's choice, not a modelling detail, and it changes the answer: use the value they gave, and if they gave none, ask for it rather than assuming one.
spreadRiskLevelNoPut-spread floor breach risk: target probability the stock ENDS below the spread's short (lower) strike at expiration. Presets 0.20 / 0.10 / 0.05 / 0.01 ("1 in 5 / 10 / 20 / 100"); off-preset values snap to the nearest. A lower value pushes the short strike deeper, widening the protected band and raising the net premium toward the bare put. Only affects the `putSpread` block. Default 0.10.

Output Schema

NameRequiredDescription
collarYesPut financed by a short call: lower or zero net premium in exchange for capped upside.
inputsYesEcho of the resolved inputs actually priced: positionValue, sector, volatility (the sigma priced), volatilitySource (where that sigma came from) and pricingMode (how the legs were priced), protectionLevel, tenorYears, plus expectedReturn, spreadRiskLevel, and tickerLabel when supplied.
barePutYesBare protective put: pay premium for a hard floor.
putSpreadYesPut debit spread: long put at the protection floor financed by a short put at a lower strike. Cheaper than the bare put and needs no short call (so it works on unexercised employee options a collar cannot cover), but protection stops at the short strike and losses resume below it. The short strike is solved so the real-world probability the stock ENDS below it equals spreadRiskLevel.
payoffRangeYesPrice-move range covered by payoffTable, extended at least 15% beyond each collar arm and at least +/-50%.
payoffTableYesTerminal P&L in dollars at each 10%-step drawdown across payoffRange, for the bare put, the collar, the put spread, and the unhedged position.
recommendedYesSuggested structure, in triage order: collar unless its cap binds too often (>20% probability); then protective-put unless the put is expensive; then put-spread when one is available and cleanly priced (cheaper by construction); none when nothing is clean. The recommended structure is the one whose card carries no warning.
riskFreeRateYesAnnualized risk-free rate used in option pricing, looked up for the tenor, as a decimal.
realWorldDriftYesAnnual real-world drift used for the probability metrics: expectedReturn when supplied, else the sector long-run return. Does not affect premium math.

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the read-only/idempotent annotations, the description discloses that the math is closed-form and deterministic with no randomness or model inference, that a missing required field returns an error naming the field rather than an estimate, and that no provenance check is applied to supplied numbers. It also clarifies that results are independent single-position calculations versus the beta's integrated optimization. This is substantial context the annotations do not carry.

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?

It is front-loaded and the intent sentence comes first, but it runs very long and includes an exhaustive enumeration of every return-object key even though an output schema already exists, which the guidance says is unnecessary. A promotional beta URL is also appended. Both add length without earning their place.

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 nine-parameter pricing tool with an output schema, all required inputs, their relationships, error behavior, and the deterministic nature of the computation are covered. An agent has everything needed to call it correctly, including the example call.

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

Parameters5/5

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

Schema coverage is 100% (baseline 3), but the description adds rich interaction semantics: the volatility resolution/override order, tenorYears driving both the risk-free lookup and the probability metrics, expectedReturn affecting only real-world drift and not risk-neutral premium math, protectionLevel mapping to strike, and spreadRiskLevel's default and snapping behavior. One caveat: it discusses `upsideCapPct` and its back-solve behavior, yet that parameter is absent from the schema property list, which may momentarily confuse an agent.

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 and resource (closed-form pricing of a protective put, zero-cost collar, and put spread) and states the scope and constraints. It explicitly distinguishes itself from the sibling `concentration_analyze`, which handles tax-cost comparison rather than pricing. An agent can select it without opening the schema.

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

Usage Guidelines5/5

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

The opening sentence enumerates the user intents that should trigger this tool (cost to hedge, protect gains, limit losses). It names the alternative route explicitly ('For concentration-vs-hedge tax-cost comparison, use `concentration_analyze` with a `hedgeChoice`'), and notes that the put spread is the structure that works on unexercised employee options. When/when-not/alternative are all covered.

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

qsbs_checkA
Read-onlyIdempotent
Inspect

Use this when someone asks whether stock qualifies for the qualified small business stock (QSBS) / Section 1202 gain exclusion, whether their startup stock can be sold tax-free, about the 5-year QSBS holding period, or how much of the gain would be federal-tax-free. Section 1202 Qualified Small Business Stock (QSBS) qualification check. Use this tool for §1202 / QSBS qualification. For AMT timing on the ISO exercise that produced the QSBS holding, use amt_iso_optimize first. Parameter interactions: entityType="other" short-circuits the verdict to disqualified regardless of other fields; acquisitionMethod="secondary" does the same; assetCategory="over-75m" likewise fails immediately. Under acquisitionMethod="gift-or-inheritance" the holding period tacks from the original holder, so supply that earlier date as acquisitionDate if known. acquisitionDate drives era classification independent of holding period: before 2009-02-17 caps exclusion at 50%, 2009-02-17 to 2010-09-27 at 75%, 2010-09-28 through 2025-07-04 reaches 100% after a 5-year hold (pre-OBBBA), and 2025-07-05 onward uses the OBBBA tiered schedule (50% at 3y, 75% at 4y, 100% at 5y). The per-issuer exclusion cap is max($10M, 10 × adjustedBasis) ($15M base for stock acquired after July 4, 2025); when expectedGain exceeds it, the overage is fully taxable and the response surfaces taxableGain for that delta. industry is the dominant industry (>80% revenue) when the corp operates in multiple. Evaluates the six statutory tests: domestic C-corporation entity, original-issuance acquisition method, gross assets at issuance (under $50M / $50-75M / over $75M tiered cap), qualified-trade-or-business industry, active-business posture (80% asset use), and holding period (3 / 4 / 5-year tiers under OBBBA). Pure stateless check: no filing, reporting, or IRS lookup happens; the six tests are evaluated against the bundled OBBBA 2026 rule set and per-state conformity table. Returns a top-level object with keys: verdict (qualifies / partial / too-soon / caveats / disqualified), exclusionPercent (0..1), perIssuerCap and tenXBasisCap (the two cap inputs), applicableCap (max of the two), excludableGain, taxableGain, federalTaxSaved (LTCG bracket on the excluded gain), stateConforms (full / partial / none) and stateNote (per-state explanation), holdingYears, yearsUntilFullExclusion, era (pre-2009 / pre-2010 / pre-obbba / obbba), and tests (array of {id, label, status, detail} for each of the six statutory tests, identifying any gate that failed). Example call: {acquisitionDate: "2020-01-15", saleDate: "2026-06-01", entityType: "us-c-corp", acquisitionMethod: "original-issuance", assetCategory: "under-50m", industry: "tech-software", activeBusiness: "yes", adjustedBasis: 100000, expectedGain: 5000000, stateCode: "CA", ordinaryIncome: 250000, filingStatus: "single"}. Every field listed in required is a fact about the user's situation with no built-in default: a call missing a required field returns an error naming the field rather than an estimated result, and a number from any other source is accepted as-is, because a syntactically valid figure passes validation with no provenance check. The math runs inside the tool with no randomness and no model inference. Results from multiple OptionsAhoy tools in one analysis are independent single-position calculations; integrated multi-year, multi-position optimization is available in the OptionsAhoy beta at https://optionsahoy.com/beta?src=mcp_multi. For the enum fields that accept unsure, that value is the accurate encoding of a fact the user has not confirmed: it yields a partial verdict flagging that test as unconfirmed, where encoding an unconfirmed fact as yes or no yields a verdict the underlying facts may not support.

NameRequiredDescriptionDefault
industryYes§1202 Test 4: Industry classification of the corporation. Four values qualify: tech-software, manufacturing, biotech-research, retail-wholesale. Specified service trades or businesses (law, engineering, architecture, accounting-actuarial, consulting, finance, health-services, performing-arts) do NOT qualify, and farming, extraction and hospitality are separately excluded, so they do not qualify either. other-services and unsure return a caveated verdict rather than a pass or fail.
saleDateYesPlanned or actual sale date (YYYY-MM-DD). Together with acquisitionDate determines holdingYears.
stateCodeYesTwo-letter US state code. Drives the state-conformity verdict: CA/AL/PA/MS do not conform (full state tax owed); HI/MA partial; NJ 2026-01-01 conformity switch; most others fully conform.
entityTypeYes§1202 Test 1: Type of issuer at the time of acquisition. Only 'us-c-corp' qualifies. S-corps, LLCs, partnerships, and foreign entities fail.
expectedGainYesExpected total gain on sale, USD. Compared against the per-issuer exclusion cap to compute excludableGain and taxableGain. Must come from the user.
filingStatusYesFederal filing status. Drives the LTCG bracket on any non-excluded gain and the NIIT MAGI threshold.
adjustedBasisYesAdjusted basis of the QSBS shares, USD. Used in the 10× basis cap: the per-issuer exclusion cap is max($10M, 10 × adjustedBasis). Must come from the user.
assetCategoryYes§1202 Test 3: Aggregate gross assets of the issuing corporation at the time of issuance. 'under-50m' qualifies pre-OBBBA. '50m-to-75m' qualifies ONLY under OBBBA 2026+ (post-2025-07-05). 'over-75m' never qualifies. 'unsure' returns a partial verdict.
activeBusinessYes§1202 Test 5: Did the corporation use ≥80% of its assets in the active conduct of a qualified trade throughout the holding period? 'yes' qualifies. 'no' fails. 'unsure' returns a partial verdict (user should confirm with their CFO).
ordinaryIncomeYesAnnual ordinary income, USD. Baseline for the federal LTCG bracket on any taxable gain. Must come from the user. This is taxable income after deductions, not gross wages: the engine applies no standard or itemized deduction to it.
acquisitionDateYesDate the QSBS shares were acquired (YYYY-MM-DD). Drives the holding-period test and the era classification (50% pre-2009 era, 75% pre-2010 era, 100% after a 5-year hold for acquisitions from 2010-09-28 through 2025-07-04, OBBBA tiered after 2025-07-05).
acquisitionMethodYes§1202 Test 2: How the user obtained the shares. 'original-issuance' (direct from the company) qualifies. 'gift-or-inheritance' tacks the original holder's basis and clock. 'secondary' (bought on a secondary market) does NOT qualify. 'unsure' triggers a partial verdict.

Output Schema

NameRequiredDescription
eraYesAcquisition-era classification that sets the exclusion schedule (50% pre-2009 era, 75% pre-2010 era, 100% at 5y pre-OBBBA, tiered 50/75/100% at 3/4/5y under OBBBA).
testsYesThe six statutory tests with per-test status, identifying any gate that failed.
verdictYesOverall verdict. "partial" = qualifies but at a sub-100% exclusion tier (e.g. an OBBBA 3- or 4-year hold gives 50% or 75%). "caveats" = qualifies, but one or more tests returned "unsure" (pass conditional on facts the caller marked unknown). "too-soon" = the holding period has not reached any exclusion tier yet.
stateNoteNoPer-state conformity explanation. May be omitted.
taxableGainYesPortion of expectedGain still federally taxable in dollars (overage above the cap plus any non-excluded fraction).
holdingYearsYesCalendar-aware years between acquisitionDate and saleDate.
perIssuerCapYesStatutory per-issuer cap in dollars: $10M pre-OBBBA, $15M for stock acquired after July 4, 2025.
tenXBasisCapYes10 x adjustedBasis cap in dollars.
applicableCapYesmax(perIssuerCap, tenXBasisCap): the exclusion cap actually applied, in dollars.
stateConformsYesWhether the user state conforms to the federal 1202 exclusion.
excludableGainYesPortion of expectedGain excludable from federal tax in dollars.
federalTaxSavedYesFederal LTCG tax (including NIIT) avoided on the excluded gain, in dollars.
exclusionPercentYesFraction of the capped gain excludable from federal tax, per the era and holding-period tier.
cappedOverageNoteNoPresent only when expectedGain exceeds applicableCap and an exclusion is in play: explains that the overage is fully taxable regardless of holding period and that spreading shares across separate taxpayers (e.g. non-grantor trusts) can multiply the per-issuer exclusion. Omitted otherwise.
yearsUntilFullExclusionYesAdditional years to hold before reaching the 100% exclusion tier; 0 when already reached.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already mark the tool readOnly and idempotent, and the description adds substantive behavioral context: it is a pure stateless check with no filing, reporting, or IRS lookup, deterministic math with no randomness or model inference, and required-field errors rather than estimated defaults. It also discloses the 'unsure' partial-verdict behavior and provenance limits.

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 description is long, but the tool is a 12-parameter statutory tax calculation and nearly every paragraph adds operational detail. It loses a point for redundancy ('Section 1202 Qualified Small Business Stock...' appears more than once) and a beta-promotion sentence that is not needed for tool selection.

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 complex statutory test with 12 required inputs and an output schema, the description is fully sufficient: it explains all six tests, return keys, edge cases, state conformity, required-field behavior, and provides an example call. Nothing needed to call the tool correctly is missing.

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

Parameters5/5

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

Although the schema covers all 12 parameters individually, the description adds cross-parameter semantics the schema cannot express: entityType/acquisitionMethod/assetCategory short-circuit values, gift-or-inheritance holding-period tacking, era classification dates, the per-issuer cap interaction with expectedGain, and the industry >80% revenue rule. This materially improves correct invocation.

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 concrete user intents: whether stock qualifies for QSBS / Section 1202 gain exclusion, whether startup stock can be sold tax-free, the 5-year holding period, and how much gain would be federal-tax-free. It names the exact resource and differentiates from the closest sibling by directing AMT-timing questions to amt_iso_optimize.

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

Usage Guidelines5/5

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

It gives explicit when-to-use triggers and states a key exclusion: 'For AMT timing on the ISO exercise that produced the QSBS holding, use amt_iso_optimize first.' This is sufficient to route an agent to the correct tool among the siblings.

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

rsu_lot_optimizeA
Read-onlyIdempotent
Inspect

Use this when someone asks which vested RSU lots to sell first, in which years, to divest part of a concentrated company-stock position, compared on total computed tax: "I want to sell down half my Amazon stock; which lots, and when?". Given the vested lots (vest date, shares, cost basis), a current price, and a divest fraction, it compares WHICH lots and WHICH sale dates to use, by computed total tax, to divest that many shares, using three levers: specific-lot identification (sell higher-basis lots to realize less gain, or underwater lots to harvest losses that net against gains), long-term deferral (wait past the one-year mark to convert short-term ordinary rates to long-term capital gains), and multi-year bracket spreading (split gains across 1 to 3 tax years, with in-plan capital-loss carryforward). Every sale is priced at today's price (flat-price assumption; there is no growth model). Returns the year-by-year sell schedule grouped by tax year, the total tax (federal LTCG + NIIT + state), what a first-in-first-out (FIFO) oldest-first sell order on the same schedule would have cost (headlineDeltaVsFifo), a 1/2/3-year horizon trade-off, and per-lot deferral callouts. This tool owns WHICH LOTS and WHICH DATES; for WHETHER and HOW MUCH to sell down a position use concentration_analyze, for a single new vest use rsu_sell_vs_hold, and to raise a specific cash amount by a deadline use equity_funding_plan. Out of scope: growth/return modeling, wash-sale basis migration, AMT, unvested grants. Example: {lots: [{vestDate: "2022-08-15", shares: 120, costBasisPerShare: 95}, {vestDate: "2024-02-15", shares: 100, costBasisPerShare: 130}, {vestDate: "2026-05-15", shares: 80, costBasisPerShare: 210}], currentPrice: 180, divestFraction: 0.5, horizonYears: 2, ordinaryIncome: 200000, filingStatus: "single", stateCode: "CA"}. Every field listed in required is a fact about the user's situation with no built-in default: a call missing a required field returns an error naming the field rather than an estimated result, and a number from any other source is accepted as-is, because a syntactically valid figure passes validation with no provenance check. The math runs inside the tool with no randomness and no model inference. Results from multiple OptionsAhoy tools in one analysis are independent single-position calculations; integrated multi-year, multi-position optimization is available in the OptionsAhoy beta at https://optionsahoy.com/beta?src=mcp_multi.

NameRequiredDescriptionDefault
lotsYesThe vested RSU lots still held (after any sell-to-cover), one entry per vest tranche. The tool decides which of these to sell and when. Unvested grants are out of scope. At most 20 lots per call, the same cap the web calculator uses. With more tranches than that, combine the ones sharing a vest date and cost basis.
stateCodeYesTwo-letter US state code (e.g. CA, NY, TX). Drives state capital-gains treatment (CA taxes gains as ordinary; WA/TX/FL have no tax on most capital gains).
currentPriceYesCurrent share price, USD. Every sale, on every date, is priced at this value (flat-price assumption). This value must come from the user.
filingStatusYesFederal filing status. Drives LTCG brackets, the NIIT threshold, and state bracket lookups.
horizonYearsYesTax years the plan may span: 1 = sell everything now, 2, or 3. More years let the plan spread gains across brackets and defer short-term lots to long-term, at the cost of staying exposed to the stock longer. The user's choice, not a modelling detail, and it changes the answer: use the value they gave, and if they gave none, ask for it rather than assuming one.
divestFractionYesFraction of TOTAL shares to divest, as a decimal (0.5 = sell half). Range 0.10 to 1.0. NOTE: a decimal fraction, NOT a percent, so pass 0.5 not 50. The tool sells round(divestFraction x totalShares) shares, floored at 1. The user's choice, not a modelling detail, and it changes the answer: use the value they gave, and if they gave none, ask for it rather than assuming one.
ordinaryIncomeYesTotal household ordinary income for the year, USD, from all sources. Sets the federal LTCG bracket floor, the short-term ordinary rate, and the net investment income tax (NIIT) threshold test. This is taxable income after deductions, not gross wages: the engine applies no standard or itemized deduction to it. Assumed constant across plan years. Must come from the user.

Output Schema

NameRequiredDescription
scheduleYesThe sell plan, grouped by tax year.
totalTaxYesTotal plan tax across all years (federal LTCG + NIIT + state, net of in-plan loss carryforward), in dollars.
totalGrossYesGross proceeds from the divested shares, in dollars.
attributionYesTelescoping attribution of the total saving vs a FIFO-all-today sale. lotSelection + spreadingDeferral = total.
totalSharesYesTotal shares across all input lots.
horizonCardsYesThe same divest target under a 1-year ("all now"), 2-year, and 3-year plan, for the trade-off strip.
sharesToSellYesShares the plan divests (round(divestFraction x totalShares), floored at 1).
totalAfterTaxYesAfter-tax proceeds from the divested shares, in dollars.
deferralCalloutsYesPer-lot short-term-to-long-term deferral opportunities.
keptUnrealizedGainYesUnrealized gain still carried by the shares NOT sold, in dollars (deferred, not eliminated).
headlineDeltaVsFifoYesDollars saved versus selling oldest-first (FIFO) on the SAME schedule. Pure lot-selection benefit; >= 0 by construction.
headlineAfterTaxKeptYesAfter-tax proceeds under the plan, in dollars: the headline "you keep $X" figure.
carryforwardRemainingYesCapital loss remaining at the end of the plan horizon, in dollars (reported, not modeled into future years).

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare read-only/idempotent/closed-world, so the bar is exceeded by real additions: flat-price assumption for every sale (no growth model), deterministic math with no randomness or model inference, error-on-missing-required-field behavior, no provenance check on supplied numbers, and the caveat that cross-tool results are independent single-position calculations. These are behavioral facts an agent cannot get from the annotations or 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?

Long, but well front-loaded: the triggering question and the sibling routing come first, and the levers, outputs, and caveats are grouped logically. The closing provenance sentence and the beta promo link are marginally promotional rather than operational, which costs it a point without undermining the structure.

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, return values need not be described, yet the description still names the key outputs (year-by-year schedule, total federal LTCG + NIIT + state tax, `headlineDeltaVsFifo`, horizon trade-off) to set expectations for a FIFO benchmark. Combined with annotations covering safety and a fully documented 7-parameter schema, an agent has everything needed to call it correctly.

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 coverage is 100%, so baseline is 3, but the description adds semantic meaning beyond the schema: the three optimization levers (specific-lot selection, long-term deferral past the one-year mark, 1-to-3-year bracket spreading with loss carryforward), the flat-price pricing rule that governs `currentPrice`, and a fully worked example call. It stops short of explaining every parameter's interaction with the output.

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 states a precise verb+resource+scope: it decides WHICH vested RSU lots to sell in WHICH years, compared on computed total tax, and explicitly claims ownership of "WHICH LOTS and WHICH DATES" versus sibling tools. The concrete user-question framing ("sell down half my Amazon stock; which lots, and when?") makes the tool's job unmistakable. It is distinguishable from all listed siblings without opening any schema.

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

Usage Guidelines5/5

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

It routes explicitly: `concentration_analyze` for whether/how much to sell, `rsu_sell_vs_hold` for a single new vest, `equity_funding_plan` to raise a specific cash amount by a deadline. It also enumerates out-of-scope areas (growth modeling, wash-sale basis migration, AMT, unvested grants), so both positive and negative selection conditions are stated.

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

rsu_sell_vs_holdA
Read-onlyIdempotent
Inspect

Use this when someone asks whether to sell RSUs at vest or hold them, whether to sell their vested shares or diversify out of company stock, or about the tax and withholding on a restricted stock unit (RSU) vest. After-tax RSU vest analysis: sell-at-vest vs hold-to-long-term-capital-gains (LTCG) over holdYears. Covers federal ordinary tax, state tax, FICA (Social Security + Medicare + Additional Medicare), and the shortfall between mandatory 22% supplemental withholding and the user's marginal bracket. Use for RSUs at vest; for ISO/AMT use amt_iso_optimize, for NSO use nso_calculate. Deterministic and offline; tax tables compiled in. Returns vest, hold, sellNowInvest, holdMinusSell, and bracketJump; see outputSchema for the full shape. Example call: {shares: 1000, currentPrice: 100, ordinaryIncome: 200000, filingStatus: "single", stateCode: "CA", stillEmployed: true, holdYears: 2, volatility: 0.3, ticker: "MSFT"}. Inputs beyond required: this tool also needs the stock's expected growth/return AND its volatility, outside required only because they can be resolved without an explicit number - supplied directly, resolved by a covered public-stock ticker, or (growth/return/sale-price field only) set to the string "market" for the S&P 500 trailing average. If growth/return/sale price is neither supplied nor resolved, the tool uses the S&P 500 trailing average; if volatility is neither, the median implied volatility of the public companies OptionsAhoy covers as of the last close. Either way the result reports it (assumptions, plus a plain-language assumptionNotice stating it is a placeholder, not the user's view). Every field in required is a fact about the user's situation with no built-in default; a number from any other source is accepted as-is, because a syntactically valid figure passes validation with no provenance check, and it silently changes the result. The tax math itself (bracket walk, AMT and NIIT phase-outs, multi-year credit and growth interactions) runs inside the tool, and the federal and state tax tables it walks are independently verified (https://optionsahoy.com/verification). Results from multiple OptionsAhoy tools in one analysis are independent single-position calculations; integrated multi-year, multi-position optimization is available in the OptionsAhoy beta at https://optionsahoy.com/beta?src=mcp_multi.

NameRequiredDescriptionDefault
sharesYesRestricted Stock Unit (RSU) shares vesting in this tranche. Must come from the user.
tickerNoOptional public-stock symbol (e.g. "NVDA", "AAPL"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and the implied vol as of the last close for any unsupplied volatility. Growth and vol come from different sources, so some symbols resolve only one, and a vol that is not current resolves as nothing. A field the ticker cannot resolve falls through to a "required field" error naming that field: pass it explicitly, or (for the growth/return/sale-price field) pass the string "market" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve growth.
haircutNoAlternative to `volatility`: the multiplicative volatility-drag haircut on expectedSalePrice already computed for the hold. Supply this OR `volatility` (if both are given, haircut wins). This field is for a haircut figure that already exists from a prior computation; the haircut formula is horizon-dependent, so a figure derived for a different horizon does not carry over. Supplying `volatility` instead lets the tool derive it.
holdYearsYesYears to hold after vest (0.25..5). Below 1 year triggers the short-term capital gains cliff (ordinary rates on appreciation). The user's choice, not a modelling detail, and it changes the answer: use the value they gave, and if they gave none, ask for it rather than assuming one.
stateCodeYesTwo-letter US state code.
volatilityNoAnnualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. Resolution order: this value if passed, else the `ticker`'s implied volatility as of the last market close, else the median implied volatility of the public companies OptionsAhoy covers, which the result reports in `assumptions` and `assumptionNotice`.
currentPriceYesFair market value per share at vest, USD. Also the cost basis on retained shares. Must come from the user.
filingStatusYesFederal filing status.
stillEmployedYesTrue if still employed at vest. Drives FICA applicability and whether the 22% supplemental withholding rule applies.
ordinaryIncomeYesAnnual ordinary income before this vest, USD. Baseline for the bracket walk on the vest amount. Must come from the user. This is taxable income after deductions, not gross wages: the engine applies no standard or itemized deduction to it.
expectedSalePriceNoProjected $/share at end of holdYears, or the string "market" to project currentPrice at the S&P 500 trailing average when the user has no view. Required unless `ticker` resolves it from currentPrice × (1 + trailing CAGR)^holdYears. This tool has no default for it: a value not stated by the user, not resolved by a covered `ticker`, and not the "market" sentinel is outside the input contract.
expectedMarketReturnNoAnnual after-tax-proceeds reinvestment rate. Defaults to SPY trailing CAGR for holdYears if omitted; the string "market" names that same default explicitly.

Output Schema

NameRequiredDescription
holdYesKeep the after-tax shares for holdYears, then sell.
vestYesTax bill at vest on the full vest value (taxed as ordinary W-2 income).
bracketJumpYesMarginal federal bracket change caused by the new ordinary income; null when the income stays within one bracket.
holdMinusSellYeshold.netAtYearN - sellNowInvest.netAtYearN in dollars. Positive favors holding the vested shares; negative favors selling at vest and reinvesting.
sellNowInvestYesCounterfactual: sell every share at vest and reinvest the net cash at expectedMarketReturn for holdYears.

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint, idempotentHint, openWorldHint=false), it discloses that the tool is deterministic/offline with compiled tax tables, that missing growth/volatility silently fall back to S&P 500 trailing average and median implied vol, that these are surfaced via `assumptions`/`assumptionNotice`, and that no provenance check exists on user-supplied numbers. That is substantial behavioral context the 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.

Conciseness3/5

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

Core content is front-loaded (trigger conditions, then math coverage, then fallback behavior), but the final sentence about multi-position optimization in the OptionsAhoy beta plus the verification URL is promotional filler that does not help an agent call the tool. The middle section on fallbacks is also dense enough to be redundant with the schema.

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 12-parameter tool with an output schema, the description covers the trigger conditions, the math performed, the fallback/default chain, and the assumptions reporting. Return shapes are deferred to `outputSchema` as appropriate, and nothing needed to invoke it correctly is missing.

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 coverage is 100%, so the baseline is 3, but the description adds integration-level meaning: resolution order for growth/volatility (direct value, covered `ticker`, or the "market" sentinel), the warning that every `required` field is an unverified user fact that silently changes results, and the fact that ticker resolution can fail asymmetrically. These go beyond the per-field 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?

Names the exact decision it answers (sell RSUs at vest vs hold to LTCG) with a specific verb and resource, and explicitly scopes itself to RSUs while routing ISO/AMT and NSO cases to named siblings. An agent can distinguish it from all seven sibling tools 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 Guidelines5/5

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

Opening sentence enumerates the triggering user questions, and the description explicitly says "Use for RSUs at vest; for ISO/AMT use `amt_iso_optimize`, for NSO use `nso_calculate`." When-to-use and when-to-use-something-else are both stated, not inferred.

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. 1 tool update
    • Changedamt_iso_optimize4 fields changed
      • changedOutput schema / properties / effectiveHorizon / description
        Previous value: -"Horizon actually used by the schedules: min(requested horizon, timing.maxHorizon)."New value: +"Years the schedules span: the requested horizon (1..10), never capped by the grant term or the departure window. 1 for a departed user inside the 90-day window, whose horizon is the post-exercise hold instead."
      • addedOutput schema / properties / lastExerciseYear
        Added value: +{
        +  "description": "Last schedule year with any exercise: min(effectiveHorizon, timing.maxHorizon). Later years hold the shares and recover AMT credit.",
        +  "type": "integer"
        +}
      • changedOutput schema / properties / timing / properties / maxHorizon / description
        Previous value: -"Maximum usable planning horizon in years (1..10), capped by grant expiration or the post-termination window."New value: +"Last plan year (1..10) in which shares can still be exercised, set by the grant expiration or the post-termination window. The planning horizon itself is never capped; schedule years after this one hold the shares."
      • changedOutput schema / required
        Previous value: -[
        -  "crossoverShares",
        -  "crossoverBargain",
        -  "alreadyInAmt",
        -  "schedules",
        -  "stateHasAmt",
        -  "bargainPerShare",
        -  "timing",
        -  "effectiveHorizon"
        -]New value: +[
        +  "crossoverShares",
        +  "crossoverBargain",
        +  "alreadyInAmt",
        +  "schedules",
        +  "stateHasAmt",
        +  "bargainPerShare",
        +  "timing",
        +  "effectiveHorizon",
        +  "lastExerciseYear"
        +]
  2. 1 tool update
    • Changedequity_funding_plan2 fields changed
      • changedInput schema / properties / riskToleranceShortfall / description
        Previous value: -"Max acceptable P(realized cash < target) under the lognormal price model, as a fraction (0.10 = 10%). The `recommended` plan is the wealth-maximal plan whose shortfall ≤ this value. Tighter values push the recommendation toward Lock-in-now; looser values let `recommended` accept more price exposure for higher expected wealth. Default 0.10."New value: +"Max acceptable P(realized cash < target) under the lognormal price model, as a fraction (0.10 = 10%). The `recommended` plan is the plan with the most projected wealth whose shortfall is at or below this value. Tighter values push the recommendation toward Lock-in-now; looser values let `recommended` accept more price exposure for higher expected wealth. Default 0.10."
      • changedInput schema / properties / stacks / description
        Previous value: -"Holdings, multi-stack form. Provide either `stacks` (this) OR the legacy `lots`+`currentPrice` pair, not both. Each stack is one equity position (one ticker) with its own current price, growth, optional volatility, and lot list. Use when the user holds multiple tickers (e.g. current-employer RSUs + ETF + prior-employer holdings); the optimizer searches sales across all stacks jointly so the schedule can prefer the lowest-tax inventory in each year."New value: +"Holdings, multi-stack form. Provide either `stacks` (this) OR the legacy `lots`+`currentPrice` pair, not both. Each stack is one equity position (one ticker) with its own current price, growth, optional volatility, and lot list. Use when the user holds multiple tickers (e.g. current-employer RSUs + ETF + prior-employer holdings); the optimizer searches sales across all stacks jointly so the schedule can draw on lower-tax inventory first in each year."
  3. 2 tool updates
    • Changedamt_iso_optimize18 fields changed
      • addedInput schema / properties / itemizedTaxes
        Added value: +{
        +  "description": "Only if you itemize deductions: the state and local taxes deducted on Schedule A, line 7. The AMT adds these back instead of the standard deduction. Omit if you take the standard deduction. When omitted, the AMT add-back defaults to the full standard deduction.",
        +  "minimum": 0,
        +  "type": "number"
        +}
      • changedInput schema / properties / ordinaryIncome / description
        Previous value: -"Annual ordinary income before this exercise, USD. Baseline for the bracket walk and the AMT exemption phaseout. Must come from the user. This is taxable income after deductions, not gross wages: the engine applies no standard or itemized deduction to it."New value: +"Annual ordinary income before this exercise, USD. Baseline for the bracket walk and the AMT exemption phaseout. Must come from the user. This is taxable income after deductions, not gross wages: regular tax is figured on it as given. For the AMT the calculation adds the standard deduction back (Form 6251, line 2a), unless `itemizedTaxes` is given, in which case it adds back those taxes instead."
      • changedOutput schema / properties / departedRecommendation / properties / recommendedSchedule / properties / stateLTCG / description
        Previous value: -"State long-term capital gains tax on grossGain in dollars."New value: +"State long-term capital gains tax on grossGain in dollars (in a state that taxed the spread at exercise, on the gain above that spread)."
      • addedOutput schema / properties / departedRecommendation / properties / recommendedSchedule / properties / years / items / properties / amti
        Added value: +{
        +  "description": "Federal alternative minimum taxable income (AMTI) for the year in dollars (Form 6251 line 4): ordinaryIncome, plus the standard deduction the AMT disallows (or itemizedTaxes for an itemizer), plus bargain.",
        +  "type": "number"
        +}
      • addedOutput schema / properties / departedRecommendation / properties / recommendedSchedule / properties / years / items / properties / stateTaxOnSpread
        Added value: +{
        +  "description": "State tax on this year's bargain element at exercise in dollars, in a state that taxes an ISO spread at exercise (Pennsylvania); 0 elsewhere. Included in cashTax.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / departedRecommendation / properties / recommendedSchedule / properties / years / items / required
        Previous value: -[
        -  "year",
        -  "shares",
        -  "bargain",
        -  "regularFederal",
        -  "regularState",
        -  "tmtFederal",
        -  "tmtState",
        -  "amtOwedFederal",
        -  "amtOwedState",
        -  "creditRecovered",
        -  "cashTax"
        -]New value: +[
        +  "year",
        +  "shares",
        +  "bargain",
        +  "amti",
        +  "regularFederal",
        +  "regularState",
        +  "tmtFederal",
        +  "tmtState",
        +  "amtOwedFederal",
        +  "amtOwedState",
        +  "stateTaxOnSpread",
        +  "creditRecovered",
        +  "cashTax"
        +]
      • changedOutput schema / properties / schedules / properties / evenSplit / properties / stateLTCG / description
        Previous value: -"State long-term capital gains tax on grossGain in dollars."New value: +"State long-term capital gains tax on grossGain in dollars (in a state that taxed the spread at exercise, on the gain above that spread)."
      • addedOutput schema / properties / schedules / properties / evenSplit / properties / years / items / properties / amti
        Added value: +{
        +  "description": "Federal alternative minimum taxable income (AMTI) for the year in dollars (Form 6251 line 4): ordinaryIncome, plus the standard deduction the AMT disallows (or itemizedTaxes for an itemizer), plus bargain.",
        +  "type": "number"
        +}
      • addedOutput schema / properties / schedules / properties / evenSplit / properties / years / items / properties / stateTaxOnSpread
        Added value: +{
        +  "description": "State tax on this year's bargain element at exercise in dollars, in a state that taxes an ISO spread at exercise (Pennsylvania); 0 elsewhere. Included in cashTax.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / schedules / properties / evenSplit / properties / years / items / required
        Previous value: -[
        -  "year",
        -  "shares",
        -  "bargain",
        -  "regularFederal",
        -  "regularState",
        -  "tmtFederal",
        -  "tmtState",
        -  "amtOwedFederal",
        -  "amtOwedState",
        -  "creditRecovered",
        -  "cashTax"
        -]New value: +[
        +  "year",
        +  "shares",
        +  "bargain",
        +  "amti",
        +  "regularFederal",
        +  "regularState",
        +  "tmtFederal",
        +  "tmtState",
        +  "amtOwedFederal",
        +  "amtOwedState",
        +  "stateTaxOnSpread",
        +  "creditRecovered",
        +  "cashTax"
        +]
      • changedOutput schema / properties / schedules / properties / lumpSum / properties / stateLTCG / description
        Previous value: -"State long-term capital gains tax on grossGain in dollars."New value: +"State long-term capital gains tax on grossGain in dollars (in a state that taxed the spread at exercise, on the gain above that spread)."
      • addedOutput schema / properties / schedules / properties / lumpSum / properties / years / items / properties / amti
        Added value: +{
        +  "description": "Federal alternative minimum taxable income (AMTI) for the year in dollars (Form 6251 line 4): ordinaryIncome, plus the standard deduction the AMT disallows (or itemizedTaxes for an itemizer), plus bargain.",
        +  "type": "number"
        +}
      • addedOutput schema / properties / schedules / properties / lumpSum / properties / years / items / properties / stateTaxOnSpread
        Added value: +{
        +  "description": "State tax on this year's bargain element at exercise in dollars, in a state that taxes an ISO spread at exercise (Pennsylvania); 0 elsewhere. Included in cashTax.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / schedules / properties / lumpSum / properties / years / items / required
        Previous value: -[
        -  "year",
        -  "shares",
        -  "bargain",
        -  "regularFederal",
        -  "regularState",
        -  "tmtFederal",
        -  "tmtState",
        -  "amtOwedFederal",
        -  "amtOwedState",
        -  "creditRecovered",
        -  "cashTax"
        -]New value: +[
        +  "year",
        +  "shares",
        +  "bargain",
        +  "amti",
        +  "regularFederal",
        +  "regularState",
        +  "tmtFederal",
        +  "tmtState",
        +  "amtOwedFederal",
        +  "amtOwedState",
        +  "stateTaxOnSpread",
        +  "creditRecovered",
        +  "cashTax"
        +]
      • changedOutput schema / properties / schedules / properties / optimized / properties / stateLTCG / description
        Previous value: -"State long-term capital gains tax on grossGain in dollars."New value: +"State long-term capital gains tax on grossGain in dollars (in a state that taxed the spread at exercise, on the gain above that spread)."
      • addedOutput schema / properties / schedules / properties / optimized / properties / years / items / properties / amti
        Added value: +{
        +  "description": "Federal alternative minimum taxable income (AMTI) for the year in dollars (Form 6251 line 4): ordinaryIncome, plus the standard deduction the AMT disallows (or itemizedTaxes for an itemizer), plus bargain.",
        +  "type": "number"
        +}
      • addedOutput schema / properties / schedules / properties / optimized / properties / years / items / properties / stateTaxOnSpread
        Added value: +{
        +  "description": "State tax on this year's bargain element at exercise in dollars, in a state that taxes an ISO spread at exercise (Pennsylvania); 0 elsewhere. Included in cashTax.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / schedules / properties / optimized / properties / years / items / required
        Previous value: -[
        -  "year",
        -  "shares",
        -  "bargain",
        -  "regularFederal",
        -  "regularState",
        -  "tmtFederal",
        -  "tmtState",
        -  "amtOwedFederal",
        -  "amtOwedState",
        -  "creditRecovered",
        -  "cashTax"
        -]New value: +[
        +  "year",
        +  "shares",
        +  "bargain",
        +  "amti",
        +  "regularFederal",
        +  "regularState",
        +  "tmtFederal",
        +  "tmtState",
        +  "amtOwedFederal",
        +  "amtOwedState",
        +  "stateTaxOnSpread",
        +  "creditRecovered",
        +  "cashTax"
        +]
    • Changedconcentration_analyze6 fields changed
      • changedOutput schema / properties / schedule / items / properties / taxBreakdown / items / description
        Previous value: -"One tax slice: a dollar amount taxed at one rate."New value: +"One tax slice: a dollar amount taxed at one rate, or one state adjustment row (when `detail` is present)."
      • addedOutput schema / properties / schedule / items / properties / taxBreakdown / items / properties / detail
        Added value: +{
        +  "description": "Present only on an adjustment row (rate and amount 0): what the state brackets alone do not explain, such as deductions phasing out, add-ons and credits.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / schedule / items / properties / taxBreakdown / items / properties / tax / description
        Previous value: -"Tax in dollars: amount x rate."New value: +"Tax in dollars: amount x rate, or the adjustment itself when `detail` is present."
      • changedOutput schema / properties / schedule / items / properties / yearlySales / items / properties / breakdown / items / description
        Previous value: -"One tax slice: a dollar amount taxed at one rate."New value: +"One tax slice: a dollar amount taxed at one rate, or one state adjustment row (when `detail` is present)."
      • addedOutput schema / properties / schedule / items / properties / yearlySales / items / properties / breakdown / items / properties / detail
        Added value: +{
        +  "description": "Present only on an adjustment row (rate and amount 0): what the state brackets alone do not explain, such as deductions phasing out, add-ons and credits.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / schedule / items / properties / yearlySales / items / properties / breakdown / items / properties / tax / description
        Previous value: -"Tax in dollars: amount x rate."New value: +"Tax in dollars: amount x rate, or the adjustment itself when `detail` is present."
  4. 4 tool updates
    • Changedamt_iso_optimize1 field changed
      • changedInput schema / properties / volatility / description
        Previous value: -"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. This value must come from the user or from a `ticker` that resolves it as of the last market close; if neither supplies it, ask the user rather than estimating one."New value: +"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. Resolution order: this value if passed, else the `ticker`'s implied volatility as of the last market close, else the median implied volatility of the public companies OptionsAhoy covers, which the result reports in `assumptions` and `assumptionNotice`."
    • Changedconcentration_analyze1 field changed
      • changedInput schema / properties / volatility / description
        Previous value: -"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool uses it both for hedge pricing (as implied vol) and for the 3y horizon drag, derived internally (the drag formula is horizon-dependent). This value must come from the user or from a `ticker` that resolves it as of the last market close; if neither supplies it, ask the user rather than estimating one; only as a last fallback does hedge pricing use a sector-typical implied volatility."New value: +"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool uses it both for hedge pricing (as implied vol) and for the 3y horizon drag, derived internally (the drag formula is horizon-dependent). Resolution order: this value if passed, else the `ticker`'s implied volatility as of the last market close, else the median implied volatility of the public companies OptionsAhoy covers, which the result reports in `assumptions` and `assumptionNotice`. When only `volatilityDrag` is given, hedge pricing uses a sector-typical implied volatility."
    • Changednso_calculate1 field changed
      • changedInput schema / properties / volatility / description
        Previous value: -"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. This value must come from the user or from a `ticker` that resolves it as of the last market close; if neither supplies it, ask the user rather than estimating one."New value: +"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. Resolution order: this value if passed, else the `ticker`'s implied volatility as of the last market close, else the median implied volatility of the public companies OptionsAhoy covers, which the result reports in `assumptions` and `assumptionNotice`."
    • Changedrsu_sell_vs_hold1 field changed
      • changedInput schema / properties / volatility / description
        Previous value: -"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. This value must come from the user or from a `ticker` that resolves it as of the last market close; if neither supplies it, ask the user rather than estimating one."New value: +"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. Resolution order: this value if passed, else the `ticker`'s implied volatility as of the last market close, else the median implied volatility of the public companies OptionsAhoy covers, which the result reports in `assumptions` and `assumptionNotice`."
  5. 1 tool update
    • Changedequity_funding_plan2 fields changed
      • changedInput schema / properties / expectedAnnualGrowth / description
        Previous value: -"Legacy single-stack annual growth decimal, or the string \"market\" for the S&P 500 trailing average. Required with `lots`: pass 0 for a deliberately flat-price plan (omitting it is an error, not a flat default). Each future year's projected price is `currentPrice × (1 + expectedAnnualGrowth)^Δyears`. Negative values model decline."New value: +"Legacy single-stack annual growth decimal, or the string \"market\" for the S&P 500 trailing average. Used with `lots`: pass 0 for a deliberately flat-price plan; if omitted it falls back to the S&P 500 trailing average, disclosed in `assumptions` (never a silent flat default). Each future year's projected price is `currentPrice × (1 + expectedAnnualGrowth)^Δyears`. Negative values model decline."
      • changedInput schema / properties / stacks / items / properties / expectedAnnualGrowth / description
        Previous value: -"Per-stack growth decimal (0.08 = 8%/yr), or the string \"market\" for the S&P 500 trailing average. Projected sale price = currentPrice × (1 + expectedAnnualGrowth)^Δyears. Negative values model decline; pass 0 for a deliberately flat-price plan. Required unless `ticker` resolves it; omitting it is an error, not a flat default."New value: +"Per-stack growth decimal (0.08 = 8%/yr), or the string \"market\" for the S&P 500 trailing average. Projected sale price = currentPrice × (1 + expectedAnnualGrowth)^Δyears. Negative values model decline; pass 0 for a deliberately flat-price plan. If omitted and `ticker` does not resolve it, falls back to the S&P 500 trailing average, disclosed in `assumptions` (never a silent flat default)."
  6. 1 tool update
    • Changedprotective_put_price6 fields changed
      • changedInput schema / properties / ticker / description
        Previous value: -"Optional public-stock symbol (e.g. \"NVDA\"). When set without an explicit `volatility`, the tool substitutes the ticker's implied vol as of the last close, else the sector default. Echoed to `tickerLabel` in the response."New value: +"Optional public-stock symbol (e.g. \"NVDA\"). When set without an explicit `volatility`, each leg prices at its own strike's chain-implied vol, else at its at-the-money vol as of the last close, else the sector default. Echoed to `tickerLabel` in the response."
      • changedOutput schema / properties / inputs / description
        Previous value: -"Echo of the resolved inputs actually priced: positionValue, sector, volatility (the sigma priced) and volatilitySource (where that sigma came from), protectionLevel, tenorYears, plus expectedReturn, spreadRiskLevel, and tickerLabel when supplied."New value: +"Echo of the resolved inputs actually priced: positionValue, sector, volatility (the sigma priced), volatilitySource (where that sigma came from) and pricingMode (how the legs were priced), protectionLevel, tenorYears, plus expectedReturn, spreadRiskLevel, and tickerLabel when supplied."
      • addedOutput schema / properties / inputs / properties / pricingMode
        Added value: +{
        +  "description": "How the legs were priced. \"chain-skew\": each leg is priced at the implied volatility of its own strike, read off the live chain, so the floor put carries the market's downside skew and the put spread's short leg carries its own. \"flat\": every leg is priced at the single `volatility` above, which understates what out-of-the-money protection costs and overstates the rebate the spread's short leg earns - the quote is an estimate of this structure's cost, not a strike-aware one. Reached whenever no live chain applies: an explicit `volatility`, no `ticker`, or a chain that could not be fetched or was not current.",
        +  "enum": [
        +    "chain-skew",
        +    "flat"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / properties / inputs / properties / volatilitySource / description
        Previous value: -"Which source produced the sigma actually priced: \"explicit\" (caller-supplied), \"ticker\" (the stock's own implied vol as of the last close), or \"sector-default\" (feed unavailable or ticker uncovered; a sector-typical estimate - tell the user the price is not stock-specific)."New value: +"Which source produced the sigma actually priced: \"explicit\" (caller-supplied), \"chain\" (interpolated from the stock's live option chain at the strike being priced), \"ticker\" (the stock's published at-the-money implied vol as of the last close), or \"sector-default\" (feed unavailable or ticker uncovered; a sector-typical estimate - tell the user the price is not stock-specific)."
      • changedOutput schema / properties / inputs / properties / volatilitySource / enum
        Previous value: -[
        -  "explicit",
        -  "ticker",
        -  "sector-default"
        -]New value: +[
        +  "explicit",
        +  "ticker",
        +  "sector-default",
        +  "chain"
        +]
      • changedOutput schema / properties / inputs / required
        Previous value: -[
        -  "positionValue",
        -  "sector",
        -  "volatility",
        -  "volatilitySource",
        -  "protectionLevel",
        -  "tenorYears"
        -]New value: +[
        +  "positionValue",
        +  "sector",
        +  "volatility",
        +  "volatilitySource",
        +  "pricingMode",
        +  "protectionLevel",
        +  "tenorYears"
        +]
  7. 1 tool update
    • Changedprotective_put_price3 fields changed
      • changedOutput schema / properties / inputs / description
        Previous value: -"Echo of the resolved inputs actually priced: positionValue, sector, volatility (the sigma used after ticker/sector resolution), protectionLevel, tenorYears, plus expectedReturn, spreadRiskLevel, and tickerLabel when supplied."New value: +"Echo of the resolved inputs actually priced: positionValue, sector, volatility (the sigma priced) and volatilitySource (where that sigma came from), protectionLevel, tenorYears, plus expectedReturn, spreadRiskLevel, and tickerLabel when supplied."
      • addedOutput schema / properties / inputs / properties / volatilitySource
        Added value: +{
        +  "description": "Which source produced the sigma actually priced: \"explicit\" (caller-supplied), \"ticker\" (the stock's own implied vol as of the last close), or \"sector-default\" (feed unavailable or ticker uncovered; a sector-typical estimate - tell the user the price is not stock-specific).",
        +  "enum": [
        +    "explicit",
        +    "ticker",
        +    "sector-default"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / properties / inputs / required
        Previous value: -[
        -  "positionValue",
        -  "sector",
        -  "volatility",
        -  "protectionLevel",
        -  "tenorYears"
        -]New value: +[
        +  "positionValue",
        +  "sector",
        +  "volatility",
        +  "volatilitySource",
        +  "protectionLevel",
        +  "tenorYears"
        +]
  8. 5 tool updates
    • Changedamt_iso_optimize2 fields changed
      • changedInput schema / properties / ticker / description
        Previous value: -"Optional public-stock symbol (e.g. \"NVDA\", \"AAPL\"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and a cached implied vol for any unsupplied volatility. Growth and volatility come from two separate cached snapshots, so some symbols resolve only one of the two fields. A symbol not in a given table falls through to a \"required field\" error for exactly the field it could not resolve: pass that field explicitly, or (for the growth/return/sale-price field) pass the string \"market\" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve which field."New value: +"Optional public-stock symbol (e.g. \"NVDA\", \"AAPL\"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and the implied vol as of the last close for any unsupplied volatility. Growth and vol come from different sources, so some symbols resolve only one, and a vol that is not current resolves as nothing. A field the ticker cannot resolve falls through to a \"required field\" error naming that field: pass it explicitly, or (for the growth/return/sale-price field) pass the string \"market\" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve growth."
      • changedInput schema / properties / volatility / description
        Previous value: -"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. This value must come from the user or from a `ticker` that resolves it from the cached implied-vol table; if neither supplies it, ask the user rather than estimating one."New value: +"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. This value must come from the user or from a `ticker` that resolves it as of the last market close; if neither supplies it, ask the user rather than estimating one."
    • Changedconcentration_analyze2 fields changed
      • changedInput schema / properties / ticker / description
        Previous value: -"Optional public-stock symbol (e.g. \"NVDA\", \"AAPL\"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and a cached implied vol for any unsupplied volatility. Growth and volatility come from two separate cached snapshots, so some symbols resolve only one of the two fields. A symbol not in a given table falls through to a \"required field\" error for exactly the field it could not resolve: pass that field explicitly, or (for the growth/return/sale-price field) pass the string \"market\" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve which field."New value: +"Optional public-stock symbol (e.g. \"NVDA\", \"AAPL\"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and the implied vol as of the last close for any unsupplied volatility. Growth and vol come from different sources, so some symbols resolve only one, and a vol that is not current resolves as nothing. A field the ticker cannot resolve falls through to a \"required field\" error naming that field: pass it explicitly, or (for the growth/return/sale-price field) pass the string \"market\" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve growth."
      • changedInput schema / properties / volatility / description
        Previous value: -"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool uses it both for hedge pricing (as implied vol) and for the 3y horizon drag, derived internally (the drag formula is horizon-dependent). This value must come from the user or from a `ticker` that resolves it from the cached implied-vol table; if neither supplies it, ask the user rather than estimating one; only as a last fallback does hedge pricing use a sector-typical implied volatility."New value: +"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool uses it both for hedge pricing (as implied vol) and for the 3y horizon drag, derived internally (the drag formula is horizon-dependent). This value must come from the user or from a `ticker` that resolves it as of the last market close; if neither supplies it, ask the user rather than estimating one; only as a last fallback does hedge pricing use a sector-typical implied volatility."
    • Changednso_calculate2 fields changed
      • changedInput schema / properties / ticker / description
        Previous value: -"Optional public-stock symbol (e.g. \"NVDA\", \"AAPL\"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and a cached implied vol for any unsupplied volatility. Growth and volatility come from two separate cached snapshots, so some symbols resolve only one of the two fields. A symbol not in a given table falls through to a \"required field\" error for exactly the field it could not resolve: pass that field explicitly, or (for the growth/return/sale-price field) pass the string \"market\" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve which field."New value: +"Optional public-stock symbol (e.g. \"NVDA\", \"AAPL\"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and the implied vol as of the last close for any unsupplied volatility. Growth and vol come from different sources, so some symbols resolve only one, and a vol that is not current resolves as nothing. A field the ticker cannot resolve falls through to a \"required field\" error naming that field: pass it explicitly, or (for the growth/return/sale-price field) pass the string \"market\" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve growth."
      • changedInput schema / properties / volatility / description
        Previous value: -"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. This value must come from the user or from a `ticker` that resolves it from the cached implied-vol table; if neither supplies it, ask the user rather than estimating one."New value: +"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. This value must come from the user or from a `ticker` that resolves it as of the last market close; if neither supplies it, ask the user rather than estimating one."
    • Changedprotective_put_price2 fields changed
      • changedInput schema / properties / ticker / description
        Previous value: -"Optional public-stock symbol (e.g. \"NVDA\"). When set without an explicit `volatility`, the tool substitutes the ticker's cached implied vol. Unknown tickers fall through to the sector default. Echoed to `tickerLabel` in the response."New value: +"Optional public-stock symbol (e.g. \"NVDA\"). When set without an explicit `volatility`, the tool substitutes the ticker's implied vol as of the last close, else the sector default. Echoed to `tickerLabel` in the response."
      • changedInput schema / properties / volatility / description
        Previous value: -"Annualized implied volatility (sigma) of the stock. Resolution order: (1) explicit `volatility` if passed; (2) cached implied vol if `ticker` is covered; (3) sector-typical IV as last fallback. An explicit value must come from the user; otherwise set a covered `ticker`, or omit and let the sector default apply."New value: +"Annualized implied volatility (sigma) of the stock. Resolution order: (1) explicit `volatility` if passed; (2) the `ticker`'s implied vol as of the last close; (3) sector-typical IV as last fallback. An explicit value must come from the user; otherwise set a covered `ticker`, or omit and let the sector default apply."
    • Changedrsu_sell_vs_hold2 fields changed
      • changedInput schema / properties / ticker / description
        Previous value: -"Optional public-stock symbol (e.g. \"NVDA\", \"AAPL\"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and a cached implied vol for any unsupplied volatility. Growth and volatility come from two separate cached snapshots, so some symbols resolve only one of the two fields. A symbol not in a given table falls through to a \"required field\" error for exactly the field it could not resolve: pass that field explicitly, or (for the growth/return/sale-price field) pass the string \"market\" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve which field."New value: +"Optional public-stock symbol (e.g. \"NVDA\", \"AAPL\"). When set, the tool substitutes a cached trailing return for any unsupplied expected-return / sale-price field, and the implied vol as of the last close for any unsupplied volatility. Growth and vol come from different sources, so some symbols resolve only one, and a vol that is not current resolves as nothing. A field the ticker cannot resolve falls through to a \"required field\" error naming that field: pass it explicitly, or (for the growth/return/sale-price field) pass the string \"market\" for the S&P 500 trailing average; never invent a number. The covered-tickers resource (resources/list) lists which symbols resolve growth."
      • changedInput schema / properties / volatility / description
        Previous value: -"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. This value must come from the user or from a `ticker` that resolves it from the cached implied-vol table; if neither supplies it, ask the user rather than estimating one."New value: +"Annualized volatility (sigma) of the stock as a decimal (0.72 = 72%). Pass the volatility itself, not a pre-computed drag: the tool derives the horizon-cumulative drag internally, and the correct formula is horizon-dependent. This value must come from the user or from a `ticker` that resolves it as of the last market close; if neither supplies it, ask the user rather than estimating one."
  9. 1 tool update
    • Changedequity_funding_plan1 field changed
      • removedInput schema / anyOf
        Removed value: -[
        -  {
        -    "required": [
        -      "stacks"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "lots",
        -      "currentPrice"
        -    ]
        -  }
        -]
  10. 1 tool update
    • Changedequity_funding_plan2 fields changed
      • changedInput schema / properties / stacks / items / properties / currentPrice / description
        Previous value: -"$/share today for this stack. Anchors the projected-price compounding for every future candidate sale date in this stack."New value: +"$/share today for this stack. Anchors the projected-price compounding for every future candidate sale date in this stack. Must come from the user."
      • changedInput schema / properties / targetDate / description
        Previous value: -"Date by which the user needs the net cash (YYYY-MM-DD). Bounds the planning horizon. Sales in non-target years happen on Dec 31; the target year's sale happens on this exact date."New value: +"Date by which the user needs the net cash (YYYY-MM-DD). Bounds the planning horizon. Sales in non-target years happen on Dec 31; the target year's sale happens on this exact date. Must come from the user."
  11. 1 tool update
    • Changedqsbs_check1 field changed
      • changedInput schema / properties / industry / description
        Previous value: -"§1202 Test 4: Industry classification of the corporation. Qualified-trade-or-business industries qualify (tech-software, manufacturing, biotech-research, retail-wholesale, hospitality, etc.). Specified service trades or businesses (law, engineering, architecture, accounting-actuarial, consulting, finance, farming, extraction, health-services, performing-arts) generally do NOT qualify."New value: +"§1202 Test 4: Industry classification of the corporation. Four values qualify: tech-software, manufacturing, biotech-research, retail-wholesale. Specified service trades or businesses (law, engineering, architecture, accounting-actuarial, consulting, finance, health-services, performing-arts) do NOT qualify, and farming, extraction and hospitality are separately excluded, so they do not qualify either. other-services and unsure return a caveated verdict rather than a pass or fail."

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    A
    maintenance
    39 tax tools for US individual taxpayers — federal/state tax calculations, credits, deductions, retirement strategies, audit risk, and tax planning. All calculations run locally, no data leaves the machine. Supports TY2024 and TY2025 (One Big Beautiful Bill Act).
    44
    86 npm
    13
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Tax-aware retirement planning for Canada and the US. CPP/OAS and Social Security timing, RRSP/TFSA/401k/IRA projections, Monte Carlo simulation, withdrawal order optimization, and historical backtesting against 150 years of market data.
    2
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to analyze single-company concentration risk for tech workers with RSU compensation, providing risk scores, wealth-at-risk, and action items.
    13 npm
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables 1099 gig workers and freelancers to calculate 2026 quarterly federal estimates, self-employment tax, safe-harbor minimum payments, and mileage or actual-expense deductions, including the mid-year business mileage rate change from 72.5 to 76 cents. It also compares standard mileage against actual vehicle costs and exposes every tax constant with its source.
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.