solar_mcp
solar-plan-mcp
Agente que responde a una pregunta doméstica: ¿podré cubrir mañana este conjunto de consumidores con mi propia generación, y si no — qué traslado?
Tejado con paneles, batería, inversor, calendario de cortes conocido. El agente toma la previsión meteorológica de un servidor MCP ya preparado, calcula la producción esperada por horas en su propio servidor MCP, comprueba el plan contra las reglas físicas y, si no lo supera, traslada las cargas flexibles y demuestra con números que ha mejorado.
Dos conexiones MCP:
Servidor | Rol | |
Listo |
| previsión: tipo de cielo y temperatura cada 3 horas |
Propio |
| 4 herramientas sustantivas del dominio + análisis del texto de la previsión |
Documentación: contratos de las herramientas · razón de diseño · guion de demostración
Qué se necesita
Para qué | Nota | |
Python 3.13 | agente y servidor propio | no se necesitan permisos de administrador |
Go 1.24+ | solo para compilar el servidor meteorológico | el proyecto no publica binarios listos; |
Clave de OpenWeather | servidor meteorológico | gratuita, openweathermap.org/api; tarda hasta varias horas en activarse |
CLI | solo el agente; el servidor propio y sus pruebas no lo necesitan | Claude Agent SDK lanza este CLI como proceso hijo — ver Acceso al modelo |
Node + npx | opcional — MCP Inspector |
|
El conjunto de datos PVGIS ya está en el repositorio (data/pvgis_kyiv_5kwp.csv, 1,1 MB), por lo que el servidor propio funciona sin red. No hay que descargar nada.
Related MCP server: KinSwitch
Instalación
Windows, y no es cosmético: todos los comandos son en PowerShell, porque && en PowerShell 5.1 no es un operador en absoluto. En adelante, siempre .venv\Scripts\python.exe.
Primero dos variables de codificación, y son distintas. PYTHONUTF8=1 le dice a Python que escriba en UTF-8; [Console]::OutputEncoding le dice a PowerShell que también lo lea. Sin la segunda, la salida en ucraniano se convierte en ╨▓╨╗╨░╤ü╨╜╨╕╨╣ — medido, y precisamente en la tubería (| Tee-Object, | Select-String), porque allí PowerShell decodifica los bytes con la página de códigos de la consola. Hay que configurarlas en cada ventana nueva, y antes de la instalación, no después:
[Console]::OutputEncoding = [Text.Encoding]::UTF8
$env:PYTHONUTF8 = "1"git clone https://github.com/prasolantoncp-bot/solar-plan-mcp.git
cd solar-plan-mcp
python -m venv .venv # або: uv venv .venv
.venv\Scripts\python.exe -m pip install -r requirements.txtSe necesita Python 3.13 — exactamente el que responde a python --version, porque venv hereda la versión del intérprete con el que se creó.
Por qué las versiones están fijadas. La demostración debe ser reproducible, no «funcionar en algún sitio». mcp==2.0.0 ya es MCPServer en lugar de FastMCP, y el código para 1.x no funcionará aquí; claude-agent-sdk==0.2.144 — en esa versión están verificados tools y el formato del mensaje init del que el agente imprime ambas conexiones; tzdata — porque Windows no tiene una base de datos de zonas horarias del sistema, y sin Europe/Kyiv no habrá ninguna hora local. El propio requirements.txt se mantiene en ASCII a propósito: pip lo lee con la codificación de la configuración regional, y una sola letra cirílica en un comentario rompe pip install -r con UnicodeDecodeError en cualquier máquina donde la configuración regional no sea UTF-8. Medido en cp1252 desde un clon limpio — por eso la explicación vive aquí y no en ese archivo.
Compilar el servidor meteorológico
Go se instala en el perfil del usuario, sin administrador y sin cambios en el registro:
# 1. портативний Go у профіль (один раз). curl.exe є у Windows 10 1803+
curl.exe -Lo go.zip https://go.dev/dl/go1.27.0.windows-amd64.zip
Expand-Archive go.zip -DestinationPath "$env:LOCALAPPDATA\Programs"
# 2. клон і збірка. GOROOT і PATH живуть лише в цьому вікні — так і треба
$env:GOROOT = "$env:LOCALAPPDATA\Programs\go"
$env:PATH = "$env:GOROOT\bin;$env:PATH"
New-Item -ItemType Directory -Force vendor | Out-Null
cd vendor
git clone https://github.com/mschneider82/mcp-openweather.git
cd mcp-openweather
git checkout e032683574a0723591445462ef7104d360ad0889
go build -o mcp-weather.exe .
cd ..\..El agente busca el binario listo en la ruta vendor\mcp-openweather\mcp-weather.exe. Si lo tienes en otro sitio — no lo muevas, sino indica la variable: $env:WEATHER_MCP_BINARY = "…\mcp-weather.exe" (ver env.example). El agente comprueba la existencia del archivo antes de iniciar la sesión y se niega con una frase, no con un traceback desde dentro del SDK.
vendor/ está en .gitignore: la historia git ajena y 13 MB de binario en este repositorio no tienen nada que ver. El commit está fijado — precisamente sobre él está escrita la documentación del contrato.
Si el curso fija otro commit de
mcp-openweather— toma ese y anótalo aquí; la descripción del contrato endocs/TOOLS.mdse escribió a partir demain.goene032683.
Clave
Los secretos no entran en el repositorio: .env y .env.* están en .gitignore, y la plantilla está en env.example sin ningún valor.
La demostración necesita tres terminales, y $env: solo vive en uno, por lo que conviene configurar la clave a nivel de usuario — no se necesitan permisos de administrador para ello:
# так ключ не потрапляє ні в скролбек, ні в історію PSReadLine
$s = Read-Host "OWM_API_KEY" -AsSecureString
[Environment]::SetEnvironmentVariable("OWM_API_KEY",
[Runtime.InteropServices.Marshal]::PtrToStringBSTR(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($s)), "User")El nuevo valor lo verán solo las terminales nuevas. Comprobación de que ha llegado, sin revelar la clave: .venv/Scripts/python.exe -c "import os; print(len(os.environ.get('OWM_API_KEY','')))" — debe dar 32. En cámara no ejecutar dir env:: imprime la clave.
La forma de sesión única $env:OWM_API_KEY = "…" también funciona, pero tiene aquí un único uso correcto — borrar la clave en una ventana aparte para el escenario de fallo: $env:OWM_API_KEY = "".
La clave se lee solo del entorno — ni en el código ni en .mcp.json.example está; allí hay una sustitución ${OWM_API_KEY}. El archivo .env nadie lo lee: en el código solo hay os.environ.get, así que copiar env.example a .env es una acción vacía.
Acceso al modelo
El servidor propio y los 57 tests funcionan sin ninguna credencial de Anthropic — son cosas distintas y no conviene confundirlas. El modelo lo necesita exactamente un archivo, agent/run.py.
Claude Agent SDK no se comunica con la API por sí mismo: lanza el CLI claude como proceso hijo, y es ese CLI el que busca la autorización. Por tanto se necesitan dos cosas:
claudeenPATH. Comprobación:(Get-Command claude).Source. Instalación — según la instrucción oficial; en este proyecto está instalado mediante WinGet y se encuentra en%LOCALAPPDATA%\Microsoft\WinGet\Links\claude.exe.Autorización — una de dos vías, y el CLI toma la que encuentre:
claude login— inicio de sesión interactivo; el CLI guarda el token en~/.claude/.credentials.json. Precisamente esta vía se ha usado aquí: en el entorno del proceso no hay ninguna variableANTHROPIC_*, pero el archivo de credenciales existe. La ejecución registrada del 25 de agosto de 2026 transcurrió así.ANTHROPIC_API_KEYen el entorno — clave de console.anthropic.com. Se configura igual queOWM_API_KEYarriba, y tampoco entra en el repositorio.
Lo que está fijado en el código: el modelo claude-opus-5 (agent/run.py) y claude-agent-sdk==0.2.144 (requirements.txt). Si tienes otro acceso y este id de modelo no se resuelve — sustitúyelo en run.py por uno disponible y anota aquí cuál; el resto de la ejecución no depende del id.
Este código no lee ninguna credencial ni la transmite a ningún sitio: agent/run.py no accede ni a ANTHROPIC_API_KEY ni al archivo de credenciales — de eso se encarga el CLI. En el repositorio no hay secretos, y env.example está vacío.
Límites de la API externa
El plan gratuito de OpenWeather da 60 llamadas por minuto (documentación). Una ejecución del agente hace una llamada a la herramienta weather; dentro, el servidor meteorológico la convierte en dos peticiones HTTP (tiempo actual + previsión a 5 días). Es decir, hasta el techo hay tres órdenes de margen incluso con ensayos continuos.
En el código no hay ningún bucle de sondeo, reintento ante error ni actualización en segundo plano: el tiempo se consulta exactamente cuando el modelo llama a la herramienta. El servidor propio no sale a la red en absoluto — su conjunto de datos está en data/, por lo que cualquier número de ejecuciones de estimate_pv_generation, validate_energy_plan y el resto no genera ninguna petición externa.
Ejecución: dos procesos independientes
El servidor propio se levanta por separado del agente y no sabe nada de él.
Terminal 1 — servidor MCP propio:
$env:PYTHONUTF8 = "1"
.venv\Scripts\python.exe -m solar_mcp --transport streamable-http --port 8931Terminal 2 — agente:
[Console]::OutputEncoding = [Text.Encoding]::UTF8
$env:PYTHONUTF8 = "1"
.venv\Scripts\python.exe agent\run.pySin --date, el agente planifica la jornada de mañana: la pregunta del producto es precisamente sobre mañana, y la previsión de OpenWeather solo cubre ahora … +5 días, así que la jornada de hoy ya está a medias fuera del horizonte. Una fecha fuera de esa ventana dará NO_FORECAST_FOR_DATE, no ceros silenciosos.
El agente levanta el servidor meteorológico él mismo, por stdio — así está configurada la conexión. El servidor propio también se puede ejecutar por stdio (python -m solar_mcp, es el valor por defecto) — así lo esperan clientes como Claude Code, y es precisamente esa variante la descrita en .mcp.json.example. Para la demostración es mejor HTTP: entonces se ve que el servidor es realmente un proceso aparte.
Indicadores útiles del agente:
--plan boiler:18:2 --plan aircon:18:3 # свій план замість дефолтного (можна кілька разів)
--date YYYY-MM-DD # інша доба; вт/чт/пт — без відключень, сб/нд — вечірнє вікно
--objective maximize_outage_reserve # інша цільова функція
--city Lviv # інше місто
--width 120 # скільки символів сліду друкувати--date solo acepta una jornada dentro del horizonte de la previsión — mañana … hoy + 5. Una fecha fuera de él dará NO_FORECAST_FOR_DATE, y la presencia de una ventana de corte en el calendario no lo salva: el calendario está en el repositorio y conoce cualquier fecha, pero la previsión vive cinco días. Comprobar antes de ejecutar: scripts/call_weather.py --city Kyiv --covers YYYY-MM-DD.
Las fechas del calendario de cortes tienen un patrón semanal y procedencia — ver data/outage_windows.json: las ventanas del 22 al 26 de agosto están tomadas del calendario público, y a partir de ahí el mismo patrón se repite hacia adelante para que la demostración no dependa de la fecha de grabación.
Comprobación de que todo está vivo
# 4 інструменти домену + 1 допоміжний, зі схемами входу І виходу
.venv\Scripts\python.exe scripts\inspect_tools.py
.venv\Scripts\python.exe scripts\inspect_tools.py --url http://127.0.0.1:8931/mcp --schemas
# сервер погоди напряму: сирий текст і те, що з нього вийшло
.venv\Scripts\python.exe scripts\call_weather.py --city Kyiv
# 57 тестів: фізика, правила домену, планувальник, контракт через MCP-клієнта
$env:PYTHONUTF8 = "1"; $env:PYTHONPATH = "."
.venv\Scripts\python.exe -m pytest tests\ -qLos tests no necesitan ni red, ni clave de OpenWeather, ni acceso al modelo: el conjunto de datos está en el repositorio, y las respuestas del servidor ajeno están grabadas en tests/fixtures/.
Qué hay dónde
solar_mcp/ власний MCP-сервер (окремий процес)
server.py інструменти й ресурс — увесь контракт
models.py схеми входу й виходу (Pydantic → справжні inputSchema/outputSchema)
errors.py закритий перелік кодів; помилка ≠ порожній результат
pv.py огинаюча ясного неба × прозорість × температурний дерейтинг
rules.py симуляція балансу, порушення, планувальник, порівняння
forecast.py розбір плоского тексту сервера погоди
dataset.py store.py читання датасету; реєстр виданих оцінок
agent/run.py Claude Agent SDK, дві MCP-конекції, слід викликів
scripts/ inspect_tools.py — контракт; call_weather.py — чужий сервер напряму
data/ датасет + fetch_pvgis.py (провенанс)
tests/ 57 тестів; у fixtures/ — три записані відповіді сервера погоди й одна синтетична
docs/ TOOLS.md · DESIGN.md · DEMO.mdDos de estos directorios tienen su propio README, y son precisamente los que se buscan bajo «fuente de datos» y «fixtures»: data/README.md — de dónde se ha tomado la fila de PVGIS, la tarifa y el calendario de cortes; tests/fixtures/README.md — qué exactamente se ha grabado del servidor ajeno, cuándo y con qué.
Una observación sobre la que se sostiene la mitad del diseño
El servidor meteorológico no distingue una avería de una respuesta vacía. Sin clave devuelve is_error: false y un texto con ceros y el nombre de la ciudad vacío — grabado literalmente en tests/fixtures/owm_no_api_key.txt, aunque su README promete «FATAL: OWM_API_KEY environment variable not set».
Por eso el servidor propio está hecho al revés: lista cerrada de códigos de error, field que señala el campo culpable, y por separado — reason allí donde el vacío es legítimo (noche, ausencia de infracciones). Detalles: DESIGN.md, TOOLS.md.
This server cannot be deployed
Maintenance
Related MCP Connectors
Home energy for AI assistants: live Power flow, Energy history, solar forecast, and device control.
Solar, weatherization, EV charging, battery and heat-pump decision tools for AI agents.
EU power dispatch for wallet-enabled compute, DePIN, battery and trading agents.
Solar power estimates from the electricity bill, and the service area check, for São Paulo, Brazil.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI-powered analysis and prediction of household energy consumption through machine learning models, providing historical consumption breakdowns, price queries from Spanish electricity markets, and personalized energy optimization recommendations.-
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to manage household schedules by checking availability, proposing minimal changes, and requiring explicit human approval before executing any action.MIT
- AlicenseNot gradedqualityBmaintenanceEnables conversational home power management by providing real-time solar, battery, and grid status, plus forecasts to answer questions like whether you can run an appliance. It supports Victron and Growatt inverters, remembers household appliances and grid events, and renders an interactive dashboard card in MCP-compatible clients.5 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to size hybrid renewable energy systems by simulating candidate designs hour-by-hour for a full year, filtering out constraint violations, and ranking remaining options by net present cost and related techno-economic metrics.27 PyPIApache 2.0