Skip to content

OpenReyestr Service

overthelex edited this page May 17, 2026 · 3 revisions

OpenReyestr Service

The OpenReyestr Service (mcp_openreyestr/) is a specialized Model Context Protocol (MCP) server within the SecondLayer monorepo. It provides access to Ukrainian state registries -- primarily NAIS (National Information Systems of the Ministry of Justice) open data from data.gov.ua, plus additional sources (DPS tax registries, NAZK anti-corruption declarations, Prozorro public procurement, RNBO sanctions, ARMA seized assets, OpenStreetMap street renamings).

The service supports triple transport: MCP stdio for Claude Desktop, HTTP REST API for web integration, and SSE streaming for long-running queries. It handles tens of millions of records imported from government XML/CSV datasets.

Architecture

data.gov.ua (ZIP)                         OpenStreetMap / NAZK / Prozorro / ARMA
       |                                              |
       v                                              v
  sync-all-registries.ts                   dedicated import scripts
       |                                              |
       +--- download + unzip                          |
       +--- XML: generic-xml-importer.ts              |
       +--- CSV: csv-importer.ts (parallel workers)   |
       |                                              |
       v                                              v
  PostgreSQL (openreyestr DB)  <--------------------------+
       |
       v
  OpenReyestrTools (query layer)
       |
       v
  MCPOpenReyestrAPI (tool definitions + routing)
       |
       +--- MCP stdio (index.ts)
       +--- HTTP REST (http-server.ts, port 3005 prod / 3004 local)
       +--- SSE streaming (/api/tools/:toolName/stream)

Technical Stack

Component Technology
Runtime Node.js 20+ (TypeScript 5.3)
Database PostgreSQL 15+
XML parsing fast-xml-parser (small/medium), SAX streaming (large/huge)
CSV parsing readline + iconv-lite, parallel DB workers
HTTP framework Express 5
Auth Bearer token (SECONDARY_LAYER_KEYS) + optional Google OAuth + JWT
Metrics Prometheus (prom-client)
Rate limiting express-rate-limit (300 req/min global, per-IP)

Port Allocation

Environment HTTP Port PostgreSQL Port
Production 3005 5432 (internal)
Local (Docker) 3004 5435 (host-mapped)

MCP Tools (27 total)

The service exposes 27 tools through the MCP protocol. When accessed through the unified gateway, tool names are prefixed with openreyestr_.

Core Entity Registry (EDR)

Tool Description
search_entities Full-text search across legal entities (UO), entrepreneurs (FOP), and public associations (FSU) by name, EDRPOU, record, status
get_entity_details Full entity profile including founders, beneficiaries, signers, branches, assignees, bankruptcy info
search_beneficiaries Search beneficial owners by name across all entity types
get_by_edrpou Direct lookup by 8-digit EDRPOU code
get_statistics Registry-wide counts (total and active) by entity type

Justice Registries (NAIS)

Tool Description
search_notaries Unified Register of Notaries -- search by name, region, status
search_court_experts Register of Certified Court Experts -- search by name, region, expertise type
search_arbitration_managers Register of Arbitration Managers (bankruptcy) -- search by name, certificate status
search_special_forms Register of Special Notarial Document Forms -- search by series, number, recipient
search_forensic_methods Register of Forensic Examination Methods -- search by name, expertise type
search_legal_acts Unified State Register of Normative Legal Acts (EDRNPA) -- search by title, type, publisher
search_administrative_units Administrative-Territorial Dictionary (KOATUU) -- search by settlement, region
search_streets Streets Directory -- search by street name, settlement, region, type

Enforcement and Debtors

Tool Description
search_debtors Unified Register of Debtors -- search by name, EDRPOU, collection category
search_enforcement_proceedings Automated Enforcement Proceedings System -- search by debtor, creditor, status
search_bankruptcy_cases Register of Bankruptcy Cases -- search by debtor, case number, status
search_termination_started Entities with termination in progress -- search by record, signer, reason

Tax Registries (DPS)

