@pipeworx/guam-code

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

Connect to just the @pipeworx/guam-code pack

https://gateway.pipeworx.io/guam-code/mcp — only @pipeworx/guam-code’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

Guam Code Annotated (GCA) — Guam territorial statutes, by citation and by topic/keyword search. Keyless.

Tools

  • gu_statute(citation, title?) — full text of a GCA section by citation (“9 GCA 16.30” is Aggravated Murder Defined; “21 GCA 33101” is who may take an acknowledgment of a deed). Resolves the citation to its one chapter PDF, fetches it live, and extracts the text. title is only needed if not already embedded in citation.
  • gu_search(query, title?, limit?) — topic/keyword search over section and chapter catchlines (not full statutory prose — see below), optionally restricted to one Title (1-22).

Auth

Keyless.

Source and shape

The Compiler of Laws (Judiciary of Guam, col.guamcourts.gov) publishes the GCA as ~800 per-CHAPTER PDFs, linked from one static HTML page: 22 collapsible Title panels, each listing its Chapters. There is no per-title listing, no search API, and no site-wide section index (confirmed live) — the same gap mcps/north-dakota-code hit for the Century Code. That page is baked ONCE (title/chapter/catchline/PDF URL) by scripts/bake-index.mjs.

Unlike North Dakota, the GCA index page does not also enumerate every section. But every sampled chapter PDF opens with its own embedded table of contents — a run of § <chapter>.<nn>. Catchline. headings — so scripts/bake-sections.mjs fetches all ~800 chapter PDFs once more and bakes a section-level catchline index (15,760 rows) from that TOC block. gu_search reads it; gu_statute never trusts it for the text it returns — it re-derives section boundaries fresh from the live PDF on every call.

Refresh path

Re-run both whenever the Compiler of Laws amends the GCA enough to be worth re-baking (run the chapter index first — the section bake reads it):

node mcps/guam-code/scripts/bake-index.mjs > mcps/guam-code/src/gu-index-data.ts
node --experimental-strip-types mcps/guam-code/scripts/bake-sections.mjs > mcps/guam-code/src/gu-section-data.ts

The section bake needs --experimental-strip-types because it imports the pack’s own TypeScript extractor directly (no tsx/ts-node dependency in this repo) — nothing at runtime needs that flag, only this one offline script. Budget a few minutes: ~800 HTTP fetches at modest concurrency, as a courtesy to col.guamcourts.gov rather than because it rate-limits.

