Skip to main content
Glama
jLuPSP

EG4 Entra MCP Lab

by jLuPSP

EG4 Entra MCP Lab

A security-focused Model Context Protocol lab for an EG4 inverter. It replaces copied API keys at the MCP boundary with Microsoft Entra authentication and demonstrates three distinct authorization patterns:

  1. Direct delegated access from a signed-in MCP client to Gateway API A.

  2. True OAuth On-Behalf-Of (OBO) from Gateway A to Energy API B.

  3. Application-only read access for a bounded automation client.

The final Energy API to EG4 Monitor hop uses a server-held EG4 portal credential because EG4 does not publish user-delegated OAuth. That hop is deliberately documented as service-credential access, not OBO.

Safety status

  • EG4 mode defaults to deterministic mock data.

  • Real cloud mode requires an explicit inverter serial allowlist.

  • All writes default to disabled: ENERGY_CONTROL_ENABLED=false.

  • Quick charge uses a short-lived plan/commit operation with state-drift detection.

  • No generic register-write, arbitrary HTTP, or shell tool is exposed.

  • EG4 and Entra credentials must never be put in Git, prompts, MCP arguments, logs, or browser storage.

Related MCP server: EG4 MCP Server

Architecture

VS Code/public client -- delegated token (aud=A) --> MCP Gateway A :8930
                                                     |
                                                     | Entra OBO
                                                     v
                                           Energy API B :8931
                                                     |
                                                     | EG4 portal session
                                                     v
                                           EG4 Monitor private API

Only Gateway A has a host port. API B is reachable only on the Compose network and still validates its own Entra audience and permissions.

Entra applications

Provisioning creates four single-tenant applications:

App

Type

Permission

EG4 Lab Interactive Client

Public native client

delegated Mcp.Read, optional Mcp.Control to A

EG4 Lab MCP Gateway

Confidential API A

exposes MCP scopes; OBO client of B

EG4 Lab Energy API

Resource API B

delegated Energy.Read/Energy.Control; app role Energy.Read.All

EG4 Lab Automation Reader

Confidential daemon

B application role Energy.Read.All only

See docs/architecture.md and docs/entra-setup.md.

For the verified security properties, live validation evidence, failure modes, and operational lessons, see docs/security-learnings.md.

MCP tools

  • whoami: inspect sanitized Entra authorization claims

  • list_inverters: read allow-listed plants/inverters

  • get_current_state: power flow, SOC, battery, online and quick-charge state

  • plan_quick_charge: no mutation

  • plan_stop_quick_charge: no mutation

  • commit_operation: mutation only when every server-side gate passes

Local mock development

Copy-Item .env.example .env
# In .env only for isolated local testing:
# GATEWAY_AUTH_DISABLED=true
# ENERGY_AUTH_DISABLED=true
# ENERGY_EG4_MODE=mock
# Create an empty ignored secrets/mock_gateway.pem only for mock Compose startup.
uv sync --extra dev
uv run pytest

A local test MCP bearer is intentionally fixed as local-test-token; it is accepted only with mock auth explicitly enabled.

Container deployment

  1. Copy .env.example to a server-only .env and fill in only the documented identifiers and policy values.

  2. Run scripts/new_gateway_certificate.ps1, upload only gateway.crt.pem with the provisioning script, and mount only the ignored private gateway.pem into Gateway A. See docs/entra-setup.md.

  3. Install EG4 credentials interactively with scripts/install_eg4_credentials.sh; the secret directory is an optional first argument.

  4. Generate ignored certs/eg4-gateway.crt and certs/eg4-gateway.key files with SANs for the published hostname. Trust only the public certificate on the client.

  5. Keep ENERGY_EG4_MODE=mock and ENERGY_CONTROL_ENABLED=false for the first deployment, then run docker compose up -d --build.

  6. Verify https://127.0.0.1:8930/healthz and the RFC 9728 metadata route. Set GATEWAY_BIND_ADDRESS, GATEWAY_PUBLIC_BASE_URL, and GATEWAY_ALLOWED_HOSTS explicitly before publishing to another trusted host.

MCP clients

Copy .vscode/mcp.example.json to .vscode/mcp.json for an OAuth-capable client and substitute the generated public client ID. Do not put a client secret or bearer token in that file.

For clients that support stdio but not interactive remote MCP OAuth, this repo provides a local bridge. eg4-client-login performs Entra device-code or browser sign-in and stores the serialized MSAL cache in the OS credential store. eg4-client-bridge silently refreshes the session and proxies the authenticated remote MCP over stdio. Both commands take --tenant-id, --client-id, --scope api://GATEWAY-CLIENT-ID/Mcp.Read, and optionally --mcp-url.

EG4 caveat

EG4 Monitor has no public supported developer API found during research. This project calls a community reverse-engineered portal API through pylxpweb, pinned to a tested version. Read and control behavior can vary by role, model, and firmware.

License

MIT. This project is unaffiliated with EG4 Electronics or Microsoft.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables LLM agents to securely monitor and control MQTT devices for building automation, industrial control, and smart home systems through a standardized MCP interface.
    22
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for EG4 solar inverters, enabling real-time monitoring, performance analysis, battery health, alerts, maintenance insights, and historical data via natural language.
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables access to Fronius solar inverter data via the MCP protocol, allowing real-time monitoring of energy production, consumption, and battery storage through natural language.
    14
    20 npm
    4
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for Solplanet ASW5-T inverter, enabling natural language queries about solar energy system status and control.
    MIT