gios-air-mcp
Click on "Install 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., "@gios-air-mcpHow's the air in Kraków right now?"
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.
gios-air-mcp
Local MCP server for the GIOŚ (Główny Inspektorat Ochrony Środowiska) air-quality public API — the official Polish state environmental monitoring feed for PM2.5, PM10, NO2, SO2, O3, CO, C6H6, and the composite air-quality index.
Part of the honest-mcp family of small, auditable, local-first MCP servers.
Why
If you live in a Polish city — especially over winter — the difference between "moderate" and "very poor" air-quality index matters (indoor training vs opening the window). GIOŚ has ~200 stations and a public API but only in Polish JSON-LD. This server translates it to English keys and hands it to your AI so you can ask "how's the air in Kraków this afternoon?"
Related MCP server: airly
Features
Four tools:
list_stations— search the ~200-station network by city or voivodeshipget_station_sensors— list the sensors installed at a stationget_sensor_readings— recent measurements (~24h) from one sensorget_air_index— composite index for a station (very good / good / moderate / poor / very poor / hazardous) with the critical pollutant identified
Data source
Endpoint: api.gios.gov.pl/pjp-api/v1 — GIOŚ public JSON-LD API
No API key
Refresh: hourly per sensor
Requirements
Python 3.10+
Setup
git clone https://github.com/bartosz-kuc/gios-air-mcp.git
cd gios-air-mcp
python3 -m venv venv
./venv/bin/pip install -r requirements.txtRegister with Claude Code:
claude mcp add gios-air /absolute/path/to/venv/bin/python /absolute/path/to/server.pyClaude Desktop claude_desktop_config.json:
{
"mcpServers": {
"gios-air": {
"command": "/absolute/path/to/venv/bin/python",
"args": ["/absolute/path/to/server.py"]
}
}
}Example usage
"How's the air in Kraków right now?"
Two-step: list_stations(city="Kraków", limit=5) → pick a station ID → get_air_index(station_id=...) → text category and the critical pollutant.
"PM2.5 readings for the last 24h from station 400."
get_station_sensors(station_id=400) → find the PM2.5 sensor ID → get_sensor_readings(sensor_id=...).
Data flow
Your AI client
↕ MCP stdio
This server (Python, on your machine)
↕ HTTPS
api.gios.gov.pl (GIOŚ)No cloud middle. No telemetry.
Author
Bartosz Kuć — Warsaw-based developer, JDG owner running skanfirmy.pl.
GitHub: https://github.com/bartosz-kuc
Email: firma@bartosza.pl
Consulting
Available for consulting on Polish tax and business integrations (KSeF, GUS/NFZ/GIOŚ APIs, mBank data), MCP server design, and AI-assisted tooling for JDGs and small teams. See skanfirmy.pl/uslugi for productized packages (audit 3k PLN, setup 8-15k PLN, retainer 2-4k PLN/mo), or reach out via email.
License
MIT — see LICENSE.
Related
Part of the honest-mcp family — see the family index.
Available Tools
4 toolsget_air_indexB
Get the composite air-quality index for a station (aggregates all pollutants into a single category: very good / good / moderate / poor / very poor / hazardous).
| Name | Required | Description | Default |
|---|---|---|---|
| station_id | Yes | Numeric station ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly explains the aggregation behavior and lists the categories, but it does not mention whether the call is read-only, if it requires authentication, how the index is computed (e.g., current vs. cached), or what the response structure contains beyond the category. The description implicitly suggests a read operation via 'get,' but lacks explicit 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, tightly written sentence that front-loads the core purpose ('Get the composite air-quality index') and immediately specifies the aggregation and category levels. There is no extraneous information, making it efficient and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one parameter and no output schema, the description explains what the tool produces (a category) but stops short of describing the exact response format—whether it returns just the category label, a numeric value, or both. It also omits any caveats like error conditions or station validity. Given the low complexity, this is a minor gap, so a 3 is appropriate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description covers the only parameter (station_id) at 100% with 'Numeric station ID.' The tool description adds no additional meaning about the parameter—it does not explain how station_id is used or validated. Per the calibration rule, when schema coverage is high, the baseline is 3, and the description does not elevate it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description specifies a precise verb ('get') and resource ('composite air-quality index for a station'), and clearly distinguishes itself from siblings like get_sensor_readings by focusing on the aggregated index rather than raw data. The phrase 'aggregates all pollutants into a single category' makes the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit guidance on when to use this tool versus alternatives. With sibling tools like get_sensor_readings, it would be helpful to state 'Use this for the overall index; use get_sensor_readings for individual pollutant values.' No such direction is provided, leaving the agent to infer from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_sensor_readingsA
Get recent measurement readings from a sensor. Each reading is a (measured_at, value) pair. Returns latest ~24 hours.
| Name | Required | Description | Default |
|---|---|---|---|
| sensor_id | Yes | Numeric sensor ID from get_station_sensors |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the time window ('latest ~24 hours') and data format, but does not mention ordering, units, error behavior, or rate limits. This is more than a tautology but still sparse.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with the key purpose first, then format and time range. No filler or redundant phrasing. Every word adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and no output schema, the description conveys the core behavior (what it returns and the time scope). It does not cover details like sorting order or pagination, but these may be implicit in a simple read operation. Minor gaps remain, but it is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes sensor_id well with 100% coverage, including its source ('from get_station_sensors'). The description adds no extra parameter-specific semantics beyond what the schema provides, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb ('Get'), a specific resource ('recent measurement readings from a sensor'), and the data format ('(measured_at, value) pair'). It distinguishes from siblings like get_air_index (which implies an index, not raw readings) and get_station_sensors (which likely lists sensors, not readings).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions that sensor_id comes from get_station_sensors, implying a prerequisite call, but does not explicitly state when to use this tool versus alternatives (e.g., get_air_index). No exclusions or conditions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_station_sensorsA
List the sensors installed at a station (each sensor measures one pollutant/indicator such as PM10, PM2.5, NO2, SO2, O3, C6H6).
| Name | Required | Description | Default |
|---|---|---|---|
| station_id | Yes | Numeric station ID from list_stations |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of disclosing behavioral traits. It clearly implies a read-only operation (listing) and adds useful context about sensor characteristics (each measures a pollutant/indicator). However, it does not disclose any other behaviors such as response format, potential empty results, or pagination. For a simple list tool, this is minimally adequate but leaves room for more specificity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that is front-loaded with the primary action ('List the sensors installed at a station'). It is efficient, avoids redundant phrasing, and includes relevant examples without unnecessary elaboration. Every word contributes to clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (one parameter, no output schema, no nested objects), the description is sufficient for an agent to call it correctly. It states the purpose and the parameter is documented in the schema. While it does not describe the return structure, that is not critical for a list operation of this type, and the absence of an output schema reduces the expectation for such detail.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage for the single parameter (station_id), and its description already clarifies that it is a numeric ID from list_stations. The tool description adds no additional meaning beyond what the schema provides. As per guidelines, when schema description coverage is high (>80%), the baseline is 3 even if the description adds no parameter-specific details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and clearly specifies the resource ('sensors installed at a station'). It also adds context by naming example pollutants/indicators, which makes the tool's function unmistakable even without reference to sibling tools. This differentiates it from get_sensor_readings and get_air_index, which focus on readings and indices rather than the inventory of sensors.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus its siblings (list_stations, get_sensor_readings, get_air_index). There is no mention of alternatives or conditions. The only indirect hint is the parameter description in the schema referencing 'list_stations', but that is not part of the tool description itself. An agent must infer the usage context from the name and description alone, which is not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_stationsA
List GIOŚ air-quality monitoring stations. Optional filters: city, voivodeship — both case-insensitive substring match. The full network is ~200 stations; use filters or limit to keep responses small.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | Filter by city (substring) | |
| limit | No | Max results (default 25) | |
| voivodeship | No | Filter by voivodeship (substring) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It adds genuinely useful behavior (case-insensitive substring matching for both filters, and the overall network scale). However, it does not disclose the return format (fields per station) or any pagination behavior, which matters since there is no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler, with the core action and resource front-loaded. The filter and scale information is packed efficiently into the second sentence, and every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter, all-optional list tool with no output schema, the description covers the essentials: what is listed, filter behavior, scale, and the limit default. The return format is the only notable gap since no output schema exists, but for a straightforward listing operation the description is otherwise sufficiently complete for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — all three parameters (city, limit, voivodeship) are documented in the schema, so the baseline is 3. The description adds the case-insensitive substring nuance beyond the schema's bare 'Filter by city (substring)', which is a small but real semantic contribution, though not substantial enough to exceed the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (List), a distinct resource (GIOŚ air-quality monitoring stations), and the optional filters. The resource clearly differentiates it from sibling tools (get_station_sensors, get_sensor_readings, get_air_index) which target sensors, readings, and indices rather than the station list itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives useful operational context — the network is ~200 stations, so use filters or `limit` to keep responses small — which signals when to constrain the query. However, it never addresses when to choose this tool versus its siblings (e.g., 'use get_station_sensors for a station's sensors'), offering no exclusions or alternative routing.
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. Dates show when Glama detected each change.
4 tool updates
v0.1.0- First observed
get_air_index - First observed
get_sensor_readings - First observed
get_station_sensors - First observed
list_stations
TDQS
Each tool targets a distinct resource and action: stations, sensors, readings, and air index. There is no overlap, and an agent can easily determine which tool to call for a given query.
All tool names follow a consistent verb_noun pattern (list_stations, get_station_sensors, get_sensor_readings, get_air_index). The naming is uniform, predictable, and uses clear, specific verbs.
With exactly 4 tools, the server is tightly scoped to air quality monitoring without redundancy. Each tool covers a necessary step in the workflow, making the count ideal for the domain.
The tool surface covers the full core workflow: discover stations, inspect sensors, fetch readings, and get an aggregated index. Minor gaps include lack of historical readings beyond 24 hours and no station metadata endpoint, but these are acceptable for a minimal yet functional set.
Maintenance
Related MCP Connectors
Access UK air quality data, monitoring sites, and hourly pollutant measurements across regions
Find air-quality stations and read pollutant observations from government monitors via OpenAQ v3.
Air Quality MCP — wraps air-quality-api.open-meteo.com (free, no auth)
OpenAQ MCP — wraps OpenAQ v2 API (free, no auth required)
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides access to EPA's Air Quality System API with 31 tools for querying air quality data, monitoring sites, and pollution measurements across the United States through natural language.31MIT
- AlicenseNot gradedqualityBmaintenanceEnables natural language interaction with air quality data from Airly, including real-time measurements, nearby stations, and forecasts.21MIT
- AlicenseNot gradedqualityCmaintenanceProvides real-time Air Quality Index data from the World Air Quality Index service, enabling queries by location, station, or keyword search.6MIT
- AlicenseNot gradedqualityCmaintenanceEnables querying real-time air quality measurements, integrated air quality index (CAI), and monitoring station information from Korea's Air Korea OpenAPI, including station search and nearby station lookup.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/bartosz-kuc/gios-air-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server