Skip to main content
Glama
DV155

statistik-austria-mcp

About The Project

A Model Context Protocol server for the free Open Government Data portal of Statistik Austria (data.statistik.gv.at). It lets an AI assistant such as Claude search the catalog, read a dataset's structure and fetch its data directly, instead of you downloading and pasting CSV files.

The portal publishes each dataset as a set of files with coded values, so a raw table is hard for a model to read correctly. The server joins the classification files onto the data, so every value arrives as a readable German label together with its original code, and marks the rows that are totals of other rows.

Built as a personal learning project to practise building MCP servers.

Features:

  • Keyword search over the full OGD catalog (around 540 datasets)

  • Dataset metadata: dimensions and measures

  • Data with codes resolved to German labels, formatted label <code>

  • Total rows are flagged, so the assistant doesn't add a total to its own parts

  • Filters by dimension value, so large tables don't have to be read in full

  • Paging that never drops rows silently: every response says how many rows exist and where to continue

  • Clear messages for datasets in formats the server can't read, instead of a bare error

  • Downloads are cached for an hour, so paging through a dataset doesn't download it again

Built With

Related MCP server: mcp-podatki-si

Getting Started

The server runs locally on your computer and talks to your MCP client over stdio. uvx installs and starts it, so there is nothing to clone for normal use.

Prerequisites

  • uv (it downloads a matching Python version automatically)

  • Git

  • Claude Desktop or Claude Code (or any other MCP client)

Installation

Claude Desktop

  1. Open the config file. In Claude Desktop, go to Settings → Developer → Edit Config, or open it directly:

    • Windows: %APPDATA%\Claude\claude_desktop_config.json

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  2. Add the server

    {
      "mcpServers": {
        "statistik-austria": {
          "command": "uvx",
          "args": ["--from", "git+https://github.com/DV155/Statistik-Austria-MCP-Server", "statistik-austria-mcp"]
        }
      }
    }
  3. Quit Claude Desktop completely and start it again.

Claude Code

claude mcp add --transport stdio --scope user statistik-austria -- uvx --from git+https://github.com/DV155/Statistik-Austria-MCP-Server statistik-austria-mcp

The first start takes a while, because uv installs the dependencies (pandas is the largest). To get that out of the way, run the uvx command above once in a terminal and stop it with Ctrl+C once it is running. If Claude can't find uvx, replace "uvx" with its full path (which uvx shows it). Claude Desktop writes the server's logs to %APPDATA%\Claude\logs on Windows and ~/Library/Logs/Claude on macOS.

Local development

  1. Clone the repo

    git clone https://github.com/DV155/Statistik-Austria-MCP-Server.git
    cd Statistik-Austria-MCP-Server
  2. Install the dependencies

    uv sync
  3. Start the server in the MCP Inspector

    uv run mcp dev src/statserver/server.py

Usage

Ask Claude a question about Austrian statistics, and it uses the tools on its own.

Tool

What it does

search_dataset

Searches the catalog by keyword and returns matching dataset IDs and titles

fetch_dataset_json

Returns a dataset's dimensions and measures with their codes

fetch_dataset_csv

Returns the data with labels, total-row flags and paging; filters keeps only the rows for given dimension values

The server also provides an ogd://catalog resource with the catalog's categories.

Tip: the catalog's titles are German, so the server searches in German. Claude translates the question itself, but asking in German works just as well.

Limitations

Tested against all 543 datasets in the catalog in October 2026:

  • 474 load fully

  • 66 are published in formats the server can't read (zip archives and map services such as WFS and WMS); the server says so instead of failing

  • 2 contain no data rows

  • 1 (OGDEXT_BINNENWAND_1) loads without labels and slowly

Other limitations:

  • Only the free OGD portal is supported, not the paid STATcube API

  • The catalog is read from the portal's HTML page, so search stops working if Statistik Austria changes that page's structure

  • The first request for a very large dataset can take several seconds while it downloads

Data Source

All data comes from Statistik Austria - data.statistik.gv.at, licensed under CC BY 4.0. When you publish results obtained through this server, credit Statistik Austria as the source.

This is an independent project and is not affiliated with or endorsed by Statistik Austria.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

  1. Fork the Project

  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)

  3. Commit your Changes (git commit -m 'Add some AmazingFeature')

  4. Push to the Branch (git push origin feature/AmazingFeature)

  5. Open a Pull Request

Top contributors:

License

Distributed under the MIT license. See LICENSE for more information.

Contact

Daniil Vasilcovschii - LinkedIn - GitHub

Project Link: https://github.com/DV155/Statistik-Austria-MCP-Server

Available Tools

3 tools
fetch_dataset_csvA

Fetch an OGD dataset's data with codes resolved to German labels, formatted "label ". dataset_id is the Statistik Austria dataset identifier (e.g. "OGD_vpi86_VPI_1986_1"). "aggregate" names the dimensions in which a row is a total of other rows; never sum it with them. Empty "aggregate" does not guarantee rows can be summed (overlapping groupings exist, e.g. VPI). Dimensions in "unlabeled_dimensions" have raw codes and no aggregate information. filters: {dimension code: [value codes]} keeps matching rows, e.g. {"C-A10-0": ["A10-2024"]}; values are the parts. Pages: at most limit rows (max 5000, fewer if rows are large); if "truncated", continue at offset + returned with the same filters.

