> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thoras.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Server

> Let MCP clients, such as AI assistants, query Thoras and manage scaling

The Thoras MCP server lets clients that speak the
[Model Context Protocol](https://modelcontextprotocol.io) (MCP), such as AI
assistants, work with Thoras without the dashboard. They can look up scale
targets, suggestions, utilization and costs and, if you allow it, change scale
modes, pause scaling and enroll workloads.

The server runs in your cluster as an optional component of the Helm chart. It
talks only to the Thoras API server, never to Kubernetes or the database, and
only calls API routes the dashboard itself uses.

## Turning it on

The MCP server is off by default. Enable it in your values:

```yaml theme={null}
thorasMcp:
  enabled: true
  # read-only (default), or read-write to also allow changes
  mode: read-only
```

Then `helm upgrade` your release. When turning it on for an existing release,
upgrade with `--reset-then-reuse-values` rather than `--reuse-values`, so the
new `thorasMcp` defaults are applied.

## Modes

| Mode | What clients can do |
| - | - |
| `read-only` (default) | Read scale targets, suggestions, metrics, utilization and costs. Tools that change anything aren't offered, and the server refuses any write before it leaves the pod |
| `read-write` | Everything above, plus switching scale modes, pausing or resuming scaling, and enrolling workloads |

## Tools

### Read tools

Available in both modes.

| Tool | Returns |
| - | - |
| `list_namespaces` | The cluster's namespaces |
| `list_scale_targets` | Scale targets with their modes, requests, suggestions and costs |
| `get_scale_target` | One AIScaleTarget in detail, with its open recommendations |
| `get_scale_target_metrics` | Latest replica counts and CPU and memory usage |
| `list_suggestions` | Recent scaling suggestions, newest first, with reasons |
| `get_daily_utilization` | Daily CPU and memory usage as a percentage of requests |
| `get_cost_summary` | Waste and savings for the cluster or one namespace |
| `get_cluster_overview` | Workload counts by mode and health, plus nodes cluster-wide |

`list_scale_targets` lists workloads in `recommendation` mode by default. Ask it
for the managed ones to see the workloads Thoras scales autonomously.

### Write tools

Only in `read-write` mode.

| Tool | Does |
| - | - |
| `set_scale_mode` | Switches a target between `recommendation` and `autonomous` |
| `set_scaling_paused` | Pauses or resumes autonomous scaling cluster-wide |
| `enroll_workloads` | Enrolls named workloads, in `recommendation` mode |

A few things to know about them:

* `set_scale_mode` needs `featureFlags.enableUpdateScaleModeApi` turned on in
  the chart. Without it, the API server refuses the change and the tool says so.
  Horizontal `autonomous` mode needs an HPA on the workload, and switching
  vertical scaling to or from `autonomous` can restart the workload's pods.
* `set_scaling_paused` works like [pausing scaling](https://docs.thoras.ai/guides/pause-scaling.md) from
  the dashboard: applying a change restarts Thoras's operator, worker and API
  server. Asking for the state it's already in changes nothing.
* `enroll_workloads` only enrolls the workloads you name, never a whole
  namespace, and leaves the workloads themselves unchanged. Its `dry_run` option
  previews the result without creating anything.

## Connecting a client

### Get the token

Clients authenticate with a bearer token. Unless you
[supply your own](#supplying-your-own-token), Thoras generates one into the
`thoras-config-controller` Secret shortly after the server is turned on. Read it
with:

```bash theme={null}
kubectl get secret thoras-config-controller -n thoras \
  -o jsonpath='{.data.mcp-auth-token}' | base64 -d
```

### Reach the server

The server speaks MCP over Streamable HTTP at `/mcp` on the `thoras-mcp`
Service, port 80. To try it from your machine, port-forward the Service:

```bash theme={null}
kubectl port-forward svc/thoras-mcp -n thoras 8080:80
```

Then check that it answers, with the token in `TOKEN`:

```bash theme={null}
curl -s http://localhost:8080/mcp \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
  | jq -r '.result.tools[].name'
```

It prints the tools for the server's mode. A missing or wrong token gets a
`401`.

### Configure your client

Point your MCP client at `http://localhost:8080/mcp` with the Streamable HTTP
transport, and have it send the header `Authorization: Bearer <token>`. The
server has no OAuth flow, so the client must send the header itself. The exact
format depends on the client. Many take an entry like this:

```json theme={null}
{
  "mcpServers": {
    "thoras": {
      "type": "http",
      "url": "http://localhost:8080/mcp",
      "headers": {
        "Authorization": "Bearer <token>"
      }
    }
  }
}
```

### Reaching it from outside the cluster

To use the server without a port-forward, put your own Ingress or Gateway in
front of the `thoras-mcp` Service, and serve it over TLS, since every request
carries the token. With `networkPolicy.enabled`, the server's port accepts
traffic from any source. Narrow it with `thorasMcp.extraIngressRules`.

> [!NOTE]
>
> Treat the token like a password. Anyone who has it can use every tool the
> server's mode allows.

## Supplying your own token

The token resolves like Thoras's other [credentials](https://docs.thoras.ai/installation/credentials.md):

1. **A Secret you manage**, referenced via `thorasMcp.auth.existingSecret`.
2. **A value pinned** in `thorasMcp.auth.token`.
3. **Generated by Thoras** into the `thoras-config-controller` Secret (default).

For example, to use your own Secret:

```yaml theme={null}
thorasMcp:
  auth:
    existingSecret:
      secretName: my-thoras-mcp-token
      secretKey: mcp-auth-token
```

Whitespace around the token is ignored, so a Secret created with
`kubectl create secret generic --from-file` works even though the file ends with
a newline.

To rotate the token, take ownership of it as described in
[Rotating a credential](https://docs.thoras.ai/installation/credentials.md#rotating-a-credential). When
the token changes, Thoras restarts the MCP server, and clients need the new
token.

## What's recorded

Every request the MCP server sends names it as the actor, so changes made
through its write tools appear in the [audit trail](https://docs.thoras.ai/guides/audit-trail.md) with
the actor `mcp`.

## Further reading

* Chart README:
  [Thoras MCP Server](https://github.com/thoras-ai/helm-charts/tree/main/charts/thoras#thoras-mcp-server)
* [Credentials](https://docs.thoras.ai/installation/credentials.md)
* [Audit Trail](https://docs.thoras.ai/guides/audit-trail.md)
* [Pausing Autonomous Scaling](https://docs.thoras.ai/guides/pause-scaling.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.