Skip to content

MCP and external agents ​

Letting an assistant that is not Kiwire's read a tenant, through the same tools Kiwire's own assistants use.

What MCP is for here ​

The reporting assistant and KAIA answer questions by calling tools — a fixed set of read-only functions over the tenant's own data. Those tools are written once, as Model Context Protocol tools, and the in-app assistants use them through an adapter. Exposing the same tools over HTTP is what lets a client of the tenant's own choosing — Claude Desktop, Cursor, Windsurf, an agent the tenant has built — ask the same questions and get the same masked answers, without Kiwire having to trust that client with anything more than the tools already allow.

That is the whole scope. MCP here is a way to read a tenant; it is not a second API for writing to it. The public REST API remains the route for creating accounts or vouchers or pulling sessions on a schedule (Choosing a route).

The servers ​

Three HTTP endpoints exist, all on the app host:

/mcp/reporting — the Reporting server, with the same seven tools the reporting assistant has: a device report (brand, OS or device class), a dwell-time report, a login error report, general login statistics per zone, a profile report, a reject-reason report, and a session report with its four views. Every tool takes a month or an explicit date range, most take a zone, and usernames and device identifiers are masked in every response.

/mcp/kaia — the KAIA server, with six tools: a tenant overview (zones with their journey, forced profile and recognition rules; controllers with their last session; published journeys and login methods; profiles; account, voucher and session counts; today's login totals; open KAIA findings), a login diagnosis for one zone, controller or SSID/VLAN combination, a schema description listing the kaia_* views and their columns, guarded read-only SQL over those views, a live read of a MikroTik controller's captive-portal bypass list (device addresses masked, except the one MAC you ask about), and a propose-action tool. Over MCP the propose-action tool validates and describes a proposal but cannot create one that anybody could apply; the tool's own instructions tell the model to say so.

/mcp/kaia-marketing — the KAIA marketing server, described on KAIA marketing: the three proposal-filing tools plus the tenant overview, schema description and guarded SQL from the KAIA server, so a client can look before it proposes. It is a separate endpoint so that a diagnostics-only client never sees a tool that files marketing proposals; it shares KAIA's on-switch and each of its tools also checks the tenant's marketing switch on every call.

There is also a local, stdio-transport copy of the Reporting server (php artisan mcp:start kiwire-reporting, with the tenant named in the KIWIRE_TENANT environment variable) for a client running on the app host itself. It has no HTTP surface.

Connecting a client ​

MCP is per tenant by construction: one URL, but every call carries the tenant's ID and an API key, and the key is looked up in that tenant's own database. The keys are the same admin API keys issued from My Profile for the REST API, sent as the same X-Tenant-ID and X-Api-Key headers — MCP does not introduce a separate credential.

On top of the key, three switches all have to be on before a single call succeeds, and the refusal names whichever one is off:

  1. The platform's allowance — an MCP available flag on the tenant, set by Synchroweb. Without it the tenant's MCP Connections card shows a locked notice and its switches are disabled.
  2. The tenant's per-server switch — on the MCP Connections card at System › Settings, one switch each for the Reporting server and the KAIA server (the marketing endpoint follows the KAIA switch). Off until an admin turns it on.
  3. MCP scope on the key — an mcp flag on the specific API key, granted from the same card. A key without it can use the REST API and nothing else.

The two KAIA endpoints additionally require KAIA to be switched on for the tenant, and the request is pinned to that tenant's database for its whole life before any tool runs.

The MCP Connections card generates a ready-to-use client configuration for each server with the tenant ID filled in and the key left as a placeholder to paste in by hand: a mcp-remote-based entry for Claude Desktop, Cursor and Windsurf-style clients (which speak stdio to the app and HTTP to Kiwire), and an equivalent curl example. A stored key is a hash — the plaintext was shown once when the key was made and is never rendered again. Calls are counted per server per month, so the card can show whether anything is actually connected.

What a client can and cannot do ​

A client can call the tools listed above, for the one tenant its key belongs to, and read what they return: reports, diagnostics, and for KAIA one bounded SELECT at a time over the kaia_* views — no comments, variables or multiple statements, at most 200 rows and 5 seconds, and no way to name a base table, another database or another tenant. On tenants where KAIA's read-only database user has been provisioned, that query runs as a user that holds SELECT on those views and nothing else. Usernames, emails, phone numbers and MAC addresses arrive masked. Every string a tool hands back has been cleaned so that a crafted zone name or error message reads as data rather than as an instruction to the model.

A client cannot change anything. No tool on any server writes to a tenant's records; a KAIA action proposed over MCP is a description with nobody to apply it; a marketing proposal filed over MCP waits on the Engagement › KAIA Marketing page for a person, who is the only one who can approve, reject or execute it. No tool takes a tenant parameter, so there is nothing for a model to be talked into changing. KAIA's tools never expose admins, roles, secrets or credentials, payment or licence data, RADIUS configuration, MFA or connector settings, and nothing over MCP can delete. The full set of mechanisms, with where each one lives in the code, is on Guardrails.

Last updated:

Kiwire platform documentation