Tool Description
search_vat_payers VAT Payers Registry -- search by name or VAT code
search_single_tax_payers Single Tax Payers Registry -- search by name, TIN, tax group
search_tax_debt Tax Debt Registry -- search by name or TIN; shows debt, penalties, fines
search_esv_debt ESV (Social Contribution) Debt Registry -- search by name or TIN

Due Diligence and Anti-Corruption

Tool Description
search_nazk_declarations NAZK Anti-Corruption Declarations (322K records) -- search by declarant, workplace, year, income
search_arma_seized_assets ARMA Registry of Seized Assets in criminal proceedings -- search by owner, case, asset type
search_prozorro Prozorro Public Procurement Tenders (662K records) -- search by title, buyer EDRPOU, CPV code
search_rnbo_sanctions RNBO Sanctions Lists (21K records) -- search by name, aliases, country, identifier

Geographic / OSM

Tool Description
search_street_renamings Street Renaming History from OpenStreetMap (64K streets) -- search by current or old name
search_exchange_data Government agency data exchanges (23.2M records) -- search by entity record, type

Database Schema

14 migrations define the schema. Key tables:

Core EDR Tables

  • legal_entities -- UO (legal entities): record, edrpou, name, opf, stan, authorized_capital, etc.
  • individual_entrepreneurs -- FOP: record, name, stan, farmer flag
  • public_associations -- FSU: record, edrpou, name, type_subject, type_branch

Related Entity Data

  • founders -- company founders (linked via entity_type + entity_record)
  • beneficiaries -- beneficial owners
  • signers -- authorized signatories / directors
  • members -- members of governing bodies (UO only)
  • branches -- subsidiaries and representative offices
  • predecessors / assignees -- legal succession chain
  • executive_power -- executive branch entity link
  • termination_started -- entities in termination process
  • bankruptcy_info -- bankruptcy/readjustment details
  • exchange_data -- government agency data exchanges (23M+ records)

NAIS Registries

  • notaries -- 7K+ records, unique on certificate_number
  • court_experts -- unique on expert_id
  • arbitration_managers -- unique on registration_number
  • special_forms -- unique on (series, form_number)
  • forensic_methods -- unique on registration_code
  • bankruptcy_cases -- unique on registration_number
  • legal_acts -- EDRNPA acts, unique on act_id
  • administrative_units -- KOATUU, unique on md5 hash of composite key
  • streets -- unique on (settlement_koatuu, street_name, street_type)
  • enforcement_proceedings -- unique on proceeding_number
  • debtors -- unique on (proceeding_number, debtor_name, debtor_edrpou)

Additional Registries

  • rnbo_sanctions -- RNBO sanctions list (21K), unique on entity_id
  • prozorro_tenders -- ProZorro procurement (662K), unique on tender_id
  • vat_payers -- VAT registry, unique on vat_code
  • single_tax_payers -- single tax, unique on tin
  • tax_debt -- tax debt records
  • esv_debt -- ESV debt records
  • arma_assets -- ARMA seized assets, unique on content_hash
  • nazk_declarations -- NAZK declarations (322K), unique on declaration_id
  • street_renamings -- OSM street renamings (64K), unique on osm_id

System Tables

  • cost_tracking -- per-request API cost tracking
  • registry_metadata -- last sync dates per registry
  • import_log -- import history (status, records imported/failed, timestamps)

Data Import and Sync

Registry Configuration

All 12 NAIS registries are defined in src/config/registries.ts with:

  • Download URL, ZIP/inner file names
  • Format (xml or csv), encoding (windows-1251 or utf-8)
  • Table name, unique key, record path
  • Field mapping (XML/CSV field to DB column, with optional transform functions)
  • Update frequency (daily or weekly)
  • Size category: small, medium, large, huge (determines parser strategy)

Import Scripts