Both baked modules are combined by src/gu-baked-data.ts (a plain re-export) into the ONE data module workers/gateway/src/pack-baked-indexes.json points at for this pack — the gateway uploads its exports to KV at deploy and injects them as args._bakedIndex, never as a module-scope import (see index.ts’s ensureIndex; fleet #2754 took the gateway down the one time a baked table was value-imported into every isolate).

Two citation conventions, both real

Newer, recodified titles (9 GCA, the Criminal & Correctional Code, adapted from the 1977 Model Penal Code) cite “chapter.section” with a dot — “9 GCA § 16.30” is Aggravated Murder. Older titles (e.g. 21 GCA Ch. 33, Proof and Acknowledgments of Instruments) concatenate chapter and a zero-padded section number with no separator — “21 GCA § 33101” is chapter 33, section 101. gu_statute accepts either form (see parseGuCitation in src/index.ts). The chapter/section boundary for the no-dot form is genuinely ambiguous from the digit string alone (chapter numbers vary in length); it is resolved by picking the longest known chapter number, for the given Title, that is a literal prefix of the citation — correct in every case sampled.

shared/src/pdf-text.ts needed real fixes, forked pack-local instead

Guam’s chapter PDFs defeated the shared extractor in ways it did not yet handle, and this pack was built the same week another pack (#2884, New Mexico) was independently editing that shared file — so the fixes live in src/gu-pdf-extract.ts, a pack-local fork of shared/src/pdf-text.ts, with a loud header comment for whoever next touches the shared extractor to fold them in (nothing about them is Guam-specific):

  1. Literal strings weren’t routed through the font decoder. Guam’s producer (Neevia Document Converter, from Word) writes some non-WinAnsi subset fonts’ text as parenthesized LITERAL strings ((abc)Tj) rather than hex (<...>Tj). The shared extractor’s decodeRun passes a literal run through unchanged — correct for WinAnsi, but for these fonts the raw bytes are a tiny, arbitrary code space meaningful only via the font’s own /ToUnicode CMap, which the shared code already has the machinery for (built for North Dakota) but only wires to the HEX-string path. Confirmed live: unfixed, § 16.10 extracted as control-character noise; fixed, it reads correctly.
  2. A declared /Length a few bytes long. Several older chapter PDFs (“MS Word for Windows Document” producer — an earlier era than the Neevia-converted ones above) declare a /Length 1+ bytes longer than their actual deflate stream. Python’s zlib tolerates the trailing byte silently; Node/Workers’ strict DecompressionStream throws ERR_TRAILING_JUNK_AFTER_STREAM_END. Retried with the stream’s tail trimmed a byte at a time (up to 4) before giving up.
  3. A quote-glyph CMap that is wrong in the source file. One embedded symbol font per chapter PDF (...+WPTypographicSymbols, used only for curly quotes) carries a /ToUnicode CMap that maps its two codes to U+0041 (‘A’) and U+0040 (’@’) instead of the left/right curly quote it visually renders as. Confirmed by eye: “ADirector of Public Safety@” in raw extraction is ““Director of Public Safety”” with those two codes substituted back — the obviously intended reading, reproduced by any PDF viewer’s own copy-paste. Overridden by font name, since no general rule could derive it.
  4. Crash-adjacent, found while baking the section index. The shared inflate() helper’s two stream writes were fire-and-forget (void writer.write(...)); a malformed deflate stream (the same PDFs #2 above describes) rejected that promise as an UNHANDLED rejection, invisible to any caller’s try/catch and fatal to the whole process — crashed scripts/bake-sections.mjs outright, mid-run. Fixed by attaching a no-op .catch() to each write/close; the real failure still surfaces through reader.read(), which the caller already handles. Worth checking whether shared/src/pdf-text.ts has the same exposure.

Four capabilities — two available, two are not

  • Citation lookup — available (gu_statute).
  • Topic/keyword search — available (gu_search), over official CATCHLINES (section + chapter name), not full statutory prose. Coverage is best-effort: catchlines are derived from each chapter PDF’s own table of contents rather than a separate official index, so an unusually formatted chapter can be under-represented.
  • Amendments/enactment history — embedded in gu_statute’s text field as the statute’s own “SOURCE:” line (e.g. “Enacted 1977 as 16.30; amended by P.L. 14-125…”), not split out as a separate field — the GCA does not mark it up distinctly enough to parse reliably across both PDF eras sampled.
  • Historical version (a section’s text as it read before an amendment) — not available. col.guamcourts.gov serves the current text only; no per-year or per-session archive was found.

Known rough edge: page-furniture noise at a chapter’s last section

gu_statute strips the repeating running header (“9 GCA CRIMES AND CORRECTIONS CH. 16 CRIMINAL HOMICIDE 1”) and the “COL” stamp every page carries, self-derived from the chapter text’s own first occurrence. Older-era PDFs (the “MS Word for Windows Document” producer, #2 above) sometimes extract that header with no inter-word spacing (“21GCAREAL PROPERTY” rather than “21 GCA REAL PROPERTY”), which the stripping regex — anchored on GCA preceded by whitespace — does not match. The statutory text itself is unaffected; only a section that happens to be the LAST one on a page, in one of these older chapters, can carry a trailing fragment of the next page’s header/footer. Cosmetic, not a correctness defect.

Citations

Give citation as "9 GCA 16.30", "9 GCA § 16.30", "21 GCA 33101", or a bare section ("16.30" / "33101") with title passed separately.

Data sources

  • https://col.guamcourts.gov/guam-code-annotated/guam-code-annotated — the Title/Chapter index (one collapsible page). Baked once into src/gu-index-data.ts; never fetched per call.
  • https://col.guamcourts.gov/sites/default/files/9gc016.pdf — one chapter’s full statutory text (here, 9 GCA Chapter 16, Criminal Homicide — swap the filename for any other chapter). gu_statute fetches this live on every call and extracts the target section out of it. The same ~800 chapter PDFs are also fetched once, offline, by scripts/bake-sections.mjs to build the catchline search index.

Both are plain, keyless, server-rendered HTML/PDF — no login, no JS, no rate-limit observed during development.

Tools

  • gu_statute — Get the FULL TEXT of a section of the Guam Code Annotated (GCA) — Guam territorial law — by citation. “9 GCA 16.30” (or “9 GCA § 16.30”) is Aggravated Murder Defined; “21 GCA 33101” is who may take an
  • gu_search — Search the Guam Code Annotated BY TOPIC or keyword rather than citation — “murder”, “security deposit”, “concealed weapon permit”, “homestead”. Matches against official section and chapter CATCHLINES

Tools

  • gu_search — Search the Guam Code Annotated BY TOPIC or keyword rather than citation — murder , security deposit , concealed weapon permit , homestead . Matches against official section and chapter CATCHLINES (not
  • gu_statute — Get the FULL TEXT of a section of the Guam Code Annotated (GCA) — Guam territorial law — by citation. 9 GCA 16.30 (or 9 GCA § 16.30 ) is Aggravated Murder Defined; 21 GCA 33101 is who may take an ackn

Regenerated from source · build October 9, 2026