Kodu, maa ja keskkond
Kultuurimälestiste register
Kas hoone või objekt on mälestis, mis on selle kaitsekord ja registrinumber.
Kultuurimälestiste register (register.muinas.ee) ütleb, kas hoone, objekt või ala on mälestis, ja mis on selle registrinumber, liik, seisund ja kaitsevöönd. Mälestise kirje juures on kaitse alla võtmise õigusaktid koos Riigi Teataja linkidega, kirjeldused ja ajalugu ning sageli ka sama hoone ehitisregistri kood. Mälestiseks olemine on omanikule piirang, mitte toetus: töö mälestisel või selle kaitsevööndis vajab Muinsuskaitseameti luba.
Mida su agent peab oskama
KOODVajab käivitatavat koodi. Vähemalt üks samm nõuab koodi käivitamist: seansiküpsis, turvamärgise vahetus, PDF-i või ZIP-i lahtipakkimine, või vastus, mis on mudeli konteksti jaoks liiga suur.
Juhend ise
Inglise keeles, sest seda loeb mudel.
Cultural Heritage Register
Vetted module (use this first)
muinas.mjs ships in https://kodanikukratt.ee/kratt-agent.tar.gz (plain ESM, Node 22+) and is re-verified against the live source:
import { show } from "./kratt.mjs";
import { monuments, monumentDetails } from "./muinas.mjs";
const hits = await monuments({ address: "Kalamaja" });
show({ leitud: hits.totals.found, esimesed: hits.rows.slice(0, 5), note: hits.note });
const m = await monumentDetails(hits.rows[0].regnr);
show({ nimi: m.name, liik: m.kind, arvel: m.listedOn, seisund: m.condition, vöönd: m.protectionZone });
show(m.legalActs); // the orders that listed it, each with its riigiteataja.ee URL
show(m.descriptions, 3000); // Mälestise tunnus / Kirjeldus / Ajalugu / Kaitsevööndi ulatus
monuments({regnr, name, address, text})searches the register and reportstotals.found, the register's own "Kokku" line — state that, not a row tally. A search matching nothing answers HTTP 200 with the search form and no counter at all, so the module reportsfound: 0explicitly rather than leaving a run to read an empty page as an error.textis notaddress.textsearches the free-text descriptions too: "Kalamaja" that way returns 49 monuments, the first being a power station in Saue vald whose press-clipping field mentions the word (live, 2026-08-01).addressreturns 6. Useaddressfor "what is protected here" and treat atexthit as a mention.- Every row carries its own
page— the monument's public record. Link that, never a bareregister.muinas.eeaddress. monumentDetails(regnr)returns the labelled fields pluslegalActs(with the riigiteataja.ee URL the register itself links — do not reconstruct one from an "RT III, …" reference),descriptions,keywords,protectionZoneandehrBuilding, the construction-register code for the same building.- Listing is a restriction on the owner, not a subsidy. Work on a monument or inside its protection zone needs Muinsuskaitseamet's permission.
protectionZoneis filled only when the listing order set a bespoke extent; when it is null, name Muinsuskaitseamet as the body to ask rather than assuming a distance. - Coordinates are EPSG:3301 (L-EST97), not WGS84.
The endpoints below are the fallback if a module call throws.
Access
- Search and detail base:
https://register.muinas.ee/public.php?menuID=monument - The public server-rendered search needs no authentication and no browser automation, but it does need a cookie jar — the search POST and every page after the first are tied together by a session cookie (see Limits).
Search
POST form data to the base URL. Prefer the precise fields when known:
regnr: cultural-monument registry number.name: monument name.address: address text.county[],parish[],type[], andcm_type[]: multi-value identifiers taken from the live form options.
For a broad text search, POST nameanddescription=<at least 3 characters> and quickseatch=true; the misspelled field name is the site's actual contract.
The result is HTML. Parse the table headed Reg. nr, Nimi, Tüüp, Liik, Omavalitsus, and Aadress. Each row links to:
public.php?menuID=monument&action=view&id={regnr}
Detail
Fetch the absolute detail URL and parse labeled fields. Return the registry number, name, monument type and class, registration/protection dates, coordinates, condition, legal instruments, keywords, descriptions, address when present, and links to available detail, property, proceeding, grant, image, and document tabs.
Limits
- The search is SESSION-scoped, so this recipe needs a runtime and not just a request. The POST stores its result set against the
_Host-PHPSESSIDcookie it sets, and the rows past the first twenty are fetched as&action=list&showall=<n>carrying no query of its own — that cookie is the only thing tying the later page to your search. Drop it and an empty or somebody else's result set comes back as HTTP 200, which reads exactly like a search that had nothing more to give. So what we can offer an agent that cannot carry a cookie between requests is page one, not the search: call it the first twenty rows rather than the answer. - The search is a form POST, and the same fields in the query string are silently ignored — the register answers HTTP 200 with its whole contents:
GET …&menuID=monument&address=Kalamajacame backKokku: 25127, against the 6 rows the same field matches as a POST (measured 2026-08-02). Nothing on the page says a filter was dropped, so the obvious URL does not fail here, it succeeds with the wrong rows. Search with the POST and statetotals.found. A monument's own record IS a plain GET and stays reachable.
claim the register answers HTTP 200 with its whole contents
# Not a refusal, which is what makes this worth checking: the GET succeeds and
# only the count says the filter was dropped. Five digits is the tell — the
# unfiltered register answered Kokku: 25127 on 2026-08-02, where the same field
# as a POST answers 6.
GET https://register.muinas.ee/public.php?menuID=monument&address=Kalamaja
expect-status 200
expect /Kokku:\s*\d{5}/
# The control is that POST. It must fail the digit bound — that is what
# separates "the query string is ignored" from "the register has stopped
# filtering at all", which would confirm this claim while meaning the opposite.
control POST https://register.muinas.ee/public.php?menuID=monument
body address=Kalamaja
- Search and records are HTML, not JSON; decode HTML entities before extracting text.
- Multi-select filter values are internal IDs. Read them from the current search form instead of guessing from labels.
- A detail page can expose different tabs and fields by monument type.
Verify
Require the requested registry number in both the result row and detail heading, plus the detail labels Mälestise nimi and Mälestise registri number.
Module API
monuments({regnr, name, address, text}) -> {source, page, filter, ran, totals, rows, note} monumentDetails(regnr) -> {source, page, regnr, name, type, kind, listedOn, condition, coordinates, legalActs, protectionZone, keywords, descriptions, ehrBuilding, fields, note}