PH Civic Data
PYPI · PH-CIVIC-DATA-MCP · SCANNED SEP 20
PH civic data as MCP tools: the full PSA OpenSTAT catalog, hazards, procurement. 41 tools.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security50
- Malware scan not yet available for this package.Unverified
- No known CVEs affecting this package version or its production dependencies.Pass
- Runs hatchling.build at install time, a recognised native-build step with no shell scripting around it. View diagnostics → Pass
- 2 of 29 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency45
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
- Clear OSI-approved license (MIT).Pass
- Actively maintained (last published 16 days ago).Pass
- Disclosure check failed: no security disclosure policy was found in the source repository. See how to fix → Fail
Schema Quality & AI Usability77
- 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 13503 tokens (~314/item across 43 items; 41 tools + 2 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
- No destabilizing schema changes in the last 30 days.Pass
Tool Coverage99
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 98% of tool parameters carry a description.Partial
- Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- We read all 41 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 43 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a current MCP spec version (2026-07-28).Pass
How do I install the PH Civic Data MCP server?
PH Civic Data runs locally as a PyPI package, launched with uvx ph-civic-data-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
pypi · ph-civic-data-mcp
claude mcp add xmpuspus-ph-civic-data-mcp -- uvx ph-civic-data-mcp
{
"mcpServers": {
"xmpuspus-ph-civic-data-mcp": {
"command": "uvx",
"args": [
"ph-civic-data-mcp"
]
}
}
} {
"servers": {
"xmpuspus-ph-civic-data-mcp": {
"command": "uvx",
"args": [
"ph-civic-data-mcp"
]
}
}
} codex mcp add xmpuspus-ph-civic-data-mcp -- uvx ph-civic-data-mcp
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"xmpuspus-ph-civic-data-mcp": {
"type": "local",
"command": [
"uvx",
"ph-civic-data-mcp"
],
"enabled": true
}
}
} openclaw mcp add xmpuspus-ph-civic-data-mcp --command uvx --arg ph-civic-data-mcp
mcp_servers:
xmpuspus-ph-civic-data-mcp:
command: "uvx"
args: ["ph-civic-data-mcp"] {
"McpServers": {
"xmpuspus-ph-civic-data-mcp": {
"Transport": "stdio",
"Command": "uvx",
"Arguments": [
"ph-civic-data-mcp"
]
}
}
} assistant mcp add xmpuspus-ph-civic-data-mcp -t stdio -c uvx -a ph-civic-data-mcp
{
"mcpServers": {
"xmpuspus-ph-civic-data-mcp": {
"command": "uvx",
"args": [
"ph-civic-data-mcp"
]
}
}
} Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 20 Sept 26 +1
- Stability: 0.97 → pass security
- 18 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.
- 16 Sept 26 +1
- Security disclosure: unverified → fail ▼ functional
- 15 Sept 26 0
- Security disclosure: fail → unverified ▼ functional
- 14 Sept 26 −3
- Stability: pass → 0.80 functional
- 13 Sept 26 −14
- Malware scan: pass → unverified ▼ security
- Stability: 0.97 → pass security
- 12 Sept 26 +15
- Malware scan: unverified → pass ▲ security
- 11 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 20 Sept 2026 · Analysed pypi/ph-civic-data-mcp@0.8.0
Provenance No attestation
The registry publishes no build provenance for this version, so there is nothing to verify.
| Result | No attestation |
|---|---|
| Ecosystem | pypi |
Background: How many MCP packages publish verified provenance →
Install scripts 1 script
| Hook | Tier | Command |
|---|---|---|
| build_backend | allowlisted | hatchling.build |
Background: Why install scripts are a supply-chain risk →
Dependencies 29 packages
| Packages resolved | 29 |
|---|---|
| Stale | 2 |
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
assess_area_risk Multi-hazard risk snapshot for a place ~202
Multi-hazard risk assessment combining PHIVOLCS + PAGASA. Makes parallel upstream calls to PHIVOLCS (earthquakes, volcano alert levels) and PAGASA (active typhoons, weather alerts). Expect 3-6 second response time. earthquake_risk_level is a heuristic reading of recent seismic activity, never an official PHIVOLCS hazard assessment. Examples: assess_area_risk("Manila") assess_area_risk("Batangas") On failure: this tool never raises. A failed PHIVOLCS or PAGASA sub-call shows up as a caveats entry naming the source, and the other sources still report. data_status is "success" when every sub-call succeeded, "indeterminate" when some failed, and "unavailable" when all failed; upstream_error is true for the last two.
| Name | Type | Req | Description |
|---|---|---|---|
| location | string | yes | Municipality, city, or province name. |
Structured output declared, but exposes no named fields.
No examples provided.
browse_election_results Browse the COMELEC 2025 election results tree ~330
Walk the COMELEC 2025 election results tree: region down to precinct. Starts at the 20 regions when `code` is "0", the default. Pass a child's `code` from the response to go one level deeper. A barangay's children are its precincts, since the geography tree stops at the barangay level and precincts sit in a separate family. Examples: browse_election_results() the 20 regions browse_election_results(code="R001000") provinces of Region I browse_election_results(code="2801000") barangays of Adams, Ilocos Norte browse_election_results(code="2801001") precincts of one barangay On failure: a code that is not "0", a region code, or 7 digits gives validation_error true and data_status "invalid_request", with no request sent. A well-formed code the archive does not recognize gives the same shape after the lookup. A tree response whose rows all fail to parse gives data_status "indeterminate", never cached. A response with some bad rows returns the good rows, with a caveat naming the skipped count. A real outage gives upstream_error true and data_status "unavailable", with the real error in caveats.
| Name | Type | Req | Description |
|---|---|---|---|
| code | string | – | "0" for the region list, a region code such as "R001000", or a 7-digit province, city, or barangay code from a previous call. |
Structured output declared, but exposes no named fields.
No examples provided.
browse_psa_catalog Browse the PSA OpenSTAT catalog ~288
List one level of the PSA OpenSTAT statistical catalog. OpenSTAT publishes roughly 2,900 tables across 27 subjects. This walks that tree one level at a time, so an agent can find a dataset without guessing a table id. A `dataset` entry is a `.px` table. Pass its `path` to describe_psa_dataset before calling query_psa_dataset. Folder depth varies by subject, so keep browsing until entries come back as datasets. Examples: browse_psa_catalog() the 27 top-level subjects browse_psa_catalog("1F") one level into the Poverty subject browse_psa_catalog("1F/FY") the Full Year Poverty Statistics tables On failure: data_status is "invalid_request" for a rejected argument and "unavailable" for an OpenSTAT outage. A bad path sets validation_error true before any request goes out. An unreachable catalog sets upstream_error true, with the real error in caveats. Both return an empty entries list, which never means an empty folder.
| Name | Type | Req | Description |
|---|---|---|---|
| path | – | – | Relative catalog path such as "1F" or "1F/FY". None or "" returns the 27 top-level subjects. Use the `path` field of an entry from a previous call to go one level deeper. |
| Name | Type | Req | Description |
|---|---|---|---|
| caveats | array | yes | – |
| data_retrieved_at | string | yes | – |
| dataset_count | integer | – | – |
| entries | array | yes | – |
| folder_count | integer | – | – |
| license | string | – | – |
| note | string | – | – |
| parent_path | string|null | – | – |
| path | string|null | – | Relative path browsed. |
| source | string | yes | Upstream data source name. |
| source_url | string | yes | Canonical OpenSTAT URL used. |
| upstream_error | boolean | – | True when OpenSTAT was unreachable. Not an empty result. |
| validation_error | boolean | – | True when the caller's arguments were rejected before any request. |
No examples provided.
compare_areas Compare civic indicators across places ~337
Compare civic indicators for two to five Philippine places, side by side. Calls get_area_profile for each place and builds one row per place, so an agent does not have to call the profile tool once per place and merge the results itself. locations needs 2 to 5 entries. metrics, when given, must come from a fixed allowlist of eight names, and it defaults to all eight. format is "json" or "csv". "csv" adds a CSV string under `export`. Examples: compare_areas(["Cebu City", "Davao City"]) compare_areas(["Cebu City", "Davao City"], metrics=["population"]) On failure: a rejected request, such as a wrong location count, too many or duplicate metrics, an unknown metric, or a bad format, never calls get_area_profile. It returns validation_error: true and data_status "invalid_request". A place that fails to resolve still gets a row, with resolved_name None, the overall data_status becomes "indeterminate" or "unavailable", and comparable turns false with a caveat naming the unresolved place.
| Name | Type | Req | Description |
|---|---|---|---|
| format | string | – | "json" (default) or "csv". |
| locations | array | yes | 2 to 5 place names, e.g. ["Cebu City", "Davao City"]. |
| metrics | – | – | Names to compare, from population, population_year, poverty_incidence_pct, poverty_year, headline_inflation_pct, employment_rate_pct, infra_notice_count, earthquake_risk_level. Default… |
Structured output declared, but exposes no named fields.
No examples provided.
describe_psa_dataset Describe a PSA OpenSTAT dataset ~241
Read the dimensions and valid value codes of one PSA OpenSTAT dataset. Call this before query_psa_dataset. The query tool needs an explicit value code for every dimension, and those codes live here. total_cells is the size of the full cube. A query must select down to max_cells_per_query or fewer, so pick explicit codes per dimension. Examples: describe_psa_dataset("1F/FY/0241F3DF013.px") dimensions and value codes for one table On failure: data_status is "invalid_request" for a rejected argument and "unavailable" for an OpenSTAT outage. A path that is not a `.px` dataset sets validation_error true before any request goes out. An unreadable dataset sets upstream_error true, with the real error in caveats. Both return an empty dimensions list.
| Name | Type | Req | Description |
|---|---|---|---|
| dataset_path | string | yes | Relative path to a `.px` dataset, for example "1F/FY/0241F3DF013.px". Take it from the `path` field of a browse_psa_catalog dataset entry. |
| Name | Type | Req | Description |
|---|---|---|---|
| caveats | array | yes | – |
| data_retrieved_at | string | yes | – |
| dataset_path | string | yes | – |
| dimensions | array | yes | – |
| license | string | – | – |
| max_cells_per_query | integer | – | – |
| note | string | – | – |
| source | string | yes | Upstream data source name. |
| source_url | string | yes | Canonical OpenSTAT URL used. |
| time_dimensions | array | – | – |
| title | string | – | – |
| total_cells | integer | – | Size of the full cube. |
| upstream_error | boolean | – | True when OpenSTAT was unreachable. Not an empty result. |
| validation_error | boolean | – | True when the caller's arguments were rejected before any request. |
No examples provided.
flag_infra_anomalies Flag infrastructure spending anomalies ~383
Flag PhilGEPS infrastructure projects that warrant further review by cross-referencing PHIVOLCS earthquakes and PAGASA typhoon footprints. This tool emits heuristic anomaly indicators, not accusations. Every flagged item ships with the rule that fired and a disclaimer noting that patterns may have legitimate explanations. Heuristic rules: - duplicate_titles_same_agency: same agency files multiple notices with effectively identical titles (case-insensitive) within the window - high_cost_no_published_progress: cost_php exceeds min_cost_php. The PhilGEPS open listing publishes no progress data for ANY notice, so this is a cost-threshold transparency flag, not a project-specific "progress is missing" finding. - hazard_overlap: project location keywords overlap with a recent PHIVOLCS earthquake (>=M4.0 in last 30d) or an active PAGASA typhoon footprint, suggesting urgency or post-disaster reconstruction context. Examples: flag_infra_anomalies() flag_infra_anomalies(min_cost_php=100_000_000) On failure: this tool never raises. data_status is "success" when PhilGEPS, PHIVOLCS, and PAGASA all load, "indeterminate" when one or two fail, and "unavailable" when all three fail; upstream_error is true for the last two. A failed sub-call shows up as a caveats entry naming the source, and the flagged list still returns data from every source that did respond.
| Name | Type | Req | Description |
|---|---|---|---|
| min_cost_php | number | – | Threshold for the high_cost_no_published_progress rule (default 50,000,000 PHP). |
| province | – | – | Province filter (partial match). |
| region | – | – | PH region filter for the project list. |
Structured output declared, but exposes no named fields.
No examples provided.
get_active_typhoons Active tropical cyclones in the PAR ~255
Get active tropical cyclones in/near the Philippine Area of Responsibility (PAR). Returns an empty list when no cyclone is active. This tool parses the live PAGASA bulletin page with regular expressions. A bulletin wording change can miss a cyclone, but the "no active" state itself is reliably detected. Examples: get_active_typhoons() # only call form, no arguments On failure: When the PAGASA bulletin page is unreachable, this tool returns data_status "unavailable", upstream_error: true, results: [], and the real error in caveats. That shape never matches a genuine "no active typhoons" answer, which is a bare empty list. When the page loads but neither the "no active cyclone" marker nor a cyclone name matches, this tool returns data_status "indeterminate" instead of guessing at "no active typhoons". Returns: list of typhoons, each with local_name, international_name, category, max_winds_kph, within_par, signal_numbers, bulletin_number, source, bulletin_url, data_retrieved_at. Or the failure dict above.
Input schema present but exposes no named parameters.
| Name | Type | Req | Description |
|---|---|---|---|
| result | – | yes | – |
No examples provided.
get_air_quality Air quality at a Philippine location ~267
Real-time air quality for a Philippine city via Open-Meteo (no API key). Returns PM2.5, PM10, CO, NO2, SO2, and O3, plus European AQI and US AQI with category interpretation. Covers about 80 major PH cities through a local coordinate table. measured_at is always UTC, never Asia/Manila time. Examples: get_air_quality("Manila") # current readings for Metro Manila get_air_quality("Cebu City") # current readings for Cebu City get_air_quality("Davao") # current readings for Davao City On failure: a location not in the coordinate table returns data_status "invalid_request", with validation_error true and a caveat naming the location. An Open-Meteo fetch failure returns data_status "unavailable", with upstream_error true and the real error text in caveats. A response with no time, an unparseable time, or no pollutant field returns data_status "indeterminate", with upstream_error true and a caveat naming the problem.
| Name | Type | Req | Description |
|---|---|---|---|
| location | string | yes | City or municipality name, such as "Manila", "Cebu City", or "Davao". |
Structured output declared, but exposes no named fields.
No examples provided.
get_area_profile One-call civic profile for a place ~278
One-call correlated civic profile for a Philippine location. Resolves the place once to its PSA Standard Geographic Code, then composes demographics (population, poverty), economy (regional inflation, national labor), procurement activity, multi-hazard risk, and the short-range weather outlook — in a single agent turn instead of eight. Adds derived cross-source context (e.g. infrastructure notices per 100k residents) so the caller does not have to normalize raw counts itself. Examples: get_area_profile("Cebu City") city-level demographics, hazard, weather get_area_profile("NCR") region-level, no province in the chain get_area_profile("Tacloban") city under a resolved province On failure: each block (population, poverty, inflation, labor, hazard, weather, infra, resolve) gets its own status in blocks. A failed sibling appears there and in caveats, never as a silent null. The top-level upstream_error is true only when a block is genuinely unreachable, not when a sibling rejected an argument or returned a real empty answer.
| Name | Type | Req | Description |
|---|---|---|---|
| location | string | yes | Municipality, city, province, or region name. e.g. "Leyte", "Cebu City", "Davao Region", "NCR". |
Structured output declared, but exposes no named fields.
No examples provided.
get_data_freshness Server health and data-source catalog ~242
Server health and data-source catalog probe. Doubles as the version and health endpoint: returns server_version so an agent can confirm which release it is talking to. Also returns the full upstream-source catalog: cache TTLs, freshness expectations, and licenses. Use it to judge whether a stale cached response is fine or a re-fetch is needed. Examples: get_data_freshness() # the only call, it takes no arguments On failure: this tool calls no upstream itself, so it always returns a dict. source_health is a process-local, in-memory registry, not a database. It starts empty on a cold process and fills as fetch_with_retry runs calls, so a fresh restart always reports an empty dict here. Returns: server_version, server_name, transport, tool_count, asof, sources (list of {source, source_url, freshness, cache_ttl_seconds, license}), source_health (per-host {last_success_at, last_failure_at, last_error, last_latency_ms, success_count, failure_count}), cache_age (per-cache {size, ttl_seconds}), note.
Input schema present but exposes no named parameters.
Structured output declared, but exposes no named fields.
No examples provided.
get_earthquake_bulletin PHIVOLCS earthquake bulletin ~223
Get the full bulletin for a PHIVOLCS earthquake event. Parses the bulletin page PHIVOLCS publishes for one event: magnitude, depth, location, date and time, and per-municipality intensity reports. Give the bulletin_url a prior get_latest_earthquakes call returned. A hand-built or off-host URL is refused before any fetch is attempted. Examples: get_earthquake_bulletin("https://phivolcs.dost.gov.ph/index.php") # real bulletin URL shape On failure: an empty, malformed, or non-PHIVOLCS bulletin_url, or a 404 on the page itself, returns a dict with url, source, caveats, and data_retrieved_at only, with no data_status, upstream_error, magnitude, or location fields. A fetch that raises an exception sets data_status "unavailable" and upstream_error true.
| Name | Type | Req | Description |
|---|---|---|---|
| bulletin_url | string | yes | Full URL returned by get_latest_earthquakes.bulletin_url. |
Structured output declared, but exposes no named fields.
No examples provided.
get_election_return COMELEC 2025 precinct election return ~242
One precinct's official vote tally from the COMELEC 2025 archive. Give the 8-digit precinct code from browse_election_results. Returns every national and local contest counted at that precinct, with each candidate's vote count and share. Examples: get_election_return("28010001") Adams, Ilocos Norte, precinct 0001 On failure: a code that is not 8 digits gives validation_error true and data_status "invalid_request", with no request sent. A code the archive does not recognize (a 403 body carrying its AccessDenied marker) gives the same shape. A body missing 'information', where 'national' or 'local' is not a list, or where a contest carries a non-list nested 'candidates' value, gives data_status "indeterminate" with upstream_error true. Any other outage, including a 403 with no AccessDenied marker, gives data_status "unavailable" with upstream_error true and the real error in caveats.
| Name | Type | Req | Description |
|---|---|---|---|
| precinct_code | string | yes | 8-digit precinct code, such as "28010001". |
Structured output declared, but exposes no named fields.
No examples provided.
get_flood_forecast River flood forecast for a Philippine location ~332
Daily river discharge forecast for a Philippine place, from Open-Meteo's GloFAS model. Returns a daily river_discharge_m3s series for the nearest river cell to the resolved location, plus its max and min bounds, in cubic meters per second. This is a model estimate, not a gauge reading, so treat it as one signal among many for flood risk. Examples: get_flood_forecast("Cagayan de Oro") # 7-day default forecast get_flood_forecast("Marikina", forecast_days=14, past_days=3) # 14 days ahead, 3 days back On failure: an unresolved location, or a forecast_days or past_days value that is not a whole number or is out of range, returns data_status "invalid_request", with validation_error true and days []. A PSGC outage during location resolution, or an Open-Meteo fetch failure, returns data_status "unavailable", with upstream_error true and days []. A response with no readable daily.time entries, or a river_discharge list shorter than daily.time (including an empty list), returns data_status "indeterminate", with upstream_error true, days [], and is never cached.
| Name | Type | Req | Description |
|---|---|---|---|
| forecast_days | integer | – | Days ahead to forecast, from 1 to 30. Default 7. |
| location | string | yes | City, municipality, or province name. |
| past_days | integer | – | Days of past discharge to include, from 0 to 30. Default 0. |
Structured output declared, but exposes no named fields.
No examples provided.
get_health_indicators Philippine health indicators ~222
National health indicators from PSA OpenSTAT (subject 1D). With no argument, returns the curated national headline set: maternal mortality ratio and total fertility rate. Pass a free-text `indicator` to fuzzy-match any table published under the Health subject. The available list is browse-discovered, never hardcoded. Examples: get_health_indicators() maternal mortality ratio and fertility rate get_health_indicators(indicator="fertility") one matching table On failure: a catalog browse failure sets data_status "unavailable" and upstream_error true, with an empty indicators list. A keyword that matches no table sets data_status "success" with an empty indicators list and a caveat, not an error flag. A partial fetch failure across matched tables sets data_status "indeterminate" and upstream_error true. validation_error stays false in every case.
| Name | Type | Req | Description |
|---|---|---|---|
| indicator | – | – | Optional free-text indicator name, for example "maternal mortality", "fertility". None returns the default headline set. |
Structured output declared, but exposes no named fields.
No examples provided.
get_historical_typhoons_ph Historical typhoon tracks through the PAR ~276
Historical tropical cyclone tracks that passed through the Philippine AOR. Sourced from NOAA IBTrACS (International Best Track Archive), the authoritative global archive for tropical cyclone tracks. Filtered to the Western Pacific basin and coordinates inside the Philippine Area of Responsibility, aggregated per storm. The result streams the source CSV row by row and returns the most recent storms that crossed the PAR, sorted by start time. Returns peak intensity, minimum pressure, and track period. Examples: get_historical_typhoons_ph() # last 3 years, up to 30 storms get_historical_typhoons_ph(year=2024) # season 2024, up to 30 storms get_historical_typhoons_ph(year=2024, limit=10) # season 2024, up to 10 storms On failure: a stream error, a response with no data rows, or a CSV header missing a required column returns a dict. data_status is "unavailable", upstream_error is true, and results is empty, with the real error text in caveats.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Max storms to return (default 30). |
| year | – | – | Season year. None returns recent (last 3 years). |
| Name | Type | Req | Description |
|---|---|---|---|
| result | – | yes | – |
No examples provided.
get_inflation_stats Philippine consumer-price inflation ~229
Headline consumer-price inflation (year-on-year, all items) from PSA. Source: PSA OpenSTAT Consumer Price Index, 2018-based. The tool discovers the current CPI series by text, never a hardcoded table id, and returns the most recently published month's year-on-year change. PSA publishes with a lag, so the reported period is the latest one PSA has, not always the current month. Examples: get_inflation_stats() national headline inflation, latest month get_inflation_stats(area="NCR") one region On failure: every failure, including an area name PSA does not list, sets data_status "unavailable" and upstream_error true, with the real error or a not-found message in caveats. validation_error stays false in every case, because a bad area name is treated as an outage here, not a caller mistake.
| Name | Type | Req | Description |
|---|---|---|---|
| area | – | – | Region or "Philippines". None returns the national figure. For example "NCR", "Region VII", "Davao Region". |
Structured output declared, but exposes no named fields.
No examples provided.
get_infra_project Infrastructure notice detail ~185
Return the full record for one infrastructure project by project_id. This tool looks up project_id inside the same latest ~100-notice PhilGEPS window search_infra_projects reads. An id from an older window returns matched: false, not an error, because the window has already moved on. Examples: get_infra_project("PHILGEPS-INF-003") get_infra_project("DOES-NOT-EXIST") On failure: an empty project_id or a project missing from the current window both return matched: false with a caveat, no upstream_error, and no data_status. A PhilGEPS fetch failure returns matched: false, data_status "unavailable", upstream_error true, and the real error text in caveats.
| Name | Type | Req | Description |
|---|---|---|---|
| project_id | string | yes | Reference number from search_infra_projects. |
Structured output declared, but exposes no named fields.
No examples provided.
get_labor_stats Philippine labor-force indicators ~187
Key labor-force indicators from the PSA Labor Force Survey. Returns labor-force participation, employment, unemployment, and underemployment rates for the latest published reference period. The PSA key-indicator series is national only. Passing `region` does not filter the figure. It only adds an explanatory caveat, because this table has no regional breakdown. Examples: get_labor_stats() national rates, latest reference period get_labor_stats(region="Cebu") same national rates, plus a caveat On failure: an OpenSTAT discovery or query failure sets data_status "unavailable" and upstream_error true, with the real error in caveats. validation_error stays false in every case.
| Name | Type | Req | Description |
|---|---|---|---|
| region | – | – | Accepted for API symmetry. The LFS key-indicator table is national only. Passing a region adds an explanatory caveat. |
Structured output declared, but exposes no named fields.
No examples provided.
get_latest_earthquakes Latest PHIVOLCS earthquakes ~411
Get the latest earthquake events from PHIVOLCS. Reads the live PHIVOLCS earthquake list, the same table shown at earthquake.phivolcs.dost.gov.ph. Give center_lat, center_lon, and radius_km together to filter events near one place, and each matched event then carries a distance_km field. Give all three together, or leave out all three. Examples: get_latest_earthquakes() latest events, default filters get_latest_earthquakes(min_magnitude=4.0, limit=10) strong events only get_latest_earthquakes(center_lat=14.5995, center_lon=120.9842, radius_km=50) near Manila On failure: an invalid trio, an out-of-range radius_km, center_lat, or center_lon gives validation_error true and data_status "invalid_request". An unreachable or unparsable PHIVOLCS list gives upstream_error true and data_status "unavailable". Both return results: [] with the real error in caveats.
| Name | Type | Req | Description |
|---|---|---|---|
| center_lat | – | – | Latitude of a search point. Give with center_lon and radius_km to filter to events near one place instead of the full recent-events list. |
| center_lon | – | – | Longitude of a search point. Give with center_lat and radius_km. |
| limit | integer | – | Max events to return (default 20, max 100). |
| min_magnitude | number | – | Minimum magnitude to include (default 1.0). |
| radius_km | – | – | Keep only events within this distance of (center_lat, center_lon). Give all three of center_lat, center_lon, and radius_km together, or none of them. Each returned event then car… |
| region | – | – | Filter by PH region/province/city name (partial match). |
| Name | Type | Req | Description |
|---|---|---|---|
| result | – | yes | – |
No examples provided.
get_location_hierarchy Full PSGC hierarchy for a place ~255
Return the full chain region -> province -> city/municipality -> barangay for one PSGC code. This tool checks that psgc_code is well-formed before it sends any request. A malformed code never reaches the network. An unknown but well-formed code, or a PSGC mirror outage, both produce an empty chain instead of a match. Check the fields named below to tell the two apart. Examples: get_location_hierarchy("072217000") Cebu City, chain walks up through province and region get_location_hierarchy("999999999") well-formed but unknown code get_location_hierarchy("not-a-code") malformed, rejected before any network call On failure, a malformed code returns validation_error: true, data_status "invalid_request", and chain: [], with no network call made. A genuine mirror outage during lookup or the hierarchy walk returns chain: [], upstream_error: true, and the real error in caveats. A clean unknown-code answer returns chain: [] and caveats, with neither key set.
| Name | Type | Req | Description |
|---|---|---|---|
| psgc_code | string | yes | 9-digit PSGC code (leading zeros optional). |
Structured output declared, but exposes no named fields.
No examples provided.
get_official_gazette_feed Official Gazette RSS feed ~295
Latest issuances from the Official Gazette of the Republic of the Philippines. Reads the government's own RSS feed of proclamations, memorandum circulars, and other issuances, ten items per page, newest first. Examples: get_official_gazette_feed() # page 1, the newest 10 issuances get_official_gazette_feed(page=2) # the next 10 issuances On failure: a page outside 1 to 50 returns data_status "invalid_request" with validation_error true and no fetch attempted. A Cloudflare block page, the only other response this host sends on a bad call, returns data_status "unavailable" with upstream_error true and the real status and content type in caveats. An item with neither a title nor a link is dropped and counted in caveats. A page 1 response that parses as valid RSS but keeps zero issuances, whether the feed sent none or every item was dropped, is drift and returns data_status "indeterminate". A page above 1 with zero issuances is a genuine empty page and returns data_status "empty".
| Name | Type | Req | Description |
|---|---|---|---|
| page | integer | – | Page of the feed, 1 to 50. Page 1 reads /feed/, a page above 1 reads /feed/?paged=<page>. Default 1. |
Structured output declared, but exposes no named fields.
No examples provided.
get_population_stats Philippine population statistics ~439
Population from the PSA Census of Population, discovered live on OpenSTAT. Defaults to the latest census PSA publishes: the 2024 Census of Population, reference date 2024-07-01, as of 2026-09. Pass `year` for an older census (2010, 2015, 2020). Every result names its census, reference date and geography level, and for the 2024 tables the PSGC code PSA keyed the row on. Examples: get_population_stats() national total, latest census get_population_stats(region="NCR") one region, province or HUC by PSA label get_population_stats(region="Cebu", year=2020) get_population_stats(psgc_code="0831600000") City of Tacloban, 2024 Census get_population_stats(psgc_code="083747000") same place, 9-digit code get_population_stats(psgc_code="1380100001") one barangay, 2024 Census On failure: data_status is "unavailable" when PSA is down, with upstream_error true. data_status is "invalid_request" for an unknown region, year, or PSGC code, with validation_error true. data_status is "empty" when a valid PSGC code has no row in the chosen census table. caveats always carries the real error text. population is None in every failure. Failures are never cached.
| Name | Type | Req | Description |
|---|---|---|---|
| psgc_code | – | – | A 9- or 10-digit PSGC code from resolve_ph_location. Reaches cities, municipalities and barangays (2024 Census only). Not combined with region. |
| region | – | – | Region, province or highly urbanized city as PSA labels it, such as "NCR", "Region VII", "CAR", "BARMM", "Leyte", "City of Manila". None returns the national total. |
| year | – | – | Census year. None picks the latest. A year PSA has no census for returns validation_error with available_vintages. |
Structured output declared, but exposes no named fields.
No examples provided.
get_poverty_stats Philippine poverty incidence ~287
Poverty incidence from the PSA Full Year Poverty Statistics table. PSA publishes this once a year, with a lag. As of 2026-09 the latest published year is 2023. The tool discovers the current table live, so a later release shows up without a code change. It also returns the subsistence incidence when PSA publishes both tables for the same year. Examples: get_poverty_stats() national poverty incidence, latest year get_poverty_stats(region="Bicol") one region, PSA label get_poverty_stats(region="NCR") National Capital Region On failure: a discovery failure, a missing Incidence dimension, an unparseable year label, or a query failure sets data_status "unavailable" and upstream_error true. A region PSA does not list sets data_status "invalid_request" and validation_error true. A table with no matching incidence measure, or a cell whose values field is not a list, sets data_status "indeterminate" and upstream_error true. A published ".." cell for the region and year sets no error flag and no data_status. Check caveats instead. A subsistence-table failure sets upstream_error true on an otherwise valid poverty figure, but leaves data_status at "success".
| Name | Type | Req | Description |
|---|---|---|---|
| region | – | – | PH region (None returns national). |
Structured output declared, but exposes no named fields.
No examples provided.
get_procurement_summary Summarize PhilGEPS procurement ~222
Aggregate procurement statistics over the latest notices cached from PhilGEPS. This tool aggregates the same latest ~100-notice window search_procurement reads (6h cache). rules_evaluated names which breakdowns ran, by_mode and by_region. rules_not_computable explains why total_value_php stays null: PhilGEPS open notices do not publish approved budget amounts. Examples: get_procurement_summary() get_procurement_summary(agency="DPWH", year=2025) On failure: data_status "unavailable", upstream_error true, totals zero and by_mode/by_region/top_agencies empty, with the real PhilGEPS error in caveats. A year that is not a plain integer returns validation_error: true and data_status "invalid_request" before any fetch, naming the bad value.
| Name | Type | Req | Description |
|---|---|---|---|
| agency | – | – | Partial agency match filter. |
| region | – | – | PH region filter. |
| year | – | – | Filter publish date to this year. Drops an undated record and notes the dropped count in caveats. |
Structured output declared, but exposes no named fields.
No examples provided.
get_solar_and_climate Solar irradiance and climate at a point ~356
Daily solar irradiance and climate variables from NASA POWER for any coordinate. Returns daily solar irradiance, 2m temperature, corrected precipitation, and 2m wind speed, in kWh per m2, Celsius, mm, and m per second. Useful for solar-site screening, farm planning, and historical climate checks. Examples: get_solar_and_climate(14.5995, 120.9842) # Manila, last 14 days get_solar_and_climate(14.5995, 120.9842, "2026-04-01", "2026-04-02") # a fixed 2-day window On failure: an upstream fetch failure or a non-object response body returns data_status "unavailable", with upstream_error true, days [], and the real error text in caveats. A properties or parameter field that is missing, null, or not an object returns data_status "indeterminate", with upstream_error true and days []. A start_date or end_date that does not parse as YYYY-MM-DD, an end_date before start_date, a span over 366 days, or a latitude or longitude out of range, returns data_status "invalid_request", with validation_error true and days [].
| Name | Type | Req | Description |
|---|---|---|---|
| end_date | – | – | ISO date string (YYYY-MM-DD). Defaults to today. The span from start_date to end_date cannot exceed 366 days. |
| latitude | number | yes | Decimal degrees, WGS84. |
| longitude | number | yes | Decimal degrees, WGS84. |
| start_date | – | – | ISO date string (YYYY-MM-DD). Defaults to 14 days ago. |
Structured output declared, but exposes no named fields.
No examples provided.
get_usgs_earthquakes_ph USGS earthquakes near the Philippines ~537
Philippine-region earthquakes from USGS, cross-reference to PHIVOLCS. Returns events inside the PH bounding box (lat 4..22, lng 115..130) that USGS catalogs, including international-standard Mww/Mwc magnitudes and depth solutions. Complements PHIVOLCS with global-network analysis. Give center_lat, center_lon, and radius_km together to filter to one place, and each matched event then carries a distance_km field. Give all three together, or leave out all three. Examples: get_usgs_earthquakes_ph() last 30 days, magnitude 4.0+ get_usgs_earthquakes_ph(start_date="2026-08-01", end_date="2026-08-31") get_usgs_earthquakes_ph(center_lat=14.5995, center_lon=120.9842, radius_km=50) near Manila On failure: an invalid trio, an out-of-range radius_km, center_lat, or center_lon gives validation_error true and data_status "invalid_request". The same happens for a start_date or end_date that is not YYYY-MM-DD. An unreachable USGS API, or a payload that is not a GeoJSON FeatureCollection, gives upstream_error true and data_status "unavailable". A nonempty features list where every feature fails to parse gives upstream_error true and data_status "indeterminate", and is never cached. All three return results: [] with the real error in caveats.
| Name | Type | Req | Description |
|---|---|---|---|
| center_lat | – | – | Latitude of a search point. Give with center_lon and radius_km to filter to events near one place instead of the whole PH bbox. |
| center_lon | – | – | Longitude of a search point. Give with center_lat and radius_km. |
| end_date | – | – | ISO date (YYYY-MM-DD). Defaults to today. |
| limit | integer | – | Max events to return (default 50, USGS hard-caps at 20000). |
| min_magnitude | number | – | Minimum magnitude (default 4.0 to keep noise low). |
| radius_km | – | – | Keep only events within this distance of (center_lat, center_lon). Give all three of center_lat, center_lon, and radius_km together, or none of them. Each returned event then car… |
| start_date | – | – | ISO date (YYYY-MM-DD). Defaults to 30 days ago. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | – | yes | – |
No examples provided.
get_vegetation_index MODIS vegetation index at a point ~395
NASA MODIS MOD13Q1 NDVI and EVI vegetation index at any coordinate. NDVI (Normalized Difference Vegetation Index) ranges -1 to 1. Higher values indicate denser healthy vegetation. EVI is more sensitive in high-biomass areas. The composite period is 16 days at 250m resolution. Useful for farm monitoring, deforestation tracking, and drought checks. Examples: get_vegetation_index(15.58, 121.0) # last ~90 days at a point in Isabela get_vegetation_index(15.58, 121.0, "2026-08-01", "2026-08-15") # a fixed 15-day window On failure: both MODIS bands failing returns data_status "unavailable", upstream_error true, samples [], and both band errors in caveats. One band failing still returns the other band's samples, but data_status stays "unavailable" with upstream_error true. A band whose rows carry no numeric value counts as that band failing. A pixel with no composite in range, such as one over water, is a real success with samples []. A latitude or longitude out of range returns data_status "invalid_request", with validation_error true and samples []. A start_date or end_date that does not parse as YYYY-MM-DD, or a span over 366 days, also returns data_status "invalid_request", checked before any fetch.
| Name | Type | Req | Description |
|---|---|---|---|
| end_date | – | – | ISO date (YYYY-MM-DD). Defaults to today. |
| latitude | number | yes | Decimal degrees, WGS84. |
| longitude | number | yes | Decimal degrees, WGS84. |
| start_date | – | – | ISO date (YYYY-MM-DD). Defaults to ~90 days ago. The span from start_date to end_date cannot exceed 366 days. |
Structured output declared, but exposes no named fields.
No examples provided.
get_volcano_status Philippine volcano alert levels ~238
Get current alert level for Philippine volcanoes. Reads the WOVODAT bulletin list PHIVOLCS publishes for its monitored volcanoes: Mayon, Taal, Kanlaon, Bulusan, Pinatubo, Hibok-Hibok, and Parker. When one volcano's bulletin fetch fails, that entry carries upstream_error true and a caveat with the real error, not a null alert_level. Examples: get_volcano_status() all monitored volcanoes, one call get_volcano_status("Mayon") one volcano by name get_volcano_status("Taal") On failure: WOVODAT list unreachable or empty gives data_status "unavailable", upstream_error true, results: [], and the real error in caveats. An unmatched volcano_name gives a one-item list with alert_level null and a caveat, not a failure envelope.
| Name | Type | Req | Description |
|---|---|---|---|
| volcano_name | – | – | e.g. "Mayon", "Taal", "Kanlaon", "Bulusan". None returns all monitored volcanoes with recent bulletins. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | – | yes | – |
No examples provided.
get_weather_alerts PAGASA weather alerts ~255
Get active PAGASA weather alerts and advisories. The PAGASA homepage embeds alert names such as "Heavy Rainfall Warning" in its navigation menu and breadcrumbs, as well as in real active-warning sections. This tool reliably detects the "No Active Warnings" state, but it cannot yet isolate a real active warning from that navigation text. To avoid a fabricated advisory, this tool returns a bare empty list only for the confirmed "no active warnings" marker. For real-time advisories, call bagong.pagasa.dost.gov.ph directly. Examples: get_weather_alerts() no region argument get_weather_alerts(region="NCR") region only changes the cache key On failure, when the PAGASA homepage is unreachable, this tool returns data_status "unavailable", upstream_error: true, results: [], and the real error in caveats. When the page is reachable but the "no active warnings" marker does not match, this tool returns data_status "indeterminate" instead of guessing, and never caches that response.
| Name | Type | Req | Description |
|---|---|---|---|
| region | – | – | For example "NCR", "Region VII", "CALABARZON". None returns all. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | – | yes | – |
No examples provided.
get_weather_forecast Philippine weather forecast ~271
Get the weather forecast for a Philippine location. Uses the PAGASA TenDay API when PAGASA_API_TOKEN is set, and falls back to Open-Meteo when the token is absent or the PAGASA call fails. This tool sets no `data_status` field on a success or an unknown-location result. Check `data_source` and `caveats` instead. Examples: get_weather_forecast("Manila") 3-day default forecast get_weather_forecast("Cebu City", days=2) 2-day forecast get_weather_forecast("Wakanda") unknown location, no coordinates found On failure, a location with no known coordinates returns days: [] and a caveat, with no data_status or upstream_error key. An Open-Meteo fetch failure, or a PSGC outage during location resolution, returns data_status "unavailable", upstream_error: true, days: [], and the real error in caveats. An Open-Meteo response with no daily forecast entries returns data_status "indeterminate" instead, and is never cached.
| Name | Type | Req | Description |
|---|---|---|---|
| days | integer | – | Forecast days (1-10, default 3). |
| location | string | yes | Municipality, city, or province name. |
Structured output declared, but exposes no named fields.
No examples provided.
get_world_bank_indicator World Bank indicator for the Philippines ~328
World Bank macroeconomic and social indicator for the Philippines. Accepts a World Bank indicator code, such as "NY.GDP.MKTP.CD", or a friendly alias, such as "gdp", "poverty_ratio", "inflation", or "urban_population_pct". The tool checks the indicator code shape before it reaches the URL, so a bad value cannot redirect the request to another country's data. Examples: get_world_bank_indicator("gdp") # GDP, latest 20 years get_world_bank_indicator("NY.GDP.MKTP.CD", per_page=5) # same indicator, 5 years get_world_bank_indicator("poverty_ratio") # poverty headcount ratio On failure: an indicator code or alias that fails the shape check returns data_status "invalid_request", with validation_error true and observations []. An upstream fetch failure returns data_status "unavailable", with upstream_error true, observations [], and the real error text in caveats. A row with a non-numeric or non-finite value (NaN, inf) is skipped and counted in caveats. A response where every row is non-numeric or non-finite returns data_status "unavailable" instead of a false empty answer.
| Name | Type | Req | Description |
|---|---|---|---|
| indicator | string | yes | WB code or alias. See INDICATOR_ALIASES in source for the curated list of common indicators. |
| per_page | integer | – | Number of observations to return (latest first, default 20). |
Structured output declared, but exposes no named fields.
No examples provided.
list_admin_units List Philippine administrative units ~277
Browse children of a PSGC node, or top-level regions when parent_code is None. An unrecognized parent_code or level filter matches no children and returns an empty list. This tool never returns validation_error. A malformed argument degrades to an empty result instead of a failure. Examples: list_admin_units() top-level regions list_admin_units(parent_code="072200000") children of Cebu province list_admin_units(level="city-municipality", limit=10) first 10 cities and municipalities On failure, only a PSGC API outage returns a failure envelope: data_status "unavailable", upstream_error: true, results: [], and the real error in caveats. A malformed parent_code or level returns an empty list instead of this failure shape.
| Name | Type | Req | Description |
|---|---|---|---|
| level | – | – | Filter children by level (region|province|city|municipality|district|barangay). |
| limit | integer | – | Max units to return (default 50, capped at 500). |
| offset | integer | – | Skip this many matching units before returning results. Page past 500 children (for example, Manila has 897 barangays) by calling again with offset=500. |
| parent_code | – | – | Parent PSGC code. None returns the regions list. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | – | yes | – |
No examples provided.
list_pagasa_advisory_files PAGASA public advisory, bulletin, and storm surge files ~299
List PAGASA public PDF files from a pubfiles directory listing, newest first. Reads the nginx directory index PAGASA publishes at pubfiles.pagasa.dost.gov.ph/tamss/weather/<kind>/ and returns each PDF's name, URL, last-modified time, and size. This tool returns file URLs only, never PDF bytes, so fetch a PDF yourself if you need its contents. Examples: list_pagasa_advisory_files() latest weather advisories list_pagasa_advisory_files(kind="bulletin", limit=5) 5 newest cyclone bulletins list_pagasa_advisory_files(kind="stormsurge") storm surge folder, flagged stale On failure: an unknown kind, or a limit outside 1 to 100, gives validation_error true and data_status "invalid_request". A 404, a body with no directory listing, zero parsed files, or a parser error on a 200 body gives data_status "indeterminate". A transport failure or a non-2xx status gives data_status "unavailable". All three carry files: [] and the real error in caveats.
| Name | Type | Req | Description |
|---|---|---|---|
| kind | string | – | One of "weather_advisory", "bulletin", "stormsurge". |
| limit | integer | – | Max files to return, newest first (1 to 100, default 20). |
Structured output declared, but exposes no named fields.
No examples provided.
query_psa_dataset Query a PSA OpenSTAT dataset ~395
Run one bounded query against a PSA OpenSTAT dataset. Every dimension needs an explicit list of value codes from describe_psa_dataset. That is a hard requirement, not a convention. PXWeb expands an unselected dimension to all of its values, and PSA answers the resulting full-cube request with an HTTP 403. PSA writes a missing cell as "..", and those come back as null, never zero. Examples: # one dataset, every dimension given an explicit code list query_psa_dataset( "1F/FY/0241F3DF013.px", {"Year": ["2"], "Major Island Group": ["0", "2"], "Among Families/Population": ["0"]}, ) On failure: a bad path, a bad max_rows, or a rejected selection (a missing dimension, an unknown code, or "all"/"*") sets validation_error true and data_status "invalid_request", before any request goes out. An OpenSTAT outage sets upstream_error true and data_status "unavailable". A zero-row reply for a nonzero selection, or a row whose key does not map to the declared columns, sets data_status "indeterminate" and upstream_error true on a real HTTP 200. All four cases return an empty rows list.
| Name | Type | Req | Description |
|---|---|---|---|
| dataset_path | string | yes | Relative `.px` path, for example "1F/FY/0241F3DF013.px". |
| max_rows | integer | – | Cap on returned rows (1-5000, default 500). |
| selections | object | yes | Dimension code -> list of value codes, covering every dimension the dataset declares. "all" and "*" are rejected. Example: {"Year": ["2"], "Major Island Group": ["0", "2"], "A… |
| Name | Type | Req | Description |
|---|---|---|---|
| caveats | array | yes | – |
| data_retrieved_at | string | yes | – |
| dataset_path | string | yes | – |
| disclaimer | string | – | – |
| license | string | – | – |
| note | string | – | – |
| reference_period | string|null | – | Data vintage read from the table's own time dimension. |
| requested_cells | integer | – | – |
| row_count | integer | yes | – |
| rows | array | yes | – |
| source | string | yes | Upstream data source name. |
| source_url | string | yes | Canonical OpenSTAT URL used. |
| title | string | – | – |
| total_rows_available | integer | – | – |
| truncated | boolean | – | – |
| upstream_error | boolean | – | True when OpenSTAT was unreachable. Not an empty result. |
| validation_error | boolean | – | True when the caller's arguments were rejected before any request. |
No examples provided.
resolve_ph_location Resolve a Philippine place name to PSGC ~244
Fuzzy-resolve a Philippine place name to its canonical PSGC record. Handles common nicknames directly, such as "QC", "Gensan", "CDO", and "Metro Manila". An ambiguous name such as "San Juan" still returns one best match, plus an `alternatives` list of the other candidates. This tool sets no `data_status` field on any path. Check `matched` and `upstream_error` instead. Examples: resolve_ph_location("Cebu City") exact city match resolve_ph_location("QC") nickname resolves to Quezon City resolve_ph_location("San Juan") ambiguous name, returns alternatives On failure, a clean no-match returns matched: false and caveats, with no upstream_error key at all. When the PSGC API itself is unreachable, it returns matched: false, upstream_error: true, and the real error in caveats.
| Name | Type | Req | Description |
|---|---|---|---|
| query | string | yes | Free-text place name. Examples: "Sta. Mesa, Manila", "Cebu City", "NCR", "Pampanga", "Tagaytay". |
Structured output declared, but exposes no named fields.
No examples provided.
search_hdx_datasets Search HDX for Philippine humanitarian datasets ~348
Search HDX for Philippine humanitarian datasets by keyword. Calls the CKAN `package_search` action filtered to the Philippines country group and returns matching datasets, most recently modified first, each with its own license and up to 20 resources. Examples: search_hdx_datasets("flood") datasets matching "flood" search_hdx_datasets("food prices", rows=5) 5 most recently modified matches On failure: an empty query, a query over 200 characters, a query with a control character, or a rows value outside 1 to 50 gives validation_error true and data_status "invalid_request". An unreachable HDX API gives upstream_error true and data_status "unavailable". A response whose success field is not true, or whose result.results field is not a list, gives upstream_error true and data_status "indeterminate". Datasets sent beside a missing or non-integer count also give data_status "indeterminate", with the parsed datasets kept and never cached: CKAN always sends a real count, so a bad one is drift even when the datasets read fine. Zero datasets on a clean query with a real integer count gives data_status "empty", never a failure, and still caches. Every dataset carries its own license_id: read it before you reuse a resource.
| Name | Type | Req | Description |
|---|---|---|---|
| query | string | yes | Free-text search term, 1 to 200 printable characters, for example "flood", "food security", "displacement". |
| rows | integer | – | Number of datasets to return, 1 to 50 (default 10). |
Structured output declared, but exposes no named fields.
No examples provided.
search_infra_projects Search infrastructure notices ~393
Search Philippine government infrastructure projects. Backed by PhilGEPS open notice listing filtered for infra-related work (construction / road / bridge / flood control / drainage / school building / civil works). Source: https://www.philgeps.gov.ph/. Approved budget amounts are not published in the open notice listing, so cost_php is null in most records. min_cost_php almost never matches, because the open listing omits approved budget for nearly every record. The DPWH transparency portal API is currently blocked by Cloudflare and not used. Examples: search_infra_projects(keyword="flood control") search_infra_projects(region="ncr") search_infra_projects(min_cost_php=100_000_000) On failure: returns {results: [], upstream_error: true, data_status: "unavailable", caveats: [...]} instead of a bare list, with the real upstream error in caveats. This tool never checks an argument before the PhilGEPS fetch runs, so validation_error is always false.
| Name | Type | Req | Description |
|---|---|---|---|
| keyword | – | – | Title/agency substring (e.g. 'flood control', 'bridge'). |
| limit | integer | – | Max results (default 25, capped at 100). |
| min_cost_php | – | – | Minimum approved cost in PHP. The open notice listing does not publish approved budget for almost any record, so setting this today returns few or no results rather than… |
| province | – | – | Province name filter (partial match). |
| region | – | – | PH region filter (partial match against agency text). |
| status | – | – | Status filter (partial match, e.g. 'open', 'awarded'). |
| year | – | – | Filter publish date to this calendar year. Excludes records with no publish date, so a year filter never returns an undated record. |
| Name | Type | Req | Description |
|---|---|---|---|
| result | – | yes | – |
No examples provided.
search_procurement Search PhilGEPS procurement notices ~257
Search PH government procurement from PhilGEPS open data. Note: the PhilGEPS public portal does not expose server-side search for external clients, so this tool fetches the latest ~100 bid notices and filters them in-memory. Data is cached 6 hours. Keyword/agency/region filters are applied client-side (case-insensitive substring match). Examples: search_procurement(keyword="flood") search_procurement(keyword="", agency="DPWH", limit=10) On failure: returns {results: [], upstream_error: true, data_status: "unavailable", caveats: [...]} instead of a bare list, so an outage is never read as "no matching notices". A date_from or date_to that does not parse returns {results: [], validation_error: true, data_status: "invalid_request"} before any fetch, naming the bad value.
| Name | Type | Req | Description |
|---|---|---|---|
| agency | – | – | Partial match on procuring entity name. |
| date_from | – | – | – |
| date_to | – | – | – |
| keyword | string | yes | Search term matched against title + agency + classification. |
| limit | integer | – | Max results (default 20, max 100). |
| region | – | – | PH region filter (partial match). |
| Name | Type | Req | Description |
|---|---|---|---|
| result | – | yes | – |
No examples provided.
search_psa_catalog Search the PSA OpenSTAT catalog ~248
Find a PSA OpenSTAT dataset by keyword, without browsing level by level. Matches a case-insensitive substring against every dataset title and path in the catalog. The first call after a cold start walks the whole ~2,900-table tree and can take a few minutes. The flattened index then caches for 24 hours, so a later search answers from memory. Examples: search_psa_catalog("fertility") datasets with "fertility" in the title or path search_psa_catalog("poverty incidence", limit=5) at most 5 matches On failure: data_status is "invalid_request" for an empty keyword or a bad limit, and "unavailable" for an OpenSTAT outage during the catalog walk. validation_error or upstream_error is set to match. The real error sits in caveats. Neither failure is cached.
| Name | Type | Req | Description |
|---|---|---|---|
| keyword | string | yes | Case-insensitive substring to match against a dataset title or path, for example "fertility", "poverty incidence", "CPI". |
| limit | integer | – | Maximum number of matches to return (1-100, default 20). |
| Name | Type | Req | Description |
|---|---|---|---|
| caveats | array | yes | – |
| data_retrieved_at | string | yes | – |
| data_status | string | – | – |
| keyword | string | yes | – |
| license | string | – | – |
| limit | integer | – | – |
| match_count | integer | yes | – |
| matches | array | yes | – |
| note | string | – | – |
| source | string | yes | Upstream data source name. |
| source_url | string | yes | Canonical OpenSTAT URL used. |
| total_available | integer | – | – |
| upstream_error | boolean | – | True when OpenSTAT was unreachable. Not an empty result. |
| validation_error | boolean | – | True when the caller's arguments were rejected before any request. |
No examples provided.
search_psic_codes PSIC industrial classification search ~286
Find a PSIC code by description keyword or by code prefix. Matches a query of only digits against the PSIC code prefix. Matches any other query by whole-word text against the class description, case-insensitive. PSA publishes the full table (roughly 1,360 rows) on one page, so the first call fetches and caches it for 24 hours. Examples: search_psic_codes("rice") every description with "rice" as a whole word search_psic_codes("0111") every code that starts with "0111" search_psic_codes("mining", limit=5) at most 5 matches On failure: data_status is "invalid_request" for an empty, over-long, or non-printable query, or for a limit outside 1-100. A Cloudflare challenge in place of the table gives "unavailable". A missing, empty, or partial PSIC table gives "indeterminate". Neither failure is cached, and the real error sits in caveats.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Maximum number of matches to return (1-100). |
| query | string | yes | Digits for a code-prefix match, or text for a whole-word match against the description, case-insensitive. 1 to 100 printable characters. |
Structured output declared, but exposes no named fields.
No examples provided.
summarize_infra_spending Summarize infrastructure spending ~271
Aggregate infrastructure procurement statistics over the latest PhilGEPS window. This tool aggregates the same infra-keyword-matched notice window search_infra_projects reads (cached 6h). rules_evaluated names which breakdowns ran, today by_category and by_region. rules_not_computable names by_funding_source, retired to an always-empty dict because PhilGEPS notices carry no funding source field. sample_size and sufficient_for_per_capita flag whether the window, today under the 500-notice threshold, is large enough for a per-100k rate. Examples: summarize_infra_spending() summarize_infra_spending(region="ncr", year=2025) On failure: data_status "unavailable", upstream_error true, totals zero and by_category/by_region/top_agencies empty, with the real PhilGEPS error in caveats. No validation_error path exists.
| Name | Type | Req | Description |
|---|---|---|---|
| funding_source | – | – | Reserved for future DPWH integration; PhilGEPS notices do not expose funding source, so this filter is a no-op today. |
| region | – | – | PH region filter (partial match). |
| year | – | – | Filter publish date to this calendar year. Drops an undated record and notes the dropped count in caveats. |
Structured output declared, but exposes no named fields.
No examples provided.
What is the PH Civic Data MCP server?
PH Civic Data is an MCP server listed in the public MCP registry as io.github.xmpuspus/ph-civic-data-mcp. PH civic data as MCP tools: the full PSA OpenSTAT catalog, hazards, procurement. 41 tools. This page covers its PyPI package (ph-civic-data-mcp).
Is the PH Civic Data MCP server safe to use?
PH Civic Data scores 70 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 20 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the PH Civic Data MCP server expose?
PH Civic Data exposes 41 tools: get_data_freshness, get_latest_earthquakes, get_earthquake_bulletin, get_volcano_status, get_weather_forecast, and 36 more. Their descriptions and schemas cost roughly 12,026 tokens of context every time the server is loaded.
Is the PH Civic Data MCP server still maintained?
PH Civic Data is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the PH Civic Data MCP server under?
PH Civic Data declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.