---
name: cdn-mn
description: Set up and operate CDN.MN's image-optimization CDN through its MCP server — analyze a website's image savings, create a project, verify a domain, activate the generated delivery hostname, rewrite image URLs, manage prepaid credit and plan, view analytics, and purge cached variants. Use when a user wants to put a site's images behind CDN.MN, or mentions CDN.MN, an image CDN / image optimization setup, domain verification, an agent-provisioned workspace, or the cdnmn MCP tools.
metadata:
  homepage: https://cdn.mn
  access: https://app.cdn.mn/auth.md
compatibility: Operates CDN.MN over its MCP server; needs a scoped bearer token and network access to app.cdn.mn.
---

# CDN.MN — agent install skill

A step-by-step workflow to put a site behind CDN.MN's image optimization, using
only the tools that are live today. Get access first: [auth.md](https://app.cdn.mn/auth.md).

## Preconditions

- You hold a scoped bearer token (`cdnmn_at_…`) — see auth.md.
- Send every call to `POST https://app.cdn.mn/api/mcp` with `Authorization: Bearer …`.
- No account yet? Register with `owner_email` + `provision_workspace: true`
  (auth.md step 3) — you get a token and a LIVE workspace immediately. Do steps
  1–3 below: the first domain you verify unlocks a one-time $5 credit and the
  generated hostname starts serving. Then tell your human to adopt it from the
  email we sent (billing/deletion stay locked until they do); unclaimed
  workspaces are deleted after ~72h.

## Workflow

1. **Survey.** `tools/call list_projects` → the workspace's sites, their
   verification state, and the current delivery settings. `get_domains` → each
   site's delivery hostname and DNS/certificate status. `get_billing` → plan +
   remaining prepaid credit. If the site doesn't exist yet and you hold
   `project:create`, `create_project` `{ origin: "example.com/img" }` creates
   it and returns EVERY verification proof (a DNS-TXT record; a DNS-CNAME on
   the same name, whose target does not need to resolve; and a LIST of
   acceptable HTTP-file paths — serve the token at any one of them, whichever
   the host actually lets you write) for the next step. Use the TXT record OR
   the CNAME, never both: DNS forbids a CNAME alongside other records on one
   name. Deciding whether CDN.MN is worth it? `analyze_website`
   `{ url }` (scope `site:analyze`) scans a public site and estimates the image
   savings, detects the platform, and recommends a safe integration strategy.

2. **Prove origin ownership.** For an unverified site, `verify_domain`
   `{ site_id }` runs the check now (DNS-TXT, DNS-CNAME, or an HTTP file — any
   one proves it).
   It's rate-limited per site; if it returns `not_verified`, tell the human which
   record to add, then retry after the cooldown.

3. **Activate delivery.** Once verified, `activate_hostname` `{ site_id }`
   publishes the generated `cdn{5}.<domain>` hostname to the edge. Depending on
   how the owner set you up this either runs immediately (`status: executed`) or
   returns `approval_required` with an `approval_id` — in that case surface it
   to the human and poll `get_approval_status` for the outcome. Never re-call to
   "retry"; that opens a second request.

4. **Keep credit topped up (optional).** If `get_billing` shows low prepaid
   credit, call `add_funds` to request a top-up to the configured target — if no
   payment method is on file it refuses with `no_payment_method` (ask the owner
   to add one in the dashboard). Money ALWAYS needs the owner's approval first —
   you'll get `approval_required`; poll `get_approval_status`. The amount is
   fixed by the workspace's settings and bounded; you don't choose it.

   **Change the plan (optional).** `change_plan` (`billing:write`, also
   owner-approved) switches a workspace that ALREADY has a paid subscription
   between paid plans — `{"target_plan_id":"business"}` — with the price
   difference prorated onto the next invoice (no charge now), or downgrades to
   `payg` (cancels at the end of the paid period). Starting the FIRST paid plan
   from Pay-as-you-go is refused (`no_live_subscription`) — tell the owner to
   subscribe from the billing dashboard, which needs their payment authorization.

5. **Rewrite image URLs.** Point the site's image URLs at the delivery hostname,
   keeping the same path — e.g. `https://example.com/img/a.jpg` →
   `https://cdn12345.<domain>/img/a.jpg`. That host swap is the whole rewrite: no
   query is added, so the image serves at its origin-size default. If you want a
   specific size, add a width `w` (snapped to the site's configured ladder);
   format and quality are chosen server-side — you never pass them. The
   `@cdnmn/cli` automates the host rewrite — `cdnmn rewrite --apply`
   auto-writes **Markdown** files (`.md`/`.markdown`) and REPORTS every other
   file type (HTML, CSS, JSX/TSX, Vue, MDX) as a `manual` mapping for you to
   apply — so run it, then apply the reported mappings yourself. (dry-run by
   default; it reads AGENTS.md and downgrades `--apply` to a dry run on a "do
   not auto-edit" rule, backs up every change and can
   `--revert`). Keep the original origin as the fallback.

6. **Verify + report.** Fetch a few rewritten URLs; a second request should be a
   cache hit. If a stale image lingers after an origin-side change, `purge_urls`
   `{ site_id, path }` drops its cached variants (rate-limited per site; folder
   and whole-site scopes are paid-plan features). Report to the human: what
   changed, the delivery hostname, the verification method, and how to roll back
   (revert the URL rewrite; revoke the agent from the workspace's Agents page at
   any time).

## Rules

- Ask for the narrowest scopes that do the job; you may be granted a subset —
  always read the `scope` field in the token response and adapt.
- Never modify DNS, billing, or production deployment beyond what a granted scope
  and (where required) an owner approval allow.
- Never commit or echo the `device_code` or the `access_token`.
- Every state-changing action you take is in the workspace audit log; a revoked
  token stops working immediately.

## Machine index

[llms.txt](https://app.cdn.mn/llms.txt) · [openapi.json](https://app.cdn.mn/openapi.json) ·
[auth.md](https://app.cdn.mn/auth.md) · [CLI & SDK](https://app.cdn.mn/docs/cli)
