Write an AGENTS.md

Last updated: June 20, 2026

AGENTS.md is a small convention: a markdown file at the root of your repo that AI coding agents read for project-specific instructions. Claude Code, Cursor, and a growing list of agents look for it (Claude Code also reads CLAUDE.md) and treat its contents as standing guidance for that repo.

Your agent already knows how to build your app — it's been writing the code with you. What it doesn't know is how you want it deployed. This drop-in teaches it exactly that: the happy path for shipping this project to American Cloud through the American Cloud MCP server. Once the file is in place, "deploy this" becomes a single prompt, and the agent already knows to price the server before creating it, keep secrets out of your repo, and report back the IP, URL, and monthly cost when it's done.

What you need first

Install it

Pick whichever is easier:

  • Download examples/AGENTS.md from github.com/American-Cloud/americancloud-mcp and drop it at the root of your repo.
  • Copy the block below into a file named AGENTS.md at your repo root. (For Claude Code you can name it CLAUDE.md instead — Claude Code reads both.)

Commit it like any other repo file so every teammate's agent gets the same instructions. Then add your own deploy details under the "Project state" section at the bottom as you go.

The file

This is the complete drop-in, byte-for-byte. The header comment links back to this page and the source repo so anyone who opens the file later knows where it came from.

markdown
<!--
  AGENTS.md — deploy this project to American Cloud.
  Drop-in instructions for any AI coding agent (Claude Code, Cursor, etc.).
  Source & updates: https://americancloud.com/docs/deploy-with-ai/agents-md
  Repo: https://github.com/American-Cloud/americancloud-mcp
  Append your own project notes under "Project state" at the bottom.
-->
 
# Deploying this project to American Cloud
 
You are an AI coding agent working in this repository. When the user asks to
deploy, host, ship, or "put this online" on American Cloud, follow this file.
You provision and manage American Cloud infrastructure through the
**americancloud** MCP server (tools are snake_case, e.g. `list_regions`,
`create_vm`). You run commands on the resulting server over SSH from the
terminal.
 
## Preflight
 
1. Confirm the **americancloud** MCP server is connected: the `get_server_info`
   tool should exist. If it does not, stop and tell the user to set it up at
   https://americancloud.com/docs/mcp/overview, then continue.
2. Call `get_server_info` and check `readOnly`. If it reports `readOnly: true`,
   you can inspect and price things but cannot create them. Tell the user to
   switch to a **read-write API key** and add `--allow-writes` to the server's
   args (see the overview link above), then continue. Do not pretend a create
   succeeded.
3. Note the enabled service groups from `get_server_info`. If the user needs a
   group that is not enabled (e.g. `dns`), tell them to add it via `--services`.
 
## Conventions (always)
 
- **Price before you build.** Before any create, call the matching
  `get_cost_estimate_*` tool and show the user the monthly estimate. Wait for
  approval. Never invent or guess prices — only repeat what the tool returns.
- **Smallest viable size first.** Pick the smallest package that runs the
  workload and tell the user it can scale up later (`scale_vm`,
  `scale_kubernetes_cluster`, `resize_block_storage_volume`). Don't over-provision.
- **Confirm before anything destructive.** Deletes, releases, reinstalls, and
  reverts are irreversible — describe what will be destroyed and get an explicit
  yes first.
- **Never write secrets into the repo.** API keys, object storage keys,
  kubeconfigs, DB passwords: these go into a server-side env file over SSH (e.g.
  `/etc/myapp.env`, mode 600) or your secret manager — never into tracked files.
  Don't echo full secrets back into chat.
- **One VM until you need more.** Start with a single VM; add load balancers,
  more VMs, or Kubernetes only when the user's traffic or architecture calls for
  it.
- **Name resources after this project** so they're identifiable later — use the
  repo/project name (e.g. `myapp-web`, `myapp-assets`) for VMs, SSH keys, object
  storage units, and DNS records.
 
## Canonical deploy flow: web app to a VM
 
1. **Pick a region.** `list_regions` and choose one near the users (or ask).
2. **Ensure an SSH key.** `list_ssh_keys`. If the user's key isn't there, create
   one with `create_ssh_key`, or have them add their public key in the console.
   You'll pass its name in `keypairs` so you can SSH in afterward.
3. **Choose a package and image.** `list_vm_packages` and `list_images` (Ubuntu
   LTS is a safe default). Start with the smallest package that fits.
4. **Estimate cost.** `get_cost_estimate_vm` with the chosen region, package,
   specs, and `subscriptionPeriod`. Show the user the monthly number and wait
   for approval.
5. **Create the VM — with the ports in the same call.** `create_vm` with
   `name`, `region`, `vmPackage`, `image`, `subscriptionPeriod`, `keypairs`,
   and `networkAccess.inboundPorts` for the ports you need — typically 22
   (SSH), 80 (HTTP), and 443 (HTTPS), `protocol: "TCP"`. This opens both the
   firewall and the port forwarding on the network's public IP; a firewall
   rule alone is not enough to reach the VM. Omit `network` to auto-create an
   isolated network, or pass an existing network UUID. Save the returned VM id
   and public IP.
