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 cumple, 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 · escenario de demostración
Qué se necesita
Para qué | Nota | |
Python 3.13 | agente y servidor propio | no se necesitan privilegios 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 los tests 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.
Instalación
git clone <цей-репозиторій>
cd solar-plan-mcp
python -m venv .venv # або: uv venv .venv
.venv\Scripts\python.exe -m pip install -r requirements.txtWindows, y esto no es cosmético: todos los comandos de abajo son en PowerShell, porque && en PowerShell 5.1
no es un operador en absoluto. En adelante, siempre .venv\Scripts\python.exe.
Dos variables de codificación, y son distintas. PYTHONUTF8=1 le dice a Python que escriba UTF-8;
[Console]::OutputEncoding le dice a PowerShell que lo lea igualmente. 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. Por eso, en cada ventana nueva:
[Console]::OutputEncoding = [Text.Encoding]::UTF8
$env:PYTHONUTF8 = "1"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— tómalo 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 una, por lo que la clave conviene
establecerla a nivel de usuario — no se necesitan privilegios 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 ser 32. En cámara no ejecutar dir env:: imprime la clave.
La forma de sesión puntual $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 — no está ni en el código ni en .mcp.json.example;
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 eso se necesitan dos cosas:
claudeenPATH. Comprobación:(Get-Command claude).Source. Instalación — según la instrucción oficial; en este proyecto se instaló con WinGet y está 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 usó aquí: en el entorno del proceso no hay ninguna variableANTHROPIC_*, y el archivo de credenciales existe. La ejecución grabada del 25 de agosto de 2026 pasó así.ANTHROPIC_API_KEYen el entorno — clave de console.anthropic.com. Se establece 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 resuelve — sustitúyelo en run.py por uno disponible y anota aquí
cuál; el resto de la ejecución no depende del id.
Ninguna credencial la lee ni la transmite este código: 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, hay tres órdenes de margen hasta el techo 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 aparte del agente y no sabe nada del agente.
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 esta ventana dará NO_FORECAST_FOR_DATE, no ceros silenciosos.
El agente levanta él mismo el servidor meteorológico, por stdio — así está configurada la conexión. El servidor propio
también se puede lanzar 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 existencia de una ventana de corte en el calendario no
lo salva: el calendario está en el repositorio y conoce cualquier fecha, mientras que 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 luego 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 tomó la fila de PVGIS, la tarifa y el calendario
de cortes; tests/fixtures/README.md — qué exactamente se grabó 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 un fallo de una respuesta vacía. Sin clave devuelve
is_error: false y un texto con ceros y el nombre de 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 se ha hecho al revés: lista cerrada de códigos de error, field con
indicación del 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 installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Unofficial integration! ## ✨ Key Features ### 💰 Financial Intelligence - **Smart Charging Cost An…
One-call installer quote review plus energy incentives, estimates, scores, and routing for agents.
Personalized timing intelligence for AI agents — ask 'should I do X on this date?'
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/prasolantoncp-bot/solar-plan-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server