moodle-cli 0.5.5 → 0.7.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moodle-cli",
3
- "version": "0.5.5",
3
+ "version": "0.7.0-alpha.0",
4
4
  "description": "Terminal-first CLI for Moodle LMS",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -10,36 +10,42 @@
10
10
  "files": [
11
11
  "dist",
12
12
  "README.md",
13
+ "ONBOARDING.md",
13
14
  "SKILL.md",
15
+ "references",
16
+ "agents",
14
17
  "LICENSE"
15
18
  ],
16
19
  "scripts": {
17
- "build": "tsup && rm -f dist/.gitignore",
20
+ "build": "tsc --noEmit && tsup && npm run build:worker && rm -f dist/.gitignore",
21
+ "build:worker": "tsup --config tsup.worker.config.ts && node scripts/check-worker-bundle.mjs",
18
22
  "check": "tsc --noEmit",
19
- "pack:check": "npm pack --dry-run --json | node -e \"let data = ''; process.stdin.on('data', chunk => data += chunk); process.stdin.on('end', () => { const files = JSON.parse(data)[0]?.files?.map(file => file.path) ?? []; if (!files.includes('dist/moodle.js')) throw new Error('npm package is missing dist/moodle.js'); });\"",
20
- "pack:smoke": "tmp=\"$(mktemp -d)\" && npm pack --pack-destination \"$tmp\" >/dev/null && npm install --prefix \"$tmp/install\" \"$tmp\"/moodle-cli-*.tgz >/dev/null && test \"$(\"$tmp/install/node_modules/.bin/moodle\" --version)\" = \"$(node -p \"JSON.parse(require('node:fs').readFileSync('package.json', 'utf8')).version\")\"",
23
+ "pack:check": "npm pack --dry-run --json | node -e \"let data = ''; process.stdin.on('data', chunk => data += chunk); process.stdin.on('end', () => { const files = JSON.parse(data)[0]?.files?.map(file => file.path) ?? []; for (const required of ['dist/moodle.js', 'dist/worker/worker.js', 'README.md', 'ONBOARDING.md', 'SKILL.md', 'references/command-reference.md', 'references/downloads.md', 'agents/openai.yaml']) if (!files.includes(required)) throw new Error('npm package is missing ' + required); });\"",
24
+ "pack:smoke": "tmp=\"$(mktemp -d)\" && npm pack --pack-destination \"$tmp\" >/dev/null && npm install --prefix \"$tmp/install\" \"$tmp\"/moodle-cli-*.tgz >/dev/null && test \"$(\"$tmp/install/node_modules/.bin/moodle\" --version)\" = \"$(node -p \"JSON.parse(require('node:fs').readFileSync('package.json', 'utf8')).version\")\" && \"$tmp/install/node_modules/.bin/moodle\" download --help >/dev/null && \"$tmp/install/node_modules/.bin/moodle\" mcp --help >/dev/null",
21
25
  "test": "vitest run",
26
+ "test:mcp": "vitest run tests/mcp-*.test.ts tests/deployment-*.test.ts tests/renewal-*.test.ts tests/connectors-*.test.ts",
27
+ "test:worker": "vitest run tests/worker-*.test.ts",
22
28
  "test:watch": "vitest",
23
29
  "skill:generate": "node dist/moodle.js skills generate",
24
- "prepublishOnly": "npm run check && npm run test && npm run build"
30
+ "prepublishOnly": "npm run test && npm run build && npm run pack:check"
25
31
  },
26
32
  "dependencies": {
27
- "commander": "^14.0.0",
33
+ "@bunizao/cli-kit": "^0.1.0",
34
+ "@steipete/sweet-cookie": "^0.4.0",
35
+ "commander": "^13.1.0",
28
36
  "node-html-parser": "^7.0.1",
37
+ "wrangler": "^4.120.0",
29
38
  "yaml": "^2.8.0",
30
39
  "zod": "^4.0.5"
31
40
  },
32
- "optionalDependencies": {
33
- "chrome-cookies-secure": "^3.0.2"
34
- },
35
41
  "devDependencies": {
36
42
  "@types/node": "^24.0.10",
37
43
  "tsup": "^8.5.0",
38
- "typescript": "^5.8.3",
44
+ "typescript": "^7.0.2",
39
45
  "vitest": "^3.2.4"
40
46
  },
