mcp-server-taxcode 0.1.2__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/.github/workflows/ci.yml +7 -0
  2. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/AGENTS.md +1 -1
  3. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/PKG-INFO +7 -2
  4. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/README.md +6 -1
  5. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/db.py +11 -0
  6. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/tools/compliance.py +28 -0
  7. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_db.py +3 -0
  8. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_server.py +7 -0
  9. mcp_server_taxcode-0.1.2/research.md +0 -241
  10. mcp_server_taxcode-0.1.2/tax-mcp-pr-and-docs.md +0 -97
  11. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/.github/dependabot.yml +0 -0
  12. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/.github/workflows/dependabot-automerge.yml +0 -0
  13. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/.github/workflows/drift-monitor.yml +0 -0
  14. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/.github/workflows/release.yml +0 -0
  15. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/.gitignore +0 -0
  16. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/CHANGELOG.md +0 -0
  17. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/CODE_OF_CONDUCT.md +0 -0
  18. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/CONTRIBUTING.md +0 -0
  19. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/Dockerfile +0 -0
  20. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/LICENSE +0 -0
  21. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/SECURITY.md +0 -0
  22. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/conformance-baseline.yml +0 -0
  23. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ca/caccr_17014.md +0 -0
  24. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ca/rtc_17014.md +0 -0
  25. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ca/rtc_17041.md +0 -0
  26. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ca/rtc_17951.md +0 -0
  27. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/fl/flconst_art__vii_sec__5.md +0 -0
  28. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/fl/flstat_196_031.md +0 -0
  29. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/fl/flstat_222_17.md +0 -0
  30. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ga/gareg_560_7_3__01.md +0 -0
  31. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ga/ocga_48_7_1.md +0 -0
  32. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ga/ocga_48_7_20.md +0 -0
  33. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ga/ocga_48_7_20_2024.md +0 -0
  34. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ga/ocga_48_7_20_2025.md +0 -0
  35. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ga/ocga_48_7_27.md +0 -0
  36. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ga/ocga_48_7_30.md +0 -0
  37. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/il/ilcs_5_1501_a_20.md +0 -0
  38. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/il/ilcs_5_201.md +0 -0
  39. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/il/ilcs_5_301.md +0 -0
  40. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/llms-full.txt +0 -0
  41. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/llms.txt +0 -0
  42. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ma/maconst_art__xliv.md +0 -0
  43. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ma/mgl_62_1_f.md +0 -0
  44. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ma/mgl_62_4.md +0 -0
  45. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/nj/njac_18_35_5_2.md +0 -0
  46. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/nj/njsa_54a_1_2.md +0 -0
  47. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/nj/njsa_54a_2_1.md +0 -0
  48. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ny/nycrr_105_20.md +0 -0
  49. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ny/nycrr_132_18.md +0 -0
  50. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ny/nytax_601.md +0 -0
  51. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/ny/nytax_605.md +0 -0
  52. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/pr/cri_1010_01.md +0 -0
  53. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/pr/cri_1031_01.md +0 -0
  54. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/pr/cri_1031_02.md +0 -0
  55. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/pr/cri_1062_01.md +0 -0
  56. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/pr/ley22_3_2012.md +0 -0
  57. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/pr/ley60_2021_01.md +0 -0
  58. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/pr/ley60_2022_01.md +0 -0
  59. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/pr/ley60_2031_01.md +0 -0
  60. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/pr/ley60_2032_01.md +0 -0
  61. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/pr/ley60_6070_55.md +0 -0
  62. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/tx/txconst_art__viii_sec__24_a.md +0 -0
  63. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/tx/txtax_171_001.md +0 -0
  64. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/us/cfr_1_937_1.md +0 -0
  65. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/us/cfr_1_937_2.md +0 -0
  66. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/us/cfr_1_937_3.md +0 -0
  67. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/us/irc_1411.md +0 -0
  68. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/us/irc_6688.md +0 -0
  69. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/us/irc_865.md +0 -0
  70. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/us/irc_933.md +0 -0
  71. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/us/irc_937.md +0 -0
  72. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/us/irc_957.md +0 -0
  73. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/wa/rcw_82_87_020.md +0 -0
  74. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/wa/rcw_82_87_040.md +0 -0
  75. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/docs/wa/waconst_art__vii_sec__1.md +0 -0
  76. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/fastmcp.json +0 -0
  77. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/pyproject.toml +0 -0
  78. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/scripts/check_conformance.sh +0 -0
  79. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/scripts/check_openapi_drift.py +0 -0
  80. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/scripts/check_tool_contract.py +0 -0
  81. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/scripts/check_version.py +0 -0
  82. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/scripts/ingest_statutes.py +0 -0
  83. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/scripts/release_notes.py +0 -0
  84. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/scripts/setup_repo_governance.sh +0 -0
  85. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/server.json +0 -0
  86. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/skills/taxcode-mcp/SKILL.md +0 -0
  87. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/__init__.py +0 -0
  88. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/auth.py +0 -0
  89. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/client.py +0 -0
  90. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/config.py +0 -0
  91. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/errors.py +0 -0
  92. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/middleware.py +0 -0
  93. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/profiles.py +0 -0
  94. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/server.py +0 -0
  95. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/ssrf.py +0 -0
  96. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/tools/__init__.py +0 -0
  97. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/tools/statutes.py +0 -0
  98. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/src/taxcode_mcp/tools/system.py +0 -0
  99. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/conftest.py +0 -0
  100. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_batch.py +0 -0
  101. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_check_version.py +0 -0
  102. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_client.py +0 -0
  103. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_code_mode_extra.py +0 -0
  104. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_config.py +0 -0
  105. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_conftest_auth_env.py +0 -0
  106. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_drift.py +0 -0
  107. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_e2e_live.py +0 -0
  108. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_errors.py +0 -0
  109. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_http_auth.py +0 -0
  110. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_ingest.py +0 -0
  111. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_layered.py +0 -0
  112. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_otel_spans.py +0 -0
  113. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_profiles.py +0 -0
  114. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_protocol.py +0 -0
  115. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_release_notes.py +0 -0
  116. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_ssrf.py +0 -0
  117. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/tests/test_version.py +0 -0
  118. {mcp_server_taxcode-0.1.2 → mcp_server_taxcode-0.1.3}/uv.lock +0 -0
@@ -5,6 +5,13 @@ on:
5
5
  branches: [main]
6
6
  pull_request:
7
7
  branches: [main]
8
+ # Merges made by dependabot-automerge.yml use GITHUB_TOKEN, and events caused
9
+ # by GITHUB_TOKEN never start new workflow runs, so the push trigger above
10
+ # misses them. The daily run tests main itself; schedule runs only on the
11
+ # default branch. The minute is off the hour to avoid peak scheduler load.
12
+ schedule:
13
+ - cron: '17 9 * * *'
14
+ workflow_dispatch:
8
15
 
9
16
  concurrency:
10
17
  # Each push to main gets its own group, keyed on the commit SHA, so runs for
@@ -199,6 +199,6 @@ coderabbit review --agent --uncommitted
199
199
 
200
200
  ## 🔄 CI & Releases
201
201
 
202
- CI is defined in `.github/workflows/ci.yml` (jobs: `lint-and-types`, `test` on Python 3.10–3.13, `tool-contract`, `build-check`, `docker-build` (builds the image without pushing and checks its MCP server-name label against `server.json`)). Run the commands above before opening a PR. Scheduled upstream drift runs in `drift-monitor.yml`. `dependabot-automerge.yml` turns on squash auto-merge only for Dependabot PRs whose highest update is minor or patch; major updates wait for a human review.
202
+ CI is defined in `.github/workflows/ci.yml` (jobs: `lint-and-types`, `test` on Python 3.10–3.13, `tool-contract`, `build-check`, `docker-build` (builds the image without pushing and checks its MCP server-name label against `server.json`)). It runs on pushes and pull requests to `main`, daily on `main` at 09:17 UTC (`schedule`), and on manual dispatch (`workflow_dispatch`); the daily run exists because merges by `dependabot-automerge.yml` use `GITHUB_TOKEN` and so never trigger the `push` run. Run the commands above before opening a PR. Scheduled upstream drift runs in `drift-monitor.yml`. `dependabot-automerge.yml` turns on squash auto-merge only for Dependabot PRs whose highest update is minor or patch; major updates wait for a human review.
203
203
 
204
204
  `release.yml` runs on `v*` tag pushes only: it creates the GitHub Release, then builds the container image, pushes it to GHCR, attests it, and publishes to the MCP Registry. In the template repo the image is built only (no push), and the attest and registry jobs skip. Release procedure (tag-based versioning, release notes, pre-tag checks): **`COOKBOOK.md`** Recipes 1–2; product-repo migration steps: Recipe 9.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: mcp-server-taxcode
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Enterprise Model Context Protocol (MCP) server for Tax Code
5
5
  Project-URL: Homepage, https://github.com/christianclaudio/mcp-server-taxcode
6
6
  Project-URL: Documentation, https://github.com/christianclaudio/mcp-server-taxcode#readme
