# Pneumonia Severity Index (Fine / PORT)

PSI / PORT

Status: WEDGE
Price: $0.005 USDC
`GET /api/calc/psi_port`
HTML: https://magentlab.com/docs/psi-port
Markdown: https://magentlab.com/docs/psi-port.md

Not a medical device. Not a diagnosis, dose, or listing recommendation.

## What it computes

Compute the Fine 1997 Pneumonia Severity Index (PORT) two-step risk class and Table 2 point total for community-acquired pneumonia.

## When to use

When an agent needs the published Fine 1997 PSI/PORT two-step class and Table 2 total and must not invent bands or skip Step 1.

## When not to use

- Not a medical device and not a site-of-care, admission, or treatment protocol.
- Fine 1997 two-step rule only. Class I is assigned from Step 1 even when Table 2 points would map to class II–V. The Table 2 total is always returned.
- Glucose is mg/dL only (Fine Table 2). magent does not convert mmol/L.
- The caller assigns comorbidities, mental status, nursing-home status, and pleural effusion. magent does not examine the patient.
- Not CURB-65 or CRB-65. Those are separate tools.

## Formula

```
PSI/PORT two-step (Fine 1997): Class I if age<=50 and no neoplastic, liver, CHF, cerebrovascular, renal, AMS and HR<125, RR<30, SBP>=90, temp>=35 and <40; else Table 2 points: age (men) or age-10 (women) + nursing_home 10 + neoplastic 30 + liver 20 + CHF 10 + cerebrovascular 10 + renal 10 + AMS 20 + RR>=30 20 + SBP<90 20 + (temp<35 or >=40) 15 + HR>=125 10 + pH<7.35 30 + BUN>=30 20 + Na<130 20 + glucose>=250 10 + Hct<30 10 + PaO2<60 10 + pleural_effusion 10; class I from step 1 else 2 if <=70, 3 if 71-90, 4 if 91-130, 5 if >130
```

## Citation

