@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.titleis only needed if not already embedded incitation.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):
- 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’sdecodeRunpasses 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/ToUnicodeCMap, 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.10extracted as control-character noise; fixed, it reads correctly. - A declared
/Lengtha few bytes long. Several older chapter PDFs (“MS Word for Windows Document” producer — an earlier era than the Neevia-converted ones above) declare a/Length1+ bytes longer than their actual deflate stream. Python’s zlib tolerates the trailing byte silently; Node/Workers’ strictDecompressionStreamthrowsERR_TRAILING_JUNK_AFTER_STREAM_END. Retried with the stream’s tail trimmed a byte at a time (up to 4) before giving up. - 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/ToUnicodeCMap 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. - 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 — crashedscripts/bake-sections.mjsoutright, mid-run. Fixed by attaching a no-op.catch()to each write/close; the real failure still surfaces throughreader.read(), which the caller already handles. Worth checking whethershared/src/pdf-text.tshas 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’stextfield 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.govserves 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 “COLGCA 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 intosrc/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_statutefetches this live on every call and extracts the target section out of it. The same ~800 chapter PDFs are also fetched once, offline, byscripts/bake-sections.mjsto 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 (notgu_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