6. **Verify or adjust the ports.** `list_firewall_rules` and
   `list_port_forwarding_rules` on the VM's public IP confirm what's open. To
   open another port later, add BOTH a `create_firewall_rule` and a
   `create_port_forwarding_rule` for it (or map the whole IP to the VM with
   `enable_static_nat`). Use the narrowest `sourceCidrList` that works
   (`0.0.0.0/0` only for the public web ports).
7. **Wait until reachable.** Poll `get_vm` until it's running, then confirm SSH
   answers on port 22 before continuing.
8. **Install over SSH.** SSH in and install the runtime (Node, Python, etc.) and
   a reverse proxy (nginx or Caddy) in front of the app on 127.0.0.1.
9. **Create a systemd service** for the app so it starts on boot and restarts on
   failure. App config and secrets live in the server-side env file, not the repo.
10. **DNS (if the user has a domain here).** `list_dns_zones`; if the zone
    exists, `create_dns_record` with an `A` record pointing the hostname at the
    VM's public IP. (If the domain is elsewhere, give the user the IP and the
    record to add.)
11. **Enable TLS.** Once DNS resolves, use certbot (or Caddy's automatic TLS) to
    issue a certificate for the domain and serve HTTPS on 443.
12. **Verify and report.** Curl the public URL and confirm it serves the app.
    Report back: the VM name and id, public IP, the URL, and the monthly cost
    estimate from step 4. Offer to record it in "Project state" below.
 
## Static assets and uploads to object storage
 
Use this when the app serves images/uploads/static files or needs durable
storage separate from the VM.
 
1. `create_object_storage_unit` named after the project, then
   `create_object_storage_bucket` inside it. Preview with
   `get_cost_estimate_object_storage` first.
2. `get_object_storage_keys` for the unit — these are **sensitive** S3-style
   access keys. Put them in the server-side env file, never in the repo.
3. Wire the app via any S3-compatible SDK (AWS SDK, boto3, etc.), pointing it at
   the unit's S3 endpoint with those keys and the bucket name.
 
## Kubernetes (only when the user asks for it)
 
For a single app, the VM flow above is simpler and cheaper. Use Kubernetes when
the user explicitly wants a cluster or multi-service orchestration.
 
1. `list_kubernetes_versions` and `list_kubernetes_packages` for options.
2. `get_cost_estimate_kubernetes` and show the user the monthly cost; wait for
   approval.
3. `create_kubernetes_cluster`, then poll `get_kubernetes_cluster` until ready.
4. `get_kubernetes_cluster_config` for the kubeconfig — **sensitive**, it grants
   full cluster access. Write it to `~/.kube/` locally (gitignored), never into
   the repo.
5. Use `kubectl` from the terminal to apply manifests and deploy workloads.
 
## After deploying
 
Report what was created, where it runs, and the cost estimate. Then suggest the
user save the details in the "Project state" section below so the next session
(yours or another agent's) starts with the facts instead of rediscovering them.
 
Template:
 
```markdown
## Project state
 
- Region: us-west-0
- VM: myapp-web (id: <uuid>) — <package>, <public-ip>
- Open ports: 22, 80, 443
- Domain: myapp.com → A record at <public-ip>
- Object storage: myapp-assets unit / uploads bucket (keys in /etc/myapp.env)
- Monthly estimate: $XX (from get_cost_estimate_vm on <date>)
- Deploy: systemd service `myapp`, nginx reverse proxy, certbot TLS
```
 
## Troubleshooting
 
- **Domain doesn't resolve yet.** DNS changes take time to propagate. Confirm the
  record with `list_dns_records`, verify with `dig`/`nslookup`, and wait before
  re-running certbot.
- **Connection refused / times out.** The port needs BOTH a firewall rule and a
  path to the VM. Check `list_firewall_rules` (ingress rule whose
  `sourceCidrList` includes the caller) and `list_port_forwarding_rules` (the
  public port forwards to the VM) on the VM's public IP. Add what's missing
  with `create_firewall_rule` / `create_port_forwarding_rule`, or use
  `enable_static_nat` to map the IP to the VM one-to-one.
- **App isn't serving.** SSH in and check the service:
  `systemctl status myapp` and `journalctl -u myapp -n 100 --no-pager`. Confirm
  the reverse proxy is up and pointed at the app's local port.
- **VM unreachable.** `get_vm` to confirm it's running; `power_vm` with
  `action: "reboot"` if it's stuck.
 
<!--
## Project state
(Fill this in after the first deploy — see the template above.)
-->

How it behaves

With the file in place, you don't have to spell out the steps each time. When you say "deploy this to American Cloud," the agent reads AGENTS.md and:

  • Checks the connection and mode first. It confirms the MCP server is there and whether it's read-only, and tells you what to change rather than failing silently halfway through.
  • Shows you the price before it builds. Every create is preceded by a cost estimate you approve — no surprise bills, no made-up numbers.
  • Keeps your secrets out of the repo. Access keys and configs land in a server-side env file over SSH, not in tracked files.
  • Picks a sensible default and scales later. Smallest viable VM, one server until you need more, resources named after the project so they're easy to find.
  • Reports back and remembers. When it's done you get the IP, URL, and monthly estimate, and the agent offers to record them in the file's "Project state" section so the next session starts with the facts.

You stay in control: you approve the cost, you approve anything destructive, and the work happens on your machine through the MCP server you configured.

Next steps