canette
AI Agents

MCP Server

Connect AI agents (Claude Code, Cursor, Codex) to your canette instance using the Model Context Protocol.

canette exposes a Model Context Protocol server at /mcp on your instance. AI agents can use it to deploy repositories, check deployment status, and diagnose failures — all through natural language instructions.

Connecting an AI client

The MCP server uses the Streamable HTTP transport and authenticates via OAuth 2.1 with PKCE. When you connect for the first time, your client will open a browser window where you log in with your existing canette credentials — the same GitHub, Google, or email login you use in the UI.

Claude Code

Run this command to register canette as an MCP server in Claude Code:

claude mcp add --transport http canette https://your-canette.company.com/mcp

Or add it manually to ~/.claude/claude_code_config.json (or the project-level .claude/settings.json):

{
  "mcpServers": {
    "canette": {
      "type": "http",
      "url": "https://your-canette.company.com/mcp"
    }
  }
}

Replace your-canette.company.com with your instance's hostname. Claude Code will prompt you to authenticate in the browser the first time it connects.

Cursor

In Cursor, open Settings → MCP and add a new server:

  • Name: canette
  • Type: HTTP
  • URL: https://your-canette.company.com/mcp

Other clients

Any MCP client that supports the Streamable HTTP transport and OAuth 2.1 can connect. Point it at https://your-canette.company.com/mcp. The OAuth discovery document is at https://your-canette.company.com/.well-known/oauth-authorization-server.

Authentication

The MCP server uses standard OAuth 2.1 with PKCE. You do not need to create or manage API tokens manually.

  1. The client discovers the OAuth endpoints from /.well-known/oauth-authorization-server
  2. The client opens a browser to https://your-canette.company.com/oauth/authorize
  3. If you are not already logged in, you are redirected to the canette login page
  4. After login, the client receives an access token automatically
  5. The token is valid for 1 hour; the client will re-authenticate when it expires

An access token is tied to the browser session you authorized it from. Signing out of canette in that browser ends the client's access immediately, and the client will ask you to authorize again.

Available tools

ToolDescription
list_projectsList all projects you have access to
list_appsList apps within a project
create_projectCreate a new project (uses your personal team by default)
create_appCreate an app in a project — built from a Git repository (including monorepo subdirectories and private repositories) or run from a Docker image, as a web, private or cronjob app
update_appChange an existing app's settings, such as branch, port or image tag — applied on the next deployment (a rebuild for source changes, a redeploy for runtime settings)
list_git_credentialsList the Git credentials a project can use for private repositories (names and types only, never tokens or keys)
trigger_deploymentBuild and deploy an app from its source — fetches the latest commit and runs a full build for a Git app. For the first deployment and whenever the code or source changed
list_deploymentsList recent deployments for an app — use this to find a deployment_id when troubleshooting a deployment not triggered in this session
get_deploymentGet the status and details of a deployment — provide app_id for the latest, or deployment_id for a specific one
get_build_logsFetch full build logs for a deployment — useful for diagnosing build failures
redeploy_deploymentDeploy an already-built image again, without rebuilding, using the app's current settings and environment — to apply configuration changes or to roll back
get_appGet an app's current state — live URL, custom hostnames, latest deployment and runtime health
get_runtime_logsFetch recent logs and pod status (restarts, CrashLoopBackOff, exit code) from the running app. Automatically returns the crashed container's logs when the app is crash-looping
get_app_metricsGet per-pod readiness, restarts, last termination reason (e.g. OOMKilled) and CPU/memory usage. Usage requires metrics-server on the cluster
list_env_varsList an app's environment variables and the names of its secrets (secret values are never returned)
set_env_varCreate or update a plaintext environment variable — applied on the next deployment, a redeploy is enough
delete_env_varDelete an environment variable — applied on the next deployment, a redeploy is enough

Secrets can't be set or deleted through MCP. Agents can see which secret names exist, but values are added in the canette UI so they never pass through the AI client.

Rebuild or redeploy

There are two ways for an agent to start a deployment, and the server tells the agent which one to use:

  • trigger_deployment builds the app from its source and then deploys it. For a Git app that means fetching the latest commit and running a full image build, which takes minutes. It is needed when the source changed: new commits, or a different repository, branch, app path, Git credential or image tag.
  • redeploy_deployment deploys an image that is already built, with the app's current settings, environment variables and secrets. It takes seconds. It is enough when only configuration changed: environment variables, secrets, port, schedule, deployment type, volumes, hostnames or password protection.

Environment variables are injected when the app starts, not when it is built, so changing one never requires a rebuild. After set_env_var, delete_env_var or a runtime-only update_app, the tool result tells the agent to redeploy the app's latest live deployment. You should not have to spell this out in your prompt.

Example prompts

Deploying a repository:

"Add my repo https://github.com/myorg/my-app to canette and deploy it"

The agent will create a project, create an app pointing at the repository, and trigger the first deployment.

Troubleshooting a failure:

"My canette app my-app is failing to deploy — what's wrong?"

The agent will fetch the latest deployment status and build logs, then explain the error.

Debugging a running app:

"my-app deployed but returns 502 — why?"

The agent will check the app's state, read the runtime logs and pod status (including the output of a crashed container), and look at memory usage to spot an OOMKilled restart.

Fixing missing configuration:

"my-app crashes on startup — fix it"

The agent will read the runtime logs, spot a missing variable such as LOG_LEVEL, set it and redeploy the existing image without rebuilding. If the missing value is a secret (for example DATABASE_URL), it will ask you to add it in the canette UI.

Changing configuration:

"Set LOG_LEVEL to debug on my-app"

The agent will set the variable and redeploy the app's current image. No build runs, so the change is live in seconds.

Rolling back:

"The latest deploy of my-app is broken — roll back to the previous version"

The agent will list recent deployments, pick the last one that was live, and redeploy its image. The rollback uses the app's current settings and environment variables, not the ones from the earlier deployment.

Prerequisites

The MCP server requires MCP_JWT_SECRET to be set. If you installed canette via Helm, this secret is auto-generated on first install and stored in the canette-api-secrets Kubernetes Secret. No manual configuration is needed for a standard install.

See Helm configuration below if you need to rotate the key or use an external secret.

Helm configuration

The MCP_JWT_SECRET is stored in the canette-api-secrets Kubernetes Secret and auto-generated on first install. You can override this behaviour:

Provide your own value in values.yaml:

api:
  mcpJwtSecret: "your-secret-here"  # min 32 characters

Use a pre-existing Kubernetes Secret (useful when secrets are managed externally):

api:
  mcpJwtSecretRef:
    name: my-external-secret
    key: mcp-jwt-secret

The secret must exist in the canette namespace before running helm install or helm upgrade.

Rotating MCP_JWT_SECRET invalidates all existing access tokens. Connected clients will re-authenticate automatically on their next request.

On this page