[A prediction rule to identify low-risk patients with community-acquired pneumonia](https://doi.org/10.1056/NEJM199701233360402)
Fine MJ, Auble TE, Yealy DM, et al.
N Engl J Med. 1997;336(4):243-250
DOI: [10.1056/NEJM199701233360402](https://doi.org/10.1056/NEJM199701233360402)

## Worked example

### Age 45, male, all flags false, normal vitals and labs

Given: `age=45, altered_mental_status=false, arterial_ph=7.40, bun_mg_dl=14, cerebrovascular=false, chf=false, glucose_mg_dl=90, heart_rate_bpm=80, hematocrit_percent=42, liver_disease=false, neoplastic=false, nursing_home=false, pao2_mm_hg=90, pleural_effusion=false, renal_disease=false, respiratory_rate=16, sex=male, sodium_mmol_l=140, systolic_mm_hg=120, temperature_c=37.0`

1. Age 45 ≤50, no neoplastic/liver/CHF/cerebrovascular/renal disease, no AMS, HR 80 <125, RR 16 <30, SBP 120 ≥90, temperature 37.0 is ≥35 and <40 → Step 1 Class I
2. Table 2: male age points = 45; remaining items absent
3. score = 45; risk_class = 1 (Class I, not class II from the ≤70 point cutoff)


### Age 80, male, all other items absent (class III)

Given: `age=80, altered_mental_status=false, arterial_ph=7.40, bun_mg_dl=14, cerebrovascular=false, chf=false, glucose_mg_dl=90, heart_rate_bpm=80, hematocrit_percent=42, liver_disease=false, neoplastic=false, nursing_home=false, pao2_mm_hg=90, pleural_effusion=false, renal_disease=false, respiratory_rate=16, sex=male, sodium_mmol_l=140, systolic_mm_hg=120, temperature_c=37.0`

1. Age 80 is not ≤50 → Step 2
2. Table 2: male age points = 80; remaining items absent
3. score = 80; risk_class = 3 (71–90)


## Also searched as

- psi
- port
- fine
- cap
- pneumonia severity
- pneumonia severity index
- Fine PSI
- PORT score
- PSI PORT

## Parameters

- `age` (integer, required): Age in years (18-120). Table 2: men add the age integer; women add age − 10. Step 1 Class I requires age ≤50 (Fine: 50 years of age or younger).
- `sex` (string, required): Sex (female or male). Women subtract 10 from the age points.
- `nursing_home` (boolean, required): Nursing home resident as assigned by the caller. true or false. Table 2 +10 if true. Not a Step 1 Class I item.
- `neoplastic` (boolean, required): Neoplastic disease as assigned by the caller. true or false. Step 1 excludes Class I if true. Table 2 +30 if true.
- `liver_disease` (boolean, required): Liver disease as assigned by the caller. true or false. Step 1 excludes Class I if true. Table 2 +20 if true.
- `chf` (boolean, required): Congestive heart failure as assigned by the caller. true or false. Step 1 excludes Class I if true. Table 2 +10 if true.
- `cerebrovascular` (boolean, required): Cerebrovascular disease as assigned by the caller. true or false. Step 1 excludes Class I if true. Table 2 +10 if true.
- `renal_disease` (boolean, required): Renal disease as assigned by the caller. true or false. Step 1 excludes Class I if true. Table 2 +10 if true.
- `altered_mental_status` (boolean, required): Altered mental status as assigned by the caller. true or false. Step 1 excludes Class I if true. Table 2 +20 if true.
- `heart_rate_bpm` (integer, required): Heart rate in beats per minute (integer 30-220). Step 1 Class I requires <125. Table 2 +10 when ≥125; 124 does not score.
- `respiratory_rate` (integer, required): Respiratory rate in breaths/min (integer 4-80). Step 1 Class I requires <30. Table 2 +20 when ≥30; 29 does not score.
- `systolic_mm_hg` (number, required): Systolic blood pressure in mm Hg (50-250). Step 1 Class I requires ≥90. Table 2 +20 when <90; 90 does not score.
- `temperature_c` (number, required): Temperature in °C (30-45). Step 1 Class I requires ≥35 and <40. Table 2 +15 when <35 or ≥40; 35.0 and 39.9 do not score.
- `arterial_ph` (number, required): Arterial pH (6.80-7.80). Table 2 +30 when <7.35; 7.35 does not score. Not a Step 1 Class I item.
- `bun_mg_dl` (number, required): Blood urea nitrogen in mg/dL (1-200). Table 2 +20 when ≥30; 29.9 does not score. Not a Step 1 Class I item.
- `sodium_mmol_l` (number, required): Serum sodium in mmol/L (110-160). Table 2 +20 when <130; 130 does not score. Not a Step 1 Class I item.
- `glucose_mg_dl` (number, required): Serum glucose in mg/dL (50-1000). Fine Table 2 is mg/dL only. Table 2 +10 when ≥250; 249 does not score. Not a Step 1 Class I item.
- `hematocrit_percent` (number, required): Hematocrit percent (10-70). Table 2 +10 when <30; 30 does not score. Not a Step 1 Class I item.
- `pao2_mm_hg` (number, required): Arterial PaO2 in mm Hg (20-700). Table 2 +10 when <60; 60 does not score. Not a Step 1 Class I item.
- `pleural_effusion` (boolean, required): Pleural effusion as assigned by the caller. true or false. Table 2 +10 if true. Not a Step 1 Class I item.

## Bulk (POST)

POST the same path with a JSON items array. The first item is the GET unit; each additional item is $0.002. Invalid items return HTTP 400 before settlement.

Method: `POST /api/calc/psi_port`
Max items: 25
Price: unit_amount + extra_item_amount * (n - 1) (unit 5000 atomic, extra 2000 atomic)
Status: PREVIEW

- 1 to 25 items. Each item uses the same keys as the GET query parameters.
- POST of 1 item costs the same as GET. Lists longer than 25: chunk into multiple POSTs. Extra items still execute; do not pad dummy rows.
- The first invalid item fails the whole request (index in the 400 JSON). You are not charged.
- HTTP 200 is {count, path, items}. Each items[i] is the GET 200 body for that row.
- Catalog misses (empty matches, found=false) stay paid 200s inside that slot.
- x402 resource URL is this path plus n and body_sha256. Browsers that prefer text/html get the same paywall as GET; Pay retries POST with the same items.

Example request:

```json
{
  "items": [
    {
      "age": "45",
      "altered_mental_status": "false",
      "arterial_ph": "7.40",
      "bun_mg_dl": "14",
      "cerebrovascular": "false",
      "chf": "false",
      "glucose_mg_dl": "90",
      "heart_rate_bpm": "80",
      "hematocrit_percent": "42",
      "liver_disease": "false",
      "neoplastic": "false",
      "nursing_home": "false",
      "pao2_mm_hg": "90",
      "pleural_effusion": "false",
      "renal_disease": "false",
      "respiratory_rate": "16",
      "sex": "male",
      "sodium_mmol_l": "140",
      "systolic_mm_hg": "120",
      "temperature_c": "37.0"
    },
    {
      "age": "45",
      "altered_mental_status": "false",
      "arterial_ph": "7.40",
      "bun_mg_dl": "14",
      "cerebrovascular": "false",
      "chf": "false",
      "glucose_mg_dl": "90",
      "heart_rate_bpm": "80",
      "hematocrit_percent": "42",
      "liver_disease": "false",
      "neoplastic": "false",
      "nursing_home": "false",
      "pao2_mm_hg": "90",
      "pleural_effusion": "false",
      "renal_disease": "false",
      "respiratory_rate": "16",
      "sex": "male",
      "sodium_mmol_l": "140",
      "systolic_mm_hg": "120",
      "temperature_c": "37.0"
    }
  ]
}
```

Human paywall (two-item fixture): https://api.magentlab.com/paywall/bulk/psi-port

Example 200:

```json
{
  "count": 2,
  "path": "/api/calc/psi_port",
  "items": [
    {
      "components": [
        {
          "value": 45,
          "factor": "age",
          "points": 45,
          "present": true
        },
        {
          "factor": "nursing_home",
          "points": 0,
          "present": false
        },
        {
          "factor": "neoplastic",
          "points": 0,
          "present": false
        },
        {
          "factor": "liver_disease",
          "points": 0,
          "present": false
        },
        {
          "factor": "chf",
          "points": 0,
          "present": false
        },
        {
          "factor": "cerebrovascular",
          "points": 0,
          "present": false
        },
        {
          "factor": "renal_disease",
          "points": 0,
          "present": false
        },
        {
          "factor": "altered_mental_status",
          "points": 0,
          "present": false
        },
        {
          "value": 16,
          "factor": "respiratory_rate_ge_30",
          "points": 0,
          "present": false
        },
        {
          "value": 120.0,
          "factor": "systolic_mm_hg_lt_90",
          "points": 0,
          "present": false
        },
        {
          "value": 37.0,
          "factor": "temperature_extreme",
          "points": 0,
          "present": false
        },
        {
          "value": 80,
          "factor": "heart_rate_ge_125",
          "points": 0,
          "present": false
        },
        {
          "value": 7.4,
          "factor": "arterial_ph_lt_7_35",
          "points": 0,
          "present": false
        },
        {
          "value": 14.0,
          "factor": "bun_ge_30",
          "points": 0,
          "present": false
        },
        {
          "value": 140.0,
          "factor": "sodium_lt_130",
          "points": 0,
          "present": false
        },
        {
          "value": 90.0,
          "factor": "glucose_ge_250",
          "points": 0,
          "present": false
        },
        {
          "value": 42.0,
          "factor": "hematocrit_lt_30",
          "points": 0,
          "present": false
        },
        {
          "value": 90.0,
          "factor": "pao2_lt_60",
          "points": 0,
          "present": false
        },
        {
          "factor": "pleural_effusion",
          "points": 0,
          "present": false
        }
      ],
      "disclaimer": "Not a medical device. Deterministic published-formula or published-code output for autonomous agents. A licensed clinician remains responsible for patient care and billing submissions.",
      "citation": {
        "authors": "Fine MJ, Auble TE, Yealy DM, et al.",
        "doi": "10.1056/NEJM199701233360402",
        "id": "fine-1997",
        "pmid": "8995086",
        "source": "N Engl J Med. 1997;336(4):243-250",
        "title": "A prediction rule to identify low-risk patients with community-acquired pneumonia"
      },
      "formula": "psi_port",
      "formula_expression": "PSI/PORT two-step (Fine 1997): Class I if age<=50 and no neoplastic, liver, CHF, cerebrovascular, renal, AMS and HR<125, RR<30, SBP>=90, temp>=35 and <40; else Table 2 points: age (men) or age-10 (women) + nursing_home 10 + neoplastic 30 + liver 20 + CHF 10 + cerebrovascular 10 + renal 10 + AMS 20 + RR>=30 20 + SBP<90 20 + (temp<35 or >=40) 15 + HR>=125 10 + pH<7.35 30 + BUN>=30 20 + Na<130 20 + glucose>=250 10 + Hct<30 10 + PaO2<60 10 + pleural_effusion 10; class I from step 1 else 2 if <=70, 3 if 71-90, 4 if 91-130, 5 if >130",
      "age_years": 45,
      "score": 45,
      "risk_class": 1
    },
    {
      "components": [
        {
          "value": 45,
          "factor": "age",
          "points": 45,
          "present": true
        },
        {
          "factor": "nursing_home",
          "points": 0,
          "present": false
        },
        {
          "factor": "neoplastic",
          "points": 0,
          "present": false
        },
        {
          "factor": "liver_disease",
          "points": 0,
          "present": false
        },
        {
          "factor": "chf",
          "points": 0,
          "present": false
        },
        {
          "factor": "cerebrovascular",
          "points": 0,
          "present": false
        },
        {
          "factor": "renal_disease",
          "points": 0,
          "present": false
        },
        {
          "factor": "altered_mental_status",
          "points": 0,
          "present": false
        },
        {
          "value": 16,
          "factor": "respiratory_rate_ge_30",
          "points": 0,
          "present": false
        },
        {
          "value": 120.0,
          "factor": "systolic_mm_hg_lt_90",
          "points": 0,
          "present": false
        },
        {
          "value": 37.0,
          "factor": "temperature_extreme",
          "points": 0,
          "present": false
        },
        {
          "value": 80,
          "factor": "heart_rate_ge_125",
          "points": 0,
          "present": false
        },
        {
          "value": 7.4,
          "factor": "arterial_ph_lt_7_35",
          "points": 0,
          "present": false
        },
        {
          "value": 14.0,
          "factor": "bun_ge_30",
          "points": 0,
          "present": false
        },
        {
          "value": 140.0,
          "factor": "sodium_lt_130",
          "points": 0,
          "present": false
        },
        {
          "value": 90.0,
          "factor": "glucose_ge_250",
          "points": 0,
          "present": false
        },
        {
          "value": 42.0,
          "factor": "hematocrit_lt_30",
          "points": 0,
          "present": false
        },
        {
          "value": 90.0,
          "factor": "pao2_lt_60",
          "points": 0,
          "present": false
        },
        {
          "factor": "pleural_effusion",
          "points": 0,
          "present": false
        }
      ],
      "disclaimer": "Not a medical device. Deterministic published-formula or published-code output for autonomous agents. A licensed clinician remains responsible for patient care and billing submissions.",
      "citation": {
        "authors": "Fine MJ, Auble TE, Yealy DM, et al.",
        "doi": "10.1056/NEJM199701233360402",
        "id": "fine-1997",
        "pmid": "8995086",
        "source": "N Engl J Med. 1997;336(4):243-250",
        "title": "A prediction rule to identify low-risk patients with community-acquired pneumonia"
      },
      "formula": "psi_port",
      "formula_expression": "PSI/PORT two-step (Fine 1997): Class I if age<=50 and no neoplastic, liver, CHF, cerebrovascular, renal, AMS and HR<125, RR<30, SBP>=90, temp>=35 and <40; else Table 2 points: age (men) or age-10 (women) + nursing_home 10 + neoplastic 30 + liver 20 + CHF 10 + cerebrovascular 10 + renal 10 + AMS 20 + RR>=30 20 + SBP<90 20 + (temp<35 or >=40) 15 + HR>=125 10 + pH<7.35 30 + BUN>=30 20 + Na<130 20 + glucose>=250 10 + Hct<30 10 + PaO2<60 10 + pleural_effusion 10; class I from step 1 else 2 if <=70, 3 if 71-90, 4 if 91-130, 5 if >130",
      "age_years": 45,
      "score": 45,
      "risk_class": 1
    }
  ]
}
```

## Response fields

- `formula` (string): psi_port
- `formula_expression` (string): Exact expression used
- `score` (integer): Fine Table 2 point total (always returned, including Class I)
- `risk_class` (integer): 1 if Step 1 Class I; else 2 if score ≤70, 3 if 71-90, 4 if 91-130, 5 if >130
- `age_years` (integer): Age used for Step 1 and Table 2
- `components` (array): Per-factor Table 2 points
- `citation` (object): Fine 1997 citation
- `disclaimer` (string): Not-a-device notice

## Example JSON

Frozen fixture. Not a live lookup.

```json
{
  "components": [
    {
      "value": 45,
      "factor": "age",
      "points": 45,
      "present": true
    },
    {
      "factor": "nursing_home",
      "points": 0,
      "present": false
    },
    {
      "factor": "neoplastic",
      "points": 0,
      "present": false
    },
    {
      "factor": "liver_disease",
      "points": 0,
      "present": false
    },
    {
      "factor": "chf",
      "points": 0,
      "present": false
    },
    {
      "factor": "cerebrovascular",
      "points": 0,
      "present": false
    },
    {
      "factor": "renal_disease",
      "points": 0,
      "present": false
    },
    {
      "factor": "altered_mental_status",
      "points": 0,
      "present": false
    },
    {
      "value": 16,
      "factor": "respiratory_rate_ge_30",
      "points": 0,
      "present": false
    },
    {
      "value": 120.0,
      "factor": "systolic_mm_hg_lt_90",
      "points": 0,
      "present": false
    },
    {
      "value": 37.0,
      "factor": "temperature_extreme",
      "points": 0,
      "present": false
    },
    {
      "value": 80,
      "factor": "heart_rate_ge_125",
      "points": 0,
      "present": false
    },
    {
      "value": 7.4,
      "factor": "arterial_ph_lt_7_35",
      "points": 0,
      "present": false
    },
    {
      "value": 14.0,
      "factor": "bun_ge_30",
      "points": 0,
      "present": false
    },
    {
      "value": 140.0,
      "factor": "sodium_lt_130",
      "points": 0,
      "present": false
    },
    {
      "value": 90.0,
      "factor": "glucose_ge_250",
      "points": 0,
      "present": false
    },
    {
      "value": 42.0,
      "factor": "hematocrit_lt_30",
      "points": 0,
      "present": false
    },
    {
      "value": 90.0,
      "factor": "pao2_lt_60",
      "points": 0,
      "present": false
    },
    {
      "factor": "pleural_effusion",
      "points": 0,
      "present": false
    }
  ],
  "disclaimer": "Not a medical device. Deterministic published-formula or published-code output for autonomous agents. A licensed clinician remains responsible for patient care and billing submissions.",
  "citation": {
    "authors": "Fine MJ, Auble TE, Yealy DM, et al.",
    "doi": "10.1056/NEJM199701233360402",
    "id": "fine-1997",
    "pmid": "8995086",
    "source": "N Engl J Med. 1997;336(4):243-250",
    "title": "A prediction rule to identify low-risk patients with community-acquired pneumonia"
  },
  "formula": "psi_port",
  "formula_expression": "PSI/PORT two-step (Fine 1997): Class I if age<=50 and no neoplastic, liver, CHF, cerebrovascular, renal, AMS and HR<125, RR<30, SBP>=90, temp>=35 and <40; else Table 2 points: age (men) or age-10 (women) + nursing_home 10 + neoplastic 30 + liver 20 + CHF 10 + cerebrovascular 10 + renal 10 + AMS 20 + RR>=30 20 + SBP<90 20 + (temp<35 or >=40) 15 + HR>=125 10 + pH<7.35 30 + BUN>=30 20 + Na<130 20 + glucose>=250 10 + Hct<30 10 + PaO2<60 10 + pleural_effusion 10; class I from step 1 else 2 if <=70, 3 if 71-90, 4 if 91-130, 5 if >130",
  "age_years": 45,
  "score": 45,
  "risk_class": 1
}
```

## Errors

- HTTP 400 `invalid_age`: age must be an integer from 18 to 120 Returned before settlement; you are not charged.
- HTTP 400 `invalid_sex`: sex must be female or male Returned before settlement; you are not charged.
- HTTP 400 `invalid_flag`: boolean clinical flags must be true or false Returned before settlement; you are not charged.
- HTTP 400 `invalid_heart_rate`: heart_rate_bpm must be an integer from 30 to 220 Returned before settlement; you are not charged.
- HTTP 400 `invalid_respiratory_rate`: respiratory_rate must be an integer from 4 to 80. Returned before settlement; you are not charged.
- HTTP 400 `invalid_temperature`: temperature_c must be a number from 30.0 to 45.0. Returned before settlement; you are not charged.
- HTTP 400 `invalid_systolic_bp`: systolic_mm_hg or systolic_bp_mm_hg must be a number from 50 to 250. Returned before settlement; you are not charged.
- HTTP 400 `invalid_arterial_ph`: arterial_ph must be a number from 6.80 to 7.80. Returned before settlement; you are not charged.
- HTTP 400 `invalid_bun`: bun_mg_dl must be a number from 1 to 200. Returned before settlement; you are not charged.
- HTTP 400 `invalid_sodium`: sodium_mmol_l must be a number from 110 to 160 Returned before settlement; you are not charged.
- HTTP 400 `invalid_glucose`: glucose_mg_dl (50-1000) or glucose_mmol_l (2.8-55.5) is required Returned before settlement; you are not charged.
- HTTP 400 `invalid_hematocrit`: hematocrit_percent must be a number from 10 to 70. Returned before settlement; you are not charged.
- HTTP 400 `invalid_pao2`: pao2_mm_hg must be a number from 20 to 700. Returned before settlement; you are not charged.
- HTTP 400 `invalid_items`: POST body must be a JSON object with only an items array Returned before settlement; you are not charged.
- HTTP 400 `invalid_item_count`: items must be an array of 1 to 25 objects Returned before settlement; you are not charged.
- HTTP 400 `invalid_item`: each items entry must be a JSON object Returned before settlement; you are not charged.

Shared HTTP 402 and 503: https://magentlab.com/docs/payments

## Related tools

- [CURB-65](https://magentlab.com/docs/curb65) — Compute the CURB-65 community-acquired pneumonia severity score from age and discrete flags.
- [CRB-65](https://magentlab.com/docs/crb-65) — Compute the Lim 2003 CRB-65 community-acquired pneumonia score from age and caller-assigned confusion, respiratory-rate, and blood-pressure flags. Urea is not an input.

## Payment

Unpaid requests return HTTP 402 even if query parameters or POST items are missing or invalid, so CDP and agents can index the path. After a PAYMENT-SIGNATURE, invalid params return HTTP 400 JSON before settlement. magent does not charge. Fix the params, then request a new 402 quote for that complete URL. Catalog misses (empty matches, found=false) are valid paid 200s.

- GET the tool with Accept: application/json (do not send Accept: text/html unless you want the human paywall).
- HTTP 402 means you have not paid. Decode the base64 PAYMENT-REQUIRED header. HTTP 503 is not a new quote.
- Sign accepts[0] (exact, EIP-3009) with validBefore = now + maxTimeoutSeconds (600 seconds), or accepts[1] (batch-settlement deposit/voucher) on product GET. Ping and POST {items} stay exact. Magent retries transient facilitator 429/5xx before answering.
- Retry the same URL with PAYMENT-SIGNATURE (base64 JSON echoing accepted, payload, and extensions when present).
- Success is HTTP 200 JSON plus PAYMENT-RESPONSE. exact settles before the tool. batch-settlement verifies (and deposit-settles) before the tool and commits the charge after HTTP 2xx. HTTP 503: retry the same PAYMENT-SIGNATURE. Mint a new exact nonce only after a new HTTP 402.

- offered `exact` on eip155:8453: Fixed-price USDC on Base. The buyer authorizes the advertised amount (EIP-3009). magent settles before the tool runs (paymentFlow upfront). extra.assetTransferMethod=eip3009 extra.paymentFlow=upfront.
- offered `batch-settlement` on eip155:8453: Payment-channel vouchers claimed later in batches. Exact stays accepts[0]. Same-path POST {items} is still exact. extra.assetTransferMethod=eip3009 extra.paymentFlow=authorization.

- not offered `upto`: Not offered. Usage-based: buyer authorizes a ceiling, seller settles the actual amount after work. Reserved for a future metered tool. Not for current calculators or code search.

Same-path POST {items} is still scheme exact: one EIP-3009 authorization for GET unit plus $0.002 per extra item. That is not x402 batch-settlement (payment channels / vouchers).

Shared HTTP 402 and 503 table: https://magentlab.com/docs/payments

Stdio MCP (one process per host): https://magentlab.com/docs/mcp

## Guarantees

- HTTP 402 is unpaid, including a missing query. After PAYMENT-SIGNATURE, invalid parameters return HTTP 400 before settlement. You are not charged.
- exact: settlement finishes before the tool (paymentFlow upfront). batch-settlement: verify/deposit before the tool; chargedCumulativeAmount commits after HTTP 2xx. Uncertain or failed settlement fails closed (HTTP 503). Retry the same PAYMENT-SIGNATURE.
- HTTP 402 is unpaid only. Do not sign a second authorization because of a 503.
- Execution is timeout-bounded and concurrency-capped.
- Calculator inputs are stored encrypted for allowlisted operators (Magent Console). They are not in public logs, SSH lookups, catalog, or rollups. Request logs store path without query.
