skills/mops-cli/SKILL.md
Manage Motoko projects with the mops CLI — toolchain pinning, dependency management, type-checking, building, and linting. Use when working with mops.toml, mops.lock, running mops commands, adding/removing packages, pinning moc or lintoko versions, checking or building canisters, configuring moc flags, or setting up a new Motoko project.
npx skillsauth add dfinity/icskills mops-cliInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Opinionated guide for Motoko projects. Covers project config, dependency management, type-checking, building, and linting.
moc in [toolchain]. Use the newest moc version.mo:base — it is deprecated. Always use mo:core (import Array "mo:core/Array").mops.toml — canisters, moc flags, toolchain versions, build settings.[canisters]; never pass file paths to mops check. Exception: library packages (no [canisters]) use file paths directly: mops check src/**/*.mo.mops.toml[toolchain]
moc = "1.7.0"
lintoko = "0.10.0"
[dependencies]
core = "2.5.0"
[moc]
args = ["--default-persistent-actors", "-W=M0223,M0236,M0237"]
[canisters.backend]
main = "src/backend/main.mo"
[canisters.backend.migrations]
chain = "src/backend/migrations"
check-limit = 10 # optional — speeds up `mops check` when the chain gets long
[canisters.backend.check-stable]
path = ".old/src/backend/dist/backend.most"
[build]
outputDir = "src/backend/dist"
args = ["--release"]
check-stable verifies stable variable compatibility against a .most file from the deployed version. For a new project with no prior deployment, create a trivial .most file representing an empty actor:
// Version: 1.0.0
actor {
};
Optional canister fields: candid (path to .did for compatibility checking), initArg (Candid-encoded init args).
-W=M0223,M0236,M0237 — redundant type instantiation (M0223), suggest contextual dot notation (M0236), suggest redundant explicit arguments (M0237). These are allowed (disabled) by default; -W= enables them as warnings.
Flags are applied in this order (later overrides earlier):
[moc].args — global, all commands (check, build, test, etc.)[build].args — build only (e.g. --release)[canisters.<name>.migrations] — auto-injected --enhanced-migration (managed by mops)[canisters.<name>].args — per-canister-- <flags> — one-off overridesmops installmops install
Run after cloning or after manual mops.toml edits. Updates mops.lock. In CI, uses --lock check by default (fails if lockfile is stale).
mops add <package>mops add core # latest version
mops add [email protected] # specific version
mops add --dev test # dev dependency
Updates mops.toml and mops.lock.
mops checkPrimary correctness command — runs moc check, then check-stable (if configured), then lint (if lintoko is in toolchain).
mops check # all canisters
mops check backend # single canister
mops check --fix # autofix + check + stable + lint
mops check --verbose # show moc invocations
mops check -- -Werror # treat warnings as errors
Always use canister names, not file paths. Per-canister args from mops.toml are applied automatically.
--fix applies machine-applicable fixes from both moc and lintoko in one pass.
mops buildmops build # all canisters
mops build backend # single canister
mops build --verbose # show compiler commands
mops build -- --ai-errors # pass extra moc flags
Produces .wasm, .did, and .most files in [build].outputDir (default .mops/.build).
mops toolchainmops toolchain use moc 1.7.0 # pin specific version
mops toolchain use moc latest # pin latest version (non-interactive)
mops toolchain use lintoko 0.10.0 # pin specific version
mops toolchain update moc # update to latest (requires existing [toolchain] entry)
mops toolchain update # update all tools to latest
mops toolchain bin moc # print path to binary
Agent note: toolchain use <tool> without a version opens an interactive picker — do not use in scripts or agents. Always pass a version or latest. toolchain update only works when the tool already has a [toolchain] entry.
When [canisters.<name>.migrations] is configured, mops check, mops build, and mops check-stable automatically inject --enhanced-migration. Do not add --enhanced-migration to [canisters.<name>].args — mops will error.
Create migration files directly in the chain directory.
check-limit (optional) caps how many recent chain files mops check and mops lint consider — useful when the chain grows long and re-checking every old migration slows feedback down. mops build is unaffected by check-limit. When the limit kicks in, mops stages the included files into .migrations-<canister>/ next to the chain directory (auto-.gitignored). moc diagnostics may then print paths there — the real file lives in the chain directory with the same name.
mops remove <package>mops remove base
mops outdated # list outdated dependencies (caret-bound)
mops update # update all within caret bound (no major-version crossing)
mops update core # update specific package within caret bound
mops update --major # allow updates that cross major versions
mops sync # add missing / remove unused packages
mops testTests live in test/*.test.mo:
mops test # run all tests
mops test my-test # filter by name
mops test --mode wasi # use wasmtime (for to_candid/from_candid)
mops test --reporter verbose # show Debug.print output
mops test --watch # re-run on file changes
mops lintRuns lintoko (also runs automatically as part of mops check when lintoko is in toolchain):
mops lint # lint all .mo files
mops lint --fix # autofix lint issues
mops lint <name> # filter to .mo files matching <name>
When [canisters.<name>.migrations].check-limit is set, mops lint skips the trimmed chain migrations to match what moc sees during mops check. To lint a trimmed migration on demand, pass an explicit filter (e.g. mops lint OldMigrationName).
mops formatmops format # format all .mo files
mops format --check # check formatting without modifying
Use per-canister args (not global) for suppressions:
[canisters.backend]
main = "src/backend/main.mo"
args = ["-A=M0198"]
mops init -y
mops toolchain use moc latest # pin latest moc (non-interactive)
mops toolchain use lintoko latest # pin latest lintoko
mops add core
Then configure [moc].args, [canisters], and [build] in mops.toml.
To update tools later: mops toolchain update moc or mops toolchain update (all tools).
data-ai
Inline actor migration for Motoko canisters using `(with migration = ...)` syntax. Use when upgrading canister state, renaming fields, changing field types, or restructuring actor state without the --enhanced-migration flag. For multi-step migration chains, use migrating-motoko-enhanced instead.
devops
Enhanced multi-step migration for Motoko actors using a migrations/ directory and --enhanced-migration flag. Use when upgrading canister state across multiple deployments, writing migration files, changing actor field types, or managing a migration chain. For a single one-shot migration, use migrating-motoko instead.
tools
Motoko language pitfalls, modern syntax, and architecture patterns for the Internet Computer. Covers persistent actors, stable types, mo:core standard library, dot notation, mixins, and common compilation errors. Use when writing Motoko canister code, fixing Motoko compiler errors, or generating Motoko actors. Do NOT use for deployment, icp.yaml, or CLI commands.
tools
Guides use of the icp command-line tool for building and deploying Internet Computer applications. Covers project configuration (icp.yaml), recipes, environments, canister lifecycle, and identity management. Use when building, deploying, or managing any IC project. Use when the user mentions icp, dfx, canister deployment, local network, or project setup. Do NOT use for canister-level programming patterns like access control, inter-canister calls, or stable memory — use domain-specific skills instead.