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

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 for the full tools reference, and Example prompts and workflows 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.

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.

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
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

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:

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:

systemctl restart httpd

Connect clients

OpenCode 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.

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

Install OpenCode using homebrew 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:

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

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

  3. 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 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 servers to your CMP instance. This requires exposing the required endpoints publicly and depends on customer networks and policies.

Cursor/VS Code with MCP support

The Cursor and VS Code extensions that support MCP follow a similar pattern:

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

Consult the extension’s documentation for specific configuration details.

Manual OAuth configuration for custom clients

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

  1. Register a client via DCR:

    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.

  2. 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.

    code_verifier=$(openssl rand -hex 32)
    code_challenge=$(printf '%s' "$code_verifier" | openssl dgst -binary -sha256 | openssl base64 | tr '+/' '-_' | tr -d '=')
    
  3. Start the authorization flow. Direct the user’s browser to:

    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.

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

    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.

  5. Call the MCP server:

    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/

MCP server tools

Reference for the built-in tools available on the Cloud Management Platform (CMP) MCP server

Example prompts and workflows

Example natural-language prompts and multi-tool workflows for the Cloud Management Platform MCP server