# MCP server

> Connect an AI assistant to the hub with the Model Context Protocol. It signs in as a Proxus user and reads plant model, device status, logs and telemetry.

Source: https://proxus.io/docs/develop/mcp

At the end of this guide, an AI assistant that speaks the Model Context Protocol (MCP), such as Claude, Cursor or
VS Code, is connected to your hub. It can answer questions about devices, pipelines, rules and alerts from the live
system, with the rights of the Proxus user it signs in as.

## Before you start

You need:

- The hub's address. The MCP server is at `/mcp` on the hub's port, for example `http://localhost:8080/mcp`.
- A Proxus user for the assistant. Its role limits what the assistant may read and change. See
  [Users and roles](https://proxus.io/docs/administer/users-and-roles).
- An MCP client that supports the Streamable HTTP transport.
- `[MCP] Enabled = true` in the hub's configuration (the default).

## Step 1: Add the server to your client

```bash
claude mcp add --transport http proxus http://localhost:8080/mcp
```
```json
{
  "servers": {
    "proxus": { "type": "http", "url": "http://localhost:8080/mcp" }
  }
}
```
Most clients take a JSON entry with the server's URL:

```json
{
  "mcpServers": {
    "proxus": { "url": "http://localhost:8080/mcp" }
  }
}
```

No header or key is configured in the client. Signing in happens inside the conversation, in the next step.

## Step 2: Sign in

Before it signs in, the assistant can only list the tools and call `schema_overview`, which explains the server and
the sign-in step. Ask it to sign in and give it the Proxus user name and password when it asks. It calls `auth_login`
with them.

The sign-in is tied to this MCP connection and lasts `SessionTtlMinutes` (25 minutes by default). After that, or
after `auth_logout`, the assistant asks again. `auth_whoami` shows which user the connection is signed in as.

> **Warning:**
The password passes through the conversation with the assistant. Use a dedicated user with a password that is not
used anywhere else, and give its role only the rights the assistant needs.

## What the assistant can do

| Tool | What it does | Who may use it |
| --- | --- | --- |
| `schema_overview` | Explains the server, the sign-in state and which tool fits which task. | anyone |
| `auth_login`, `auth_whoami`, `auth_logout` | Sign in, show the signed-in user, sign out. | anyone |
| `schema_entities` | Lists the object types (devices, profiles, rules, pipelines and others) and their readable fields. | signed in |
| `schema_templates` | Example bodies for creating objects. | signed in |
| `schema_protocols` | The connection settings and tag address formats of a protocol. | signed in |
| `schema_telemetry` | Describes the stored values table and how to query it. | signed in |
| `schema_odata_metadata` | A summary of the full data model. | administrators |
| `odata_request` | Reads objects (GET only, at most 100 per call). | signed in |
| `odata_mutate` | Creates or changes an object when you asked for that exact change. | signed in, with the role's rights |
| `device_status` | Live online or offline state of the devices the user may see. | signed in |
| `log_query` | Recent system log entries, filtered by level, source or text. | signed in |
| `telemetry_query` | One read-only SQL query on the stored values, with row, time and memory limits. | administrators |
| `graph_schema`, `graph_neighbors`, `graph_impact`, `graph_lineage`, `graph_paths`, `graph_context_pack` | What a device, rule, pipeline or dashboard depends on and what depends on it (the [operational graph](https://proxus.io/docs/organize/operational-graph)). | signed in |

The server also offers three prompts, `proxus_read_entity`, `proxus_write_change` and `proxus_analyze_telemetry`,
and resources under `proxus://schema/` (overview, entities, telemetry, templates, protocols).

Every call runs with the signed-in user's permissions. A change the role does not allow is refused, as it would be
in the hub's screens. Deleting is blocked by default even for users who may delete (`BlockDelete = true`).

## Secure it for production

Set these in the `[MCP]` section of the hub's configuration (environment form `MCP__<Key>`):

| Key | Default | Meaning |
| --- | --- | --- |
| `Enabled` | `true` | Turns the MCP server on or off. |
| `ServerBaseUrl` | `""` | The hub's public address, for example `https://proxus.example.com`. Required when clients connect from other machines; empty works only through `localhost`. |
| `AllowedBaseUrls` | `[]` | Other exact Proxus addresses `auth_login` may send credentials to. |
| `AllowedOrigins` | `[]` | Browser origins allowed to call `/mcp`. Clients that are not browsers send none. |
| `IPWhitelist` | `[]` | Addresses or ranges allowed to connect, for example `["10.0.0.0/8"]`. Empty allows all. |
| `AdminOnly` | `false` | Only users with an administrative role may use the protected tools. |
| `AllowedMethods` | `"GET,POST,PATCH,PUT"` | Methods `odata_mutate` may use. `"GET"` makes the assistant read-only. |
| `BlockDelete` | `true` | Refuse deletes even if the role allows them. |
| `BlockBulkOperations` | `false` | Refuse changes to several objects in one call. |
| `RateLimitEnabled` | `true` | Limit calls per user and minute. |
| `RateLimitRequestsPerMinute` | `60` | All calls. |
| `ODataRateLimitRequestsPerMinute` | `30` | `odata_request` and `odata_mutate`. |
| `TelemetryRateLimitRequestsPerMinute` | `120` | `telemetry_query`. |
| `GraphRateLimitRequestsPerMinute` | `60` | The graph tools. |
| `MaxConcurrentSessionsPerUser` | `0` | Open MCP sessions per user, `0` for no limit. |
| `SessionTtlMinutes` | `25` | How long a sign-in lasts. |
| `AuditLogging` | `true` | Logs every call with user, address, tool and result. |
| `AnonymousDiscoveryMode` | `"ToolsAndOverview"` | What clients see before signing in: `ToolsAndOverview`, `ToolsOnly` or `Disabled`. |
| `DebugLogging` | `false` | Detailed request logging for connection problems. |

`[MCP.ClickHouse]` limits `telemetry_query`: `MaxResultRows` (1000), `MaxRowsToRead` (10000000), `MaxBytesToRead`
and `MaxMemoryUsage` (512 MiB), `MaxExecutionTimeSeconds` (10), `MaxThreads` (4) and `MaxResultBytes` (16 MiB). Set
`Username` and `Password` to a database user that may only read the `DeviceRawData` and `Logs` tables.

When several hub instances run behind a load balancer, sign-ins are shared through Redis when
`Cluster:RedisConnection` (or `MCP:RedisConnection`) is set.

Refusals reach the client as errors: `403` when the address is not allowed, an `authorization_denied` error when an administrative tool is called by a
user without an administrative role, `401` when a protected tool is called before signing in,
`429` when a rate limit is reached.

## What's next

- [REST API](https://proxus.io/docs/develop/rest-api): the same data for your own programs.
- [Operational graph](https://proxus.io/docs/organize/operational-graph): what the graph tools read.
- [Security hardening](https://proxus.io/docs/operate/security).
