Everything here is static files over HTTPS with range requests — no API key, no rate limit, no login. An agent can read the catalogue, query 272,354 scored line sections without downloading the file, and build its own exports.
One document describing every dataset: URL, format, row count, byte size, SHA-256, and a description of every column. It is generated by the build from the files that actually shipped, so it cannot drift from reality.
# the single entry point
curl -s https://sce.weleber.net/data/out/dist/catalog.json | jq '.datasets[].name'
llms.txt is the same thing in about forty lines of prose, including the rules on how these numbers may and may not be characterised.
The GeoParquet files are HTTP range-readable. DuckDB will pull only the row
groups and columns a query touches, so a GROUP BY over 272,354
sections costs a few hundred kilobytes rather than the 46 MB file.
All EPSG:3310 (NAD83 / California Albers). Lengths, areas and distances were computed in that projection — reproject at the point of display, not before.
| Dataset | Rows | Grain | Formats |
|---|---|---|---|
| line_section_index | 272,354 | One scored SCE ICA line section. The product. | parquet · csv |
| circuit_index | 3,005 | Distribution circuit rollup. | parquet · csv |
| substation_index | 574 | Substation rollup. | parquet · csv |
| service_territory | 1 | The clip boundary every count sits inside. | parquet · geojson |
| cost cube | 8 levels | Meters per (geography × install class), plus the polygon scalars the cost model multiplies against. Census levels are generated from one pass over the fact table, so they cannot disagree. | tract · bg · county · circuit · substation · place |
| cost_model | 41 controls | Every rate, its range, and its provenance label. | json |
| parcels | 4,133,590 | Every assessor parcel inside net SCE territory, with its estimated service points, install class, dwelling units and build year. The finest grain published. Citation required — name the county as author. | pmtiles · report |
| vector tiles | 4 archives | PMTiles, range-readable. Parcels, the cube at six geographies, the difficulty index, and the basemap. | parcels · cube · index · basemap |
DuckDB, over HTTPS. Nothing is installed on our side and nothing is cached on yours.
INSTALL httpfs; LOAD httpfs;
-- the ten circuits carrying the most meters, and how hard they are
SELECT circuit_name, substation_name,
meters_est, route_km, difficulty_index, cost_multiplier, confidence
FROM 'https://sce.weleber.net/data/out/dist/circuit_index.parquet'
ORDER BY meters_est DESC LIMIT 10;
-- where the multifamily access problem actually is
SELECT county_fips,
sum(meters_est) AS meters,
sum(meters_est * mf_share) / sum(meters_est) AS mf_share
FROM 'https://sce.weleber.net/data/out/dist/line_section_index.parquet'
GROUP BY 1 ORDER BY meters DESC;
-- hardest substations, restricted to sections where the index is reliable
SELECT substation_name, sum(meters_est) AS meters,
avg(difficulty_index) AS idx
FROM 'https://sce.weleber.net/data/out/dist/line_section_index.parquet'
WHERE index_reliable
GROUP BY 1 HAVING meters > 5000 ORDER BY idx DESC LIMIT 15;
Python, if you want geometry:
import geopandas as gpd
gdf = gpd.read_parquet("https://sce.weleber.net/data/out/dist/circuit_index.parquet")
print(gdf.crs) # EPSG:3310
hard = gdf.nlargest(20, "difficulty_index")
hard.to_file("hardest_circuits.gpkg", driver="GPKG")
A read-only Model Context Protocol server, so Claude Code connects to the dataset natively instead of being handed URLs. It exposes a fixed set of tools over the same files described above — there is no write path and no arbitrary filesystem access.
# Claude Code
claude mcp add --transport http sce https://sce.weleber.net/mcp
# or, in .mcp.json
{ "mcpServers": { "sce": {
"type": "http",
"url": "https://sce.weleber.net/mcp" } } }
Tools it exposes:
| Tool | Does |
|---|---|
| catalog | The full catalogue — datasets, columns, provenance, the rules below. |
| describe | Column names, types and descriptions for one dataset. |
| query | Read-only SQL over the published tables. Row-capped and time-limited. |
| headline | The build's top-line figures and the measured/inferred/modelled mix. |
| cost_model | Every control, its range and its provenance label. |
Status: checking… · GET the endpoint for a machine-readable description of it.
For OpenAI, remote MCP goes through the Responses API tool type rather than the browsing tool:
{
"model": "gpt-5",
"tools": [{
"type": "mcp",
"server_label": "sce",
"server_url": "https://sce.weleber.net/mcp",
"require_approval": "never"
}],
"input": "Which SCE substations carry the most meters, and how hard are they?"
}
In the ChatGPT app it has to be added as
a connector; the built-in web tool will not do it. And if all you have is HTTP,
nothing here needs MCP at all — every tool above is backed by the static
files in the table, and catalog.json
is the same content the catalog tool returns.