41
47
  "engines": {
42
- "node": ">=20"
48
+ "node": ">=22"
43
49
  },
44
50
  "repository": {
45
51
  "type": "git",
@@ -0,0 +1,48 @@
1
+ # Command Reference
2
+
3
+ Read this file for exact arguments, flags, and defaults after selecting a branch from `SKILL.md`.
4
+
5
+ | Command | Description | Arguments | Flags |
6
+ | --- | --- | --- | --- |
7
+ | moodle activities | Inspect activities. | | |
8
+ | moodle activities list | List activities in a unit. | <unit> | --json<br>--yaml<br>--table<br>--fields (value required) |
9
+ | moodle activities show | Show activity detail. | <id> | --json<br>--yaml<br>--table<br>--fields (value required) |
10
+ | moodle alerts | List notifications and message counts. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (value required) |
11
+ | moodle auth | Session and keepalive utilities. | | |
12
+ | moodle auth keepalive | Renew the Moodle session once; used by the background keepalive agent. | | --no-renew<br>--json<br>--yaml<br>--table<br>--fields (value required) |
13
+ | moodle auth keepalive install | Install a macOS launch agent that renews the session periodically. | | --interval (value required)<br>--json<br>--yaml<br>--table<br>--fields (value required) |
14
+ | moodle auth keepalive status | Show whether the keepalive launch agent is installed. | | --json<br>--yaml<br>--table<br>--fields (value required) |
15
+ | moodle auth keepalive uninstall | Remove the keepalive launch agent. | | --json<br>--yaml<br>--table<br>--fields (value required) |
16
+ | moodle auth login | Extract a fresh session, opening the browser when needed. | | --json<br>--yaml<br>--table<br>--fields (value required) |
17
+ | moodle auth status | Show cached session freshness and keepalive state. | | --json<br>--yaml<br>--table<br>--fields (value required) |
18
+ | moodle commands | Describe the complete command tree. | | --json<br>--yaml<br>--table<br>--fields (value required) |
19
+ | moodle download | Download one authenticated Moodle file. | <source> | --dest (value required)<br>--force<br>--json<br>--yaml<br>--table<br>--fields (value required) |
20
+ | moodle forums | Inspect forums. | | |
21
+ | moodle forums list | List forum activities in a unit. | <unit> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (value required) |
22
+ | moodle forums search | Search forum discussion titles and post text. | <query> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--course (value required)<br>--forum (value required)<br>--titles-only<br>--unread-only<br>--recent<br>--limit-forums (value required)<br>--limit-discussions (value required)<br>--limit (value required) |
23
+ | moodle forums show | List discussions from a forum. | <forum> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (value required)<br>--query (value required) |
24
+ | moodle grades | Inspect grades. | | |
25
+ | moodle grades list | Show grade details for a unit. | <unit> | --json<br>--yaml<br>--table<br>--fields (value required) |
26
+ | moodle mcp | Deploy and manage a private Moodle MCP server. | | |
27
+ | moodle mcp bridge | Bridge a stdio MCP client to the managed remote server. | | --profile (value required) |
28
+ | moodle mcp connect | Connect a supported MCP client. | [client] | --json<br>--yaml<br>--table<br>--fields (value required)<br>--mode (value required)<br>--show-token |
29
+ | moodle mcp deploy | Deploy or update the managed Moodle MCP server. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--dry-run<br>--repair<br>--rotate-token<br>--rollback |
30
+ | moodle mcp login | Acquire and upload a fresh Moodle session. | | --json<br>--yaml<br>--table<br>--fields (value required) |
31
+ | moodle mcp remove | Remove one managed Moodle MCP deployment. | | --json<br>--yaml<br>--table<br>--fields (value required) |
32
+ | moodle mcp renewal | Run the installed managed-session renewal job. | | |
33
+ | moodle mcp renewal run | Check and renew one managed Moodle session. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--profile (value required) |
34
+ | moodle mcp serve | Run the local Moodle MCP server. | | --stdio |
35
+ | moodle mcp session | Advanced managed-session operations. | | |
36
+ | moodle mcp session push | Upload a Moodle cookie from standard input. | | --stdin<br>--json<br>--yaml<br>--table<br>--fields (value required) |
37
+ | moodle mcp status | Show local and remote Moodle MCP readiness. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--verbose<br>--logs |
38
+ | moodle overview | Show a compact multi-source overview. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--todo-limit (value required)<br>--todo-days (value required)<br>--alerts-limit (value required) |
39
+ | moodle skills | Show skill metadata or delegate to the shared skills CLI. | | |
40
+ | moodle skills add | Install the published skill through npx skills add. | | |
41
+ | moodle skills generate | Regenerate the agent skill bundle from the CLI command tree. | | |
42
+ | moodle threads | Inspect forum discussion threads. | | |
43
+ | moodle threads show | Show posts in a forum discussion. | <discussion> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--post (value required)<br>--body |
44
+ | moodle todo | List upcoming actionable timeline items. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (value required)<br>--days (value required) |
45
+ | moodle units | Inspect enrolled units. | | |
46
+ | moodle units list | List enrolled units. | | --json<br>--yaml<br>--table<br>--fields (value required) |
47
+ | moodle units show | Show unit detail with sections. | <unit> | --json<br>--yaml<br>--table<br>--fields (value required) |
48
+ | moodle user | Show authenticated user info. | | --json<br>--yaml<br>--table<br>--fields (value required) |
@@ -0,0 +1,45 @@
1
+ # Coursework and Grades
2
+
3
+ Read this file for grades or detail about assignments, quizzes, resources, links, pages, and folders.
4
+
5
+ ## Grades
6
+
7
+ Use a course ID or unique course name:
8
+
9
+ ```bash
10
+ moodle grades UNIT --json
11
+ ```
12
+
13
+ Report the course total and requested grade items. Preserve displayed values and percentages; Moodle gradebooks may expose text such as ranges, letters, or incomplete totals.
14
+
15
+ ## Activity Detail
16
+
17
+ Each command accepts a numeric module ID or its full Moodle URL:
18
+
19
+ | Activity | Command |
20
+ | --- | --- |
21
+ All supported activity types share the course-module ID namespace and use one command:
22
+
23
+ ```bash
24
+ moodle activities show ACTIVITY_ID --json
25
+ ```
26
+
27
+ The result includes `type` (`assign`, `quiz`, `resource`, `link`, `page`, or `folder`).
28
+
29
+ Resource and folder details include `file_entries` with a filename, authenticated URL, and authentication requirement. When the user wants local files, continue with [downloads.md](downloads.md) instead of fetching those URLs outside the CLI.
30
+
31
+ When the user supplies a supported Moodle URL without naming a command, route it directly:
32
+
33
+ ```bash
34
+ moodle 'MOODLE_URL' --json
35
+ ```
36
+
37
+ The CLI recognizes course, grade report, forum, assignment, quiz, resource, link, page, and folder URLs. For another activity URL, it may fall back to the containing course.
38
+
39
+ ## Agent Steps
40
+
41
+ 1. Use the activity-specific command when the activity type is known.
42
+ 2. Use direct URL routing when the user already supplied a URL and only wants its content.
43
+ 3. Return structured links and `file_entries` from the result instead of scraping prose from the formatted table.
44
+
45
+ The branch is complete when the answer identifies the course or module and quotes the grade or activity state returned by Moodle.
@@ -0,0 +1,25 @@
1
+ # Deadlines and Alerts
2
+
3
+ Read this file for upcoming work, due dates, notifications, unread counts, or a combined snapshot.
4
+
5
+ ## Choose the Command
6
+
7
+ | Need | Command |
8
+ | --- | --- |
9
+ | Nearest actionable items | `moodle todo --limit 5 --days 14 --json` |
10
+ | Notifications and message counts | `moodle alerts --limit 10 --json` |
11
+ | User, courses, todo, and alerts together | `moodle overview --todo-limit 5 --alerts-limit 5 --json` |
12
+
13
+ Use `todo` for “next,” “due,” “deadline,” and “upcoming.” Add `--days N` for a time window and `--limit N` for result size.
14
+
15
+ Use `alerts` for notifications, unread items, starred messages, and conversation counts.
16
+
17
+ Use `overview` only when the user explicitly wants multiple categories in one snapshot. A narrow request should stay on `todo` or `alerts`.
18
+
19
+ ## Agent Steps
20
+
21
+ 1. Run the narrow command.
22
+ 2. Sort or filter the returned data only when the command does not already express the request.
23
+ 3. Report exact timestamps and course/activity names; preserve the Moodle URL when it helps the user act.
24
+
25
+ The branch is complete when every reported deadline or alert comes from the command result and the requested time window is explicit.
@@ -0,0 +1,38 @@
1
+ # Local File Downloads
2
+
3
+ Read this file when the user wants one or more Moodle files saved locally. The canonical command is `moodle download`; `moodle dl` is an optional alias.
4
+
5
+ ## One Resource
6
+
7
+ When the caller has an activity but not a direct file URL, inspect it first:
8
+
9
+ ```bash
10
+ moodle activities show ACTIVITY_ID --json
11
+ ```
12
+
13
+ For one resource, pass its positive course-module ID, same-site resource URL, or same-site `pluginfile.php` URL:
14
+
15
+ ```bash
16
+ moodle download ACTIVITY_ID --dest './Course/Week 03/slides.pdf' --json
17
+ moodle download 'MOODLE_RESOURCE_URL' --dest './Course/Week 03/slides.pdf' --json
18
+ ```
19
+
20
+ `--dest` is the exact downloaded file path. Without it, the CLI writes the upstream filename in the current directory. Existing files are preserved by default.
21
+
22
+ ## Folder Files
23
+
24
+ The CLI does not recursively download a Moodle folder. Inspect the folder, select the relevant `file_entries`, plan each destination, and invoke `moodle download` separately for every chosen URL:
25
+
26
+ ```bash
27
+ moodle activities show FOLDER_ACTIVITY_ID --json
28
+ moodle download 'FILE_ENTRY_URL' --dest './Course/Week 03/chapter-1.pdf' --json
29
+ ```
30
+
31
+ Treat every `file_entries.url` as authenticated Moodle data. Use it only through the CLI and never expose Moodle cookies, sesskeys, or other credentials.
32
+
33
+ ## Replacement and Verification
34
+
35
+ - Preserve an existing destination unless the user explicitly authorized replacement or you independently verified that replacing that exact path is safe.
36
+ - Add `--force` only for that verified replacement. It atomically replaces the completed destination; downloads do not use `--yes`.
37
+ - Keep `-o/--output` separate from `--dest`: output selects where the receipt is written, while destination selects the downloaded file.
38
+ - Validate the receipt fields, confirm `file_path` exists, and verify the saved file is non-empty and not a Moodle login page or unresolved resource wrapper. Command success alone is not proof of valid file content.
@@ -0,0 +1,57 @@
1
+ # Forums
2
+
3
+ Read this file for forum discovery, title or body search, discussion reading, grouped forums, unread posts, or rendering checks.
4
+
5
+ ## Default Search
6
+
7
+ Start with the narrowest high-level command:
8
+
9
+ ```bash
10
+ moodle forums search QUERY --json
11
+ ```
12
+
13
+ Refine it with:
14
+
15
+ - `--course COURSE` to restrict the course.
16
+ - `--forum FORUM_OR_URL` to restrict the forum.
17
+ - `--unread-only` for unseen content.
18
+ - `--titles-only` to avoid fetching post bodies.
19
+ - `--list --limit N` for a shortlist.
20
+ - `--body` only when the winning snippet is insufficient.
21
+ - `--limit-forums N` and `--limit-discussions N` to bound large-site scans.
22
+
23
+ Use `moodle forums search QUERY --json` and narrow with `--limit` when only a few matches are needed.
24
+
25
+ When one request combines search with the full matching post, use one command:
26
+
27
+ ```bash
28
+ moodle forums search QUERY --course UNIT --limit 1 --json
29
+ ```
30
+
31
+ Reserve `forum discussion` for an existing discussion ID or URL, or for selecting a known post ID.
32
+
33
+ ## Browse or Open Directly
34
+
35
+ | Need | Command |
36
+ | --- | --- |
37
+ | List forum activities | `moodle forums UNIT --json` |
38
+ | List discussions in one forum | `moodle forums show FORUM_OR_URL --json` |
39
+ | Read a discussion | `moodle threads show DISCUSSION_OR_URL --json` |
40
+ | Read one post | `moodle threads show DISCUSSION_OR_URL --post POST_ID --json` |
41
+ | Include full bodies in terminal format | `moodle threads show DISCUSSION_OR_URL --body --table` |
42
+
43
+ Skip discovery when the user already supplied a discussion URL. Use `forum discussions` when they supplied a forum view URL and want nearby threads.
44
+
45
+ Grouped forums are resolved automatically. An empty default group page does not prove the forum has no discussions.
46
+
47
+ ## Structured Forum Content
48
+
49
+ Prefer these fields over text heuristics:
50
+
51
+ - `image_urls` for original images
52
+ - `links` for extracted hyperlinks
53
+ - `tables` for table rows and headers
54
+ - `group_id` and `group_name` for group context
55
+ - `unread` and `time_created` for unread/recent requests
56
+
57
+ The branch is complete when the selected discussion or post matches the query and the answer retains the source URL.
@@ -0,0 +1,31 @@
1
+ # Maintenance
2
+
3
+ Read this file for CLI upgrades or agent-skill installation.
4
+
5
+ ## Update the CLI
6
+
7
+ Check the npm registry without changing the installation:
8
+
9
+ ```bash
10
+ npm view moodle-cli version
11
+ ```
12
+
13
+ Upgrade an npm installation with `npm install -g moodle-cli@latest`. Standalone binaries are available from GitHub Releases.
14
+
15
+ If the registry check fails, verify network access and retry before proposing an upgrade command.
16
+
17
+ ## Install the Agent Skill
18
+
19
+ Show skill metadata with:
20
+
21
+ ```bash
22
+ moodle skills
23
+ ```
24
+
25
+ Install from the published repository with:
26
+
27
+ ```bash
28
+ moodle skills add
29
+ ```
30
+
31
+ Extra arguments are passed to the shared `skills` CLI, for example `moodle skills add --agent codex`.
@@ -0,0 +1,31 @@
1
+ # Output and Errors
2
+
3
+ Read this file when choosing an output mode, filtering fields, consuming errors, or interpreting exit codes.
4
+
5
+ ### Output Contract
6
+
7
+ - `--json` writes JSON to stdout.
8
+ - `--yaml` writes YAML to stdout when supported.
9
+ - `--table` forces human-readable table/tree output.
10
+ - When stdout is not a TTY, commands default to JSON unless `--table` is set.
11
+ - `--fields a,b,c` keeps only listed top-level fields. Arrays apply the field filter to each item.
12
+ - Invalid `--fields` values are usage errors and list valid fields.
13
+ - Structured errors use `{ok:false,error:{code,message,hint},exit_code}` on stderr.
14
+
15
+ Exit codes:
16
+
17
+ | Code | Meaning |
18
+ | --- | --- |
19
+ | 0 | Success |
20
+ | 1 | Network, configuration, or unexpected error |
21
+ | 2 | Usage error |
22
+ | 3 | Authentication error |
23
+ | 4 | Requested course, activity, forum, or discussion was not found |
24
+ | 5 | Moodle rejected a well-formed request |
25
+
26
+ ## Agent Handling
27
+
28
+ - Parse structured stdout locally and return only the facts the user requested.
29
+ - Treat stderr as the error channel; JSON mode emits one parseable error object there.
30
+ - Use the exit code to distinguish authentication/configuration, usage, not-found, and unexpected failures.
31
+ - Retry only after acting on the error hint. A repeated authentication failure needs a fresh login or session source, not another identical command.
@@ -0,0 +1,27 @@
1
+ # Profile and Courses
2
+
3
+ Read this file for identity, enrolled-course discovery, course sections, or course activity lists.
4
+
5
+ ## Choose the Command
6
+
7
+ | Need | Command |
8
+ | --- | --- |
9
+ | Authenticated user and site | `moodle user --json` |
10
+ | Enrolled units | `moodle units --json` |
11
+ | Sections and nested activities | `moodle units show UNIT --json` |
12
+ | Flat activity list | `moodle activities UNIT --json` |
13
+
14
+ `UNIT` accepts a numeric ID or a unique name match. When a name could match several units, run `moodle units --json`, identify the intended unit, and continue with its ID.
15
+
16
+ ## Agent Steps
17
+
18
+ 1. Use `user` only for account or site identity.
19
+ 2. Use `units` for discovery and ID resolution.
20
+ 3. Use `course` when section placement matters; use `activities` when the user wants a flat inventory.
21
+ 4. Use `--fields` only for fields present in the returned objects, for example:
22
+
23
+ ```bash
24
+ moodle units --json --fields id,shortname,fullname
25
+ ```
26
+
27
+ The branch is complete when the requested course or activity facts are tied to an unambiguous course ID.
@@ -0,0 +1,91 @@
1
+ # Setup and Authentication
2
+
3
+ Read this file for installation, first-run configuration, browser-session reuse, or authentication recovery.
4
+
5
+ ## Install
6
+
7
+ Prefer the published npm package:
8
+
9
+ ```bash
10
+ npm install -g moodle-cli
11
+ moodle --version
12
+ ```
13
+
14
+ Use `npx moodle-cli --help` for a one-off run. Existing PyPI users should migrate with:
15
+
16
+ ```bash
17
+ uv tool uninstall moodle-cli
18
+ npm install -g moodle-cli
19
+ ```
20
+
21
+ Standalone binaries are available from GitHub Releases for supported platforms.
22
+
23
+ ## Configure the Moodle Site
24
+
25
+ Set `MOODLE_BASE_URL` to the Moodle site root, such as `https://school.example.edu`. A URL ending in `/login/index.php`, `/my/`, or another page is invalid.
26
+
27
+ For an interactive first run, allow the CLI to prompt for the root URL and save it under `~/.config/moodle-cli/config.yaml`.
28
+
29
+ ## Authenticate
30
+
31
+ The CLI tries these session sources:
32
+
33
+ 1. `MOODLE_SESSION`
34
+ 2. A fresh local session cache
35
+ 3. Supported browser cookies
36
+ 4. `okta-auth-cli`
37
+
38
+ For automatic Okta login:
39
+
40
+ ```bash
41
+ uv tool install okta-auth-cli
42
+ okta config
43
+ ```
44
+
45
+ Validate setup with:
46
+
47
+ ```bash
48
+ moodle user --json
49
+ ```
50
+
51
+ Setup is complete when this returns the authenticated Moodle user.
52
+
53
+ ## Keep the Session Alive
54
+
55
+ Moodle expires idle sessions server-side (often a few hours). To avoid re-running SSO logins:
56
+
57
+ ```bash
58
+ moodle auth status --json # cache freshness + server session state
59
+ moodle auth keepalive --json # renew once (re-login from browser/okta cookies if expired)
60
+ moodle auth keepalive install # macOS launch agent, renews every 30 min
61
+ moodle auth keepalive install --interval 15
62
+ moodle auth keepalive uninstall
63
+ moodle auth login --json # extract a session; open the browser if needed
64
+ ```
65
+
66
+ On Linux, schedule `moodle auth keepalive --json` with cron instead of `install`.
67
+
68
+ `moodle auth login` first checks local session sources. If none is valid, it opens Moodle's login page in the system browser and waits up to two minutes for the completed SSO/OAuth login.
69
+
70
+ ## Recover Failures
71
+
72
+ - **No usable MoodleSession**: sign in to Moodle in a supported browser and retry; otherwise configure `okta-auth-cli` or provide `MOODLE_SESSION` through the environment.
73
+ - **Configured site is wrong**: correct `MOODLE_BASE_URL` or the saved `base_url`, then rerun `moodle user --json`.
74
+ - **Cached session expired**: run `moodle auth login`, or rerun with `--no-cache` once so the CLI reacquires a session.
75
+ - **Non-interactive config error**: set `MOODLE_BASE_URL`; a pipe cannot answer the first-run prompt.
76
+
77
+ ## Manage the Private MCP Server
78
+
79
+ Use the lifecycle commands instead of asking the user to copy cookies, tokens, Wrangler commands, or client configuration:
80
+
81
+ ```bash
82
+ moodle mcp deploy
83
+ moodle mcp status --json
84
+ moodle mcp login
85
+ moodle mcp connect
86
+ moodle mcp remove
87
+ ```
88
+
89
+ `moodle mcp deploy` validates the local Moodle session, deploys and verifies a private Cloudflare Worker, installs local renewal, and connects detected clients. The default bridge mode keeps the Bearer token out of client files. Use `moodle mcp login` when status reports `SESSION_EXPIRED`; use `moodle mcp deploy --repair` when Cloudflare authorization or managed deployment state needs repair.
90
+
91
+ Never print or request the raw Moodle cookie, MCP access token, session sync token, or sesskey. An advanced operator may pipe a cookie directly to `moodle mcp session push --stdin`; do not place it in arguments or shell history.