DeepPVMapper
Open registry of 1.14M+ rooftop-solar detections across France, queryable by natural language.
Should I use this
Quality & Safety
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"deeppvmapper": {
"url": "https://zelhliylrlktnasircwp.supabase.co/functions/v1/mcp/mcp"
}
}
}Remote endpoints
https://zelhliylrlktnasircwp.supabase.co/functions/v1/mcp/mcpstreamable-httpWhat it can do
Tool inventory
Tools (8)
🟢get_data_quality_reference
Return the DeepPVMapper/OpenPVMapper registry's documented data-quality characteristics: estimated detection recall, which fields are model-derived estimates vs. structural/observed fields, the source-encoding table, the recommended confidence threshold, confidence signals, and licensing/liability terms. Call this before advising how much to trust a result for a specific use case (e.g. exploratory research vs. a commercial or regulatory decision) — pair it with the quality_summary attached to search_detections / aggregate_detection_capacity results, which reflects the specific query rather than the registry as a whole.
Input Schema
{
"type": "object",
"properties": {},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟢get_department_capacity_stats(dpt, top_n)
Get installed rooftop-PV capacity (total kWp) and system counts for one or all French départements, from the DeepPVMapper/OpenPVMapper registry. This is a fixed, pre-computed department-wide aggregate with no other filters — use aggregate_detection_capacity instead if you need a filtered subset (e.g. only cross-validated detections). Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
Input Schema
{
"type": "object",
"properties": {
"dpt": {
"description": "French département code, e.g. \"33\" for Gironde. Omit for all départements.",
"type": "string"
},
"top_n": {
"description": "If set and dpt is omitted, return only the top N départements by installed capacity.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 96
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟢get_department_yearly_stats(dpt)
Get yearly system counts and capacity by département, based on first-seen imagery year. Useful for tracking apparent PV deployment growth over time. Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
Input Schema
{
"type": "object",
"properties": {
"dpt": {
"description": "French département code, e.g. \"33\". Omit for all départements.",
"type": "string"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟢search_detections(dpt, insee, min_kwp, max_kwp, min_vintages, ...)
Search individual rooftop-PV detections by département, commune (INSEE code), estimated capacity range, and/or cross-validation confidence (min_vintages, cross_validated). Returns a bounded list of detection records plus a quality_summary for the returned sample (use get_detections_in_bbox instead for map/spatial queries with geometry). Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
Input Schema
{
"type": "object",
"properties": {
"dpt": {
"description": "French département code, e.g. \"33\".",
"type": "string"
},
"insee": {
"description": "INSEE commune code.",
"type": "string"
},
"min_kwp": {
"description": "Minimum estimated installed capacity, in kWp.",
"type": "number"
},
"max_kwp": {
"description": "Maximum estimated installed capacity, in kWp.",
"type": "number"
},
"min_vintages": {
"description": "Minimum number of distinct imagery vintages (years) the installation was independently detected in. Use 2+ as a persistence/confidence signal, since a one-off detection in a single vintage is more likely to be a transient artifact.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"cross_validated": {
"description": "If true, only include detections confirmed by at least two independent sources (e.g. the automated DeepPVMapper pipeline plus OpenStreetMap or the FRPV reference dataset), not just a single pipeline. This is a stronger confidence signal than min_vintages.",
"type": "boolean"
},
"quality_filter": {
"default": true,
"description": "If true (default), only include detections with frpv_proba >= 0.1, the threshold recommended in the data contract for a good precision/recall trade-off.",
"type": "boolean"
},
"limit": {
"default": 20,
"description": "Maximum number of records to return (max 200).",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 200
}
},
"required": [
"quality_filter",
"limit"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟡aggregate_detection_capacity(dpt, insee, min_kwp, max_kwp, min_vintages, ...)
Compute the total estimated installed capacity (kWp) and count of detections matching a set of filters — département, commune, capacity range, and cross-validation across sources (cross_validated) or imagery vintages (min_vintages) — plus a quality_summary for the summed sample. Unlike get_department_capacity_stats, which is a fixed pre-computed département-wide aggregate with no other filters, this tool sums a live filtered subset, up to max_rows detections. Example: "installed capacity in Gironde confirmed by at least two sources" -> dpt="33", cross_validated=true. Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
Input Schema
{
"type": "object",
"properties": {
"dpt": {
"description": "French département code, e.g. \"33\".",
"type": "string"
},
"insee": {
"description": "INSEE commune code.",
"type": "string"
},
"min_kwp": {
"description": "Minimum estimated installed capacity, in kWp.",
"type": "number"
},
"max_kwp": {
"description": "Maximum estimated installed capacity, in kWp.",
"type": "number"
},
"min_vintages": {
"description": "Minimum number of distinct imagery vintages (years) the installation was independently detected in. Use 2+ as a persistence/confidence signal, since a one-off detection in a single vintage is more likely to be a transient artifact.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"cross_validated": {
"description": "If true, only include detections confirmed by at least two independent sources (e.g. the automated DeepPVMapper pipeline plus OpenStreetMap or the FRPV reference dataset), not just a single pipeline. This is a stronger confidence signal than min_vintages.",
"type": "boolean"
},
"quality_filter": {
"default": true,
"description": "If true (default), only include detections with frpv_proba >= 0.1, the threshold recommended in the data contract for a good precision/recall trade-off.",
"type": "boolean"
},
"max_rows": {
"default": 5000,
"description": "Cap on the number of matching detection rows fetched to compute the capacity sum. If the true match count exceeds this, total_kwp is a partial lower bound and `truncated` is true — increase max_rows or narrow the filters (e.g. add dpt or insee) for an exact total.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 20000
}
},
"required": [
"quality_filter",
"max_rows"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟢get_detections_in_bbox(min_lon, min_lat, max_lon, max_lat, max_count)
Get rooftop-PV detections within a geographic bounding box (WGS84 lon/lat), including footprint geometry. Intended for map-style spatial queries over a small area. Data quality note: this is a detection dataset, not an exhaustive inventory (estimated recall ~0.6). A missing detection does not mean no PV installation exists there. kwp, surface, tilt and azimuth are model estimates, not surveyed values. Call get_data_quality_reference for the full picture before assessing fitness for a specific use case.
Input Schema
{
"type": "object",
"properties": {
"min_lon": {
"type": "number"
},
"min_lat": {
"type": "number"
},
"max_lon": {
"type": "number"
},
"max_lat": {
"type": "number"
},
"max_count": {
"default": 100,
"description": "Maximum number of detections to return (max 500 here; the underlying API defaults to 2000, capped lower to keep responses manageable for an LLM).",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 500
}
},
"required": [
"min_lon",
"min_lat",
"max_lon",
"max_lat",
"max_count"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟡get_community_activity(recent_limit)
Get a snapshot of ongoing community contribution activity on the map: how many corrections are currently pending moderation, their breakdown by action type (add / modify / delete), and the most recent submissions (timestamp, action, target). Submitted free-text comments are intentionally excluded from this tool. This reflects unmoderated, unverified user activity, not the registry itself — do not present it as confirmed detection data.
Input Schema
{
"type": "object",
"properties": {
"recent_limit": {
"default": 15,
"description": "How many of the most recent pending contributions to list.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 50
}
},
"required": [
"recent_limit"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟢get_community_activity_in_area(dpt, min_lon, min_lat, max_lon, max_lat, ...)
Find pending, unmoderated community contributions relevant to a specific area, to answer "has anyone flagged anything here that is not in the registry yet?" Two independent filters: dpt finds pending edits/deletions (action=modify/delete) targeting existing detections in that département; a full bounding box (min_lon/min_lat/max_lon/max_lat) finds pending new additions (action=add) whose proposed footprint centroid falls inside it. Combine with get_department_capacity_stats / search_detections / get_detections_in_bbox for the confirmed registry picture, and present this separately and clearly as unverified, pending community input — not confirmed detection data. Free-text comments are never included.
Input Schema
{
"type": "object",
"properties": {
"dpt": {
"description": "Filter pending edits/deletions of EXISTING detections (action=modify or delete) to this département. Does not apply to proposed new additions (action=add), which have no département recorded on the pending item itself — use the bbox parameters for those.",
"type": "string"
},
"min_lon": {
"type": "number"
},
"min_lat": {
"type": "number"
},
"max_lon": {
"type": "number"
},
"max_lat": {
"type": "number"
},
"scan_limit": {
"default": 500,
"description": "How many recent proposed additions (action=add) to scan for a bbox match. Only relevant when all four bbox parameters are given — there is no server-side spatial index on pending items, so matching is done by fetching this many of the most recent ones and checking their centroid against the box.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 2000
},
"recent_limit": {
"default": 30,
"description": "Maximum number of matching items to return per category.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 100
}
},
"required": [
"scan_limit",
"recent_limit"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}Community
Evidence