Skip to content

Connecting an AI Assistant

OpenZEV can answer questions about your own data through an AI assistant — Claude Code, Claude Desktop, Cursor, n8n, or any other client that speaks the Model Context Protocol (MCP). Instead of clicking through the readiness cockpit, invoice detail, import logs and audit log yourself, you ask in plain language: "Is Q2 ready to bill for ZEV Sonnenhof?", "Why is this invoice higher than last quarter?", "What went wrong in yesterday's import?"

The assistant sees exactly what your account can see in the API — nothing more — and every question it asks OpenZEV is recorded in the audit log.

Privacy note

Enabling this feature lets the signed-in user send OpenZEV data — participant names, consumption figures, invoice amounts, audit history — to whichever LLM provider the assistant uses, which is very likely a third party outside Switzerland. Only enable it if that is acceptable for your community, and only give a key to an assistant you trust with that data.

The MCP endpoint is read-only in this release: no tool can create, change, approve, send or delete anything.

Enabling it

An administrator must turn the feature on first — it is off by default:

  1. Open Platform → Settings → Functions.
  2. Enable mcp_server_enabled.

While the flag is off, the MCP endpoint does not exist as far as any caller can tell (404, whether or not they are signed in).

Creating a key for the assistant

The assistant authenticates the same way a script does — see API Keys for the full picture. For an assistant:

  1. Open Account → Tokens & keys.
  2. Choose New API key.
  3. Give it a name that says what it's for — claude-code-mcp beats key 3.
  4. Tick Read-only key. Every tool in this release only reads, so a read-only key loses nothing and keeps the credential's blast radius small if it ever leaks.
  5. Choose Create key and copy the value shown — it is not shown again.

Only admins and accounts that manage or view a community can use the MCP endpoint. A participant's key is refused with 403.

Connecting a client

The endpoint is https://<your-openzev-host>/api/v1/mcp/, speaking MCP's Streamable HTTP transport. Send the key as a bearer token.

Claude Code

claude mcp add --transport http openzev \
  https://your-openzev.example.com/api/v1/mcp/ \
  --header "Authorization: Bearer ozv_3f9a1c04b7e2_kR8vN2pQ..."

Generic MCP client configuration

Most desktop clients (Claude Desktop via a local HTTP-to-stdio bridge, Cursor, …) take a JSON block naming the server:

{
  "mcpServers": {
    "openzev": {
      "url": "https://your-openzev.example.com/api/v1/mcp/",
      "headers": {
        "Authorization": "Bearer ozv_3f9a1c04b7e2_kR8vN2pQ..."
      }
    }
  }
}

n8n

Add an MCP Client node, set its Endpoint to https://your-openzev.example.com/api/v1/mcp/, and set Authentication to a header credential: Authorization: Bearer ozv_3f9a1c04b7e2_kR8vN2pQ....

What you can ask

Once connected, the assistant has eleven tools. You do not need to know their names — asking a normal question is enough — but knowing what exists helps you phrase a better question:

Tool Answers
list_zevs Which ZEVs can I see? (call this first to get a ZEV's id)
list_participants Who is in this ZEV, since when, and which metering points are they assigned to? (names and dates only — no email, phone, address or IBAN)
period_readiness Can this billing period be invoiced, and what is blocking it?
find_invoices Which invoices match this participant / period / status?
explain_invoice Break one invoice down into its line items, and compare it with the participant's previous invoice
import_triage What happened in recent metering imports, and what went wrong?
consumption_summary Consumption, production and self-consumption over a date range, by month, day or hour (hour for up to a week); for the whole ZEV it also shows each participant's consumption and how much of it came from the ZEV
consumption_profile A participant's average day: how much they use in each hour, and how much of it comes from the ZEV's own solar
data_gaps Which metering points are missing readings, and where?
live_energy What the ZEV produces and uses right now, how much is spare, which metering points report, and when production is expected to peak (only when live energy data is switched on; indicative, never billing)
audit_query Who did what, and when?

Example questions:

  • "List the ZEVs I have access to."
  • "Is the current period ready to bill for ZEV Sonnenhof?"
  • "Who are the current participants of ZEV Sonnenhof, and which meters do they have?"
  • "Find Anna Muster's invoices from this year."
  • "Explain invoice OZV-00013 — why did it go up from last quarter?"
  • "What errors came up in yesterday's metering import?"
  • "How much energy did ZEV Sonnenhof self-consume in August, by day?"
  • "Which participants used the most electricity last quarter, and how much of it was solar?"
  • "When in the day does Anna Muster use the most electricity, and how much of that is covered by solar?"
  • "Which metering points have gaps in the last 30 days?"
  • "How much is ZEV Sonnenhof producing right now, and is anything spare?"
  • "When is production expected to peak tomorrow?"
  • "Who approved invoices for ZEV Sonnenhof last week?"

Limits

  • Read-only. No tool changes anything. A future release may add write tools (approving or sending invoices) with an explicit confirmation step.
  • No raw meter data. Consumption is aggregated into monthly, daily or (for up to a week) hourly buckets; the underlying 15-minute readings are not exposed through MCP.
  • Scoped to your account. An assistant connected with a manager's key sees only that manager's ZEVs — the same tenant isolation that protects the REST API protects MCP, because MCP tools call the same REST endpoints internally.
  • Bearer-token clients only, for now. The endpoint accepts a static API key, not an OAuth login. Connectors that only support OAuth (such as claude.ai's custom connectors) cannot connect yet.
  • Lists are capped. A question that would return hundreds of rows comes back truncated with a note saying so — narrow the question (a shorter date range, a specific participant) rather than asking for everything at once.

Revoking access

Revoke the key the same way you would revoke any other API key: Account → API keys → Revoke. It takes effect on the assistant's next request. See Revoking a key for the full picture, including how an administrator can revoke it on your behalf.

Audit trail

Every tool call the assistant makes is recorded in the audit log as an mcp.tool.call event, naming the tool, the arguments, the key that was used (by its prefix), and the ZEV it concerned (when the question named one you can see). The event is named Abfrage durch KI-Assistent (AI assistant query) and its details show the source KI-Assistent (mcp). To see exactly what an assistant looked at, open the platform audit log's Technical filters and enter the action code mcp.tool.call — or ask the assistant itself, since audit_query can answer that question too.

Troubleshooting

Symptom Cause
404 on the endpoint mcp_server_enabled is off — ask an administrator to enable it. The endpoint answers 404 to everyone while the flag is off, so this is the first thing to check.
401 Missing, wrong, revoked or expired key. Same causes as any other API key — see API Keys → Troubleshooting.
403 Your key's account manages or views no community (for example, it is only a participant), or its access was removed. Only admins, managers and viewers can use MCP.
The assistant says a tool failed with "Permission denied" or "not found" You (or the assistant) named a ZEV or invoice your account cannot see. This is the same scoping the REST API enforces — it is not a bug.
Answers feel stale Ask the assistant to call the tool again — MCP calls always read live data, there is no caching layer of its own.