Portable DB framework with italaw and ICSID scrapers

Gadoes builds a self-hosted alternative to API-based MCP sources - a scraper framework for jurisdictions with no published MCP server - and ships two concrete implementations: italaw (international investment arbitration) and ICSID (World Bank arbitration awards). Three chunks, six commits.

integrationknowledge-management

Chunk 14 - Framework. Three files under backend/src/lib/mcp/portable/: baseScraper.ts (69 lines) defines the BaseScraper contract with an async generator scrape() method; portableMcpServer.ts (57 lines) wraps a scraped corpus as an MCP-compatible server; freshnessManager.ts (120 lines) tracks when a corpus was last refreshed and whether it's within its configured staleness window. New runtime dependencies: better-sqlite3@^12.9.0 (for the local corpus DB), cheerio@^1.2.0 (for HTML parsing), and p-throttle@^8.1.0 (to rate-limit scrape requests).

Chunk 15 - italaw. portable/italaw/scraper.ts (104 lines) fetches and parses case pages from italaw.com into better-sqlite3 rows. server.ts (40 lines) wraps it as an MCP server. Five HTML fixtures cover cases like Metalclad v. Mexico, Vattenfall v. Germany (Energy Charter Treaty), and Siemens v. Argentina. A scripts/scrape-italaw.ts CLI entry point runs the scrape manually: npm run scrape:italaw [path/to/italaw.db]. 216-line test suite.

Chunk 16 - ICSID. Same pattern: portable/icsid/scraper.ts (102 lines) and server.ts (40 lines), five HTML fixtures covering awards, jurisdiction decisions, and an annulment (Siemens ARB/03/8; Occidental v. Ecuador ARB/06/11, the $1.7B award; Salini v. Morocco for the jurisdiction test). npm run scrape:icsid. This chunk also drops supabase/config.toml (406 lines) - local Supabase dev environment setup, unrelated to the portable DB feature.

The italaw and ICSID citation verification_status is auto-set to verified on save (see Chunk 20) because the corpus is a local scrape rather than a live API call.

So what The framework (Chunk 14) is the interesting piece for most forks. `BaseScraper` + `PortableMcpServer` + `FreshnessManager` is a reusable pattern for adding any jurisdiction whose source doesn't have an API or published MCP server. The italaw and ICSID implementations confirm the abstraction works. Caveats: scraping ties you to the target sites' HTML structure, so expect maintenance. If you don't specifically need investment-arbitration coverage, import just the framework and build your own scrapers against it.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

6 commits from Gadoes/dispumike, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
5512f4f2 Chunk 14: Portable DB Framework (BaseScraper, PortableMcpServer, FreshnessManager) Gadoes 2026-05-02 ↗ GitHub
610e68de Merge Chunk 14: Portable DB Framework Gadoes 2026-05-02 ↗ GitHub
6500aec7 Chunk 15: italaw Portable DB (scraper, server, fixtures, test) Gadoes 2026-05-02 ↗ GitHub
a2e9ca95 Merge Chunk 15: italaw Portable DB Gadoes 2026-05-02 ↗ GitHub
a37fcd0c Chunk 16: ICSID Portable DB (scraper, server, fixtures, test) Gadoes 2026-05-02 ↗ GitHub
aa2d8c12 Merge Chunk 16: ICSID Portable DB Gadoes 2026-05-02 ↗ GitHub

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-28.md from inside the repo you want the changes in.

⬇ Download capture-thread-28.md