Using the mgd CLI for MAGDA workflows
Instructions for assistant tools (and humans) driving a MAGDA data catalog
through the mgd command-line interface. Tool-agnostic: adapt the framing to
your assistant environment, keep the rules.
This file is the always-loaded core: ground rules, the command index, error
triage, and a router pointing at the reference file for your task. The detailed
recipes and their safety notes live in those reference files — read the one
that matches your task before acting.
Ground rules
- Check auth first. Before any MAGDA access, run
mgd auth status --json.
If it fails with exit code 2, no usable profile is configured — relay the
error message, which says whether to run mgd profile create <name> (none
set up) or mgd profile use <name> (one exists but isn't active). If
authenticated is false, read-only public commands may still work, but
mutations will fail — say so up front.
- Prefer curated commands (
search, dataset, dist, file, aspect)
over mgd api request. Use the raw command only when no curated command
covers the endpoint, and mention that you did.
- Always parse machine output. Use
--json (single document) or --jsonl
(one JSON object per line) on every command whose output you consume.
Never scrape human-mode output. Read and list commands emit their data as
JSON; the aspect/record mutations (aspect create, dataset aspect set/
patch/delete, dataset/dist update) print a compact {…, "ok": true} result in
--json mode; and aspect get / dataset aspect get emit JSON already (the
flag is optional there). Downloads write the file itself, so they take no
--json.
- Respect exit codes.
0 ok; 2 usage error (your command line is wrong);
3 auth error (key missing/invalid or no permission); 4 not found;
1 anything else. In --json mode a failing command prints
{"error": {"code", "message", "status", "hint"}} on stderr.
- Confirm before mutating or publishing. Never run
dataset create --publish, add-file, replace-file, update, aspect create/set/patch/delete,
or any api request with POST/PUT/PATCH/DELETE without the user's explicit
go-ahead in this conversation. Uploading or attaching generated artifacts
happens only when the user asked for it. For how to create and publish once
the user has agreed, see authoring.md.
- Report identifiers. Every user-facing summary must include the dataset
IDs, distribution IDs, local file paths, and upload targets you touched.
- Versioning is automatic. The CLI maintains the
version aspect on
high-level commands (create/update/add-file/replace-file/remove)
and tags versions with registry event ids. publish/unpublish never bump
versions. Never hand-edit the version aspect; raw aspect set/patch/
delete never auto-bump.
set replaces the whole aspect; patch merges. To change one field (e.g.
add keywords to dcat-dataset-strings) use patch — it deep-merges your
partial object server-side and leaves the other fields intact. Using set for a
partial edit silently drops every field you didn't include (title,
description, keywords, license, dates), so default to patch; reach for set
only when you intend to overwrite the whole aspect. For advanced RFC 6902 ops
(remove/test/move), use mgd api request PATCH …/aspects/<id> --body @patch.json.
Command index
Curated commands (prefer these over api request, ground rule 2):
| Command |
Does |
auth status |
show the active profile + authenticated user |
profile create/update/remove · use/list |
manage site profiles & credentials |
search datasets <q> · search semantic <q> |
keyword / embedding search → search.md |
dataset get <id> · dataset distributions <id> |
read a dataset / list its distributions → search.md |
dataset create · dataset update <id> |
create (draft by default) / edit dataset metadata → authoring.md |
dataset add-file <id> [file] |
upload a file, or register a link with --access-url, as a distribution → authoring.md |
dataset publish/unpublish <id> |
set publishing state (cascades to distributions) → authoring.md |
dataset aspect get/set/patch/delete <recordId> <aspectId> |
read/write any aspect on any record (set=replace, patch=merge) |
dist get/update <id> · dist publish/unpublish <id> |
inspect / edit / flip a single distribution |
dist download <id> · dist replace-file <id> <file> · dist remove <id> |
download / replace / remove a distribution → search.md, authoring.md |
file upload/download |
direct storage transfer |
aspect list/get/create/delete <id> |
manage custom aspect definitions → authoring.md |
api request <method> <path> |
raw REST call (fallback only) |
Raw fallback (documented REST endpoints only):
mgd api request GET /v0/registry/records --query limit=3 --query aspect=dcat-dataset-strings
Which reference file to read
Read the file(s) matching your task before acting — that's where the recipes
and their caveats are:
| If the task is… |
Read |
| searching, finding, inspecting, or downloading datasets/distributions |
search.md |
| creating, editing, or publishing a dataset; attaching files; editing or defining aspects |
authoring.md (+ dataset-elicitation.md for the metadata conversation) |
| assigning or changing a dataset's publisher / organisation |
publisher.md |
| making a preview render, or cataloguing remote/link distributions (ArcGIS/WMS/remote CSV/JSON); a format→preview question; a 403 on a preview |
preview.md |
dataset-elicitation.md defines the metadata-consultant behaviour (infer before
asking, quick vs guided path, confirm-then-write) for any create/edit conversation.
Error triage
- exit 3 +
unauthorized → API key invalid/expired: ask the user to update the
profile (mgd profile update <name> --key-id … --key …) or recreate it
(mgd profile create <name>).
- exit 3 +
forbidden → the key is valid but the account lacks permission for
that operation. Common cause: the user assumed they could create/upload/publish
but haven't been granted those rights. Report which operation was denied,
explain it's a permissions grant (not a missing record or a bug), and advise
them to ask their MAGDA system administrator to grant the relevant
permission/role. Do not retry.
- exit 4 → record/object doesn't exist: re-check the ID (search again) before
reporting data as missing.
semantic-search-unavailable → use keyword search only (see search.md).
- Network errors mention the base URL — verify
mgd auth status and the site
URL before concluding the service is down.
1---2name: magda-mgd3description: Use when accessing a MAGDA data catalog from the command line — searching/downloading datasets, analysing them locally, or creating/editing dataset records and uploading files via the mgd CLI.4---56# Using the `mgd` CLI for MAGDA workflows78Instructions for assistant tools (and humans) driving a MAGDA data catalog9through the `mgd` command-line interface. Tool-agnostic: adapt the framing to10your assistant environment, keep the rules.1112This file is the always-loaded **core**: ground rules, the command index, error13triage, and a router pointing at the reference file for your task. The detailed14recipes and their safety notes live in those reference files — **read the one15that matches your task before acting.**1617## Ground rules18191. **Check auth first.** Before any MAGDA access, run `mgd auth status --json`.20 If it fails with exit code 2, no usable profile is configured — relay the21 error message, which says whether to run `mgd profile create <name>` (none22 set up) or `mgd profile use <name>` (one exists but isn't active). If23 `authenticated` is `false`, read-only public commands may still work, but24 mutations will fail — say so up front.252. **Prefer curated commands** (`search`, `dataset`, `dist`, `file`, `aspect`)26 over `mgd api request`. Use the raw command only when no curated command27 covers the endpoint, and mention that you did.283. **Always parse machine output.** Use `--json` (single document) or `--jsonl`29 (one JSON object per line) on every command whose output you consume.30 Never scrape human-mode output. Read and list commands emit their data as31 JSON; the aspect/record mutations (`aspect create`, `dataset aspect set`/32 `patch`/`delete`, `dataset`/`dist update`) print a compact `{…, "ok": true}` result in33 `--json` mode; and `aspect get` / `dataset aspect get` emit JSON already (the34 flag is optional there). Downloads write the file itself, so they take no35 `--json`.364. **Respect exit codes.** `0` ok; `2` usage error (your command line is wrong);37 `3` auth error (key missing/invalid or no permission); `4` not found;38 `1` anything else. In `--json` mode a failing command prints39 `{"error": {"code", "message", "status", "hint"}}` on stderr.405. **Confirm before mutating or publishing.** Never run `dataset create --publish`, `add-file`, `replace-file`, `update`, `aspect create/set/patch/delete`,41 or any `api request` with POST/PUT/PATCH/DELETE without the user's explicit42 go-ahead in this conversation. Uploading or attaching generated artifacts43 happens only when the user asked for it. For *how* to create and publish once44 the user has agreed, see `authoring.md`.456. **Report identifiers.** Every user-facing summary must include the dataset46 IDs, distribution IDs, local file paths, and upload targets you touched.477. **Versioning is automatic.** The CLI maintains the `version` aspect on48 high-level commands (`create`/`update`/`add-file`/`replace-file`/`remove`)49 and tags versions with registry event ids. `publish`/`unpublish` never bump50 versions. Never hand-edit the `version` aspect; raw `aspect set`/`patch`/51 `delete` never auto-bump.5253**`set` replaces the whole aspect; `patch` merges.** To change one field (e.g.54add `keywords` to `dcat-dataset-strings`) use `patch` — it deep-merges your55partial object server-side and leaves the other fields intact. Using `set` for a56partial edit **silently drops every field you didn't include** (title,57description, keywords, license, dates), so default to `patch`; reach for `set`58only when you intend to overwrite the whole aspect. For advanced RFC 6902 ops59(remove/test/move), use `mgd api request PATCH …/aspects/<id> --body @patch.json`.6061## Command index6263Curated commands (prefer these over `api request`, ground rule 2):6465| Command | Does |66| --- | --- |67| `auth status` | show the active profile + authenticated user |68| `profile create/update/remove` · `use/list` | manage site profiles & credentials |69| `search datasets <q>` · `search semantic <q>` | keyword / embedding search → `search.md` |70| `dataset get <id>` · `dataset distributions <id>` | read a dataset / list its distributions → `search.md` |71| `dataset create` · `dataset update <id>` | create (draft by default) / edit dataset metadata → `authoring.md` |72| `dataset add-file <id> [file]` | upload a file, or register a link with `--access-url`, as a distribution → `authoring.md` |73| `dataset publish/unpublish <id>` | set publishing state (cascades to distributions) → `authoring.md` |74| `dataset aspect get/set/patch/delete <recordId> <aspectId>` | read/write any aspect on any record (`set`=replace, `patch`=merge) |75| `dist get/update <id>` · `dist publish/unpublish <id>` | inspect / edit / flip a single distribution |76| `dist download <id>` · `dist replace-file <id> <file>` · `dist remove <id>` | download / replace / remove a distribution → `search.md`, `authoring.md` |77| `file upload/download` | direct storage transfer |78| `aspect list/get/create/delete <id>` | manage custom aspect *definitions* → `authoring.md` |79| `api request <method> <path>` | raw REST call (fallback only) |8081Raw fallback (documented REST endpoints only):8283```sh84mgd api request GET /v0/registry/records --query limit=3 --query aspect=dcat-dataset-strings85```8687## Which reference file to read8889Read the file(s) matching your task **before acting** — that's where the recipes90and their caveats are:9192| If the task is… | Read |93| --- | --- |94| searching, finding, inspecting, or downloading datasets/distributions | `search.md` |95| creating, editing, or publishing a dataset; attaching files; editing or defining aspects | `authoring.md` (+ `dataset-elicitation.md` for the metadata conversation) |96| assigning or changing a dataset's **publisher / organisation** | `publisher.md` |97| making a **preview** render, or cataloguing **remote/link distributions** (ArcGIS/WMS/remote CSV/JSON); a format→preview question; a **403** on a preview | `preview.md` |9899`dataset-elicitation.md` defines the metadata-consultant behaviour (infer before100asking, quick vs guided path, confirm-then-write) for any create/edit conversation.101102## Error triage103104- exit 3 + `unauthorized` → API key invalid/expired: ask the user to update the105 profile (`mgd profile update <name> --key-id … --key …`) or recreate it106 (`mgd profile create <name>`).107- exit 3 + `forbidden` → the key is valid but the account lacks permission for108 that operation. Common cause: the user assumed they could create/upload/publish109 but haven't been granted those rights. Report which operation was denied,110 explain it's a permissions grant (not a missing record or a bug), and advise111 them to ask their MAGDA system administrator to grant the relevant112 permission/role. Do not retry.113- exit 4 → record/object doesn't exist: re-check the ID (search again) before114 reporting data as missing.115- `semantic-search-unavailable` → use keyword search only (see `search.md`).116- Network errors mention the base URL — verify `mgd auth status` and the site117 URL before concluding the service is down.