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/mcpOr 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.
- The client discovers the OAuth endpoints from
/.well-known/oauth-authorization-server - The client opens a browser to
https://your-canette.company.com/oauth/authorize - If you are not already logged in, you are redirected to the canette login page
- After login, the client receives an access token automatically
- 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
| Tool | Description |
|---|---|
list_projects | List all projects you have access to |
list_apps | List apps within a project |
create_project | Create a new project (uses your personal team by default) |
create_app | Create 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_app | Change 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_credentials | List the Git credentials a project can use for private repositories (names and types only, never tokens or keys) |
trigger_deployment | Build 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_deployments | List recent deployments for an app — use this to find a deployment_id when troubleshooting a deployment not triggered in this session |
get_deployment | Get the status and details of a deployment — provide app_id for the latest, or deployment_id for a specific one |
get_build_logs | Fetch full build logs for a deployment — useful for diagnosing build failures |
redeploy_deployment | Deploy an already-built image again, without rebuilding, using the app's current settings and environment — to apply configuration changes or to roll back |
get_app | Get an app's current state — live URL, custom hostnames, latest deployment and runtime health |
get_runtime_logs | Fetch 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_metrics | Get per-pod readiness, restarts, last termination reason (e.g. OOMKilled) and CPU/memory usage. Usage requires metrics-server on the cluster |
list_env_vars | List an app's environment variables and the names of its secrets (secret values are never returned) |
set_env_var | Create or update a plaintext environment variable — applied on the next deployment, a redeploy is enough |
delete_env_var | Delete 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_deploymentbuilds 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_deploymentdeploys 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-appto 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-appis 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-appdeployed 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-appcrashes 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_LEVELtodebugonmy-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-appis 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 charactersUse a pre-existing Kubernetes Secret (useful when secrets are managed externally):
api:
mcpJwtSecretRef:
name: my-external-secret
key: mcp-jwt-secretThe 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.