@pipeworx/california-tax-appeals

Connect: https://pipeworx.io/mcp — every tool in the catalog, including @pipeworx/california-tax-appeals’s. Install: one-click buttons

Connect to just the @pipeworx/california-tax-appeals pack

https://gateway.pipeworx.io/california-tax-appeals/mcp — only @pipeworx/california-tax-appeals’s own tools, nothing else in the catalog.

No MCP client? Skip the connection: POST https://gateway.pipeworx.io/v1/tools/search_packs {"query":"..."} to find a tool below, GET /v1/tools/<name> for its schema, POST the same URL with arguments for the data — see For AI agents.

Tools: 2

California Office of Tax Appeals (OTA) opinions — search by statute citation or topic across 4,254 issued opinions (precedential and nonprecedential, 2018–2026), or retrieve one specific opinion’s full text and cited provisions by its OTA citation.

Tools

  • ca_ota_search(query, category?, precedential_only?, limit?) — find opinions by topic keyword (e.g. “residency”, “innocent spouse”) or statute citation (e.g. “17014”). Returns citation, title, date, tax category (Franchise/Income Tax vs Business Tax), precedential status, and OTA’s own one-line “Issues” tag, most recent first. Searches listing metadata only (title + Issues tag) — OTA publishes no full-text search.
  • ca_ota_opinion_lookup(cite) — fetch one opinion by its OTA citation (e.g. “2020-OTA-263P”), live. Returns the full opinion text, exact date issued, OTA’s internal case number, tax category, precedential status, and statute citations found in the text (best-effort R&TC/Cal. Code Regs./IRC).

Auth

Keyless. No signup — this is a read of OTA’s own published, public opinions.

Data sources

Shape and known limits

ota.ca.gov (WordPress/WP Engine, TablePress tables) has no JSON search backend — every opinion-listing page renders its whole table as static HTML; the DataTables plugin paginates it client-side only (confirmed live: every DataTable('#tablepress-NNN', {...}) init call on these pages carries no ajax/serverSide option). So this pack bakes a citation-indexed table from OTA’s own listing pages rather than proxying a search endpoint — see scripts/bake-index.mjs’s own header for exactly which pages it fetches and how it discovers new years without a code change.

Per root CLAUDE.md’s standing rule on baked data (fleet #2754), the index (4,254 rows, ~1.6MB) lives in KV, never gateway module scope — uploaded by scripts/sync-gateway-static-json.mjs and injected as args._bakedIndex (registered in workers/gateway/src/pack-baked-indexes.json).

ca_ota_search searches listing metadata only — the opinion title and OTA’s own one-line “Issues” tag (e.g. “Residency (R&TC 17014; Reg. 17014)”). A statute cited only in an opinion’s full body text, and not in its Issues tag, will not be found by search; use ca_ota_opinion_lookup on a specific citation to read that opinion’s full text.

“Case number” = OTA’s own citation (e.g. “2020-OTA-263P”, the trailing “P” marking Precedential status) — what OTA itself cites opinions by, not the PDF’s internal 8-digit “OTA Case No.” docket number (which only appears inside the PDF body and is surfaced in ca_ota_opinion_lookup’s response as ota_case_no, read live, not indexed). The trailing precedential marker may be omitted when looking up a citation; ca_ota_opinion_lookup tries both forms before reporting a miss. Some opinions carry other OTA suffix letters (e.g. ”…SCP” for a Summary Conclusion of Proceedings) — those must be typed exactly.

A transport failure (non-200) or a listing/PDF mismatch (a 404 for a citation the index says has a PDF) throws loudly naming the upstream status — never a silent found: false. A PDF that exists but fails to extract (rare; e.g. a scanned, non-text PDF) degrades to full_text: null with a warning rather than throwing, since the opinion’s metadata (title, date, decision type, Issues tag) is still valid from the listing page.

Re-run node scripts/bake-index.mjs > src/ca-ota-index-data.ts periodically to pick up newly issued opinions — it refuses to write a suspiciously small index (fewer than 2,000 opinions or fewer than 15 listing pages fetched), so a silent partial bake from an OTA markup change is caught rather than shipped.

Tools

  • ca_ota_search — Find California Office of Tax Appeals (OTA) opinions by statute citation or topic keyword (e.g. “residency”, “innocent spouse”, “17014”, “17951-4”) — returns citation, title, date, tax category (Fran
  • ca_ota_opinion_lookup — Look up a California Office of Tax Appeals opinion by its OTA citation (e.g. “2020-OTA-263P” for a Precedential opinion, “2020-OTA-374” for a Nonprecedential one) — fetches the opinion PDF live and r

Tools

  • ca_ota_opinion_lookup — Look up a California Office of Tax Appeals opinion by its OTA citation (e.g. 2020-OTA-263P for a Precedential opinion, 2020-OTA-374 for a Nonprecedential one) -- fetches the opinion PDF live and retur
  • ca_ota_search — Find California Office of Tax Appeals (OTA) opinions by statute citation or topic keyword (e.g. residency , innocent spouse , 17014 , 17951-4 ) -- returns citation, title, date, tax category (Franchis

Regenerated from source · build October 8, 2026