Decide before runtime whether a workflow is modeled, deterministic-decline, needs_review, planned, or unsupported.
Backend engineers deciding what to send to Tax MCP.
The capability manifest is the pre-payload source of truth. Roadmap pages are intent, not shipped support.
Reference links: GET /api/mcp/tax-capabilities for the supported envelope, OpenAPI for request and response schema, roadmap feedback, changelog/release notes, support/contact, and terms.
Call GET /api/mcp/tax-capabilities to inspect jurisdictions, years, filing statuses, fields, affirmations, decline codes, review states, and billing semantics.
Use OpenAPI for request shape and schema validation. Use roadmap for planned or certifying work only.
Modeled workflows can compute when all required fields and affirmations are supplied.
Missing affirmations, residual Schedule D mechanics, unsupported years, unsupported states, and broad upload-to-compute workflows must route to deterministic decline or review.
| State | HTTP | Billed | Retry safe | next_action | Client display guidance |
|---|---|---|---|---|---|
| Computed | 200 | Yes on metered customer plans | true with the same Idempotency-Key | none | Show computed figures with derivation and provenance. |
| Deterministic decline | 200 | Yes on metered customer plans | false for the same unsupported body | review_inputs | Show the reason and route to review; do not show a tax estimate. |
| needs_review | 200 | Yes on metered customer plans | true for replay; human review is still required | review_inputs | Show the review queue item, diff, reason, and provenance. |
| Validation error | 400 | No | false until request shape is fixed | fix_request_and_resubmit | Show a request-error state and tell the developer what field to fix. |
| Auth error | 401/403 | No | false until credentials are fixed | check_credentials | Ask the operator to check, rotate, or unsuspend the API key. |
| Quota or rate limit | 429 | No | quota: false; rate: true after backoff | upgrade_plan_or_wait_next_period or retry_after_backoff | Hard-stop quota or transient rate-limit message; do not overrun. |
| Idempotency replay | 200 | Once total | already replayed | none | Show the original result and reassure that replay did not double bill. |
| Idempotency mismatch | 409 | No | false with that key | use_new_idempotency_key | Client bug: same key was used for a different body. |
| Idempotency in progress | 409 | No | true with the same key after a short wait | retry_after_inflight_completes | Show in-progress and retry the same key. |
| Server failure | 500/503 | No | 500: false; 503: true after backoff | fix_request_and_resubmit or retry_after_backoff | Open support if persistent; do not show a computed result. |
First evaluators should be able to explain these states without private help before sending taxpayer-like payloads. Each row names the guide to read, the safe recovery behavior, and the privacy-safe telemetry event that can detect confusion.
| State to understand | Expected understanding | Primary guide | Safe recovery | Telemetry hook |
|---|---|---|---|---|
| Computed 200 | A computed 200 can show figures, provenance, legal_notice, billed, retry_safe, and next_action. | read-response | Replay the same Idempotency-Key for network uncertainty; do not change the body under the same key. | docs_guides_computed_comprehension |
| Deterministic decline 200 | A computed:false 200 is a successful safety answer, not an outage or a free retry loop. | deterministic-decline-ui | Show code, reason, billed, retry_safe, and next_action; route to review or feedback without a tax estimate. | docs_guides_decline_comprehension |
| needs_review 200 | needs_review is not a final computed tax answer; it is a human-review workflow state. | read-response | Show diff, reason/provenance, billed, retry_safe, and next_action; route to a review queue. | docs_guides_needs_review_comprehension |
| Validation error | A 400 validation failure is unbilled and should be fixed before resubmitting. | billing-retries-quota | Fix the request shape; do not ask support to infer a missing taxpayer fact. | docs_guides_validation_recovery_view |
| Auth error | A 401/403 auth failure is unbilled and usually means the API key or account state needs attention. | billing-retries-quota | Check, rotate, or unsuspend the key; never paste keys or bearer tokens into support or feedback. | docs_guides_auth_recovery_view |
| Quota or rate limit | A 429 is unbilled; monthly quota is a hard cap, while per-minute rate limit can wait/back off. | billing-retries-quota | Wait, back off, or use account/billing support; do not expect silent overage. | docs_guides_quota_recovery_view |
| Idempotency replay | Same-key same-body replay returns the stored result and bills once total. | billing-retries-quota | Reuse the same key for uncertainty about the same logical POST. | docs_guides_replay_comprehension |
| Idempotency mismatch | Same-key different-body mismatch is a client bug, unbilled, and must not be retried with that key. | billing-retries-quota | Use a new key only for a new logical request after fixing the client bug. | docs_guides_mismatch_recovery_view |
| Idempotency in progress | An in-progress response is unbilled at failure time and may be retried with the same key after a short wait. | billing-retries-quota | Retry the same key after the in-flight request settles. | docs_guides_in_progress_recovery_view |
| Server failure | A 500/503 is unbilled and must not produce a guessed tax result in the client UI. | read-response | Retry only when the response class says retry is safe; open support if persistent. | docs_guides_server_failure_recovery_view |
Preflight this example against the capability manifest before sending taxpayer-like payloads. It names modeled fields, required affirmations, deterministic decline codes, needs_review states, not-modeled residuals, billing semantics, and docs links. OpenAPI lives at /api/openapi.json.
{
"computed": true,
"year": 2025,
"filingStatus": "single",
"taxableIncome": 69250,
"incomeTax": 10149,
"totalTax": 10149,
"billed": true,
"retry_safe": true,
"next_action": "none",
"provenance": {
"engine": "deterministic",
"jurisdiction": "federal",
"tax_year": 2025
},
"legal_notice": {
"ref": "https://tax-mcp.com/terms#compute-notice",
"version": "v1"
}
}Preflight this example against the capability manifest before sending taxpayer-like payloads. It names modeled fields, required affirmations, deterministic decline codes, needs_review states, not-modeled residuals, billing semantics, and docs links. OpenAPI lives at /api/openapi.json.
{
"computed": false,
"code": "schedule_c_needs_review",
"reason": "Schedule C self-employment compute requires scheduleCIsSingleSolePropFinalNetAffirmed:true before Tax MCP can compute this bounded path.",
"billed": true,
"retry_safe": false,
"next_action": "review_inputs"
}Preflight this example against the capability manifest before sending taxpayer-like payloads. It names modeled fields, required affirmations, deterministic decline codes, needs_review states, not-modeled residuals, billing semantics, and docs links. OpenAPI lives at /api/openapi.json.
{
"status": "needs_review",
"computed": {
"computed": true,
"state": "ca",
"year": 2025,
"stateTaxableIncome": "<computed value elided>",
"totalTax": "<computed value elided>"
},
"diff": [
{
"line": "CA AGI (540:17)",
"engine": "<computed value elided>",
"filed": "<filed value supplied by caller, elided>",
"delta": "<difference elided>",
"cls": "DIFFERS",
"note": "source set appears incomplete vs the filed oracle; a human reviews"
}
],
"billed": true,
"retry_safe": true,
"next_action": "review_inputs",
"provenance": {
"engine": "deterministic",
"jurisdiction": "ca",
"tax_year": 2025
}
}{
"error": "invalid_request",
"billed": false,
"retry_safe": false,
"next_action": "fix_request_and_resubmit",
"reason": "Correct the request body before resubmitting."
}Privacy-safe guide telemetry may record only named events and coarse categories. It must never include API keys, bearer tokens, taxpayer documents, raw taxpayer PII, full unredacted request/response bodies, or unredacted support text.
| Event | Surface | Purpose | Safe fields |
|---|---|---|---|
docs_guide_index_view | /docs/guides | Detect whether evaluators reach the guide index from docs or quickstart. | session_id, surface, timestamp |
docs_guides_comprehension_map_view | /docs/guides | Detect whether first users see the response-class comprehension map before sending payloads. | session_id, surface, timestamp |
docs_guides_to_quickstart_click | /docs/guides/* | Measure guide-to-first-call continuity without recording request bodies or secrets. | session_id, guide_slug, timestamp |
docs_guides_support_click | /docs/guides/* | Route account or operational confusion to support without collecting raw support text. | session_id, guide_slug, support_category, timestamp |
docs_guides_feedback_click | /docs/guides/* | Route unsupported-envelope surprises to structured feedback without taxpayer PII. | session_id, guide_slug, response_class, decline_or_error_code, timestamp |
docs_guides_privacy_notice_view | /docs/guides/* | Confirm the no-secrets/no-PII support boundary is visible before support or feedback handoff. | session_id, guide_slug, timestamp |
Forbidden fields: api_key, bearer_token, raw_taxpayer_document, raw_taxpayer_pii, full_unredacted_request_body, full_unredacted_response_body, unredacted_free_form_support_text.