Command Script Description
npm run sync:registries sync-all-registries.ts Sync all 12 NAIS registries (download + import)
npm run sync:registry --only=X sync-all-registries.ts Sync specific registry(ies)
npm run sync:weekly sync-all-registries.ts Only registries due for weekly update
npm run sync:edrpou sync-edrpou.ts Sync EDRPOU (legal entities) from NAIS XML
npm run import:entities import-legal-entities.ts Import legal entities from local XML
npm run import:debtors import-debtors.ts Import debtors from local CSV
npm run import:nais download-nais-registries.ts Download all NAIS ZIP files
npm run import:street-renamings import-street-renamings.ts Import OSM street renaming data

Additional import scripts (not exposed as npm scripts but available):

  • import-fop.ts / import-fop-parallel.ts -- FOP import (single/parallel)
  • import-uo.ts / import-uo-parallel.ts -- UO import (single/parallel)
  • import-fsu.ts -- FSU (public associations) import
  • import-arma.ts -- ARMA seized assets import
  • import-nazk-declarations.ts -- NAZK declarations import
  • import-prozorro.ts -- Prozorro tenders import
  • import-from-xml.ts -- Generic XML import helper
  • import-all.ts / import-all-streaming.ts -- Bulk import (all entity types)

Sync CLI Options

# Sync all registries
node dist/scripts/sync-all-registries.js

# Sync specific registries
node dist/scripts/sync-all-registries.js --only=notaries,debtors

# Only registries due for weekly update
node dist/scripts/sync-all-registries.js --weekly

# Dry run (show what would sync)
node dist/scripts/sync-all-registries.js --dry-run

# Keep downloaded files after import
node dist/scripts/sync-all-registries.js --keep-files

Import Strategy by Size

Size Category Parser Strategy Examples
small fast-xml-parser (DOM) Upsert with ON CONFLICT notaries, court_experts, forensic_methods
medium fast-xml-parser (DOM) Upsert with ON CONFLICT bankruptcy_cases, legal_acts
large SAX streaming Pipelined multi-row INSERTs special_forms, administrative_units, streets
huge CSV readline + parallel workers TRUNCATE + bulk INSERT (no ON CONFLICT), drop/recreate indexes enforcement_proceedings (~30M), debtors (~10M)

HTTP API Endpoints

Health and Monitoring

Endpoint Auth Description
GET /health No Full health check with dependency status, uptime, memory
GET /health/live No Liveness probe (always 200)
GET /health/ready No Readiness probe (checks DB connectivity + latency)
GET /metrics No Prometheus metrics (internal network)
GET /api/stats No Detailed registry statistics: row counts, sources, update times

Tool Execution

Endpoint Auth Description
GET /api/tools Bearer List all available tools with schemas
POST /api/tools/:toolName Bearer Execute a tool (JSON response or SSE if Accept header set)
POST /api/tools/:toolName/stream Bearer Execute with SSE streaming

Admin

Endpoint Auth Description
POST /api/admin/sync-registry Bearer Trigger sync for a specific registry (async, returns 202)

Configuration

Environment Variables

Variable Default Description
DATABASE_URL -- Full PostgreSQL connection string
POSTGRES_HOST localhost PostgreSQL host
POSTGRES_PORT 5435 PostgreSQL port (host-mapped, container uses 5432)
POSTGRES_USER openreyestr PostgreSQL user
POSTGRES_PASSWORD -- PostgreSQL password
POSTGRES_DB openreyestr Database name
HTTP_PORT 3004 HTTP server port (3005 in prod)
HTTP_HOST 0.0.0.0 HTTP bind address
SECONDARY_LAYER_KEYS -- API keys for Bearer auth (comma-separated)
OPENREYESTR_API_KEYS -- Alias for API keys
JWT_SECRET -- JWT signing secret
ALLOWED_ORIGINS legal.org.ua,stage.legal.org.ua CORS allowed origins
NAIS_DATA_DIR /tmp/nais-sync Directory for downloaded registry files
CSV_IMPORT_WORKERS 10 Parallel DB workers for CSV imports
OPENAI_API_KEY -- OpenAI key (for AI-powered features)
LOG_LEVEL debug Winston log level