@@ -51,7 +51,12 @@ Description-Content-Type: text/markdown
51
51
  [![CodeRabbit Reviews](https://img.shields.io/coderabbit/prs/github/christianclaudio/mcp-server-taxcode?labelColor=171717&color=FF570A&label=CodeRabbit+Reviews)](https://coderabbit.ai)
52
52
 
53
53
  > **Enterprise-grade Model Context Protocol (MCP) server for Federal, Territorial, and Multi-State Tax Law.**
54
- > Authoritative statutory and administrative intelligence covering United States Federal (IRC/CFR), Puerto Rico (Act 60/Ley 1), and state tax corridors (GA, CA, NY, FL, TX, WA, MA, NJ, IL) with deterministic residency and capital gains compliance engines.
54
+ > Reference statutory catalog covering United States Federal (IRC/CFR), Puerto Rico (Act 60/Ley 1), and state tax corridors (GA, CA, NY, FL, TX, WA, MA, NJ, IL) with computational residency and capital gains models.
55
+
56
+ > [!WARNING]
57
+ > **NOT TAX OR LEGAL ADVICE / NO CONSTITUYE ASESORAMIENTO CONTRIBUTIVO NI LEGAL**
58
+ > **EN:** This software and its tools provide computational models, heuristic checks, and unofficial summaries for informational and research purposes only. Nothing returned by this server constitutes formal legal or tax advice, an official legal opinion, or audit representation. Unofficial translations and summaries are non-binding; official statutory and administrative sources in their enacted language control.
59
+ > **ES:** Este software y sus herramientas proporcionan modelos computacionales, verificaciones heurísticas y resúmenes no oficiales únicamente para fines informativos y de investigación. Ninguna respuesta emitida por este servidor constituye asesoramiento legal o contributivo formal, una opinión legal oficial ni representación ante auditorías. Las traducciones y resúmenes no oficiales no son vinculantes; los textos estatutarios y administrativos oficiales promulgados en su idioma original prevalecen.
55
60
 
56
61
  ---
57
62
 
@@ -8,7 +8,12 @@
8
8
  [![CodeRabbit Reviews](https://img.shields.io/coderabbit/prs/github/christianclaudio/mcp-server-taxcode?labelColor=171717&color=FF570A&label=CodeRabbit+Reviews)](https://coderabbit.ai)
9
9
 
10
10
  > **Enterprise-grade Model Context Protocol (MCP) server for Federal, Territorial, and Multi-State Tax Law.**
11
- > Authoritative statutory and administrative intelligence covering United States Federal (IRC/CFR), Puerto Rico (Act 60/Ley 1), and state tax corridors (GA, CA, NY, FL, TX, WA, MA, NJ, IL) with deterministic residency and capital gains compliance engines.
11
+ > Reference statutory catalog covering United States Federal (IRC/CFR), Puerto Rico (Act 60/Ley 1), and state tax corridors (GA, CA, NY, FL, TX, WA, MA, NJ, IL) with computational residency and capital gains models.
12
+
13
+ > [!WARNING]
14
+ > **NOT TAX OR LEGAL ADVICE / NO CONSTITUYE ASESORAMIENTO CONTRIBUTIVO NI LEGAL**
15
+ > **EN:** This software and its tools provide computational models, heuristic checks, and unofficial summaries for informational and research purposes only. Nothing returned by this server constitutes formal legal or tax advice, an official legal opinion, or audit representation. Unofficial translations and summaries are non-binding; official statutory and administrative sources in their enacted language control.
16
+ > **ES:** Este software y sus herramientas proporcionan modelos computacionales, verificaciones heurísticas y resúmenes no oficiales únicamente para fines informativos y de investigación. Ninguna respuesta emitida por este servidor constituye asesoramiento legal o contributivo formal, una opinión legal oficial ni representación ante auditorías. Las traducciones y resúmenes no oficiales no son vinculantes; los textos estatutarios y administrativos oficiales promulgados en su idioma original prevalecen.
12
17
 
13
18
  ---
14
19
 
@@ -12,6 +12,11 @@ from taxcode_mcp.config import settings
12
12
 
13
13
  logger = logging.getLogger(__name__)
14
14
 
15
+ STATUTE_TRANSLATION_DISCLAIMER = (
16
+ "Unofficial translation/summary for reference purposes only. Official "
17
+ "statutory text in the jurisdiction's authoritative language controls."
18
+ )
19
+
15
20
  # Canonical initial seed data for US Federal and Puerto Rico tax provisions
16
21
  INITIAL_STATUTES: list[dict[str, Any]] = [
17
22
  {
@@ -1195,6 +1200,9 @@ class TaxDatabase:
1195
1200
  "cross_references": result[11] or [],
1196
1201
  "language": lang.lower(),
1197
1202
  "official_language": "es" if result[1] == "PR" else "en",
1203
+ "content_type": "reference_summary",
1204
+ "unofficial_summary": True,
1205
+ "translation_disclaimer": STATUTE_TRANSLATION_DISCLAIMER,
1198
1206
  }
1199
1207
  finally:
1200
1208
  if self._mem_conn is None:
@@ -1261,6 +1269,9 @@ class TaxDatabase:
1261
1269
  "is_current": r[9] is None,
1262
1270
  "source_url": r[10],
1263
1271
  "cross_references": r[11] or [],
1272
+ "content_type": "reference_summary",
1273
+ "unofficial_summary": True,
1274
+ "translation_disclaimer": STATUTE_TRANSLATION_DISCLAIMER,
1264
1275
  }
1265
1276
  )
1266
1277
  return output
@@ -12,6 +12,26 @@ from taxcode_mcp.errors import SafetyViolationError, tool_error
12
12
 
13
13
  logger = logging.getLogger(__name__)
14
14
 
15
+ BILINGUAL_DISCLAIMER: dict[str, str] = {
16
+ "en": (
17
+ "NOT TAX OR LEGAL ADVICE. This computational determination is for reference and "
18
+ "informational purposes only based on statutory heuristic models. It does not constitute "
19
+ "formal legal or tax advice, an official opinion, or an audit defense. Any translations "
20
+ "or statutory summaries are unofficial and non-binding; official enacted statutory text "
21
+ "and administrative rulings in their original language control."
22
+ ),
23
+ "es": (
24
+ "NO CONSTITUYE ASESORAMIENTO CONTRIBUTIVO NI LEGAL. Esta determinación computacional es "
25
+ "para fines informativos y de referencia únicamente, basada en modelos heurísticos "
26
+ "estatutarios. No constituye asesoramiento legal o contributivo formal, opinión oficial "
27
+ "ni defensa de auditoría. Todas las traducciones o resúmenes estatutarios son no "
28
+ "oficiales y no vinculantes; el texto estatutario oficial promulgado y las determinaciones "
29
+ "administrativas en su idioma original prevalecen."
30
+ ),
31
+ }
32
+
33
+ CONTENT_NOTICE = "Computational heuristic model with unofficial statutory reference summaries."
34
+
15
35
  ANNOTATION_READ_ONLY = ToolAnnotations(
16
36
  read_only_hint=True,
17
37
  destructive_hint=False,
@@ -102,6 +122,8 @@ def evaluate_pr_bona_fide_residency(
102
122
  },
103
123
  "authoritative_basis": "26 U.S.C. § 937; 26 CFR § 1.937-1",
104
124
  "reporting_requirements": reporting_triggers,
125
+ "disclaimer": BILINGUAL_DISCLAIMER,
126
+ "content_notice": CONTENT_NOTICE,
105
127
  }
106
128
 
107
129
 
@@ -184,6 +206,8 @@ def calculate_built_in_gain_sourcing(
184
206
  "(0% grandfathered, or 4% for post-2026 decrees)."
185
207
  ),
186
208
  "statutory_basis": "26 CFR § 1.937-2(f); 26 U.S.C. § 865; 26 U.S.C. § 933",
209
+ "disclaimer": BILINGUAL_DISCLAIMER,
210
+ "content_notice": CONTENT_NOTICE,
187
211
  }
188
212
  except Exception as exc:
189
213
  failure = tool_error(exc)
@@ -291,6 +315,8 @@ def evaluate_georgia_residency(
291
315
  "estimated_georgia_tax": estimated_tax,
292
316
  "statutory_rate_authority": "O.C.G.A. § 48-7-20 (HB 1023 / HB 1015 flat tax)",
293
317
  },
318
+ "disclaimer": BILINGUAL_DISCLAIMER,
319
+ "content_notice": CONTENT_NOTICE,
294
320
  }
295
321
 
296
322
 
@@ -519,6 +545,8 @@ def evaluate_state_residency(
519
545
  "rate_description": rate_desc,
520
546
  "statutory_rate_authority": rate_authority,
521
547
  },
548
+ "disclaimer": BILINGUAL_DISCLAIMER,
549
+ "content_notice": CONTENT_NOTICE,
522
550
  }
523
551
 
524
552
 
@@ -34,6 +34,9 @@ def test_lookup_statute_by_citation_and_section() -> None:
34
34
  assert "bona fide resident" in res_en["operative_text"]
35
35
  assert res_en["language"] == "en"
36
36
  assert res_en["official_language"] == "en"
37
+ assert res_en["content_type"] == "reference_summary"
38
+ assert res_en["unofficial_summary"] is True
39
+ assert "Unofficial translation/summary" in res_en["translation_disclaimer"]
37
40
 
