ris-austria-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ris-austria-mcp-serverSearch for the latest VwGH decision on privacy."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Public Hosted Server: https://ris-austria.caseyjhand.com/mcp
Overview
Austrian law from RIS, the government's official legal information system: consolidated federal, state, and municipal law, case law from Austria's courts and tribunals, the authentic gazettes back to 1848, the pre-parliamentary lawmaking pipeline, and ministerial decrees. Covers all 39 applications of the keyless RIS OGD REST API (v2.6, CC BY 4.0) and labels every document with its binding status, since only the authentic (amtssigniert) gazette text is legally binding. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
Tools
Tool | Description |
| Search consolidated federal, state, and municipal law as in force on a date (default today), plus English translations of selected laws |
| Search case law in one court or tribunal per call, across 17 court codes |
| Browse the federal, state, district, and municipal gazettes, with federal history auto-routed back to 1848 |
| Search ministerial review drafts (Begutachtungsentwürfe) and government bills (Regierungsvorlagen) |
| Search seven sectoral collections, from social-insurance notices to ministerial decrees and council-of-ministers minutes |
| Resolve one Austrian legal citation ("§ 6 DSG", "BGBl. I Nr. 165/1999", a Geschäftszahl) to its document |
| Fetch one document as markdown, HTML, or XML, or just its rendition URLs, with its binding status |
| List every document added, changed, or deleted in one application within a date window |
| Look up RIS vocabularies offline: applications, courts, states, ministries, gazette parts, citation formats, search syntax |
Resources
Resource | Description |
| Markdown text of one RIS document |
The resource mirrors ris_get_document, so tool-only clients lose nothing.
Related MCP server: swiss-courts-mcp
Capability reference
ris_search_legislation tool
query(full text) andtitle(title, short title, or abbreviation such as "DSG");scopeisfederal(default) or a Bundesland,municipalityswitches a state scope to municipal law, andlanguage: englishsearches the ~138 English translationsin_force_as_ofdefaults to today in Austria and is echoed asappliedInForceAsOf;include_all_versionsand theentered_force_*/left_force_*windows are mutually exclusive alternativesRecords carry
law_id(filter on it to get every section of a law),section_label, in-force dates,eli,celex_references, andcontent_urls;section_from/section_to,index, andsort_bynarrow further
ris_search_case_law tool
courtis required, one code per call; filter byquery, citednorm("DSG §1"),case_number,decided_from/decided_to,decision_type(headnote,full_text,all), and court-conditional filters such ascourt_name(justiz),state(lvwg/uvs), orcollection_number(vfgh/vwgh/uvs)Records carry
case_numbers,decision_date,ecli,norms_cited, andguiding_principleon headnotes;court: normenlistereturns indexed laws undernorm_indexinstead of decisionsA conditional filter sent to the wrong court fails as
court_filter_mismatchbefore any upstream call
ris_search_gazette tool
scopeisfederal(default), a Bundesland,district, ormunicipal; filter bynumber,part,type,published_from/published_to,issuer,district_authority, ormunicipality. State scopes also takeseries(law_gazette/ordinance_gazette) andstate_era(current/legacy)Federal queries route to one era tier (BgblAuth 2004+, BgblPdf 1945–2003, BgblAlt 1848–1940), echoed as
servedApplication; a date range crossing a tier boundary fails ascross_tier_rangewith the dates to split atRecords carry
binding(authentic,historical_record,consolidated_informational),authentic_pdf_urlwhere one exists, andalex_url(the ÖNB scan) for 1848–1940 entries
ris_search_drafts tool
stageis required:review_drafts(within_review_onfor drafts in review on a date) orgovernment_bills(2004+, withdecided_from/decided_to);ministryaccepts an abbreviation such as "BMF" or a full designationRecords carry
review_deadlineordecided, plusmaterials[]: the Erläuterungen, Textgegenüberstellung, Vorblatt/WFA, covering letter, and annexes, classified bytype. Pass amaterials[].urltoris_get_documentto read one
ris_search_announcements tool
collectionis required:social_insurance,veterinary,court_rules,trade_exam_rules,health_structure_plans,ministerial_decrees, orcouncil_minutes. Each accepts its own filter set, and a filter outside it fails ascollection_filter_mismatch. That includeschanged_sinceonsocial_insuranceandveterinary, where RIS ignores itissuerexpands ministry abbreviations ("BMF") and social-insurance carrier abbreviations ("ÖGK")Records carry
binding(authenticfor five collections,administrative_directivefor decrees,preparatoryfor council minutes),authentic_pdf_url, anddocument_url, the only browsable view of council minutes and decrees
ris_lookup_citation tool
One
citationper call, auto-classified as a norm ("§ 6 DSG", "DSG §1"), gazette number ("BGBl. I Nr. 165/1999", "RGBl. Nr. 189/1902"), case number ("Ro 2026/03/0016"), or collection number ("VfSlg 19.632/2012").kindforces a route,courtandstatehints narrow it, andin_force_as_ofpins a norm's version (default today)Returns
found,kind, and arecordin the matching search tool's shape, withalternatives_countwhen more than one document matched. A miss returnsfound: falsewithguidanceinstead of an error
ris_get_document tool
Address by
document_number+application, or by adocument_urlfromcontent_urlsor a draft'smaterials[].url, onwww.ris.bka.gv.atorogd.ris.bka.gv.at;formatismarkdown(default),html,xml, orurls_onlyEvery result carries
binding_status(seven values, fromauthentictotranslation) andauthentic_pdf_urlwhere one exists. Applications with no text rendition (district and municipal promulgations, court rules, party-transparency decisions, council minutes, 1848–1940 gazettes) return a notice with the usable URL instead of failingMarkdown over 40,000 bytes comes back as
kind: outline, listing §/Artikel/Anlage sections orPart n of Nwindows; re-call withsectionsto fetch entrieshtmlandxmlare never sliced. Over 40,000 bytes they come back askind: linkwith no text, onlybyte_sizeandcontent_urls, which fetches the whole artifact in one request. Nearly every HTML rendition carries a 40–70 KB stylesheet and lands here, so read withmarkdown
ris_track_changes tool
application(any of the 39 codes) pluschanged_from/changed_to;include_deletedadds removals, which no other tool reportsRecords carry
changed,published, andbinding_status; deletion records setdeleted: truewithdeleted_at
ris_list_reference tool
topicselects one of 17 static tables: applications, courts, states, decision types and kinds, issuing bodies, ministries, collections, stages, changed-since intervals, section types, gazette parts, law types, district authorities, justiz subject areas, search syntax, and citation formatsReturns
summaryandentries(value,label,details) with no upstream call; recovery hints across the other tools name the topic to read
ris://document/{application}/{documentNumber} resource
text/markdownof one document, addressed byapplication+documentNumbercopied from a search or lookup result; same content asris_get_documentwithformat: markdownApplications with no text rendition return a note pointing at the PDF or scan. Oversized text returns the outline without a
sectionsselector, so use the tool to fetch an entry
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
RIS-specific:
All 39 OGD applications: consolidated law, the federal, state, district, and municipal gazettes, 17 court and tribunal collections, the lawmaking pipeline, and sectoral announcements
Citations route to deterministic upstream filters (section plus title, gazette number, Geschäftszahl, Sammlungsnummer) rather than keyword search
Strict parameter allowlist: RIS silently ignores unknown parameters, so conditional filters are checked locally and only live-confirmed spellings go upstream
Retries use a 1.5 s base delay for the rate-limited API, and an HTML page in place of JSON counts as a throttle signal
Shared conventions: dates are
YYYY-MM-DD; search tools page withpageandpage_size(10 or 20; default 20); a text filter must be non-blank, so omit it to leave the search unfiltered; court, application, state, and ministry codes come fromris_list_referenceTool descriptions are English, while titles, field values, and in-band RIS error messages stay German; legal terms such as Geschäftszahl and Rechtssatz are glossed in the descriptions
Agent-friendly output:
Discriminated binding status: every record carries a typed label (
authentic,consolidated_informational,historical_record,decision,preparatory,administrative_directive,translation), so callers branch on data, not string parsingProvenance: paged results report
totalCountandtruncatedand echo what the server applied:appliedInForceAsOf, the gazette tier inservedApplication, and thechangedFrom/changedTowindow of a change feedActionable recovery: typed error reasons (
court_filter_mismatch,cross_tier_range,invalid_query,document_not_found, …) and zero-hit notices name the next call, whether aris_list_referencetopic, another search tool, orris_lookup_citation
Getting started
Public Hosted Instance
A public instance is available at https://ris-austria.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"ris-austria-mcp-server": {
"type": "streamable-http",
"url": "https://ris-austria.caseyjhand.com/mcp"
}
}
}Self-Hosted / Local
Add the server to your MCP client configuration with Bun:
{
"mcpServers": {
"ris-austria-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/ris-austria-mcp-server@latest"]
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"ris-austria-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/ris-austria-mcp-server@latest"]
}
}
}Or with Docker:
{
"mcpServers": {
"ris-austria-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/ris-austria-mcp-server:latest"
]
}
}
}Add any configuration variables under an "env" key for bunx/npx, or as additional -e NAME=value arguments for Docker.
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.4.0 or higher (or Node.js v24+).
No API key: the RIS OGD API is keyless.
Installation
Clone the repository:
git clone https://github.com/cyanheads/ris-austria-mcp-server.gitNavigate into the directory:
cd ris-austria-mcp-serverInstall dependencies and build:
bun install
bun run rebuildAdd to your MCP client configuration file:
{
"mcpServers": {
"ris-austria-mcp-server": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/to/ris-austria-mcp-server/dist/index.js"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Configuration
Variable | Description | Default |
| RIS OGD REST API base URL. |
|
| Document content host that rendition URLs are built on. |
|
| Contact string appended to the User-Agent (RIS netiquette asks integrators to be identifiable). | none |
| Transport: |
|
| HTTP server port. |
|
| HTTP session mode: |
|
| Authentication: |
|
| Log level ( |
|
| Enable OpenTelemetry. |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Build and run:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:httpRun checks and tests:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t ris-austria-mcp-server .
docker run --rm -p 3010:3010 ris-austria-mcp-serverThe Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/ris-austria-mcp-server. OpenTelemetry peer dependencies are installed by default; build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Directory | Purpose |
|
|
| Optional RIS endpoint and contact configuration, parsed with Zod. |
| Tool definitions ( |
| Resource definitions ( |
| RIS request building, HTTP access, normalization, and static reference data. |
| Design notes: tool surface, service spec, live-confirmed RIS API reference. |
| Unit and integration tests mirroring |
| Development skills synced from |
Development guide
See CLAUDE.md / AGENTS.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storageRegister new tools and resources via
createApp()insrc/index.tsWrap the RIS API: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
RIS OGD data is CC BY 4.0 (attribution: RIS, Bundeskanzleramt Österreich). The underlying legal texts are copyright-free official works. Only the authentic, amtssignierte gazette wording is legally binding — consolidated RIS text is informational.
This server cannot be deployed
Maintenance
Related MCP Connectors
Search Swiss federal legislation: laws, articles, amendments via the Fedlex SPARQL endpoint.
Public Indian legal search MCP for Roop judgments, statutes, and corpus grounding.
Search German and EU law from official sources with your AI assistant. PRIMAMCP provides citable legal texts via MCP, with daily updates and hosting in Germany.
Search ReliefWeb humanitarian reports, disasters, jobs, training, and country profiles via MCP.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceMCP server that exposes Austrian federal law (Bundesrecht) to LLMs, enabling full-text search, paragraph retrieval, historical versions, statute lookup, BGBl lookups, amendment timelines, and citation searches via the public RIS OGD API.MIT
- AlicenseAqualityAmaintenanceMCP server for searching Swiss court decisions from federal and cantonal courts via entscheidsuche.ch. Enables full-text search, law reference lookup, and filtering by canton, court level, and date without API keys.847 PyPI1MIT
- AlicenseAqualityFmaintenanceEnables querying Swedish statutes, provisions, case law, preparatory works, and EU law cross-references from any MCP-compatible client.1956 npm1Apache 2.0
- AlicenseAqualityAmaintenanceEnables searching and retrieving Austrian federal legislation and case law from the official legal information system RIS, with verifiable ELI and ECLI identifiers.648 PyPIApache 2.0