NameRequiredDescriptionDefault
limitNo
offsetNo
filtersNo
dataset_idYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses pagination behavior and the "truncated" flag, the 5000-row cap with rows possibly being large, the aggregate-total pitfall, and that empty aggregate does not guarantee summable rows. It omits any mention of error behavior for invalid dataset_ids or permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded, then detail escalates from identifier to aggregate semantics to filters to paging — a sensible order. The paging sentence ("continue at offset + returned") is slightly compressed and takes a reread, but no line is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter tool with no annotations and no output schema, the description covers the response shape (label-and-code formatting, aggregate and unlabeled_dimensions columns, truncation) well enough to call it correctly. What it lacks is any statement of failure modes or how to discover valid dataset_ids and dimension codes beforehand.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate and it does: dataset_id is explained with a concrete example, filters get exact syntax and a worked example with the caveat that values are the <code> parts, and limit/offset are given defaults semantics, a max, and a continuation rule.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Fetch an OGD dataset's data") plus a distinguishing output trait (codes resolved to German labels, formatted "label <code>"). It never mentions the sibling fetch_dataset_json, so the agent must infer the CSV-vs-JSON distinction from the tool names alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Operational guidance is strong — how to filter, how to page with offset/limit, and the caveat about summing aggregate rows — but there is no explicit statement of when to choose this tool over fetch_dataset_json or search_dataset. Usage is implied by the output format rather than stated as a selection rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_dataset_jsonA

Return the dimension and measure metadata for an OGD dataset. dataset_id is the Statistik Austria dataset identifier (e.g. "OGD_vpi86_VPI_1986_1").

NameRequiredDescriptionDefault
dataset_idYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the full burden. It does usefully disclose that the response is metadata (dimensions and measures), not the underlying observations, which prevents a caller from expecting data rows. However, it says nothing about failure behavior for invalid dataset_ids, response size, or any access constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, both load-bearing, with the return content stated first and the parameter clarification second. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with no output schema, the description covers what is returned only at a high level ('dimension and measure metadata') and does not indicate the shape of that metadata. Adequate to call correctly, but thin on what to expect back.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% — the schema only says 'Dataset Id' with no description — so the description must compensate. It does: it identifies the identifier as a Statistik Austria dataset id and gives a concrete format example ('OGD_vpi86_VPI_1986_1'), which is exactly what the schema lacks.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: returns 'dimension and measure metadata for an OGD dataset.' That is materially more precise than the name alone, which only says 'json.' It doesn't explicitly contrast with fetch_dataset_csv or search_dataset, so differentiation from siblings is left to the name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: an agent can infer this is the JSON-format metadata variant, but the description never says when to prefer it over fetch_dataset_csv or search_dataset, and gives no prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_datasetA

Search the OGD catalog by keyword. By default every query word of 3+ characters must appear in a result; word parts match too. An empty query returns recently updated datasets. Titles are in German, so search with German keywords (e.g. "Bevölkerung", not "population"). Pass a result's "id" to fetch_dataset_json or fetch_dataset_csv. Some datasets aren't standard CSV tables; fetch_dataset_csv then explains why it can't load them. Pages: at most limit results (max 50); if "truncated", continue at offset + returned. Setting match_all=False returns datasets containing any query word, best matches first.

NameRequiredDescriptionDefault
limitNo
queryNo
offsetNo
match_allNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, it discloses match semantics (3+ character words, word parts, match_all default/false), empty-query behavior, page truncation, and downstream CSV limitations. This is substantial behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense and front-loaded; every sentence adds search semantics, pagination, language guidance, or sibling-routing context. There is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations or output schema and 0% schema coverage, it covers invocation and continuation well, including result id and truncated. It still omits the full result shape and precise offset defaults.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but the description gives meaning for all four parameters: query matching, limit max 50, offset continuation, and match_all false behavior. It compensates strongly for the absent schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Search the OGD catalog by keyword') and clearly distinguishes the tool from fetch_dataset_json/csv by routing result ids to them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains empty-query behavior, German keyword requirement, pagination continuation, and points to fetch tools for retrieval. It lacks an explicit 'when not to use this' statement, so it is strong but not fully exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev1.1.0
    • Changedsearch_dataset2 fields changed
      • addedInput schema / properties / match_all
        Added value: +{
        +  "default": true,
        +  "title": "Match All",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / offset
        Added value: +{
        +  "default": 0,
        +  "title": "Offset",
        +  "type": "integer"
        +}
  2. 3 tool updatesv1.0.0
    • First observedfetch_dataset_csv
    • First observedfetch_dataset_json
    • First observedsearch_dataset

TDQS

A4.2/5.0

Scored across 3 tools

Disambiguation5/5

The three tools have clearly distinct roles: catalog search, CSV data retrieval, and metadata retrieval. An agent can easily determine whether it needs to search, fetch data, or inspect metadata.

Naming Consistency5/5

All tool names use consistent snake_case and follow a predictable verb_dataset pattern. The suffixes _csv and _json clearly distinguish the two fetch variants.

Tool Count5/5

Three tools are well-scoped for a read-only statistical catalog server: search, fetch data, and fetch metadata. Each tool has a clear purpose and no extraneous operations.

Completeness4/5

The surface covers the core read-only workflow of finding datasets, retrieving their data, and inspecting metadata. However, datasets that are not standard CSV tables appear to be a dead end for actual data access, with only an explanatory error from fetch_dataset_csv.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Enables AI assistants to search, explore, and query any CKAN open data portal through natural language, making public datasets accessible without requiring knowledge of the portal's API.
    20
    1,614 npm
    59
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to search and query datasets from Slovenia Open Data (podatki.gov.si) via its CKAN API, including searching datasets, retrieving metadata, and querying tabular resources.
    8 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables language models to search and query Statistics Netherlands open data, turning natural-language questions into traceable statistics by discovering tables, resolving codes, and retrieving filtered observations.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI assistants to search, preview, and query Ireland's public-sector open data catalogue, including CSV, Excel, JSON, GeoJSON, and JSON-stat resources. It supports filtering, grouping, counting, summing, and sorting datasets conversationally without manual downloads or cleanup.
    MIT