# MCP server integration

> Connect an AI agent to the Cloud Management Platform (CMP) Model Context Protocol server and interact with your cloud infrastructure using natural language

---

Site [llms.txt](/llms.txt)

---

CMP includes an MCP server. By connecting an MCP-compatible AI agent to it, users can manage their cloud infrastructure without navigating the CMP UI. All operations are scoped to the authenticated user's permissions, so agents can only see and act on resources they have access to in CMP.

## Example interactions

> "Who am I, according to CloudBolt?"
>
> "List all my active servers."
>
> "Power off SVR-abc12345."
>
> "Show me all Kubernetes resources."
>
> "How much am I spending in the Quality Assurance group?"

See [MCP server tools](/docs/cmp/developer-resources/mcp/server/tools/) for the full tools reference, and [Example prompts and workflows](/docs/cmp/developer-resources/mcp/server/examples/) for sample prompts and multi-tool workflows.

## Prerequisites

You need a valid CMP user account with appropriate group memberships. The CMP server must also be reachable over HTTPS from the workstation running the AI agent. Verify the following network requirements:

| Requirement | Details |
| --- | --- |
| Protocol | HTTPS (SSL) |
| Port | 443 |
| DNS/IP | The CMP hostname must resolve from the client machine and the AI agent service. |
| Firewall | Inbound access to the following paths must be permitted if using an external agent service, such as [claude.ai](https://claude.ai/). |

The following endpoints must be reachable:

| Endpoint | Purpose |
| --- | --- |
| `/mcp` | MCP tool execution endpoint |
| `/.well-known/oauth-authorization-server` | OAuth server discovery |
| `/.well-known/openid-configuration` | OIDC discovery |
| `/register` | Dynamic Client Registration |
| `/authorize` | OAuth authorization |
| `/token` | Token issuance |
| `/oauth2/*` | Django OAuth Toolkit endpoints |

## Logging

CMP logs MCP requests to `/var/log/cloudbolt/mcp.log`. Each entry includes the MCP server tool name, the CMP username, parameters, and the time (in milliseconds) to process the request.

## Authentication

The MCP server is protected by **OAuth 2.0** using the **Authorization Code Flow**. Most modern MCP-compatible AI agents handle this flow automatically via **Dynamic Client Registration** (DCR), meaning that manual OAuth application configuration is not required.

CMP requires PKCE (RFC 7636) for this flow. Agents that support DCR handle it themselves. A hand-written client must implement it, as described under [Manual OAuth configuration for custom clients](#manual-oauth-configuration-for-custom-clients).

| Setting | Value |
| --- | --- |
| **Grant type** | Authorization Code |
| **Client type** | Public (enforced by DCR) |
| **PKCE** | Required. A client using the authorization code flow must send a `code_challenge` with `code_challenge_method=S256`. The `plain` method is not accepted. |
| **Scopes** | `read` (default), `write` (required for write actions) |
| **Access token lifetime** | 5 minutes, configurable; see [Extending the token lifetime](#extending-the-token-lifetime) |
| **Refresh token lifetime** | 14 days of inactivity. Each refresh issues a new token and resets the clock, so a client that refreshes within that window is not interrupted. The `SIMPLE_JWT` settings below do not affect it. If the token expires or is revoked, reauthorize the client. |
| **Redirect URI requirement** | Must be HTTPS |

<div class="alert alert-info" role="alert">


For agents requiring HTTPS redirect URIs that cannot use DCR, a CMP administrator can pre-register an OAuth application via the CMP Admin UI at `/oauth-applications/add/`.
</div>


### Extending the token lifetime

Some MCP clients (such as Visual Studio Code) do not support automatic token refresh. A CMP administrator can increase the access token lifetime by setting `ACCESS_TOKEN_LIFETIME` in a `SIMPLE_JWT` dictionary in `customer_settings.py`. The dictionary replaces the built-in one, so include both keys:

```python
from datetime import timedelta

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(hours=1),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=1),
}
```

`SIMPLE_JWT` also sets the lifetimes of REST API tokens, so this change applies to them too. `REFRESH_TOKEN_LIFETIME` affects only the REST API refresh token; the example keeps its default of 1 day. The MCP refresh token is separate and expires after 14 days of inactivity.

Restart the Apache HTTP Server to apply the change:

```bash
systemctl restart httpd
```

## Connect clients

### OpenCode (recommended)

[OpenCode](https://opencode.ai/docs) operates entirely within your corporate firewall and connects directly to the CMP server. This eliminates the need to expose CMP endpoints to external services such as [claude.ai](https://claude.ai).

OpenCode supports both OAuth-protected MCP servers configured outside the OpenCode client application and DCR.

[Install OpenCode using homebrew](https://formulae.brew.sh/formula/opencode) on macOS, or your preferred Linux or Windows package manager. Once installed, connect to your AI agent from OpenCode using OpenCode's `/connect` command.

1. **Define the MCP server**

   Open `~/.config/opencode/opencode.json` and define a connection to your CMP server, replacing `<HOSTNAME/IP>` with your CMP server's hostname or IP address:

   ```json
   {
     "$schema": "https://opencode.ai/config.json",
     "mcp": {
       "cloudbolt": {
         "type": "remote",
         "url": "https://<HOSTNAME/IP>/mcp"
       }
     }
   }
   ```

1. **Authenticate**

   <div class="alert alert-info" role="alert">


   If using a self-signed certificate, run `export NODE_TLS_REJECT_UNAUTHORIZED=0` before the following OpenCode commands.
   </div>


   At the command line, run `opencode mcp auth cloudbolt` to authenticate with the server via OAuth.

1. **Start OpenCode**

   Start OpenCode by running `opencode`. The console should display `1 MCP` in the lower-left corner. To view the status, run `/status` — this should indicate that the `cloudbolt` MCP server is connected.

### Claude Desktop

[Claude Desktop](https://code.claude.com/docs/en/desktop-quickstart) natively supports remote MCP servers with OAuth. The OAuth redirect URI is `https://claude.ai/api/mcp/auth_callback` (HTTPS), meaning it satisfies CMP's requirements and can register itself automatically via DCR.

To use the CMP MCP server with Claude Desktop, you must have direct network access from the [claude.ai](https://claude.ai) servers to your CMP instance. This requires exposing the [required endpoints](#prerequisites) publicly and depends on customer networks and policies.

### Cursor/VS Code with MCP support

The [Cursor](https://cursor.com/docs) and [VS Code](https://code.visualstudio.com/docs) extensions that support MCP follow a similar pattern:

1. Open the MCP or AI settings panel in your editor.
1. Add a new remote MCP server with the URL: `https://{your-cmp-server}/mcp`
1. When prompted, complete the OAuth authorization flow in your browser.
1. Verify by asking the assistant: *"Who am I, according to CloudBolt?"*

Consult the extension's documentation for specific configuration details.

<div class="alert alert-info" role="alert">


VS Code does not currently support automatic token refresh. See [Extending the token lifetime](#extending-the-token-lifetime) for details on setting a custom lifetime.
</div>


### Manual OAuth configuration for custom clients

Follow these steps for clients that do not support automatic DCR.

1. Register a client via DCR:

   ```http
   POST https://<your-cmp-server>/register
   Content-Type: application/json

   {
     "client_name": "My MCP Client",
     "grant_types": ["authorization_code", "refresh_token"],
     "redirect_uris": ["https://<your-redirect-uri>"],
     "response_types": ["code"],
     "token_endpoint_auth_method": "none"
   }
   ```

   The response includes a `client_id`. All DCR clients are forced to use `client_type=public`.

   <div class="alert alert-info" role="alert">


   Redirect URIs **must** use HTTPS. If your client uses a `http://localhost` callback, request that a CMP administrator pre-register the application at `/oauth-applications/add/`.
   </div>


1. Generate a PKCE code verifier and challenge. The verifier is a random string; the challenge is its SHA-256 hash, Base64url-encoded without padding. Keep the verifier for the token exchange.

   ```bash
   code_verifier=$(openssl rand -hex 32)
   code_challenge=$(printf '%s' "$code_verifier" | openssl dgst -binary -sha256 | openssl base64 | tr '+/' '-_' | tr -d '=')
   ```

1. Start the authorization flow. Direct the user's browser to:

   ```bash
   https://<your-cmp-server>/authorize
     ?response_type=code
     &client_id=<client_id>
     &redirect_uri=<your-redirect-uri>
     &scope=read+write
     &code_challenge=<code_challenge>
     &code_challenge_method=S256
   ```

   The user logs in with CMP credentials and approves the scopes. CMP redirects to your `redirect_uri` with a `code` parameter.

1. Exchange the code for a token, sending the verifier:

   ```bash
   POST https://<your-cmp-server>/token
   Content-Type: application/x-www-form-urlencoded

   grant_type=authorization_code
   &code=<code>
   &client_id=<client_id>
   &redirect_uri=<your-redirect-uri>
   &code_verifier=<code_verifier>
   ```

   The response includes an `access_token` (JWT) and a `refresh_token`.

1. Call the MCP server:

   ```bash
   POST https://<your-cmp-server>/mcp
   Authorization: Bearer <access_token>
   Content-Type: application/json

   {"jsonrpc": "2.0", "method": "tools/call", "params": {"name": "fetch_identity", "arguments": {}}, "id": 1}
   ```

## Troubleshooting

| Issue | Possible cause | Solution |
| --- | --- | --- |
| Connection refused/timeout | CMP unreachable from client | Verify network access to the CMP hostname on HTTPS; check VPN if applicable |
| 401 Unauthorized | Invalid or expired token | Reauthorize by removing and re-adding the connector, or wait for automatic refresh |
| Every integration returns 401 immediately after an upgrade | Access tokens issued before the upgrade are no longer accepted | Expected once. Clients recover on their next refresh; no action is needed |
| Authorization rejected as an invalid request | Client sent no PKCE challenge, or used `code_challenge_method=plain` | Send `code_challenge` with `code_challenge_method=S256`. CMP names the rejected client in a warning in the CMP log |
| Browser does not open during authorization | `/authorize` endpoint blocked by firewall | Ensure the path is reachable; check proxy settings |
| DCR redirect URI rejected | Client uses `http://` redirect | Use a client with an HTTPS redirect URI, or ask a CMP administrator to register the app at `/oauth-applications/add/` |
| Registration fails when adding several clients in quick succession | Dynamic Client Registration is rate-limited | Wait briefly and retry |
| Tool returns an empty list | User lacks permissions | Verify the CMP user is in a group with access to the relevant resources |
| Power action has no effect | Server is already in the target state | Check the server status with `fetch_server_details` |
| Token not refreshing | Refresh token expired after 14 days without use, or was revoked | Reauthorize the client |

## Endpoint reference

| Purpose | Method | Path |
| --- | --- | --- |
| MCP tool execution | `POST` | `/mcp` |
| OAuth server discovery | `GET` | `/.well-known/oauth-authorization-server` |
| OIDC discovery | `GET` | `/.well-known/openid-configuration` |
| Protected resource metadata | `GET` | `/.well-known/oauth-protected-resource` |
| Dynamic Client Registration | `POST` | `/register` |
| Authorization | `GET` | `/authorize` |
| Token | `POST` | `/token` |
| OAuth app admin (CMP admins) | `GET`, `POST` | `/oauth-applications/` |

## Related

- [MCP custom tools](/docs/cmp/developer-resources/mcp/custom-tools/): Adding tools of your own to the set an agent can reach.

---

Section pages:

- [MCP server tools](/docs/cmp/developer-resources/mcp/server/tools/): Reference for the built-in tools available on the Cloud Management Platform (CMP) MCP server
- [Example prompts and workflows](/docs/cmp/developer-resources/mcp/server/examples/): Example natural-language prompts and multi-tool workflows for the Cloud Management Platform MCP server
