{
  "$schema": "https://modelcontextprotocol.io/schema/manifest.json",
  "schemaVersion": "2024-11-05",
  "name": "ppp-calculator",
  "displayName": "PPP Calculator",
  "description": "Purchasing Power Parity calculator. Converts a US-baseline income into its real-world equivalent across countries, returning effective local purchasing power and lifestyle equilibrium cost. Free and key-less: anonymous callers get 300 requests/hour per IP. An optional API key (Authorization: Bearer gp_live_..., created at https://geo-parity.com/account) raises that ceiling without changing any response; over the limit, endpoints return HTTP 429 with a Retry-After header, so back off and retry.",
  "version": "0.1.0",
  "vendor": {
    "name": "PPP Calculator",
    "url": "https://geo-parity.com"
  },
  "documentation": "https://geo-parity.com/llms.txt",
  "tools": [
    {
      "name": "calculate_ppp",
      "title": "Calculate Purchasing Power Parity",
      "description": "Given a US-denominated annual income and a target country code, returns the effective local purchasing power (income / pppIndex), the lifestyle equilibrium cost (income * pppIndex), and the purchasing power ratio (1 / pppIndex). Figures use real PPP data (World Bank, IMF, OECD, Penn World Table) relative to a US baseline of 1.0.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["income", "target"],
        "properties": {
          "income": {
            "type": "number",
            "minimum": 0,
            "description": "Nominal annual income, denominated against the US baseline."
          },
          "target": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2 target country code (case-insensitive). Available codes depend on the chosen source.",
            "enum": [
              "US", "AR", "AU", "BR", "CA", "CL", "CN", "CO", "CZ", "DK",
              "EG", "FR", "DE", "GR", "HU", "IN", "ID", "IE", "IT", "JP",
              "KR", "MY", "MX", "NL", "NZ", "NG", "NO", "PH", "PL", "PT",
              "SA", "SG", "ZA", "ES", "SE", "CH", "TH", "TR", "AE", "GB", "VN"
            ]
          },
          "source": {
            "type": "string",
            "description": "PPP dataset to draw figures from. 'consensus' = per-country median across the GDP-based providers (recommended default); 'worldbank' = World Bank GDP price level; 'imf' = IMF WEO implied PPP; 'oecd' = OECD PPP-for-GDP (members + key partners only); 'pwt' = Penn World Table; 'worldbank-cons' = World Bank household-consumption price level; 'bigmac' = The Economist Big Mac index (single-good consumer PPP, ~40 countries); 'factbook' = CIA World Factbook derived price level for ~100 micro-states/territories the macro sources ignore (coarse). Defaults to 'consensus' if omitted.",
            "enum": ["consensus", "worldbank", "imf", "oecd", "pwt", "worldbank-cons", "bigmac", "factbook"],
            "default": "consensus"
          },
          "city": {
            "type": "string",
            "description": "Optional city slug (e.g. 'london', 'san-francisco') for a sub-national Capital-to-Rural adjustment: multiplies the national price level by a per-city factor (curated overrides / US-metro BEA RPP / population-tier heuristic). Unknown slug = national figure."
          }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "source": {
            "type": "object",
            "properties": {
              "id": { "type": "string" },
              "label": { "type": "string" }
            }
          },
          "target": {
            "type": "object",
            "properties": {
              "code": { "type": "string" },
              "name": { "type": "string" },
              "currency": { "type": "string" },
              "pppIndex": { "type": "number" }
            }
          },
          "metrics": {
            "type": "object",
            "properties": {
              "effectivePurchasingPower": { "type": "number" },
              "lifestyleEquilibriumCost": { "type": "number" },
              "purchasingPowerRatio": { "type": "number" }
            }
          }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/calculate.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/calculate.json?income=100000&target=TH"
      }
    },
    {
      "name": "localize_salary",
      "title": "Localize a salary for fair pay across borders",
      "description": "Convert a base salary from a home country into a cost-of-living-fair local equivalent: S_local = S_base × (I_target / I_home), where I is a US-relative price level. Omit `target` to receive a localized salary matrix across every country in the source — useful for pricing one offer across many markets. Returns USD purchasing-power equivalents, not currency-converted amounts.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["baseSalary", "home"],
        "properties": {
          "baseSalary": {
            "type": "number",
            "minimum": 0,
            "description": "Base annual salary in the home country (USD-denominated)."
          },
          "home": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2 home country code the base salary is expressed in (case-insensitive)."
          },
          "target": {
            "type": "string",
            "description": "Optional ISO 3166-1 alpha-2 target country code. Omit to localize across all countries in the source."
          },
          "source": {
            "type": "string",
            "description": "PPP dataset to draw figures from. Defaults to 'consensus' if omitted.",
            "enum": ["consensus", "worldbank", "imf", "oecd", "pwt", "worldbank-cons", "bigmac", "factbook"],
            "default": "consensus"
          }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "input": {
            "type": "object",
            "properties": { "baseSalary": { "type": "number" } }
          },
          "source": {
            "type": "object",
            "properties": {
              "id": { "type": "string" },
              "label": { "type": "string" }
            }
          },
          "home": {
            "type": "object",
            "properties": {
              "code": { "type": "string" },
              "name": { "type": "string" },
              "pppIndex": { "type": "number" }
            }
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "target": {
                  "type": "object",
                  "properties": {
                    "code": { "type": "string" },
                    "name": { "type": "string" },
                    "currency": { "type": "string" },
                    "pppIndex": { "type": "number" }
                  }
                },
                "ratio": { "type": "number" },
                "localEquivalent": { "type": "number" },
                "local": {
                  "type": "object",
                  "description": "The figure in the target's local currency at market FX (omitted when no rate is known or target is USD).",
                  "properties": {
                    "currency": { "type": "string" },
                    "fxRate": { "type": "number" },
                    "fxYear": { "type": "number" },
                    "amount": { "type": "number" }
                  }
                }
              }
            }
          }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/salary.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/salary.json?base=150000&home=US&target=ES&source=consensus"
      }
    },
    {
      "name": "calculate_wage_bands",
      "title": "Benchmark local salary bands (min, median, top 10%)",
      "description": "Models a country's wage distribution as log-normal, calibrated from World Bank GNI per capita (mean) and the Gini index (spread: sigma = sqrt(2)*normInv((Gini+1)/2)), then returns the survival floor (essentials), statutory minimum (ILOSTAT where available, else curated; null where none exists), median (p50), comfortable (p75), top 10% (p90) and top 1% (p99) bands — each monthly and annual, USD and local currency. Optional `salary` locates a pay figure on the curve (percentile + out-earns %); `percentile` returns that exact threshold wage. Model estimates for benchmarking, not payroll data.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["country"],
        "properties": {
          "country": { "type": "string", "description": "ISO 3166-1 alpha-2 country code (case-insensitive)." },
          "salary": { "type": "number", "minimum": 0, "description": "Your salary to locate on the distribution. Values over 20000 are read as annual (÷12), else monthly." },
          "percentile": { "type": "number", "minimum": 0, "maximum": 100, "description": "Return the exact wage threshold at this percentile (e.g. 90 for the top-10% floor)." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "country": { "type": "object", "properties": { "code": { "type": "string" }, "name": { "type": "string" } } },
          "model": { "type": "object", "properties": { "meanMonthly": { "type": "number" }, "sigma": { "type": "number" }, "gini": { "type": "number" } } },
          "bands": {
            "type": "object",
            "properties": {
              "survival": { "type": "object" },
              "minimum": { "type": ["object", "null"] },
              "median": { "type": "object" },
              "comfortable": { "type": "object" },
              "top10": { "type": "object" },
              "top1": { "type": "object" }
            }
          },
          "standing": { "type": "object", "properties": { "percentile": { "type": "number" }, "label": { "type": "string" } } },
          "atPercentile": { "type": "object" }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/wage-bands.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/wage-bands.json?country=PL&percentile=90"
      }
    },
    {
      "name": "check_schengen",
      "title": "Check a Schengen 90/180-day visa itinerary",
      "description": "Validate a set of trips against the Schengen Area rule: a non-EU visitor may be present at most 90 days within any rolling 180-day window. Entry and exit days both count as days of presence; overlapping trips are de-duplicated. Returns days used in the current window, days remaining, an overall compliance flag, and the exact first overstay date (if any).",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["trips"],
        "properties": {
          "trips": {
            "type": "array",
            "minItems": 1,
            "description": "List of Schengen stays.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["entry", "exit"],
              "properties": {
                "entry": { "type": "string", "format": "date", "description": "Entry date, ISO YYYY-MM-DD." },
                "exit": { "type": "string", "format": "date", "description": "Exit date, ISO YYYY-MM-DD (>= entry)." }
              }
            }
          },
          "referenceDate": {
            "type": "string",
            "format": "date",
            "description": "Optional 'as of' date (ISO YYYY-MM-DD). Defaults to today (UTC)."
          },
          "plannedEntry": {
            "type": "string",
            "format": "date",
            "description": "Optional planned entry date. When set, the response adds plan: { maxStay, latestExit, fullResetDate } — the longest compliant stay starting on that date."
          }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "referenceDate": { "type": "string" },
          "windowStart": { "type": "string" },
          "daysUsed": { "type": "number" },
          "daysRemaining": { "type": "number" },
          "compliant": { "type": "boolean" },
          "firstOverstayDate": { "type": ["string", "null"] },
          "maxDaysInWindow": { "type": "number" }
        }
      },
      "invocation": {
        "type": "http",
        "method": "POST",
        "url": "https://geo-parity.com/api/visa-check",
        "parameterMapping": "body",
        "example": "POST https://geo-parity.com/api/visa-check {\"trips\":[{\"entry\":\"2025-01-01\",\"exit\":\"2025-03-01\"}]}"
      }
    },
    {
      "name": "find_meeting_slot",
      "title": "Score team timezone friction + find the meeting window",
      "description": "Given a set of cities/timezones and each participant's local working hours, find the longest UTC window where everyone is simultaneously within their working day (DST-accurate), AND score the team's overall timezone friction. Returns the overlap in UTC and in each participant's local time (or null with the best partial coverage), plus a `friction` block: a 0–100 score, grade (Effortless/Manageable/Strained/Broken), daily shared hours, coverage, and the `loneWolf` — the member whose removal would free the most team overlap. Useful for scheduling and for hiring/team-composition decisions.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["zones"],
        "properties": {
          "zones": {
            "type": "array",
            "minItems": 1,
            "description": "IANA timezone identifiers, e.g. 'Europe/London'.",
            "items": { "type": "string" }
          },
          "start": {
            "type": "number",
            "description": "Default working-window start, minutes from local midnight (default 540 = 09:00).",
            "default": 540
          },
          "end": {
            "type": "number",
            "description": "Default working-window end, minutes from local midnight (default 1080 = 18:00).",
            "default": 1080
          },
          "hours": {
            "type": "string",
            "description": "Optional per-zone overrides aligned to `zones`, e.g. '540-1080;420-720'."
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "Reference date (ISO YYYY-MM-DD) for DST. Defaults to today (UTC)."
          }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "referenceDate": { "type": "string" },
          "overlap": {
            "type": ["object", "null"],
            "properties": {
              "startUtc": { "type": "number" },
              "endUtc": { "type": "number" },
              "durationMinutes": { "type": "number" },
              "startUtcLabel": { "type": "string" },
              "endUtcLabel": { "type": "string" },
              "local": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": { "type": "string" },
                    "timeZone": { "type": "string" },
                    "offset": { "type": "number" },
                    "start": { "type": "string" },
                    "end": { "type": "string" }
                  }
                }
              }
            }
          },
          "bestPartialCount": { "type": "number" },
          "friction": {
            "type": "object",
            "properties": {
              "score": { "type": "number", "description": "0–100; higher is less friction." },
              "grade": { "type": "string", "enum": ["Effortless", "Manageable", "Strained", "Broken"] },
              "dailyOverlapHours": { "type": "number" },
              "overlapMinutes": { "type": "number" },
              "coverage": { "type": "object", "properties": { "simultaneous": { "type": "number" }, "of": { "type": "number" } } },
              "loneWolf": { "type": "object", "properties": { "label": { "type": "string" }, "timeZone": { "type": "string" }, "gainMinutes": { "type": "number" } }, "description": "Present when N≥3 and dropping one member frees ≥2h of overlap." }
            }
          }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/meeting.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/meeting.json?zones=Europe/London,America/New_York,Australia/Sydney"
      }
    },
    {
      "name": "compare_contract",
      "title": "Compare contractor vs employee net take-home",
      "description": "Compute gross-to-net parity between a self-employed contractor hourly rate and an employee (W2/EOR) hourly rate, accounting for self-employment/income tax and self-paid health insurance, and return the break-even contractor rate. Uses transparent effective-rate tax presets per country, all overridable. Estimates only — not tax advice.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["contractorRate", "employeeRate"],
        "properties": {
          "contractorRate": { "type": "number", "minimum": 0, "description": "Self-employed hourly rate (USD)." },
          "employeeRate": { "type": "number", "minimum": 0, "description": "Employee/W2/EOR hourly rate (USD)." },
          "country": { "type": "string", "description": "Country code for tax presets.", "enum": ["US", "GB", "DE", "FR", "ES", "NL", "PT", "EE", "CA", "AU", "IN", "AE", "IT", "GR", "IE", "DK", "SE", "NO", "CH", "CZ", "PL", "HU", "TR", "JP", "KR", "CN", "SG", "MY", "TH", "VN", "ID", "PH", "NZ", "SA", "EG", "ZA", "NG", "MX", "BR", "AR", "CL", "CO"], "default": "US" },
          "hours": { "type": "number", "description": "Hours per week (default 40)." },
          "contractorWeeks": { "type": "number", "description": "Contractor paid/billable weeks (default 48)." },
          "employeeWeeks": { "type": "number", "description": "Employee paid weeks (default 52)." },
          "expenses": { "type": "number", "description": "Annual business expenses (USD, default 0)." },
          "health": { "type": "number", "description": "Annual self-paid health insurance (USD); defaults to the country preset." },
          "ctRate": { "type": "number", "description": "Override contractor effective tax rate, percent (e.g. 32)." },
          "empRate": { "type": "number", "description": "Override employee effective tax rate, percent (e.g. 24)." },
          "taxMode": { "type": "string", "enum": ["flat", "brackets"], "description": "'brackets' uses progressive 2025 schedules (US and GB only; falls back to flat elsewhere — response echoes the mode)." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "breakevenRate": { "type": "number" },
          "contractorProfitable": { "type": "boolean" },
          "netDifference": { "type": "number" },
          "contractor": { "type": "object", "properties": { "gross": { "type": "number" }, "tax": { "type": "number" }, "net": { "type": "number" } } },
          "employee": { "type": "object", "properties": { "gross": { "type": "number" }, "tax": { "type": "number" }, "net": { "type": "number" } } }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/contract.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/contract.json?contractorRate=100&employeeRate=70&country=US"
      }
    },
    {
      "name": "select_region",
      "title": "Select the lowest-latency cloud host region",
      "description": "Given a user-population breakdown, find the cloud host region that minimizes population-weighted round-trip latency (argmin_j Σ_i P_i × L_ij), and compute the optimal multi-region split (each user region routed to its nearest host). Latency is estimated from great-circle distance via a fiber-propagation model, not measured.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["users"],
        "properties": {
          "users": {
            "type": "string",
            "description": "Comma-separated region:percent pairs (percentages auto-normalize), e.g. 'US-East:40,UK:30,Germany:30'. Region ids: US-East, US-West, Canada, Brazil, UK, Germany, France, Spain, Nigeria, South-Africa, UAE, India, Singapore, China, Japan, Australia."
          },
          "hosts": {
            "type": "string",
            "description": "Optional comma-separated host region ids to restrict candidates (e.g. 'us-east-1,eu-west-2')."
          },
          "provider": {
            "type": "string",
            "enum": ["AWS", "GCP", "Azure"],
            "description": "Optional cloud provider filter, applied before the hosts whitelist."
          }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "best": {
            "type": "object",
            "properties": {
              "id": { "type": "string" },
              "provider": { "type": "string" },
              "city": { "type": "string" },
              "weightedMs": { "type": "number" }
            }
          },
          "ranking": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "string" },
                "weightedMs": { "type": "number" }
              }
            }
          },
          "split": {
            "type": "object",
            "properties": {
              "weightedMs": { "type": "number" },
              "improvementMs": { "type": "number" },
              "hostsUsed": { "type": "array", "items": { "type": "string" } }
            }
          }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/region.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/region.json?users=US-East:40,UK:30,Germany:30"
      }
    },
    {
      "name": "compare_countries",
      "title": "Compare two countries' cost of living",
      "description": "Side-by-side comparison of two countries: US-relative price levels across every dataset (World Bank, IMF, OECD, Penn World Table, consumption basket), the consensus ratio, percent difference, and $100k salary equivalence in both directions.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["a", "b"],
        "properties": {
          "a": { "type": "string", "description": "First ISO 3166-1 alpha-2 country code (case-insensitive)." },
          "b": { "type": "string", "description": "Second ISO 3166-1 alpha-2 country code (must differ from a)." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "ratioAtoB": { "type": "number" },
          "pctDifference": { "type": "number" },
          "salary100k": { "type": "object", "properties": { "aToB": { "type": "number" }, "bToA": { "type": "number" } } }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/compare.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/compare.json?a=DE&b=TH"
      }
    },
    {
      "name": "required_rate",
      "title": "Compute the required freelance hourly rate",
      "description": "Given a desired annual net income, compute the freelance hourly and day rate required after taxes, self-paid health insurance, weeks off, and billable utilization. Uses the same per-country effective-rate presets as compare_contract; all overridable. Estimates only — not tax advice.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["desiredNet"],
        "properties": {
          "desiredNet": { "type": "number", "minimum": 1, "description": "Desired annual net take-home (USD)." },
          "country": { "type": "string", "enum": ["US", "GB", "DE", "FR", "ES", "NL", "PT", "EE", "CA", "AU", "IN", "AE", "IT", "GR", "IE", "DK", "SE", "NO", "CH", "CZ", "PL", "HU", "TR", "JP", "KR", "CN", "SG", "MY", "TH", "VN", "ID", "PH", "NZ", "SA", "EG", "ZA", "NG", "MX", "BR", "AR", "CL", "CO"], "default": "US" },
          "hours": { "type": "number", "description": "Hours per week (default 40)." },
          "weeksOff": { "type": "number", "description": "Unpaid weeks off per year (default 4)." },
          "utilization": { "type": "number", "description": "Billable share of working hours, 0–1 (default 0.75)." },
          "expenses": { "type": "number", "description": "Annual business expenses (USD, default 0)." },
          "health": { "type": "number", "description": "Annual self-paid health insurance (USD); defaults to the country preset." },
          "taxRate": { "type": "number", "description": "Override effective tax rate, percent (e.g. 32)." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "hourlyRate": { "type": "number" },
          "dayRate": { "type": "number" },
          "requiredGross": { "type": "number" },
          "billableHours": { "type": "number" }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/rate.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/rate.json?desiredNet=100000&country=US&weeksOff=6&utilization=0.7"
      }
    },
    {
      "name": "check_residency",
      "title": "Check tax-residency day counts",
      "description": "Count distinct days of presence per country per calendar year and evaluate the generic 183-day rule, the US Substantial Presence Test (weighted 3-year formula), and the UK 183-day tax-year test. Early-warning day counter — not tax advice.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["stays"],
        "properties": {
          "stays": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["country", "entry", "exit"],
              "properties": {
                "country": { "type": "string", "description": "ISO 3166-1 alpha-2 country code." },
                "entry": { "type": "string", "format": "date" },
                "exit": { "type": "string", "format": "date" }
              }
            }
          },
          "referenceDate": { "type": "string", "format": "date", "description": "Optional 'as of' date. Defaults to today (UTC)." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "countries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "country": { "type": "string" },
                "daysThisYear": { "type": "number" },
                "rule183": { "type": "object", "properties": { "triggered": { "type": "boolean" }, "remaining": { "type": "number" } } }
              }
            }
          }
        }
      },
      "invocation": {
        "type": "http",
        "method": "POST",
        "url": "https://geo-parity.com/api/residency-check",
        "parameterMapping": "body",
        "example": "POST https://geo-parity.com/api/residency-check {\"stays\":[{\"country\":\"PT\",\"entry\":\"2026-01-10\",\"exit\":\"2026-04-02\"}]}"
      }
    },
    {
      "name": "check_travel_residency",
      "title": "Unified Schengen + tax-residency + tax-cost tracker",
      "description": "The comprehensive engine: from one travel itinerary it returns (1) Schengen 90/180 tourist-visa status (days used/remaining, first overstay, longest compliant stay), (2) per-country tax-residency risk on each country's OWN threshold and basis — the 183-day rule, Cyprus's conditional 60-day rule (flagged only when you're not 183+ resident elsewhere), the US Substantial Presence Test and the UK tax-year test — with safe days left, leave-by dates and a safe/warning/triggered rating, and (3) with an optional income, the tax cost of triggering residency at the standard rate vs an expat regime. Supersedes check_schengen / check_residency / check_tax_residency_risk (all still available). Early-warning day math — not tax advice.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["stays"],
        "properties": {
          "stays": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["country", "entry", "exit"],
              "properties": {
                "country": { "type": "string", "description": "ISO 3166-1 alpha-2 country code." },
                "entry": { "type": "string", "format": "date" },
                "exit": { "type": "string", "format": "date" }
              }
            }
          },
          "income": { "type": "number", "description": "Optional gross annual income (USD) — enables the tax-cost projection for at-risk countries." },
          "referenceDate": { "type": "string", "format": "date", "description": "Optional 'as of' date. Defaults to today (UTC)." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "referenceDate": { "type": "string" },
          "schengen": { "type": ["object", "null"], "description": "90/180 status when any Schengen stay exists: daysUsed, daysRemaining, compliant, firstOverstayDate, maxStayFromRef." },
          "countries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "country": { "type": "string" },
                "thresholdDays": { "type": "number" },
                "daysUsed": { "type": "number" },
                "safeDaysLeft": { "type": "number" },
                "risk": { "type": "string", "enum": ["safe", "warning", "triggered"] },
                "secondary": { "type": "object", "description": "Conditional lower rule (e.g. Cyprus-60) with conditionMet/triggered." },
                "usSubstantialPresence": { "type": "object" },
                "ukTaxYear": { "type": "object" },
                "taxProjection": { "type": "object", "description": "Standard vs regime tax cost when income was supplied." }
              }
            }
          },
          "summary": { "type": "object", "properties": { "worstRisk": { "type": "string" }, "triggeredCount": { "type": "number" }, "schengenBreached": { "type": "boolean" } } }
        }
      },
      "invocation": {
        "type": "http",
        "method": "POST",
        "url": "https://geo-parity.com/api/residency-tracker",
        "parameterMapping": "body",
        "example": "POST https://geo-parity.com/api/residency-tracker {\"stays\":[{\"country\":\"ES\",\"entry\":\"2026-01-10\",\"exit\":\"2026-07-28\"}],\"income\":120000}"
      }
    },
    {
      "name": "find_fire_locations",
      "title": "Find where a portfolio can fund early retirement",
      "description": "Geo-arbitrage FIRE analysis: given a portfolio and safe withdrawal rate, returns every country where the passive income sustains a lean ($32k US-equivalent/yr), comfortable ($55k), upper ($90k), or luxury ($150k) lifestyle at local purchasing-power prices — plus FIRE numbers per tier, nomad-visa income-floor eligibility, local-currency income, an SWR sensitivity band, (with savings/coast params) years until each country unlocks, and — where covered — a `statePension` overlay with the OECD net pension replacement rate (safety net from pension age; not subtracted from the FIRE numbers). Estimates only — not financial advice.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["portfolio"],
        "properties": {
          "portfolio": { "type": "number", "minimum": 0, "description": "Total investable portfolio (USD)." },
          "swr": { "type": "number", "description": "Safe withdrawal rate as fraction (0.04) or percent (4). Default 0.04.", "default": 0.04 },
          "source": { "type": "string", "enum": ["consensus", "worldbank", "imf", "oecd", "pwt", "worldbank-cons", "bigmac", "factbook"], "default": "consensus" },
          "savings": { "type": "number", "description": "Monthly savings (USD) — enables the years-to-FIRE planner." },
          "return": { "type": "number", "description": "Expected real annual return, fraction (0.05) or percent (5). Default 0.05." },
          "coast": { "type": "string", "enum": ["1"], "description": "Set to 1 for Coast-FIRE mode (project growth with zero further savings)." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "annualIncome": { "type": "number" },
          "monthlyIncome": { "type": "number" },
          "rows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "achievedTier": { "type": ["string", "null"], "enum": ["lean", "comfortable", "upper", "luxury", null] },
                "coverage": { "type": "number" },
                "tierCosts": { "type": "object" },
                "fireNumbers": { "type": "object" },
                "visa": { "type": "object" },
                "yearsToTier": { "type": "object" }
              }
            }
          },
          "sensitivity": { "type": "array", "items": { "type": "object" } }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/fire.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/fire.json?portfolio=400000&swr=0.04"
      }
    },
    {
      "name": "estimate_micro_costs",
      "title": "Estimate everyday prices in two countries (Pint & Property Index)",
      "description": "Estimates local prices for a 32-item everyday basket (rent, pint of beer, groceries, transport, gym, …) in two countries, derived as usPrice × pppIndex^elasticity — non-tradables like rent swing harder across borders than world-priced goods like petrol (Balassa-Samuelson-style model). Returns per-item prices in USD and local currency, category subtotals, and a single-person monthly budget rollup. Model estimates, not price quotes.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["base", "target"],
        "properties": {
          "base": { "type": "string", "description": "ISO 3166-1 alpha-2 country code to compare FROM (case-insensitive)." },
          "target": { "type": "string", "description": "ISO 3166-1 alpha-2 country code to compare TO (must differ from base)." },
          "source": { "type": "string", "enum": ["consensus", "worldbank", "imf", "oecd", "pwt", "worldbank-cons", "bigmac", "factbook"], "description": "Optional dataset override. Defaults to the consumption basket (worldbank-cons) when it covers both countries, else consensus; the response echoes the source used." },
          "baseCity": { "type": "string", "description": "Optional city slug for the base side (sub-national cost adjustment, e.g. 'london'). Enables intra-country city comparisons like London vs Hull." },
          "targetCity": { "type": "string", "description": "Optional city slug for the target side (e.g. 'hull')." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "source": { "type": "object", "properties": { "id": { "type": "string" }, "auto": { "type": "boolean" } } },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "item": { "type": "object" },
                "base": { "type": "object", "properties": { "usd": { "type": "number" } } },
                "target": { "type": "object", "properties": { "usd": { "type": "number" } } },
                "pctDiff": { "type": "number" }
              }
            }
          },
          "categoryTotals": { "type": "array", "items": { "type": "object" } },
          "monthlyBudget": { "type": "object", "properties": { "base": { "type": "number" }, "target": { "type": "number" }, "pctDiff": { "type": "number" } } }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/micro-costs.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/micro-costs.json?base=GB&target=TH"
      }
    },
    {
      "name": "check_tax_residency_risk",
      "title": "Check tax-residency risk for remote work abroad",
      "description": "Remote Worker Tax Trap radar: evaluates how close a stay is to triggering tax residency (183-day rule with per-country variations across 41 countries) and estimates the tax owed on the FULL annual income if the threshold is crossed — comparing the standard resident effective rate against the country's special expat/nomad regime (Spain's Beckham Law 24%, Portugal's IFICI 20%, Italy's impatriati, territorial/remittance systems, …). Optionally computes leave-by/residency dates from an arrival date and warns where the Schengen 90/180 tourist limit bites first. Early-warning estimates — not tax advice.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["country", "days", "income"],
        "properties": {
          "country": { "type": "string", "description": "ISO 3166-1 alpha-2 country code (case-insensitive)." },
          "days": { "type": "number", "minimum": 0, "maximum": 366, "description": "Days of presence in the relevant counting period." },
          "income": { "type": "number", "minimum": 0, "description": "Gross annual income (USD) the residency cliff would expose." },
          "arrival": { "type": "string", "format": "date", "description": "Optional arrival date — adds leaveBy and residencyDate to the response." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "risk": { "type": "string", "enum": ["safe", "warning", "triggered"] },
          "daysRemaining": { "type": "number" },
          "thresholdDays": { "type": "number" },
          "pctOfThreshold": { "type": "number" },
          "projection": {
            "type": "object",
            "properties": {
              "standard": { "type": "object", "properties": { "effectiveRate": { "type": "number" }, "taxUsd": { "type": "number" } } },
              "regime": { "type": "object", "properties": { "name": { "type": "string" }, "taxUsd": { "type": "number" }, "savingUsd": { "type": "number" }, "note": { "type": "string" } } },
              "cheapest": { "type": "string" }
            }
          },
          "dates": { "type": "object", "properties": { "leaveBy": { "type": "string" }, "residencyDate": { "type": "string" } } },
          "schengenWarning": { "type": "string" }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/tax-trap.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/tax-trap.json?country=ES&days=120&income=80000"
      }
    },
    {
      "name": "rank_livability",
      "title": "Rank countries by quality of life vs cost",
      "description": "Quality-of-Life vs Cost matrix: ranks 41 countries by a user-weighted composite of livability metrics (median broadband Mbps, safety, healthcare, air quality, English usability — curated country-level data replacing the discontinued Teleport API) against the monthly cost of single-person essentials at local purchasing-power prices. Returns per-country composite and value scores, lifestyle label for your budget (comfortable → like royalty), nomad-visa eligibility, and days-to-tax-residency. Curated estimates — verify locally.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "budget": { "type": "number", "minimum": 0, "default": 3000, "description": "Monthly budget (USD) — drives lifestyle labels and visa eligibility." },
          "minInternet": { "type": "number", "minimum": 0, "description": "Filter: minimum median broadband, Mbps (e.g. 80)." },
          "minSafety": { "type": "number", "minimum": 0, "maximum": 100, "description": "Filter: minimum safety score, 0–100." },
          "maxBudget": { "type": "number", "minimum": 0, "description": "Filter: keep countries whose monthly essentials cost ≤ this (USD)." },
          "weights": { "type": "string", "description": "Five comma-separated 0–10 weights: internet,safety,healthcare,air,english (default 5,5,5,5,5)." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "rows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "entry": { "type": "object" },
                "essentialsUsd": { "type": "number" },
                "composite": { "type": "number" },
                "valueScore": { "type": "number" },
                "lifestyle": { "type": "string", "enum": ["out of budget", "comfortable", "very comfortable", "like royalty"] },
                "visa": { "type": "object" },
                "taxThresholdDays": { "type": "number" }
              }
            }
          },
          "excluded": { "type": "number" }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/livability.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/livability.json?minInternet=80&maxBudget=3000"
      }
    },
    {
      "name": "find_nomad_visas",
      "title": "Match income to digital nomad visas",
      "description": "Digital-nomad visa Income Matcher: given a monthly remote income (any currency) and household size, computes each program's real income threshold (base plus its published per-dependent uplift) and returns the programs you qualify for plus the near misses just out of reach — with duration, renewability, tax notes and official source URLs. Curated summaries — verify with the official source before applying.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "income": { "type": "number", "description": "Your gross monthly income (in `currency`, default USD)." },
          "currency": { "type": "string", "description": "ISO currency code for `income` (e.g. EUR, GBP, INR). Defaults to USD." },
          "partners": { "type": "number", "enum": [0, 1], "description": "1 if bringing a partner (raises each program's threshold by its partner uplift)." },
          "children": { "type": "number", "description": "Number of dependent children (each adds the program's child uplift)." },
          "minDuration": { "type": "number", "description": "Minimum program duration in months." },
          "renewable": { "type": "string", "enum": ["1"], "description": "Set to 1 to require renewable programs." },
          "residency": { "type": "string", "enum": ["1"], "description": "Set to 1 to require a path to permanent residency." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "updated": { "type": "string" },
          "total": { "type": "number" },
          "incomeUsd": { "type": "number", "description": "Your income converted to USD, used for matching." },
          "household": { "type": "object", "properties": { "partners": { "type": "number" }, "children": { "type": "number" } } },
          "matches": { "type": "array", "items": { "type": "object" }, "description": "Programs you qualify for; each carries requiredUsd (household threshold) and shortfallUsd (≤0)." },
          "nearMisses": { "type": "array", "items": { "type": "object" }, "description": "Programs within ~$1,000/mo of qualifying, closest first." }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/nomad-visas.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/nomad-visas.json?income=4000&currency=EUR&partners=1&children=1"
      }
    },
    {
      "name": "passport_power",
      "title": "Passport visa-free access score and global rank",
      "description": "Passport Power: for a given country's passport, returns the visa-free-access score (visa-free + visa-on-arrival + eTA destinations), global rank and percentile among all ~199 passports, and the full destination breakdown by access type with names resolved. Omit country for the ranked league table. Reference data from the open ilyankou/passport-index-dataset (public domain) — confirm entry rules with the destination authority before travel.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "country": { "type": "string", "description": "Passport country alpha-2 code (e.g. US, GB, SG). Omit for the full league table." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "passport": {
            "type": "object",
            "properties": {
              "code": { "type": "string" },
              "name": { "type": "string" },
              "mobilityScore": { "type": "number" },
              "rank": { "type": "number" },
              "counts": { "type": "object" },
              "destinations": { "type": "object" }
            }
          },
          "totalPassports": { "type": "number" },
          "percentile": { "type": "number" },
          "resolved": { "type": "object" }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/passport.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/passport.json?country=SG"
      }
    },
    {
      "name": "calculate_runway",
      "title": "Runway multiplier from relocating (bootstrap buffer)",
      "description": "For founders/freelancers stretching savings: computes how many extra months of runway relocating to a cheaper hub buys. Burn is split into fixed (location-independent — subscriptions, debt, insurance) and local; only the local slice scales by the target's cost-of-living ratio (city-level where a curated hub is given, else national, incl. Factbook-only countries). Returns the home baseline plus each hub's monthly burn, runway months, extra months, run-out date and the ×multiplier. Estimates from purchasing-power data, not financial advice.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["savings", "burn", "targets"],
        "properties": {
          "savings": { "type": "number", "description": "Total savings (in `currency`)." },
          "burn": { "type": "number", "description": "Total current monthly burn at home (in `currency`)." },
          "fixed": { "type": "number", "description": "Location-independent slice of burn (0…burn) that won't fall when you move." },
          "currency": { "type": "string", "description": "ISO code for the money inputs (e.g. GBP). Default USD." },
          "home": { "type": "string", "description": "Home country alpha-2 code. Default US." },
          "homeCity": { "type": "string", "description": "Optional curated home-city slug." },
          "targets": { "type": "string", "description": "1–3 hubs, comma-separated: COUNTRY or COUNTRY:citySlug (e.g. TH:chiang-mai,AR:buenos-aires,GE)." }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "home": { "type": "object", "properties": { "runwayMonths": { "type": "number" }, "runsOut": { "type": "string" } } },
          "fixedFloorMonths": { "type": ["number", "null"], "description": "Runway cap even at zero local cost (savings ÷ fixed burn)." },
          "hubs": { "type": "array", "items": { "type": "object" }, "description": "Sorted by extra months; each has runwayMonths, extraMonths, multiplier, monthlyBurnUsd, runsOut, priceRatio and a coverage note when approximate." }
        }
      },
      "invocation": {
        "type": "http",
        "method": "GET",
        "url": "https://geo-parity.com/api/runway.json",
        "parameterMapping": "query",
        "example": "https://geo-parity.com/api/runway.json?savings=20000&burn=3000&fixed=800&currency=GBP&home=GB&targets=TH:chiang-mai,GE"
      }
    }
  ]
}
