How do I deploy an app to Granite with Claude Code?
Install the Granite CLI, log in, then clone the Granite skill into ~/.claude/skills/novps. Claude Code loads it automatically the next time you mention deploying, and drives the CLI for you — no MCP server, no API keys beyond your own personal access token.
Three commands, then a sentence:
$ curl https://cli.granite.so | sh && novps auth login
Installed novps to ~/.local/bin/novps
Enter your Personal Access Token: nvps_****
Authenticated as you@example.com (project: default)
$ git clone https://github.com/granite-so/claude-skill ~/.claude/skills/novps
Cloning into '/Users/you/.claude/skills/novps'...
done.
$ claude
> deploy this to Granite
Reading the repository… found a Dockerfile, a GitHub Actions workflow
publishing ghcr.io/you/api, and a docker-compose.yml with Postgres.
Proposing novps.yaml with one web-app on the published image.
novps apps apply my-api -f novps.yaml --wait
Deployment succeeded. https://my-api-api.granite.app
What the skill actually does
What the agent can run
- apps apply
- Create or update an application from novps.yaml. Idempotent, matches resources by name. With --wait it polls the deployment and prints the public and private endpoints.
- apps export
- Turn an application that already exists into a manifest compatible with apply. Registry credentials are never returned.
- resources set-image, deploy
- Ship a new tag to a running resource — the two commands behind a release when your CI builds the image.
- resources logs, connect
- Follow logs with -f, filter with --since and --search, or open an interactive shell in the running container.
- resources scale, set-env
- Change replica size and count, or set environment variables, merging with what is already there or replacing it outright.
- databases create
- Managed Postgres, MySQL or Redis, with read replicas, backups, connection pools and per-app access rules. --wait returns the connection details once it is ready.
- port-forward database
- Databases are not exposed publicly. This is how the agent — or you — connects a local client to one.
The manifest it writes
$ cat novps.yaml
envs:
- key: LOG_LEVEL
value: info
- key: DATABASE_URL
value: ${DATABASE_URL}
resources:
- name: api
type: web-app
source_type: docker
source:
type: docker
name: ghcr.io/you/api
tag: ${IMAGE_TAG}
config:
port: "8080"
replicas:
type: sm
count: 2
- name: worker
type: worker
source_type: docker
source:
type: docker
name: ghcr.io/you/api
tag: ${IMAGE_TAG}
config:
command: "python -m app.worker"
Before you start
- Granite CLI v0.3.0+
- Install with
curl https://cli.granite.so | sh. Linux and macOS, x86_64 and arm64. - A personal access token
- Create one in the dashboard, then run
novps auth login. Tokens start withnvps_. - Claude Code
- Or any Claude Agent SDK harness that loads skills. The skill is a folder of markdown, so there is no daemon and no background process.
- A Dockerfile, ideally
- Docker mode deploys an image your CI already publishes. GitHub mode builds from source instead and needs the Granite GitHub App installed on the repository.
Using another agent
Cursor, Codex, a shell script in CI or an agent you wrote yourself — all of them can run the same commands. Three properties are what make that workable rather than fragile:
Where to go next
The skill itself: SKILL.md, the manifest schema and the registry-credentials guide. Read it before you install it.
Every command, every flag, the manifest reference and notes on driving the CLI from scripts and agents.
What the agent is deploying onto: web apps, workers and cron jobs, automatic deploys, encrypted secrets.
Next.js, FastAPI, Laravel, Rails, Django and nine more — what each one needs from a host, and what it costs.