Docker Deployment

Built with deployment/Dockerfile.mono-openreyestr. Services in docker-compose:

  • postgres-openreyestr-{env} -- PostgreSQL database
  • migrate-openreyestr-{env} -- Runs migrations on startup
  • app-openreyestr-{env} -- HTTP server (the main service)

Development

cd mcp_openreyestr

# Install dependencies
npm install

# Setup database (create + migrate)
npm run db:setup

# Run in development (HTTP mode)
npm run dev:http

# Run in MCP stdio mode
npm run dev

# Build
npm run build

# Run tests
npm test

# Lint
npm run lint

# Production start
npm run build && npm run start:http

Services Architecture

Service File Responsibility
OpenReyestrTools api/openreyestr-tools.ts Query execution layer (all 27 search methods)
MCPOpenReyestrAPI api/mcp-openreyestr-api.ts MCP tool definitions, routing, response formatting
Database database/database.ts PostgreSQL pool management
CostTracker services/cost-tracker.ts Per-request cost estimation and tracking
MetricsService services/metrics-service.ts Prometheus metrics (HTTP duration, PG pool)
GenericXmlImporter services/generic-xml-importer.ts Config-driven XML parser (DOM + SAX streaming)
CsvImporter services/csv-importer.ts Parallel CSV import with readline + workers
StreamingXmlParser services/streaming-xml-parser.ts SAX-based streaming for large XML files
DownloadService services/download-service.ts HTTP download with redirects and retries
EntityValidator services/entity-validator.ts Entity data validation
ImportProgress services/import-progress.ts Import progress tracking and logging

Data Sources

Registry Source Format Update Frequency Approximate Size
Legal Entities (UO) NAIS EDR XML (win-1251) Daily ~2M records
Entrepreneurs (FOP) NAIS EDR XML (win-1251) Daily ~3M records
Public Associations (FSU) NAIS EDR XML (win-1251) Daily ~300K records
Notaries NAIS XML (win-1251) Weekly ~7K records
Court Experts NAIS XML (win-1251) Weekly ~15K records
Arbitration Managers NAIS XML (win-1251) Daily ~2K records
Special Forms NAIS XML (win-1251) Weekly Large
Forensic Methods NAIS XML (win-1251) Weekly ~1K records
Bankruptcy Cases NAIS XML (win-1251) Daily Medium
Legal Acts (EDRNPA) NAIS XML (utf-8) Weekly Medium
Administrative Units NAIS XML (win-1251) Weekly Large
Streets NAIS XML (win-1251) Weekly Large
Enforcement Proceedings NAIS CSV (win-1251) Daily ~30M records
Debtors NAIS CSV (win-1251) Daily ~10M records
RNBO Sanctions OpenSanctions (ua_nsdc) JSON/API Periodic ~21K records
Prozorro Tenders ProZorro API JSON/API Periodic ~662K records
VAT Payers DPS (data.gov.ua) CSV Snapshot (23.02.2022) Large
Single Tax Payers DPS (data.gov.ua) CSV Snapshot Large
Tax Debt DPS (data.gov.ua) CSV Periodic Large
ESV Debt DPS (data.gov.ua) CSV Periodic Medium
NAZK Declarations NAZK API JSON/API Periodic ~322K records
ARMA Seized Assets ARMA open data JSON/API Periodic Medium
Street Renamings OpenStreetMap (Overpass) JSON Periodic ~64K records

Integration with Unified Gateway

When ENABLE_UNIFIED_GATEWAY=true is set on mcp_backend, the OpenReyestr tools are available through the unified endpoint at https://legal.org.ua/api/tools/openreyestr_<tool_name>. The gateway proxies requests to the OpenReyestr service internally.

Cost Tracking

Every tool call is tracked with:

  • Request ID, tool name, client key
  • Pre-execution cost estimate
  • Post-execution actual cost and duration
  • Status (completed/failed) with error messages

Data stored in cost_tracking table for billing and monitoring.

Clone this wiki locally