Morgen
Skill Axect/skills/morgen
Reusable skills for AI coding agents (Claude Code, Codex, Forge) covering paper review, commit triage, GPU rentals, reference search, research logs, image-prompt composition, and more.
npx -y skills add Axect/skills --skill morgenAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Manage calendars, events, tasks, and tags through the Morgen API (docs.morgen.so). Use when the user mentions Morgen, asks to list/create/update/delete calendar events or tasks across Google Calendar, Microsoft 365, iCloud, Fastmail, or CalDAV accounts connected through Morgen, or wants to query connected integrations and tags. Credentials live at `~/.config/morgen-skill/credentials.json`.
SKILL.md
12.5 KB, as published. Nobody here has run it
Morgen
Unified calendar + task operations via the Morgen REST API v3. Morgen is a single surface over Google Calendar, Microsoft 365, iCloud, Fastmail, and CalDAV accounts, plus native Morgen tasks. This skill wraps the HTTP API with curl + jq helpers.
Trigger conditions
Invoke this skill when the user says any of:
- "list my calendars" / "what calendars do I have in Morgen" →
scripts/calendars.sh list - "show my events for <date range>" / "what's on my calendar" →
scripts/events.sh list - "create an event" / "schedule a meeting" →
scripts/events.sh create - "update event" / "delete event" / "move event" →
scripts/events.sh update|delete - "what's on my TODO list" / "show my todos" / "today's tasks" / "overdue tasks" →
scripts/todos.sh list|today|overdue - "add a todo" / "new task for ..." →
scripts/todos.sh add - "mark X done" / "complete X" / "reopen X" →
scripts/todos.sh done|reopen - "sync my tasks" / "refresh todos" →
scripts/todos.sh sync - "list my tasks" / "raw tasks list" (API passthrough without cache) →
scripts/tasks.sh list - "create a task" / "add a task" →
scripts/tasks.sh create(or prefertodos.sh addwhich also updates the cache) - "complete task" / "close task" / "reopen task" →
scripts/tasks.sh close|reopen - "list integrations" / "what accounts are connected" →
scripts/integrations.sh accounts - "list tags" / "create a tag" →
scripts/tags.sh list|create - "set up Morgen" / "configure Morgen" / credentials file missing → follow the Setup flow section below (Claude orchestrates via
scripts/setup.sh --stdin)
For personal TODO workflows, prefer todos.sh over the raw tasks.sh: it caches the task list locally (~/.cache/morgen-skill/todos.json) so filtered reads cost 0 rate-limit points.
Prerequisites
Before any operation, check the credentials file exists:
test -f ~/.config/morgen-skill/credentials.json
If it does not exist, run the skill-orchestrated setup flow below.
Dependencies: curl, jq. If missing, the scripts exit 127 with a message.
Setup flow (skill-orchestrated)
setup.sh supports three modes:
- Interactive (TTY only) —
bash scripts/setup.sh. User runs this themselves in a terminal when Claude can't. - Non-interactive via stdin —
bash scripts/setup.sh --stdin <<< "$KEY". Preferred for skill orchestration; the key never appears in this script's argv. - Non-interactive via flag —
bash scripts/setup.sh --key <KEY>. Convenient but the key is briefly visible in/proc/<pid>/cmdline. Acceptable on a personal single-user machine only.
When the user says "set up Morgen" (or any operation is blocked by missing credentials)
- Check if credentials already exist:
test -f ~/.config/morgen-skill/credentials.json- If they exist, ask whether to re-register (re-run only if the user confirms).
- If missing, proceed.
- Ask the user to paste their Morgen API key, including this exact caveat:
Your key will be stored at
~/.config/morgen-skill/credentials.json(mode 600). Only paste it here if you trust this terminal and session transcript. Get the key at https://platform.morgen.so → Developers API. - Once the user replies with the key, run the
--stdinmode so the key stays out of argv. Quote the key literally inside the here-string:
The script verifies the key againstbash scripts/setup.sh --stdin <<< '<PASTED_KEY>'/v3/calendars/list(HTTP 200 = valid) and writes the credentials file with mode 600. - On success, confirm to the user with the
Setup complete.line the script emits, and suggest the natural next step (e.g.todos.sh syncorcalendars.sh list). - On failure (non-zero exit), show the stderr verbatim and ask whether to retry with a fresh key.
Do not echo the API key back in your own messages, and do not log it. If you must reference it, say "the key you provided".
Do not run setup unprompted. The triggers are: explicit user request ("set up Morgen", "configure Morgen"), or a blocked operation that encountered exit code 2 (missing credentials) / 3 (rejected key).
Authentication
Morgen uses a static API key sent as:
Authorization: ApiKey <KEY>
The key is stored at ~/.config/morgen-skill/credentials.json as:
{"api_key": "..."}
There is no OAuth refresh flow — if the key is revoked, re-run setup.sh.
Rate limits
- 100 points per 15-minute window, per user.
/listendpoints cost 10 points each. All other endpoints cost 1 point.- Response headers to watch:
RateLimit-Limit,RateLimit-Remaining,RateLimit-Reset,Retry-After. - On 429, respect
Retry-After(seconds) before retrying. The helper surfaces the 429 response body so you can see the wait period.
Practical implication: avoid looping list calls. Cache accountId and calendarId values from one calendars list or integrations accounts call and reuse them for the whole session.
Script usage
All scripts live in this skill directory's scripts/ folder.
setup.sh — one-time API key registration
bash scripts/setup.sh # interactive (TTY required)
bash scripts/setup.sh --stdin <<< "$K" # non-interactive, key via stdin
bash scripts/setup.sh --key "$K" # non-interactive, key via argv (argv visible in /proc briefly)
All modes verify the key against /v3/calendars/list before writing ~/.config/morgen-skill/credentials.json (mode 600). See the Setup flow section above for the end-to-end skill-orchestrated flow.
calendars.sh — calendars
bash scripts/calendars.sh list
bash scripts/calendars.sh update <accountId> <calendarId> <metadata_json>
list returns the calendars[] array. Each calendar has id, accountId, integrationId, name, color, myRights, and morgen.so:metadata. Always call this once per session to resolve (accountId, calendarId) pairs — events endpoints require both.
events.sh — calendar events
bash scripts/events.sh list <accountId> <calendarIds> <startISO> <endISO>
bash scripts/events.sh create <json_body>
bash scripts/events.sh update <json_body> [seriesUpdateMode]
bash scripts/events.sh delete <accountId> <calendarId> <eventId> [seriesUpdateMode]
calendarIdsis a comma-separated list.start/endare ISO 8601; max window is 6 months.seriesUpdateMode∈ {single(default),all,future} for recurring events.createbody requiresaccountId,calendarId,title,start,duration(ISO 8601 duration likePT1H),timeZone,showWithoutTime.updatebody requiresaccountId,calendarId, and eitheridor (masterEventId+recurrenceId).- Update gotcha:
start,duration,timeZone, andshowWithoutTimeform an atomic group — if you send any one of them, you must send all four, or the API returns HTTP 400 (MRG_ERR_VALIDATION_FAILED: Properties start, duration, timeZone and showWithoutTime must be provided together). To patch just one time field (e.g. changeduration), include the existing values for the other three.timeZonemay benullfor floating events. Other fields (title,description,location, etc.) can be patched individually without this constraint.
tasks.sh — Morgen tasks
bash scripts/tasks.sh list [limit] [updatedAfterISO]
bash scripts/tasks.sh get <taskId>
bash scripts/tasks.sh create <json_body>
bash scripts/tasks.sh update <json_body>
bash scripts/tasks.sh move <taskId> [previousId] [parentId]
bash scripts/tasks.sh close <taskId> [occurrenceStart]
bash scripts/tasks.sh reopen <taskId> [occurrenceStart]
bash scripts/tasks.sh delete <taskId>
createrequirestitle; optional:description,due,timeZone,priority,progress,tags,relatedTo.updaterequiresid; other fields are patch-style.close/reopentake an optionaloccurrenceStartfor recurring task instances.- Mutation endpoints return HTTP 204 (no body) on success — the helper prints
{"ok":true}.
integrations.sh — connected accounts and providers
bash scripts/integrations.sh accounts
bash scripts/integrations.sh providers
accounts: lists the user's connected accounts withaccountId, provider, auth status.providers: lists available integration providers (no auth required).- Connecting or disconnecting accounts must be done in the Morgen app, not via API.
todos.sh — cached TODO workflow (recommended for personal task management)
bash scripts/todos.sh sync # refresh local cache (1 list call, 10 pts)
bash scripts/todos.sh list [--all] [--tag <id>] [--priority <n>]
bash scripts/todos.sh today # tasks due today
bash scripts/todos.sh overdue # not completed, due before now
bash scripts/todos.sh show <idOrPrefix>
bash scripts/todos.sh add <title> [--due <ISO>] [--priority <n>] [--tz <IANA>] [--description <text>]
bash scripts/todos.sh done <idOrPrefix>
bash scripts/todos.sh reopen <idOrPrefix>
bash scripts/todos.sh delete <idOrPrefix>
Design: manual sync, cache-first reads, API-first writes.
syncis the only command that calls/tasks/list(10 pts). Do it once per session.list,today,overdue,showread from the local cache → 0 rate-limit points, instant.add,done,reopen,deletehit the API (1 pt each) and then patch the local cache in place. If the API call fails, the cache is untouched.- Short-ID prefixes (e.g.
aaaa1111) resolve against the cache. Ambiguous prefixes error out with the list of matches. - Stale-cache warning fires automatically when the cache is older than
MORGEN_STALE_SECONDS(default 3600 = 1 hour). Output still works; only a stderr notice appears. - No automatic sync, no conflict resolution — if you (or the mobile app) diverges, the next
syncwins. For personal use this is almost always what you want.
Environment overrides:
MORGEN_CACHE_DIR— cache directory (default~/.cache/morgen-skill)MORGEN_STALE_SECONDS— stale-warning threshold in seconds (default3600)
When to prefer tasks.sh instead:
- you explicitly want a fresh read-through to the API
- you're scripting something that doesn't need the local cache
- you need non-TODO task features (
move, recurring occurrence closes, etc.)
tags.sh — tags
bash scripts/tags.sh list [limit] [updatedAfterISO]
bash scripts/tags.sh get <tagId>
bash scripts/tags.sh create <name> [hexColor]
bash scripts/tags.sh update <tagId> [name] [hexColor]
bash scripts/tags.sh delete <tagId>
delete is a soft-delete — the tag reappears in sync payloads with deleted: true.
Path rules & invariants
- Do not hardcode
accountIdorcalendarId— resolve them fresh fromcalendars listorintegrations accountsbecause IDs can change if a user reconnects an account. - Event
startis an ISO 8601 local datetime without offset (e.g.2026-04-21T14:00:00). The separatetimeZonefield carries the offset. Do not pass aZ-suffixed UTC string instart. durationis ISO 8601 duration, not seconds.PT25M,PT1H,PT1H30M.- Event
liststart/endare ISO 8601 UTC (withZ), unlike event-bodystart. - Task
duefollows the same local-datetime +timeZoneconvention.
Error handling
If any script exits non-zero, show its stderr to the user verbatim. Do not retry auth errors automatically (exit code 3) — surface them so the user can re-run setup.
Exit code reference:
- 0 — success
- 1 — bad argument, missing positional, or malformed JSON
- 2 — credentials.json missing (→ user should run
setup.sh) - 3 — API key rejected, HTTP 401/403 (→ user should re-run
setup.sh) - 4 — Morgen returned 404 (resource not found)
- 5 — Other API error (timeout, 5xx, unexpected body)
- 6 — Rate-limited, HTTP 429 (respect
Retry-Afterbefore retrying) - 64 — usage error
- 127 — missing dependency (
curlorjq)
Resources
references/api-reference.md: endpoint table with fields, methods, and notes.references/examples.md: common workflows (scheduling a meeting, triaging tasks, bulk tag cleanup).- Upstream docs: https://docs.morgen.so/