38
41
  # Spanish language lookup
39
42
  res_es = test_db.lookup_statute("933", lang="es")
@@ -71,6 +71,9 @@ async def test_server_tools(mock_transport, monkeypatch):
71
71
  )
72
72
  assert residency["status"] == "success"
73
73
  assert residency["is_bona_fide_resident"] is True
74
+ assert "NOT TAX OR LEGAL ADVICE" in residency["disclaimer"]["en"]
75
+ assert "NO CONSTITUYE ASESORAMIENTO CONTRIBUTIVO NI LEGAL" in residency["disclaimer"]["es"]
76
+ assert "unofficial statutory reference summaries" in residency["content_notice"]
74
77
 
75
78
  # 6. Calculate built-in gain sourcing
76
79
  big = server.calculate_built_in_gain_sourcing(
@@ -83,6 +86,7 @@ async def test_server_tools(mock_transport, monkeypatch):
83
86
  assert big["status"] == "success"
84
87
  assert big["us_source_gain"] == 400000.0
85
88
  assert big["pr_source_gain"] == 300000.0
89
+ assert "NOT TAX OR LEGAL ADVICE" in big["disclaimer"]["en"]
86
90
 
87
91
  # 7. Evaluate Georgia residency & tax
88
92
  ga_res = server.evaluate_georgia_residency(
@@ -104,6 +108,7 @@ async def test_server_tools(mock_transport, monkeypatch):
104
108
  assert len(ga_res["domicile_audit_risk"]["flags"]) == 3
105
109
  assert ga_res["tax_computation"]["georgia_taxable_net_income"] == 48000.0
106
110
  assert ga_res["tax_computation"]["estimated_georgia_tax"] == 2635.20
111
+ assert "NOT TAX OR LEGAL ADVICE" in ga_res["disclaimer"]["en"]
107
112
 
108
113
 
109
114
  @pytest.mark.asyncio
@@ -709,6 +714,8 @@ def test_evaluate_state_residency_cases() -> None:
709
714
  assert flagged["domicile_audit_risk"]["risk_level"] == "high"
710
715
  assert len(flagged["domicile_audit_risk"]["flags"]) == 3
711
716
  assert flagged["tax_computation"]["estimated_state_tax"] == 0.0
717
+ assert "NOT TAX OR LEGAL ADVICE" in flagged["disclaimer"]["en"]
718
+ assert "unofficial statutory reference summaries" in flagged["content_notice"]
712
719
 
713
720
  # 4. Georgia (GA)
714
721
  ga_sr = server.evaluate_state_residency(
@@ -1,241 +0,0 @@
1
- Architecture and Implementation of Model Context Protocol Servers for United States and Puerto Rico Tax CodesAutonomous artificial intelligence agents operating within legal, accounting, and regulatory environments face severe limitations when relying solely on pre-trained parametric weights. Complex statutory frameworks—most notably the United States Internal Revenue Code (Title 26 U.S.C.) and the specialized territorial tax regime of Puerto Rico—are characterized by dense structural hierarchies, temporal volatility, and intricate multi-jurisdictional interactions. Without access to ground-truth legal texts, foundational language models frequently produce subtle hallucinations, misapply superseded statutory provisions, and fail to calculate multi-tier sourcing rules accurately.The Model Context Protocol (MCP) establishes an open, standardized integration specification that bridges language models and external computational environments. By developing dedicated MCP servers using FastMCP, engineering teams can expose authoritative federal and territorial tax statutes, dynamic retrieval engines, and deterministic legal calculation tools directly to agentic workflows. This report provides a comprehensive architectural blueprint for constructing, deploying, and maintaining high-performance MCP servers that index the United States Internal Revenue Code, Treasury Regulations, the Puerto Rico Internal Revenue Code of 2011, and the Puerto Rico Incentives Code (Act 60-2019).Architectural Foundations and FastMCP Framework DesignThe Model Context Protocol establishes a client-server topology operating over structured JSON-RPC 2.0 message framing. The MCP client—integrated into developer environments such as Cursor, native desktop interfaces like Claude Desktop, or autonomous agent frameworks—manages dialogue context and high-level reasoning loops. The MCP server functions as an authoritative boundary, hosting discrete domain tools, static and dynamic resources, and structured prompting workflows. FastMCP serves as an enterprise-grade Python framework designed to abstract protocol mechanics, converting standard asynchronous functions, type hints, and docstrings into compliant protocol schemas.Communication across the protocol relies on three primary primitives that allow client agents to interact with external data environments in distinct ways:Tools provide executable capabilities that agents invoke to perform calculations, query external indices, or evaluate statutory rules. FastMCP infers JSON parameter schemas directly from Python type signatures and populates tool documentation from docstrings, allowing language models to determine invocation criteria dynamically.Resources and resource templates expose passive, read-only data endpoints addressable via Uniform Resource Identifiers (URIs). While static resources deliver fixed payloads, resource templates accept parameterized path variables (such as tax://us/irc/{section}), allowing an agent to fetch specific legal sections without executing computational logic.Prompts define reusable, structured templates that guide multi-step agent reasoning, enforcing standardized legal frameworks and citation verification protocols.MCP PrimitiveProtocol MechanismPrimary Tax Server FunctionReturn Payload StructureTool (@mcp.tool)Client issues tools/call with validated argumentsExecutes hybrid searches, runs presence calculations, and evaluates sourcing rulesJSON object or Markdown text containing structured analytical outputsResource (@mcp.resource)Client issues resources/read with a fixed URIDelivers static rate schedules, administrative orders, and filing deadlinesPlain text, binary blob, or structured ResourceResult[cite: 1]Resource TemplateClient issues resources/read with a parameterized URIResolves direct statutory citations (e.g., 26 U.S.C. § 933 or PR Act 60 § 2021.01)Canonical legal text, effective dates, and statutory cross-referencesPrompt (@mcp.prompt)Client issues prompts/get with scenario parametersEnforces structured legal deduction across dual-jurisdiction conflictsParameterized message array establishing system constraints and instructionsTransport layer mechanics dictate how the server exchanges data with client runtimes. FastMCP natively supports both standard input/output (STDIO) and Streamable HTTP transports. The STDIO transport operates by executing the server as a local child process managed directly by the host application, passing JSON-RPC messages across standard input and output streams. STDIO offers zero-configuration deployment for single-user desktop runtimes.For distributed multi-agent systems, FastMCP generates an Asynchronous Server Gateway Interface (ASGI) application served via Uvicorn. Streamable HTTP establishes bidirectional communication over standard web infrastructure, allowing centralized deployments to serve multi-tenant agent fleets while enforcing token-based authentication and request middleware.Statutory Ingestion, Legal Data Sources, and Hierarchical ChunkingLegal statutes cannot be ingested as generic flat-text documents. Tax legislation relies on nested conditional clauses, specific exceptions, definitions of terms, and complex cross-references to other statutory titles. Maintaining structural context during ingestion is necessary to prevent retrieval failures in production.Authoritative Digital RepositoriesFederal and territorial statutes originate from separate governing authorities that maintain disparate digital publication standards:United States Internal Revenue Code (Title 26 U.S.C.): The Office of the Law Revision Counsel (OLRC) of the U.S. House of Representatives publishes Title 26 in the United States Legislative Markup (USLM) XML schema. USLM is an XML standard that models legislative structure from broad subtitles down to nested clauses and subclauses. Releases track specific Public Laws enacted by Congress, ensuring point-in-time accuracy.Treasury Regulations (Title 26 C.F.R.): The Electronic Code of Federal Regulations (eCFR) provides a continuously updated API that exposes federal regulatory titles in structured JSON and XML formats. Treasury Regulations interpret statutory IRC sections (such as 26 C.F.R. § 1.937-1 interpreting the residency rules of 26 U.S.C. § 937).Puerto Rico Internal Revenue Code of 2011 (Ley 1-2011): Administered by the Puerto Rico Department of the Treasury (Departamento de Hacienda), Ley 1-2011 encompasses territorial income, excise, sales, and administrative tax mandates. Official digital copies are published through the Puerto Rico Office of Management and Budget (Oficina de Gerencia y Presupuesto, OGP) legislative library.Puerto Rico Incentives Code (Ley 60-2019): Enacted to streamline dozens of legacy tax incentive laws, Ley 60-2019 integrates statutes such as Act 20 (Export Services) and Act 22 (Individual Investors) into a unified code administered by the Department of Economic Development and Commerce (DDEC). The text is maintained in official government compendiums via the OGP.Administrative Guidance and Circular Letters: Sub-regulatory guidance from Hacienda—specifically Circular Letters (Cartas Circulares), Administrative Determinations, and Informative Bulletins—provides binding guidance on electronic filing mandates via the Unified Internal Revenue System (SURI) and statutory interpretations.JurisdictionLegal CorpusPublishing AuthorityDistribution Schema / FormatStructural OrganizationUnited StatesInternal Revenue Code (Title 26 U.S.C.)House Office of the Law Revision Counsel (OLRC)USLM XML / Bulk Digital PackagesSubtitle $\rightarrow$ Chapter $\rightarrow$ Subchapter $\rightarrow$ Part $\rightarrow$ Section $\rightarrow$ SubsectionUnited StatesTreasury Regulations (Title 26 C.F.R.)National Archives / GPO via eCFReCFR REST API (JSON / XML)Title $\rightarrow$ Chapter $\rightarrow$ Subchapter $\rightarrow$ Part $\rightarrow$ SectionPuerto RicoPR Internal Revenue Code (Ley 1-2011)Departamento de Hacienda / OGPConsolidated PDF & Digital CompendiumsSubtítulo (A–F) $\rightarrow$ Capítulo $\rightarrow$ Subcapítulo $\rightarrow$ SecciónPuerto RicoIncentives Code (Ley 60-2019)DDEC / OGPConsolidated Digital EnactmentsSubtítulo $\rightarrow$ Capítulo $\rightarrow$ Sección (e.g., Sec. 2021.01)Puerto RicoAdministrative GuidanceDepartamento de HaciendaDigital Publications via SURISerial Guidance Numbers (e.g., CC RI 25-12, DA 21-04)Hierarchical Ingestion and Citation Graph PipelineSplitting legal codes using fixed-token chunking strategies degrades semantic retrieval by divorcing operative subsections from their parent definitions, conditions precedent, and exceptions. An optimal legal ingestion pipeline uses an Abstract Syntax Tree (AST) approach that reflects the statutory hierarchy:In the first stage, raw legislative files are processed by structural parsers. For federal materials, the parser extracts native USLM elements (<section>, <subsection>, <paragraph>, <subparagraph>). For Puerto Rico codes, the parser uses structural pattern matchers to identify Spanish legal divisions (Subtítulo, Capítulo, Sección, Inciso).In the second stage, every extracted statutory fragment is wrapped in a contextual envelope prior to vector embedding. This process prepends the entire statutory breadcrumb path to leaf-level provisions. For instance, when indexing 26 U.S.C. § 937(b)(2), the ingested text chunk includes its hierarchical lineage: "Title 26 > Subtitle A > Chapter 1 > Subchapter N > Part III > Subpart D > Section 937 (Residence and source rules involving possessions) > Subsection (b) (Source rules) > Paragraph (2)". This structural metadata ensures that dense vector representations preserve context when queried with broad legal phrases.In the third stage, an automated citation engine extracts explicit references across statutes using regular expression pattern matching (for example, identifying citations in 26 U.S.C. § 933 that point to § 937, which in turn cross-reference § 865). These links are indexed into a directed graph, enabling the retrieval pipeline to traverse statutory dependencies when an agent evaluates multi-tier tax questions.Retrieval Engineering: Hybrid Search and Deterministic Citation RoutingStatutory retrieval requires handling two distinct query modalities: exact legal citation lookups and open-ended conceptual research. Relying solely on approximate vector similarity search for exact citations often introduces irrelevant commentary or unrelated provisions. A dual-path retrieval pipeline addresses both modalities effectively.Deterministic Citation RoutingWhen an agent or user issues a prompt with an exact legal citation—such as "IRC Sec. 933", "26 CFR 1.937-2", or "Ley 60 Seccion 2022.01"—the query is intercepted by a deterministic AST router. The router matches standardized citation regular expressions:$$\text{Citations} \in \{\text{IRC § } X, \text{26 U.S.C. § } X, \text{26 CFR } X, \text{Ley 1-2011 Sec. } X, \text{Ley 60 Sec. } X\}$$Matches bypass the vector database and retrieve the canonical text directly from an indexed key-value statutory store in constant time. The returned payload includes the full statutory text, its effective date, and a pre-compiled list of outbound cross-references.Hybrid Retrieval (Dense Vector + BM25 with Reciprocal Rank Fusion)For conceptual legal inquiries—such as "criteria for establishing a tax home in a possession" or "export services exemptions for cloud computing"—the system uses a hybrid retrieval pipeline. Sparse retrieval using BM25 ensures precision for domain-specific terms (such as "bona fide resident", "effectively connected", or "decree holder"), while dense bi-encoder embeddings capture semantic relationships and bridge cross-language queries (such as mapping English tax questions to Spanish provisions in Ley 1-2011).Results from sparse and dense retrieval passes are merged using Reciprocal Rank Fusion (RRF):$$RRF\_Score(d \in D) = \sum_{m \in M} \frac{1}{k + r_m(d)}$$In this formulation, $M$ represents the retrieval models ($\{\text{BM25}, \text{Dense}\}$), $r_m(d)$ denotes the rank of document $d$ within model $m$, and $k$ represents a smoothing factor typically set to $60$. The top-ranking candidates are then processed through a cross-encoder reranking model to score semantic relevance against the query before being returned to the agent.Implementation of the Tax Intelligence MCP ServerThe Python implementation below demonstrates an enterprise FastMCP server that provides structured tools, dynamic resource templates, and prompt workflows for both U.S. federal and Puerto Rico statutory corpora. The server incorporates FastMCP's dependency injection system via CurrentContext(), structured data modeling with Pydantic, and asynchronous execution.Python"""
2
- Tax Intelligence MCP Server: United States and Puerto Rico Tax Codes.
3
- Implements Model Context Protocol (MCP) standards using FastMCP.
4
- """
5
-
6
- from typing import Any, Dict, List, Optional
7
- from pydantic import BaseModel, Field
8
- from fastmcp import FastMCP
9
- from fastmcp.dependencies import CurrentContext
10
- from fastmcp.server.context import Context
11
- from fastmcp.resources import ResourceResult, ResourceContent
12
-
13
- mcp = FastMCP(
14
- name="TaxCode-US-PR-Intelligence",
15
- instructions=(
16
- "Authoritative tax research server for the United States Internal Revenue Code "
17
- "(Title 26 U.S.C.), Treasury Regulations (26 CFR), Puerto Rico Internal Revenue Code "
18
- "(Ley 1-2011), and Puerto Rico Incentives Code (Ley 60-2019). Supports exact statutory "
19
- "lookups, hybrid conceptual search, and cross-border residency/sourcing evaluations."
20
- ),
21
- )
22
-
23
-
24
- class StatuteMetadata(BaseModel):
25
- jurisdiction: str = Field(description="Jurisdiction code: 'US' or 'PR'")
26
- code_name: str = Field(description="Name of code: 'IRC', 'CFR', 'Ley 1-2011', 'Ley 60-2019'")
27
- citation: str = Field(description="Standardized legal citation")
28
- title: str = Field(description="Official title or caption of the section")
29
- effective_year: int = Field(description="Tax year or effective enactment year")
30
-
31
-
32
- class CrossReferenceResult(BaseModel):
33
- source_citation: str
34
- target_citation: str
35
- relationship_type: str
36
- summary_of_interaction: str
37
-
38
-
39
- @mcp.resource("tax://us/irc/{section}")
40
- async def get_us_irc_section(section: str, ctx: Context = CurrentContext()) -> ResourceResult:
41
- """Fetch the full authoritative text of a US Internal Revenue Code section."""
42
- await ctx.info(f"Retrieving 26 U.S.C. Section {section}")
43
- statute_text = (
44
- f"26 U.S. Code § {section} - Statutory Provisions.\n"
45
- "[Official text extracted from OLRC Title 26 USLM release point]."
46
- )
47
- return ResourceResult(
48
- contents=[
49
- ResourceContent(
50
- content=statute_text,
51
- mime_type="text/plain",
52
- meta={"jurisdiction": "US", "code": "IRC", "section": section}
53
- )
54
- ]
55
- )
56
-
57
-
58
- @mcp.resource("tax://pr/act60/{chapter}/{section}")
59
- async def get_pr_act60_section(chapter: str, section: str, ctx: Context = CurrentContext()) -> ResourceResult:
60
- """Fetch statutory text from Puerto Rico Incentives Code (Ley 60-2019)."""
61
- await ctx.info(f"Retrieving Ley 60-2019 Chapter {chapter}, Section {section}")
62
- statute_text = (
63
- f"Ley Núm. 60-2019, Capítulo {chapter}, Sección {section}.\n"
64
- "[Texto consolidado oficial provisto por OGP/DDEC]."
65
- )
66
- return ResourceResult(
67
- contents=[
68
- ResourceContent(
69
- content=statute_text,
70
- mime_type="text/plain",
71
- meta={"jurisdiction": "PR", "code": "Ley 60-2019", "chapter": chapter, "section": section}
72
- )
73
- ]
74
- )
75
-
76
-
77
- @mcp.tool(
78
- name="lookup_statute",
79
- description="Retrieve exact statutory language and active cross-references for a specific legal citation."
80
- )
81
- async def lookup_statute(
82
- jurisdiction: str,
83
- citation: str,
84
- ctx: Context = CurrentContext()
85
- ) -> Dict[str, Any]:
86
- """
87
- Look up an exact statute across US or PR tax codes.
88
- """
89
- await ctx.info(f"Executing deterministic lookup: {jurisdiction} -> {citation}")
90
- is_sec_933 = "933" in citation
91
- return {
92
- "status": "success",
93
- "citation": citation,
94
- "jurisdiction": jurisdiction.upper(),
95
- "title": "Exclusion of Income From Sources Within Puerto Rico" if is_sec_933 else "Statutory Query",
96
- "operative_text": (
97
- "Gross income does not include, in the case of an individual who is a bona fide resident "
98
- "of Puerto Rico during the entire taxable year, income derived from sources within Puerto Rico..."
99
- if is_sec_933 else "Authoritative statutory text payload."
100
- ),
101
- "cross_references": ["26 U.S.C. § 937", "26 CFR § 1.937-1", "26 U.S.C. § 865"] if is_sec_933 else []
102
- }
103
-
104
-
105
- @mcp.tool(
106
- name="search_tax_code",
107
- description="Execute a hybrid semantic and keyword search across US and Puerto Rico tax provisions."
108
- )
109
- async def search_tax_code(
110
- query: str,
111
- jurisdiction_filter: Optional[str] = None,
112
- limit: int = 5,
113
- ctx: Context = CurrentContext()
114
- ) -> List[Dict[str, Any]]:
115
- """
116
- Hybrid search across tax statutory indices.
117
- """
118
- await ctx.info(f"Searching index for: '{query}' with filter: {jurisdiction_filter}")
119
- sample_results = [
120
- {
121
- "citation": "26 U.S.C. § 937",
122
- "jurisdiction": "US",
123
- "score": 0.94,
124
- "snippet": "Rules for determining bona fide residency in possessions (presence, tax home, closer connection tests)."
125
- },
126
- {
127
- "citation": "Ley 60-2019 Sec. 2022.01",
128
- "jurisdiction": "PR",
129
- "score": 0.89,
130
- "snippet": "Exención de Contribución sobre Ingresos a Individuos Residentes Inversionistas sobre ganancias de capital e intereses."
131
- }
132
- ]
133
- return sample_results[:limit]
134
-
135
-
136
- @mcp.tool(
137
- name="evaluate_pr_bona_fide_residency",
138
- description="Evaluates whether an individual satisfies the statutory tests for bona fide residency under IRC § 937."
139
- )
140
- def evaluate_pr_bona_fide_residency(
141
- days_present_pr: int,
142
- days_present_us: int,
143
- prior_year_1_pr_days: int = 0,
144
- prior_year_2_pr_days: int = 0,
145
- has_us_tax_home: bool = False,
146
- closer_connection_jurisdiction: str = "PR"
147
- ) -> Dict[str, Any]:
148
- """
149
- Evaluates IRC § 937 presence, tax home, and closer connection tests.
150
- """
151
- pass_183_days = days_present_pr >= 183
152
- three_year_sum = days_present_pr + prior_year_1_pr_days + prior_year_2_pr_days
153
- pass_549_days = (
154
- three_year_sum >= 549 and
155
- days_present_pr >= 60 and
156
- prior_year_1_pr_days >= 60 and
157
- prior_year_2_pr_days >= 60
158
- )
159
- pass_90_day_us = days_present_us <= 90
160
- presence_satisfied = pass_183_days or pass_549_days or pass_90_day_us
161
-
162
- tax_home_satisfied = not has_us_tax_home
163
- closer_connection_satisfied = (closer_connection_jurisdiction.upper() == "PR")
164
- is_bona_fide = presence_satisfied and tax_home_satisfied and closer_connection_satisfied
165
-
166
- return {
167
- "is_bona_fide_resident": is_bona_fide,
168
- "presence_test": {
169
- "satisfied": presence_satisfied,
170
- "details": {
171
- "183_day_rule": pass_183_days,
172
- "549_day_3_year_rule": pass_549_days,
173
- "90_day_us_limit_rule": pass_90_day_us
174
- }
175
- },
176
- "tax_home_test_satisfied": tax_home_satisfied,
177
- "closer_connection_test_satisfied": closer_connection_satisfied,
178
- "authoritative_basis": "26 U.S.C. § 937; 26 CFR § 1.937-1"
179
- }
180
-
181
-
182
- @mcp.prompt(
183
- name="cross_border_tax_analysis",
184
- description="Guides an agent through analyzing interactions between US federal tax law and Puerto Rico Act 60."
185
- )
186
- def cross_border_tax_analysis_prompt(taxpayer_scenario: str) -> str:
187
- """Creates a structured prompt guiding agentic legal deduction."""
188
- return f"""You are an elite cross-border tax attorney and computational legal analyst.
189
- Analyze the following taxpayer scenario involving United States federal tax law and Puerto Rico statutes:
190
-
191
- SCENARIO:
192
- {taxpayer_scenario}
193
-
194
- ANALYTICAL FRAMEWORK:
195
- 1. Determine bona fide residency status under 26 U.S.C. § 937 and 26 CFR § 1.937-1 (Presence, Tax Home, Closer Connection).
196
- 2. Evaluate applicability of the federal income exclusion under 26 U.S.C. § 933.
197
- 3. Sourcing determination: Apply 26 U.S.C. § 937(b) and 26 CFR § 1.937-2. Specifically apply the 10-year built-in gain rules under 26 CFR § 1.937-2(f) for pre-move appreciated property.
198
- 4. Local Puerto Rico tax incentives: Apply Puerto Rico Incentives Code (Ley 60-2019), specifying whether Chapter 2 (Individual Resident Investors) or Chapter 3 (Export Services) governs.
199
- 5. Federal filing obligations: Assess required IRS reporting, including Form 8898, Form 1040, and Net Investment Income Tax (Form 8960).
200
-
201
- Cite all operative code sections and regulations precisely.
202
- """
203
-
204
- if __name__ == "__main__":
205
- mcp.run()
206
- Federal and Puerto Rico Statutory Interaction: Act 60, IRC § 933, and IRC § 937A central function of a dual-jurisdiction tax MCP server is parsing the statutory interplay between U.S. federal tax authority and Puerto Rico territorial law. Because Puerto Rico is an unincorporated territory of the United States with an independent internal revenue system, Congress established specific statutory rules governing where federal tax jurisdiction ends and territorial authority begins.The Federal Statutory Framework: IRC § 933 and § 937Under 26 U.S.C. § 933(1), individuals who qualify as bona fide residents of Puerto Rico for an entire taxable year are granted an exclusion from federal gross income for income derived from sources within Puerto Rico. This provision does not exempt U.S. citizens residing on the island from federal taxation entirely. United States citizens remain subject to worldwide income taxation under 26 U.S.C. § 1, meaning that income sourced outside Puerto Rico—such as wages for services performed on the mainland, dividends from domestic U.S. corporations, and rental income from mainland real estate—remains fully taxable by the IRS. Additionally, Section 933 explicitly disallows any deductions or credits allocable to the excluded income.To qualify for the Section 933 exclusion, a taxpayer must satisfy three statutory requirements established in 26 U.S.C. § 937 and Treasury Regulation § 1.937-1:The physical presence test requires satisfying at least one of five alternative statutory conditions under 26 C.F.R. § 1.937-1(c). The primary condition requires spending at least 183 days in Puerto Rico during the taxable year. Alternatively, an individual may qualify by demonstrating presence in Puerto Rico for at least 549 days over a three-year period (consisting of the current year and the two preceding tax years), with a minimum of 60 days in each year. Taxpayers can also satisfy the requirement by spending no more than 90 days in the United States during the taxable year, or by earning no more than $3,000 in U.S.-sourced earned income while spending more days in Puerto Rico than in the United States. Finally, taxpayers may qualify by having no significant connection to the United States, as determined by permanent housing, voter registration, and the residence of immediate family members.The tax home test mandates that an individual cannot maintain a tax home outside Puerto Rico at any point during the taxable year under 26 U.S.C. § 937(a)(2) and 26 C.F.R. § 1.937-1(d). In this context, a tax home refers to the individual's principal place of business, regular employment, or official duty post rather than a personal domicile. Maintaining an executive office, active business operations, or regular executive functions within the mainland United States invalidates compliance under this test.The closer connection test under 26 U.S.C. § 937(a)(2) and 26 C.F.R. § 1.937-1(e) requires demonstrating that the taxpayer maintains closer economic, social, and personal relationships to Puerto Rico than to the mainland United States or any foreign jurisdiction. Judicial decisions such as Vento v. Commissioner examine factors including the location of the primary family residence, the jurisdiction of personal banking and financial holdings, the location of tangible personal belongings, local social and civic ties, vehicle registration, and active driver's licenses.Puerto Rico Incentives Code (Act 60-2019)A tax incentive decree issued under Act 60 is an administrative contract with the Government of Puerto Rico fixing local tax liabilities. It confers no exemption, status, or protection under the Internal Revenue Code. Federal tax relief depends entirely on satisfying bona fide residency under Section 937 and statutory income sourcing under Section 937(b).Act 60-2019 consolidated historical incentive programs into distinct programmatic chapters:Chapter 2 (Individual Resident Investors, formerly Act 22) provides a 100% local tax exemption on qualifying Puerto Rico-source interest, dividends, and capital gains recognized after establishing residency. For decree applications submitted on or after January 1, 2027, the local capital gains rate on qualifying passive investment income increases from 0% to 4%, while existing decree holders are grandfathered at 0% through 2035. In exchange, decree holders must comply with annual requirements, including purchasing residential property on the island within two years, making mandatory annual charitable donations to local non-profit organizations, and submitting annual compliance filings to the DDEC.Chapter 3 (Export Services and Commerce, formerly Act 20) provides a 4% corporate income tax rate on net taxable income derived from exporting eligible services rendered within Puerto Rico to foreign or mainland clients. It also provides a 75% exemption on property taxes and a 50% exemption on municipal license taxes (patente municipal). The services must be performed within Puerto Rico for clients that have no commercial nexus to a trade or business within the island.Built-In Gain Sourcing Rules: Treas. Reg. § 1.937-2(f)The sourcing of capital gains represents one of the most litigated areas of federal and territorial tax interaction. Under general federal sourcing principles codified in 26 U.S.C. § 865(a), income from the sale of personal property—including equity securities—is sourced to the residence of the seller. Consequently, if a bona fide resident of Puerto Rico sells stock, the gain is treated as Puerto Rico-source income and excluded from federal taxation under Section 933.To prevent individuals from moving to Puerto Rico to liquidate pre-existing appreciated assets without federal taxation, Treasury Regulation § 1.937-2(f)(1) establishes a ten-year built-in gain look-back rule. Under the default regulatory rule, if an individual sells property owned prior to moving within ten years of establishing bona fide residency in Puerto Rico, the entire recognized gain is treated as U.S.-source income subject to standard federal tax rates.Taxpayers can avoid this treatment by making an election under Treasury Regulation § 1.937-2(f)(1)(vi) on their federal return, which allocates the gain between pre-move and post-move holding periods:For marketable securities, gain allocation is calculated using fair market value (FMV) measured at the close of the market on the first day the taxpayer establishes bona fide residency in Puerto Rico:$$\text{Gain}_{\text{US-Source}} = \text{FMV}_{\text{Residency Date}} - \text{Adjusted Basis}$$$$\text{Gain}_{\text{PR-Source}} = \text{Gross Proceeds} - \text{FMV}_{\text{Residency Date}}$$The pre-move gain is reported on IRS Form 1040 and subject to federal capital gains tax (up to 20% plus the 3.8% Net Investment Income Tax under Section 1411 if statutory thresholds are exceeded). The post-move gain is treated as Puerto Rico-source income excluded from federal gross income under Section 933, and taxed at the preferential Act 60 rate (0% or 4%) on the territorial return.For non-marketable property—such as privately held businesses or real estate—the statutory allocation relies on a linear time-apportionment formula based on holding periods:$$\text{Gain}_{\text{PR-Source}} = \text{Total Recognized Gain} \times \left( \frac{\text{Days Held as Bona Fide Resident}}{\text{Total Days in Holding Period}} \right)$$$$\text{Gain}_{\text{US-Source}} = \text{Total Recognized Gain} - \text{Gain}_{\text{PR-Source}}$$If an asset is sold after ten years of continuous bona fide residency, the look-back rule expires, and the entire gain is treated as Puerto Rico-source income exempt from federal taxation under Section 933.Income / Transaction CategoryStatutory Sourcing BasisFederal IRS Tax TreatmentPuerto Rico Tax Treatment (Act 60)Mandatory Reporting FormsWages for Services Performed in PR26 U.S.C. § 861(a)(3); § 937(b)Excluded from gross income under § 933(1)Taxed at graduated PR income tax rates (Ley 1-2011)PR Form 480.20 via SURIWages for Services Performed in US26 U.S.C. § 861(a)(3)Fully taxable under 26 U.S.C. § 1Credit available under PR law to mitigate double taxationIRS Form 1040Securities Acquired Post-Move26 U.S.C. § 865(a); § 937(b)100% PR-Source; excluded under § 933(1)0% rate under Act 60 Chapter 2 (4% for post-2026 decrees)PR Form 480.30(II)Marketable Stock Acquired Pre-Move (Sold <10 Yrs)26 C.F.R. § 1.937-2(f)(1)(vi)Pre-move appreciation taxed at federal rates; post-move excluded0% on post-move appreciation under Act 60IRS Form 1040 (Schedule D) & PR PlanillaExport Services Entity IncomeAct 60 Chapter 3; 26 U.S.C. § 937(b)Excluded if PR entity; exempt from CFC/GILTI via § 957(c)Flat 4% corporate income tax ratePR Corporate Return Form 480.20(EC)Dividends from Mainland US Corporation26 U.S.C. § 861(a)(2)100% US-Source; fully taxable under § 1 and § 1411 (NIIT)Taxable by PR (subject to foreign tax credit limitations)IRS Form 1040 & Form 8960Federal Enforcement Campaigns and Compliance DocumentationThe IRS Large Business and International (LB&I) division maintains an ongoing compliance campaign monitoring individuals claiming tax benefits under Puerto Rico incentive laws. This initiative targets taxpayers who obtain Act 60 decrees without meeting the physical presence, tax home, or closer connection requirements of Section 937, as well as individuals who mischaracterize U.S.-source income as Puerto Rico-source to evade federal tax liabilities.Federal compliance requires filing specific disclosure and information returns:IRS Form 8898 (Statement for Individuals Beginning or Ending Bona Fide Residence in a U.S. Possession): Required for any tax year in which an individual establishes or terminates bona fide residency in Puerto Rico, provided their worldwide gross income exceeds $75,000. Failure to file without reasonable cause carries a $1,000 statutory penalty under 26 U.S.C. § 6688.IRS Form 8960 (Net Investment Income Tax): Bona fide residents with modified adjusted gross income derived outside Puerto Rico exceeding statutory thresholds ($200,000 for single filers) remain subject to the 3.8% Net Investment Income Tax on non-excluded investment income.IRS Form 5471 (Information Return of U.S. Persons With Respect to Certain Foreign Corporations): While bona fide residents are generally exempt from Controlled Foreign Corporation (CFC) shareholder reporting under 26 U.S.C. § 957(c) for Puerto Rico corporations, individuals who fail the Section 937 residency test face retroactive penalties for unfiled international corporate forms.Agent Integration, Client Configuration, and PluggabilityConnecting the tax MCP server to downstream AI runtimes requires configuring client-side manifests to establish connection parameters, authorization tokens, and execution commands.Local Agent Configuration (STDIO Transport)For desktop AI tools such as Claude Desktop or Cursor, the MCP server is configured within the client's JSON environment file. The client manages the server's lifecycle, launching it as a subprocess on demand and exchanging structured payloads over standard I/O.The listing below illustrates a standard configuration registering a local tax MCP server alongside a remote production endpoint within claude_desktop_config.json:JSON{
207
- "mcpServers": {
208
- "us-pr-tax-local": {
209
- "command": "uv",
210
- "args": [
211
- "run",
212
- "--with", "fastmcp",
213
- "--with", "pydantic",
214
- "python",
215
- "/usr/local/bin/tax_server.py"
216
- ],
217
- "env": {
218
- "PYTHONUNBUFFERED": "1",
219
- "TAX_INDEX_STORAGE_PATH": "/var/data/tax_indices",
220
- "USLM_CACHE_DIR": "/var/cache/uslm_xml"
221
- }
222
- },
223
- "us-pr-tax-remote": {
224
- "url": "http://tax-mcp.internal.enterprise.net:8000/mcp",
225
- "headers": {
226
- "Authorization": "Bearer mcp_sec_token_9823471029384"
227
- }
228
- }
229
- }
230
- }
231
- Remote Enterprise Deployment (Streamable HTTP / ASGI Architecture)For enterprise agent deployments serving distributed multi-agent systems, executing local subprocesses is inefficient and insecure. Instead, the FastMCP server is exposed as an ASGI web application deployed inside containerized infrastructure (e.g., Docker, Kubernetes, AWS ECS) using Uvicorn.Python"""
232
- ASGI Production Entrypoint for Enterprise MCP Fleet.
233
- File: app.py
234
- Run with: uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4
235
- """
236
-
237
- from tax_server import mcp
238
-
239
- # Expose standard ASGI application container
240
- app = mcp.http_app()
241
- When operating over Streamable HTTP, clients connect to http://host:8000/mcp. This transport supports concurrent connections across multiple client sessions, token-based authentication via HTTP middleware, and streaming responses.Technical Synthesis and Operational ConsiderationsOperating an enterprise tax MCP server across federal and Puerto Rico jurisdictions requires continuous attention to structural and regulatory factors:A primary architectural requirement is separating territorial decree rules from federal residency determinations. Computational agents must be designed to recognize that an Act 60 decree provides zero federal tax protection on its own. Decrees operate strictly as contractual agreements with the Government of Puerto Rico, while federal income exclusions depend entirely on satisfying the presence, tax home, and closer connection requirements of 26 U.S.C. § 937 and § 933.Maintaining structural integrity during data ingestion is equally critical. Ingesting tax legislation as flat text chunks severs operative subsections from parent definitions and statutory exceptions. Parsing legislative texts into an Abstract Syntax Tree using USLM XML specifications preserves contextual breadcrumbs and statutory hierarchy, allowing retrieval tools to return complete legal provisions with their governing limitations intact.The retrieval pipeline must combine deterministic citation routing with hybrid search capabilities. When an agent queries an exact statutory reference, such as 26 U.S.C. § 933 or Ley 60 Sec. 2021.01, the system must bypass approximate vector search and return canonical statutory text via resource templates. Conversely, conceptual and cross-jurisdictional questions require hybrid retrieval combining BM25 keyword matching and dense vector embeddings merged through Reciprocal Rank Fusion.Finally, indexing pipelines must account for temporal changes in tax law. Legislative updates require automated ingestion monitoring that polls OLRC release points and eCFR API endpoints for amendments. In Puerto Rico, systems must track key statutory transitions—such as the increase in Act 60 Chapter 2 investor capital gains rates from 0% to 4% for applicants filing on or after January 1, 2027—ensuring that agent reasoning applies the correct statutory rules across both legacy and future tax years.
@@ -1,97 +0,0 @@
1
- # Tax MCP follow-up: Puerto Rico reuse, sources, translation, docs site
2
- Prepared Sun Oct 11, 2026, ~9:00 PM ET by Grok Bot. Builds on `tax-mcp-plan.md`. **[verified]** = checked this session; **[unverified]** = needs confirming. **Not legal advice.**
3
-
4
- ## TL;DR
5
- - **Reuse:** statutes (CRI 2011) and binding regulations are almost certainly free to republish and translate (government edicts doctrine, Georgia v. PRO). Hacienda's own guidance (CC, DA, BI, Opiniones) and forms are *probably* fine, but that's the open legal question. Hacienda's site footer says "2014 © Departamento de Hacienda", and its terms page returns "Página no encontrada", so there are no published reuse terms. **Do not ingest LexJuris** (commercial, and it adds its own editorial work). A PR lawyer should confirm two points: (a) whether the edicts doctrine covers *executive-agency* guidance, and (b) how to treat Hacienda's © footer.
6
- - **Sources:** everything needed is on hacienda.pr.gov. It's a Drupal site with filterable listings and **1,261 "Publicaciones Oficiales"** (410 Cartas Circulares, 158 DAs). The CRI is one born-digital PDF: 1,104 pages, ~3.67M characters, no OCR needed.
7
- - **Translation:** Gemini 2.5 Flash on Vertex is the cheapest by far, roughly **$15–40 one-time** for an estimated ~35M-character corpus. Cloud Translation NMT costs $20/M characters (≈$700) but has native glossaries. Recommended: Gemini batch, with the glossary included in the prompt, Spanish kept authoritative, and every translation labeled "Traducción no oficial / Unofficial translation".
8
- - **Docs site:** **Astro Starlight on Firebase Hosting (or GitHub Pages), $0.** It has built-in i18n, Pagefind search, and the `starlight-llms-txt` plugin, plus our own FastMCP server for the doc-MCP. Mintlify's free Starter tier includes a custom domain and an MCP server, but its **AI translations are Pro-only ($450/mo)**, and it's a hosted SaaS that's a poor fit for an auto-generated corpus of 10k+ pages.
9
-
10
- ## 1) Puerto Rico reuse: verdicts
11
- Legal background:
12
- - **17 U.S.C. §105** covers only works of the *U.S. Government* (federal officers and employees), not states or territories. It does not reach PR. The Court in *Georgia v. PRO* notes the Act "contains no similar prohibition against works of state governments" [verified, https://www.law.cornell.edu/supremecourt/text/18-1150].
13
- - **Federal copyright law applies in PR** (PR Ley 55-2012's own exposición de motivos says "En Puerto Rico aplica el 'Copyright Act' de 1976") [verified, https://bvirtualogp.pr.gov/ogp/Bvirtual/leyesreferencia/PDF/Propiedad%20Intelectual/55-2012.pdf]. So PR's edicts stand on the federal government edicts doctrine.
14
- - **Georgia v. Public.Resource.Org, 590 U.S. 255 (2020):** officials "empowered to speak with the force of law cannot be the authors of ... the works they create in the course of their official duties". This covers judges and legislators, including non-binding annotations they write [verified, https://www.supremecourt.gov/opinions/19pdf/18-1150_7m58.pdf]. The Court did **not** decide whether executive-agency works are covered. That's the gap.
15
- - **PR moral rights (Ley 55-2012):** these are attribution and integrity rights for authors. They're a low risk for government texts, but we should attribute the source and never alter the original. [unverified as to applicability to government works; lawyer]
16
- - **Ley 122-2019 (Datos Abiertos):** "Open Data" means data that can be "usados, reutilizados y redistribuidos libre y gratuitamente por cualquier persona", and reuse "con fines comerciales o no comerciales" is expressly allowed. Its list of data to publish includes "Reglamentos, cartas, circulares, normativas ... y determinaciones" [verified via the text at https://bvirtualogp.pr.gov/ogp/bvirtual/leyesreferencia/pdf/122-2019.pdf ; English: https://bvirtualogp.pr.gov/ogp/Bvirtual/leyesreferencia/PDF/2-ingles/122-2019.pdf]. This is strong *policy* support for reusing Hacienda circulars, even though the law sets no formal license.
17
- - **Ley 141-2019 (Transparencia):** this is an access-to-information law. Hacienda links to it from its menu [verified link present]. It supports access, not a copyright waiver. [unverified details]
18
- - **hacienda.pr.gov terms:** the footer reads "2014 © Departamento de Hacienda". `/terminos-y-condiciones` is a 404 ("Página no encontrada"). No reuse license was found. [verified]
19
- - **LexJuris (lexjuris.com):** a private, commercial compilation with its own formatting and notes. Treat it as copyrighted and ToS-restricted. Link to it only; don't ingest. [unverified ToS]
20
- - **OGP Biblioteca Virtual:** the correct host is `bvirtualogp.pr.gov` (`bvirtual.ogp.pr.gov` returned 404). It's a government compilation of laws in Spanish, with some in English. [verified host]
21
-
22
- | Document type | Verdict | Basis / caveat |
23
- |---|---|---|
24
- | CRI 2011 (statute text, as amended) | **Republish + translate: yes (high confidence)** | The law itself; edicts doctrine (Banks, Georgia v. PRO). Use Hacienda's or OGP's compilation as the source. A compiler's *headings/notes* could be a thin layer: keep them attributed |
25
- | Reglamentos (8049 and others, binding regs) | **Yes (high–medium)** | Have the force of law. But the Reglamento 8049 *compilation* says it's reference-only; label it that way |
26
- | Cartas Circulares, Determinaciones Administrativas | **Probably yes (medium)** | Official guidance issued by the Secretary (statutory basis to confirm); Ley 122-2019 lists "cartas, circulares ... determinaciones" as open data. **Lawyer:** do executive edicts qualify? |
27
- | Opiniones Administrativas / rulings to taxpayers | **Probably yes, redacted only (medium)** | Publish only what Hacienda itself has published (already redacted). Never pull private rulings |
28
- | Boletines Informativos, Folletos, Tablas de Retención | **Likely yes (medium)** | Informational government works. The © footer is the main risk |
29
- | Forms and instructions (Planillas) | **Yes to link and quote; host copies cautiously (medium)** | Low risk, but forms change yearly: link to the official PDF and index the instruction text |
30
- | LexJuris, Microjuris, Westlaw PR | **No** | Private editorial work and ToS. Link only |
31
- | Translations we make | **Ours, so we can license them CC0/CC BY** | Mark them "unofficial"; the Spanish text controls |
32
-
33
- **Open legal questions (for a PR lawyer):** (1) Does the edicts doctrine reach Hacienda (executive) guidance, or do we rely on Ley 122-2019 plus fair use? (2) Is the "© Departamento de Hacienda" footer an actual copyright claim over its publications? (3) Should we send Hacienda a courtesy notice, or ask for written permission or open-data status (cheap insurance)? (4) Disclaimer wording: not tax advice, and the translation is not official, in both languages. (5) Moral rights (Ley 55-2012) and how to attribute government texts. (6) Do we need registration if we use the "Hacienda" name or seal? Don't use the seal.
34
-
35
- ## 2) PR source inventory
36
- | Source | URL | Format / lang | Count / update | Status |
37
- |---|---|---|---|---|
38
- | CRI 2011 landing | https://hacienda.pr.gov/publicaciones/codigo-de-rentas-internas-de-puerto-rico-de-2011 | HTML | Page says "según enmendado al 28 de mayo de 2026" | [verified] |
39
- | CRI PDF | https://hacienda.pr.gov/sites/default/files/codigo_de_rentas_internas_2011_segun_enmendado_28.08.2026.pdf | PDF, born-digital (Word 365), Spanish (has an «english» link marker, OGP style) | 1,104 pages, 9.2 MB, ~3.67M chars. One file replaced in full on each update. **The filename says 28.08.2026 but the page says May 28.** Diff on SHA, don't trust labels | [verified] |
40
- | Code index (2011 + 1994) | https://hacienda.pr.gov/sobre-hacienda/publicaciones/area-de-rentas-internas-y-area-de-politica-contributiva/codigo-de-rentas-internas | HTML | | [verified earlier] |
41
- | Reglamentos listing | https://hacienda.pr.gov/sobre-hacienda/publicaciones/area-de-rentas-internas-y-area-de-politica-contributiva/reglamentos | HTML → PDFs | Page loads (200). Count not parsed (JS/list markup) | [partly verified] |
42
- | Reglamento 8049 compilation | https://hacienda.pr.gov/publicaciones/compilacion-del-reglamento-del-codigo-de-rentas-internas-de-puerto-rico-de-2011-segun-enmendado | PDF, Spanish | rev. Jul 13, 2026; "reference only" | [verified earlier] |
43
- | Publicaciones Oficiales (all) | https://hacienda.pr.gov/sobre-hacienda/publicaciones/area-de-rentas-internas-y-area-de-politica-contributiva/publicaciones-oficiales | HTML listing → PDFs (/sites/default/files/publicaciones/YYYY/MM/) | **1,261** items; newest CC RI 26-13 (Jun 30, 2026) | [verified] |
44
- | Filter `?field_pri_categorizacion_value=` | values: `carta-circular` (**410**), `determinacion-administrativa` (**158**), `boletin-informativo`, `boletin-informativo-politica-contributiva`, `carta-circular-politica-contributiva`, `folletos-informativos-de-rentas-internas`, `listas-oficiales`, `publicacion`, `tablas-de-retencion` | Mostly Spanish; some English (e.g. "Administrative Determination No. 23-04") | Date filters available (field_pri_fecha_antes_de/despues_de) → incremental crawl | [verified] |
45
- | Opiniones Administrativas | Not a separate filter value; may fall under `publicacion` or not be published | | **unknown**: confirm | [unverified] |
46
- | Planillas, Formularios y Anejos | https://hacienda.pr.gov/formularios (200) and "Planillas, Formularios y Anejos" menu | PDFs (fillable), Spanish, some English | Yearly per tax year; hundreds of files [unverified count] | [partly verified] |
47
- | Contabilidad Central CCs (not tax) | .../contabilidad-central/cartas-circulares-de-contabilidad-central | | 595; **exclude** (gov accounting) | [verified] |
48
- | OGP Biblioteca Virtual | https://bvirtualogp.pr.gov/ (laws in force, some English) | PDF | Cross-check the CRI and source laws like 60-2019 (Incentives Code) | [verified host] |
49
- | Legislature SUTRA | https://sutra.oslpr.org/ (200) | HTML/PDF | Bills and enacted laws as they pass: an early signal that a CRI amendment is coming | [verified reachable] |
50
- | Departamento de Estado | Leyes aprobadas/Reglamentos registry (Ley 38-2017 LPAU filings) | PDF | Official registry of filed regulations. URL to confirm | [unverified] |
51
- | Ley 60-2019 Incentives Code (DDEC) | via bvirtualogp | PDF | Phase 1 add-on (Act 60 decrees are core PR tax) | [unverified] |
52
-
53
- Size estimate (Spanish): CRI ~3.7M + regs ~3–5M + 1,261 publications at ~10–20k chars each ≈ 13–25M + form instructions ~5–10M ≈ **~25–45M characters (call it ~35M)**. This is an estimate.
54
-
55
- ## 3) Translation
56
- Official prices [verified, https://cloud.google.com/translate/pricing ; https://cloud.google.com/gemini-enterprise-agent-platform/generative-ai/pricing]:
57
- - **Cloud Translation NMT:** $20 per 1M chars (first 500k chars/mo free). Glossary creation is free. Document translation is $0.08/page.
58
- - **Translation LLM (Advanced):** $10 per 1M input chars + $10 per 1M output chars.
59
- - **Gemini 2.5 Flash (Vertex):** $0.30 per 1M input tokens and $2.50 per 1M output tokens; Batch/Flex is $0.15 / $1.25.
60
-
61
- Estimate for ~35M chars (≈9M tokens in, ~10M out at ~4 chars/token, assumed):
62
- | Option | One-time cost | Notes |
63
- |---|---|---|
64
- | Gemini 2.5 Flash batch | **≈ $14** (+ glossary/prompt overhead → ~$20–40) | Best quality-per-$; glossary goes in the prompt; legal-register control |
65
- | Gemini 2.5 Flash standard | ≈ $28 (~$40–60 with overhead) | |
66
- | Translation LLM | ≈ $700 | |
67
- | NMT + glossary | ≈ $700 | Deterministic, native glossary |
68
- Ongoing diffs (a few CCs per week plus CRI amendments): **under $1/mo** on Gemini.
69
-
70
- Approach: translate per section (CRI "Sección xxxx.xx", CC paragraphs) so the EN and ES pages align 1:1. Spanish is authoritative. Every EN page gets a banner "Unofficial translation. The Spanish original controls", plus a link to the source PDF. Keep a versioned glossary (`glossary.csv`: planilla→return, contribución sobre ingresos→income tax, IVU→sales and use tax (IVU), arbitrios→excise taxes, Secretario→Secretary of the Treasury, decreto→decree, etc.), and seed it from Hacienda's own English documents and OGP's English laws. Only re-translate sections whose SHA changed. QA: back-translate a sample, check the glossary terms, and get a human spot-check on the top 50 CRI sections. Translate the federal content to Spanish later, on the same pipeline.
71
-
72
- ## 4) Docs site comparison
73
- | | Mintlify Starter | Starlight (Astro) | Docusaurus | MkDocs Material | Fumadocs |
74
- |---|---|---|---|---|---|
75
- | Price | $0; Pro $450/mo [verified https://www.mintlify.com/pricing] | $0 OSS | $0 OSS | $0 OSS | $0 OSS |
76
- | Custom domain | Yes on Starter | Yes (Firebase/GH Pages) | Yes | Yes | Yes (needs a server/Vercel for full features) |
77
- | MCP server | Built in on Starter | DIY: FastMCP over the markdown | DIY | DIY | DIY |
78
- | llms.txt | Built in | `starlight-llms-txt` (llms/-full/-small, customSets per jurisdiction) | `docusaurus-plugin-llms` | `mkdocs-llmstxt` (no .md per page) | Built in (`npx @fumadocs/cli feature llms`, lang-aware `index(lang)`) |
79
- | EN/ES i18n | Supported; **AI translations Pro-only** | Built in (locales, fallback banner) | Built in (mature) | Plugin (mkdocs-static-i18n) | Built in |
80
- | Search | Built in | Pagefind (static, scales) | Algolia DocSearch or local plugin | lunr built in (heavy at scale) | Orama |
81
- | 10k+ pages | Hosted; repo-sync limits [unverified] | Good; static builds; Pagefind chunked | OK but slow builds and memory-hungry [unverified] | Slow search index at scale | Next.js; fine |
82
- | OSS program | Mintlify has had an OSS program [unverified, check] | n/a | n/a | n/a | n/a |
83
-
84
- **Recommendation: Starlight + `starlight-llms-txt` + Pagefind on Firebase Hosting** (GitHub Pages works as a fallback). It costs $0, handles i18n with a fallback note out of the box, and generates per-jurisdiction llms sets. The doc MCP is the tax MCP itself: FastMCP serving the same markdown/SQLite, so the docs aren't duplicated. Fumadocs is runner-up if a lang-aware `llms.txt` per locale matters a lot. Revisit Mintlify only if their OSS program grants Pro features for free.
85
-
86
- ## 5) Recommended stack
87
- Cloud Run Jobs + Scheduler crawlers (Hacienda filter + date window, SHA diffs) → GCS raw → pdftotext/PyMuPDF section splitter → Markdown ES (authoritative) → Gemini 2.5 Flash batch EN with glossary → git repo `content/{es,en}/pr/...` → Starlight build → Firebase Hosting with `/llms.txt`, `/es/llms.txt` and per-jurisdiction `llms-full` → SQLite FTS5 index baked into the FastMCP server (from Christian's template) on Cloud Run. Tools: `search`, `get_section`, `cite("PR CRI Sec. 1031.01")`, `list_publications(type, since)`, `changes_since(date)`, all returning `lang`, `official: true/false` and source URL.
88
-
89
- ## 6) Updated Phase 1: Puerto Rico first (~4–5 weeks, estimate)
90
- 1. **Week 0:** legal review (questions above); choose the domain and repo name; optional courtesy email to Hacienda (needs Christian's go).
91
- 2. **Week 1:** Hacienda crawler (listing + filters + date windows), CRI and Reglamento 8049 download, SHA change detection, raw archive.
92
- 3. **Week 2:** CRI section splitter (Sección xxxx.xx, Subtítulo/Capítulo), CC/DA/BI metadata (number, date, asunto), ES markdown with provenance.
93
- 4. **Week 3:** glossary v1 plus Gemini batch EN, with the banner and QA sample; Starlight site with ES default and EN locale; llms.txt sets.
94
- 5. **Week 4:** FastMCP server from the template (100% tests), SQLite FTS5 bilingual index, cite parser for CRI/CC/DA/BI numbers.
95
- 6. **Week 5:** Scheduler (daily listing crawl, weekly CRI hash check), stale flags, SUTRA watch for new laws, deploy; registry listing only on Christian's go.
96
- Phase 1b: Ley 60-2019 Incentives Code and its Reglamento. Then IRS (Phase 2), then states (Phase 3).
97
- Phase 1 cost: translation ~$20–60 one-time, then under $1/mo. Hosting stays as in the plan (~$15–50/mo, mostly Cloud Run/DB, estimated).