Solar Data
PYPI · SOLAR-DATA-MCP · SCANNED SEP 21
US open solar data for agents: PVWatts production, tariffs & ROI, market data, forecasts. 18 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 Security100
- No malware found by supply-chain analysis.Pass
- 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
- 0 of 35 dependencies flagged as unhealthy. View diagnostics → Pass
Provenance & Transparency35
- 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
- License check failed: no license is declared. See how to fix → Fail
- Actively maintained (last published 76 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability50
- 14% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Partial
- AI-judged instruction clarity (good).Pass
- Tool/resource definitions use about 3437 tokens (~79/item across 43 items; 18 tools + 25 resources), lean.Pass
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management87
- Stability observed for 26 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage71
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 0% of tool parameters carry a description.Fail
- 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 18 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 20 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
How do I install the Solar Data MCP server?
Solar Data runs locally as a PyPI package, launched with uvx solar-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 · solar-data-mcp
claude mcp add hoodsy-solar-data-mcp -- uvx solar-data-mcp
{
"mcpServers": {
"hoodsy-solar-data-mcp": {
"command": "uvx",
"args": [
"solar-data-mcp"
]
}
}
} {
"servers": {
"hoodsy-solar-data-mcp": {
"command": "uvx",
"args": [
"solar-data-mcp"
]
}
}
} codex mcp add hoodsy-solar-data-mcp -- uvx solar-data-mcp
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"hoodsy-solar-data-mcp": {
"type": "local",
"command": [
"uvx",
"solar-data-mcp"
],
"enabled": true
}
}
} openclaw mcp add hoodsy-solar-data-mcp --command uvx --arg solar-data-mcp
mcp_servers:
hoodsy-solar-data-mcp:
command: "uvx"
args: ["solar-data-mcp"] {
"McpServers": {
"hoodsy-solar-data-mcp": {
"Transport": "stdio",
"Command": "uvx",
"Arguments": [
"solar-data-mcp"
]
}
}
} assistant mcp add hoodsy-solar-data-mcp -t stdio -c uvx -a solar-data-mcp
{
"mcpServers": {
"hoodsy-solar-data-mcp": {
"command": "uvx",
"args": [
"solar-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.
- 21 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.
- 19 Sept 26 −3
- Stability: pass → 0.80 functional
- 18 Sept 26 +16
- Malware scan: unverified → pass ▲ security
- Stability: 0.97 → pass security
- 17 Sept 26 −15
- Malware scan: pass → unverified ▼ security
- 16 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.
- 15 Sept 26 +15
- Malware scan: unverified → pass ▲ security
- 14 Sept 26 −14
- Malware scan: pass → unverified ▼ security
- 12 Sept 26 +12
- Malware scan: unverified → pass ▲ security
- Stability: pass → 0.80 functional
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 21 Sept 2026 · Analysed pypi/solar-data-mcp@0.1.1
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 35 packages
| Packages resolved | 35 |
|---|---|
| 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 →
compare_forecast_to_model ~179
Is the forecast unusual? Quartz forecast vs PVWatts typical-year rate. Use this for "is today a good solar day here". Returns the forecast total, the TMY-typical total for the same horizon, their ratio, and a plain-language verdict. Horizons in multiples of 24h compare cleanest (see assumptions for the uniform-spread simplification). Example: compare_forecast_to_model(lat=39.74, lon=-105.18, capacity_kw=6, horizon_hours=24) -> ratio_pct ~120 on a clear day. Units: energies in kWh; ratio in percent.
| Name | Type | Req | Description |
|---|---|---|---|
| azimuth_deg | – | – | – |
| capacity_kw | number | yes | – |
| horizon_hours | – | – | – |
| lat | number | yes | – |
| lon | number | yes | – |
| tilt_deg | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
compare_orientations ~247
Rank tilt x azimuth combinations by annual production for one system. Use this for "how bad is my north-facing roof really" or "is 10 vs 25 degrees of tilt worth it". Use estimate_production for a single known orientation. The sweep is capped at 25 combinations per call; unset tilts/azimuths sweep a default 5x5 grid. Example: compare_orientations(lat=33.42, lon=-111.83, system_capacity_kw=8, tilts=[10, 25], azimuths=[180]) -> ranked table with pct_delta_vs_best. Units: tilt_deg/azimuth_deg in degrees (azimuth 90=E, 180=S, 270=W); ac_annual_kwh in kWh AC/year; pct_delta_vs_best in percent (0 = best).
| Name | Type | Req | Description |
|---|---|---|---|
| array_type | – | – | – |
| azimuths | – | – | – |
| dc_ac_ratio | – | – | – |
| lat | number | yes | – |
| lon | number | yes | – |
| losses_pct | – | – | – |
| module_type | – | – | – |
| system_capacity_kw | number | yes | – |
| tilts | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
estimate_production ~313
Estimate annual and monthly AC production for a PV system (PVWatts v8). Use this when the user describes a specific system at a location. Use get_solar_resource for raw irradiance without a system, compare_orientations to sweep tilt/azimuth options, size_system_for_target to go from a kWh goal to a system size. Unset parameters default to: tilt = site latitude, azimuth 180 (south), array_type fixed_roof, module_type standard, losses 14%, dc_ac_ratio 1.2 — each applied default is listed in the result's assumptions. Example: estimate_production(lat=33.42, lon=-111.83, system_capacity_kw=8, tilt_deg=25) -> ~14,100 kWh/yr for Mesa, AZ. Units: ac_annual_kwh in kWh AC/year; ac_monthly in kWh AC per month; capacity_factor in percent; solrad_annual in kWh/m2/day. tilt_deg and azimuth_deg in degrees (azimuth 180 = south); losses_pct in percent.
| Name | Type | Req | Description |
|---|---|---|---|
| albedo | – | – | – |
| array_type | – | – | – |
| azimuth_deg | – | – | – |
| bifacial | boolean | – | – |
| dc_ac_ratio | – | – | – |
| lat | number | yes | – |
| lon | number | yes | – |
| losses_pct | – | – | – |
| module_type | – | – | – |
| system_capacity_kw | number | yes | – |
| tilt_deg | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
estimate_roi ~292
Screening ROI for a solar system: payback, NPV, IRR, 25-yr cash flow. Use this for "would solar pay off here". It chains PVWatts production, URDB tariffs (EIA state average as fallback — pass state=XX to enable), and the federal ITC into one auditable calculation; audit_trail lists every component's source. It is explicitly NOT a quote (see warnings). Defaults (each stated in assumptions): escalation 2.5%/yr, discount 6%, install year = current year; cost falls back to the Tracking the Sun state median (needs state=XX and a synced snapshot) or a cited national median. Example: estimate_roi(lat=39.74, lon=-105.18, system_capacity_kw=6, state="CO") -> payback_years ~9, npv_usd, irr_pct, cash_flow table. Units: money in USD; rates in USD/kWh; payback in years; IRR in percent.
| Name | Type | Req | Description |
|---|---|---|---|
| annual_consumption_kwh | – | – | – |
| cost_per_watt | – | – | – |
| discount_rate_pct | – | – | – |
| escalation_pct | – | – | – |
| install_cost_usd | – | – | – |
| install_year | – | – | – |
| lat | number | yes | – |
| lon | number | yes | – |
| state | – | – | – |
| system_capacity_kw | number | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
find_utility_scale_projects ~146
Ground-mounted utility-scale PV facilities (USPVDB, EIA-860 attributes). Use this for the large-plant landscape: "biggest solar farms in CO", "capacity near this area". Pass exactly one of state or bbox=[west, south, east, north]. Largest first; limit defaults to 25. Example: find_utility_scale_projects(state="CO", min_capacity_mw=100) -> projects with capacity_mw_ac, year, tracking type, battery flag. Units: capacities in MW AC/DC; coordinates in degrees.
| Name | Type | Req | Description |
|---|---|---|---|
| bbox | – | – | – |
| limit | – | – | – |
| min_capacity_mw | – | – | – |
| state | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
forecast_generation ~189
Hourly generation forecast for the next hours (Quartz open model). Use this for "how much will this system produce today/tomorrow". Use nrel-solar's estimate_production for typical-year expectations, and compare_forecast_to_model to judge whether the forecast is unusual. Defaults: tilt = site latitude, azimuth 180 (south), horizon 48h — each stated in assumptions. Max horizon 48 hours. Example: forecast_generation(lat=39.74, lon=-105.18, capacity_kw=6) -> hourly kW series, total_kwh, peak_kw. Units: power in kW AC; energy in kWh; times ISO 8601 UTC.
| Name | Type | Req | Description |
|---|---|---|---|
| azimuth_deg | – | – | – |
| capacity_kw | number | yes | – |
| horizon_hours | – | – | – |
| lat | number | yes | – |
| lon | number | yes | – |
| tilt_deg | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
get_electricity_prices ~130
State average retail electricity price with a monthly trend (EIA v2). Use this for "what do people pay in Colorado" or rate-escalation context. Use lookup_tariffs for the actual rate schedules a specific address sees. sector defaults to residential; months defaults to a 12-month trend. Example: get_electricity_prices(state="CO") -> latest and average cents/kWh plus the last 12 monthly points. Units: prices in cents/kWh; periods are YYYY-MM.
| Name | Type | Req | Description |
|---|---|---|---|
| months | – | – | – |
| sector | – | – | – |
| state | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
get_incentives ~122
Solar incentives: federal ITC (current law, cited) + state/local programs. Use this to enumerate what reduces system cost. The federal table is always available; state/local programs come from a locally synced DSIRE snapshot (run sync_incentives first — a warning tells you if it's missing). Example: get_incentives(state="CO") -> 30% federal ITC + Colorado programs. Units: none (program terms are text); snapshot vintage is an ISO date.
| Name | Type | Req | Description |
|---|---|---|---|
| install_year | – | – | – |
| state | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
get_permitting_timelines ~105
Median permit, inspection, and interconnection (PTO) days (SolarTRACE). Use this for "how long does solar permitting take in X". Pass exactly one of state (all jurisdictions there) or jurisdiction (name match). Needs a synced SolarTRACE snapshot. Example: get_permitting_timelines(state="CO") -> per-jurisdiction rows plus statewide medians. Units: all durations in days.
| Name | Type | Req | Description |
|---|---|---|---|
| jurisdiction | – | – | – |
| state | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
get_solar_resource ~147
Get annual/monthly solar irradiance (GHI, DNI) for a location (NSRDB). Use this for "how sunny is it there" questions with no specific system. Use estimate_production when a system size is known — it already folds irradiance in. Example: get_solar_resource(lat=39.74, lon=-105.18) -> ghi_annual ~4.8. Units: ghi_*/dni_* in kWh/m2/day; resolved_cell_lat/lon in degrees (center of the 0.1-degree NSRDB cell actually answering the query).
| Name | Type | Req | Description |
|---|---|---|---|
| lat | number | yes | – |
| lon | number | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
identify_ahj ~145
Authority Having Jurisdiction + adopted codes for a point (SunSpec). Use this for "who permits solar at this location and under which code editions". Requires AHJ_REGISTRY_TOKEN (issued by support@sunspec.org); without it the error contains setup instructions. The registry request shape is unverified against the live service — treat results as leads, not filings-grade facts. Example: identify_ahj(lat=39.74, lon=-105.18) -> AHJ name, level, building/electric/fire code editions. Units: none (names and code editions are text).
| Name | Type | Req | Description |
|---|---|---|---|
| lat | number | yes | – |
| lon | number | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
lookup_tariffs ~175
Find retail electric rate schedules serving a point or a utility (URDB). Use this to answer "what does electricity cost on my bill here". Use get_electricity_prices for state-level averages and trends instead of actual filed tariffs. Provide either lat+lon or utility_name (not both); sector defaults to residential (stated in assumptions). Example: lookup_tariffs(lat=39.74, lon=-105.18) -> Xcel (PSCo) residential schedules with $/kWh tiers. Units: energy tier rates in USD/kWh; fixed charges in USD/month. Time-of-use schedules are flagged (is_tou) — tier values shown are an approximation for those.
| Name | Type | Req | Description |
|---|---|---|---|
| lat | – | – | – |
| lon | – | – | – |
| sector | – | – | – |
| utility_name | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
market_snapshot ~120
One-call state market overview: installs, $/W, permitting, big projects. Use this to orient in a state before drilling into the specific tools. Best-effort composite: sections needing an unsynced snapshot are skipped with a warning instead of failing the whole call. Example: market_snapshot(state="CO") -> installed_systems stats, permitting medians, top-5 utility-scale projects, audit_trail. Units: per section — USD/W, days, MW AC; see nested unit entries.
| Name | Type | Req | Description |
|---|---|---|---|
| state | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
query_installed_systems ~141
Aggregate stats from installed-system records: median $/W, sizes, equipment. Use this for "what do systems cost/look like in state X". Returns aggregates only, never row-level records. Needs a synced Tracking the Sun snapshot (the error tells you if it's missing). Example: query_installed_systems(state="CO", year_start=2022) -> median_price_per_watt ~3.2, size quartiles, top module makers. Units: prices in USD/W; sizes in kW DC; counts are counts.
| Name | Type | Req | Description |
|---|---|---|---|
| state | string | yes | – |
| year_end | – | – | – |
| year_start | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
size_system_for_target ~228
Find the system size (kW) that produces a target annual kWh. Use this to size a system from a consumption goal ("my home uses 9,000 kWh/yr"). Use estimate_production when the size is already known. Solves to within 2% using at most 6 PVWatts calls. Unset parameters default as in estimate_production (each default listed in assumptions). Example: size_system_for_target(lat=39.74, lon=-105.18, target_annual_kwh=6000, tilt_deg=25) -> required_kw ~3.6. Units: required_kw in kW DC; achieved_annual_kwh in kWh AC/year; pct_error in percent (achieved vs target).
| Name | Type | Req | Description |
|---|---|---|---|
| array_type | – | – | – |
| azimuth_deg | – | – | – |
| dc_ac_ratio | – | – | – |
| lat | number | yes | – |
| lon | number | yes | – |
| losses_pct | – | – | – |
| module_type | – | – | – |
| target_annual_kwh | number | yes | – |
| tilt_deg | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
sync_incentives ~128
Load a DSIRE program export (CSV path or https URL) into the local store. Use this once (and after DSIRE refreshes) so get_incentives can return state/local programs. This WRITES to the local bulk store — the only state this server keeps. vintage defaults to today's date. Example: sync_incentives(source="/downloads/dsire-programs.csv", vintage="2026-06") -> rows_loaded. Units: rows_loaded is a count; vintage is an ISO date.
| Name | Type | Req | Description |
|---|---|---|---|
| source | string | yes | – |
| vintage | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
sync_solartrace ~107
Load a SolarTRACE dataset export into the local bulk store. Use this before get_permitting_timelines. This WRITES to the local store. Download the dataset from https://maps.nlr.gov/solarTRACE/. Example: sync_solartrace(source="/downloads/solartrace.csv", vintage="2025-H2") -> rows_loaded. Units: rows_loaded is a count; vintage is a date/label.
| Name | Type | Req | Description |
|---|---|---|---|
| source | string | yes | – |
| vintage | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
sync_tracking_the_sun ~145
Load an LBNL Tracking the Sun release into the local bulk store. Use this once per release (files are ~1-2 GB; they stream, never held in memory; pass state=XX to keep only one state). This WRITES to the local store. Download releases from https://emp.lbl.gov/tracking-the-sun. Example: sync_tracking_the_sun(source="/downloads/tts_2024.csv", vintage="2024", state="CO") -> rows_loaded. Units: rows_loaded is a count; vintage is a date/label.
| Name | Type | Req | Description |
|---|---|---|---|
| source | string | yes | – |
| state | – | – | – |
| vintage | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| assumptions | array | – | – |
| data | object | yes | – |
| source | – | yes | – |
| units | object | – | – |
| warnings | array | – | – |
No examples provided.
What is the Solar Data MCP server?
Solar Data is an MCP server listed in the public MCP registry as io.github.hoodsy/solar-data-mcp. US open solar data for agents: PVWatts production, tariffs & ROI, market data, forecasts. 18 tools. This page covers its PyPI package (solar-data-mcp).
Is the Solar Data MCP server safe to use?
Solar Data scores 74 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 21 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 Solar Data MCP server expose?
Solar Data exposes 18 tools: estimate_production, get_solar_resource, compare_orientations, size_system_for_target, lookup_tariffs, and 13 more. Their descriptions and schemas cost roughly 3,059 tokens of context every time the server is loaded.
Is the Solar Data MCP server still maintained?
Solar Data is still listed as active in the MCP registry. We last reached this channel on 21 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.