amazing-marvin-complete-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tasks | {
"list": {},
"cancel": {},
"requests": {
"tools": {
"call": {}
},
"prompts": {
"get": {}
},
"resources": {
"read": {}
}
}
} |
| tools | {
"listChanged": true
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| test_connectionA | Test authentication against Marvin's API. Returns OK if the apiToken works. |
| create_taskA | Create a task in Amazing Marvin. Prefer priority/frog over dates where possible. The title is stored verbatim: this tool disables the server's shortcut parsing (X-Auto-Complete: false, verified against the live API 2026-08-20), so quick-add syntax like '#Category', '~15', '+YYYY-MM-DD' and '*p2' is NOT parsed — '#' in titles (e.g. ticket references) is therefore safe. Without this, every '#word' would corrupt the task (the string is stored unresolved as parentId, making the task invisible). Use the parameters instead: parent_id, day, priority, time_estimate_minutes, label_ids. Note: startDate/endDate CANNOT be set here — /addTask ignores them (verified against the live API 2026-08-29). Set them with update_task after creation. A clock time (Time/taskTime) on the task: fully possible in Marvin, but it is set in the APP, not via this MCP — an MCP limitation, NOT a Marvin limitation. A set Time automatically becomes (with auto-created reminders enabled in the user's settings) a reminder at that time; the task does NOT become an event and blocks no time (time blocking = time blocks). The reason for the app route is the double-write sync — see set_reminder. Strategy-dependent fields (planned_week/month, review_date, backburner, is_reward/reward_points, the sections) are stored even when the strategy is disabled in the app — they just are not shown in the UI then. |
| mark_doneA | Mark a task as done (via /markDone, with the correct timezone offset).
Tasks ONLY: for projects the API responds 400 'Can only mark Tasks done
with this API' (verified live 2026-08-19) — projects are completed in the
Marvin app (done=true via /doc/update would technically work but skips
the app's side effects). Safe for generated instances of recurring tasks
too (verified live): the instance ID is deterministic
('YYYY-MM-DD_'), so no duplicates can occur.
Error codes (live-tested 2026-08-29): 404 = the task does not exist
(deleted/wrong ID — unlike /doc/update, which responds 500);
400 = already marked done (harmless, nothing changes). Stops running
time tracking on the task and writes the tracking interval to
task.times (receipt also in /tracks; live-tested 2026-09-02 in two
runs — on 2026-08-29 times was NOT written, the server behavior has
changed; a direct /track STOP still does not write times, see
stop_tracking). Pinned task: the original stays open and
pinned as documented; the completed copy gets its own ID and can be
found via get_done_items. Leaves |
| unmark_doneA | Undo a completion (sets done=false and clears doneAt via /doc/update). Requires the Full Access Token. Safe for generated instances of recurring tasks too (verified live). Note: any kudos from the completion are not adjusted; awarded reward points can however be undone with unclaim_reward_points. A permanent 500 = the document does not exist (deleted or wrong ID; the server responds 500 instead of 404, verified live 2026-08-29). |
| update_taskA | Update fields on an existing TASK via /doc/update (Full Access Token). For categories/projects, use update_category_or_project. For priority, use set_priority. Always complete tasks via mark_done, never here. Strategy-dependent fields (start/end date, planned_week/month, review_date, backburner, orbit, the sections) can be set even when the strategy is disabled in the app — they just are not shown in the UI then. A clock time (Time/taskTime) and the task's reminder fields are set in the APP, not here — an MCP limitation (double-write sync, see set_reminder), NOT a Marvin limitation: Marvin fully supports times on tasks. Note on recurring tasks: never edit recurrence rules here — neither on a generated instance (recurring=true, id 'YYYY-MM-DD') nor on the generator document. Do that editing in the Marvin app. Simple field changes (title, note) on a single instance are fine. Note: Marvin's server can sporadically respond 500 on /doc/update (transient and atomic — no partial write); just retry. But a PERMANENT 500 (persists across retries) means the document does not exist — deleted, or a wrong/never-existing ID (the server responds 500 instead of 404 for missing IDs, verified live 2026-08-29). Fetch a fresh ID via get_categories/get_children. |
| set_priorityA | Set or change priority (isStarred) and/or the frog marker on an existing TASK. Requires the Full Access Token. The app's four levels are stored as isStarred 3/2/1/-1 (Most/Very/Important/Low priority; -1 verified against the app's code and live-tested 2026-08-30). Low priority is shown in the app only with 'Enable low priority' on in the Priorities strategy; the value is stored regardless. Does not apply to projects: they use the string field priority ('high'/'mid'/'low' = Most/Very/Important; no Low level), not isStarred — set it via update_category_or_project. A permanent 500 = the task does not exist (deleted or wrong ID) — the server responds 500 instead of 404 (verified live 2026-08-29); fetch a fresh ID. |
| delete_taskA | Delete a task/document PERMANENTLY via /doc/delete (Full Access Token). Marvin's trash is client-side — an API deletion bypasses it and CANNOT be undone (deleting in the app instead puts the item in the trash, where it can be restored — prefer the app when undo matters). Only use when the user explicitly wants a deletion. Never delete the generator document of a recurring task here (risk of the whole series disappearing without the app's cleanup logic) — remove the recurrence in the Marvin app instead. THE APP'S VIEW (live-tested 2026-09-12, PWA + Windows desktop app 1.70.0): an API deletion is NOT rendered in an open Marvin client — neither waiting nor switching views helps. First confirm the server with get_children on the parent (the task should be missing), then ask the user to reload the client BEFORE the row is touched in the app: F5 in the web app/PWA, restart of the desktop app. Editing the stale row in the app can RECREATE the document via the client's conflict resolution (observed once, 2026-09-12, in one of the two clients — which one is not recorded: row still shown after the deletion, unscheduled with the x button in the app, document back on a new _rev 84-97 s after the deletion; reported upstream). If the user has the app open: suggest deleting IN THE APP first (goes to the trash, no conflict with the app's own copy); API deletion when the user explicitly wants it, and then with the reload rule above. |
| get_today_itemsA | Get open tasks/projects with |
| get_due_itemsA | Get open tasks/projects with a deadline today or earlier. |
| get_done_itemsA | Tasks completed on a given date (doneAt within that day, configured
timezone) — regardless of priority and deadline. Built on the
UNDOCUMENTED endpoint GET /doneItems?date= (missing from the OpenAPI
spec and the wiki; live-tested 2026-08-30, may disappear): it filters
on the task's |
| get_childrenA | Get open tasks and subprojects in a category/project. Returns direct children only — call again for deeper levels. Note: orphans (tasks whose parentId points to a deleted/non-existent document) do NOT show up under 'unassigned' — only in get_today_items/get_due_items if they have a day/dueDate (live-tested 2026-08-29). Orphans are repaired by running FIX_CYCLES() in the app's console (a documented troubleshooting path). |
| get_categoriesA | Get all categories and projects (the whole hierarchy; parentId='root' is the top level). Use to find the right parent_id when creating/moving. |
| create_category_or_projectA | Create a category (via /doc/create, Full Access Token) or a project (via /addProject). Categories can contain categories; projects cannot. day/due_date/priority/frog are rejected for kind='category' for a structural reason, not a technical one: a category can never be completed or checked off, and deadline, scheduling, priority and frog belong to things that can be finished — projects and tasks. The API accepts the fields on categories (live-tested 2026-09-11) but they are not meaningful there (rule 2026-09-11). label_ids applies to both categories and projects. startDate/endDate cannot be set at creation (/addProject ignores them, verified live 2026-08-29) — use update_category_or_project afterwards. Note: project titles must not contain '#word' — /addProject has the same corruption bug as /addTask (the string is stored unresolved as parentId and the project becomes invisible) but ignores the X-Auto-Complete header (verified against the live API 2026-08-20), so the client blocks it locally before any API call. Category titles are unaffected (/doc/create parses nothing). |
| update_category_or_projectA | Update fields on an existing CATEGORY or PROJECT via /doc/update (Full Access Token). For tasks, use update_task. Fields marked 'Projects ONLY' (day/due_date/priority/frog) are blocked for categories: if any of them is given, the tool first reads the document (1 extra API call) and refuses if it is a category. The reason is structural, not technical: a category can never be completed or checked off, and deadline, scheduling, priority and frog belong to things that can be finished — projects and tasks. The API accepts the fields on categories (live-tested 2026-09-11) but they are not meaningful there (rule 2026-09-11). label_ids applies to both categories and projects. Strategy-dependent fields (start/end date, planned_week/month, review_date, orbit) can be set even when the strategy is disabled in the app. Do not complete projects here (done via /doc/update skips the app's side effects) — that is done in the Marvin app. Note: Marvin's server can sporadically respond 500 on /doc/update (transient and atomic); just retry. But a PERMANENT 500 (persists across retries) means the document does not exist — deleted, or a wrong/never-existing ID (the server responds 500 instead of 404 for missing IDs, verified live 2026-08-29). Fetch a fresh ID via get_categories/get_children. |
| convert_category_or_projectA | EXPERIMENTAL: Convert project→category or category→project IN PLACE via /doc/update (Full Access Token; there is no official conversion endpoint, and this relies on undocumented server behavior that Marvin could change). Same _id, createdAt and children remain — conversion is a pure type change (verified against the live API 2026-08-29: the server accepts and persists the change in both directions, and the app renders correctly after an API-set change). LOSSLESS BY DEFAULT (since 1.5.0): only type is changed — the same semantics as the app's correct conversion path (the right-click/hover menu, verified as a lossless round trip 2026-08-30: all project fields incl. firstScheduled preserved through project→category→project). Project fields remaining on the category are then intentional round-trip data; the type guard in update_category_or_project only prevents NEW project fields from being written to it. If you want a clean category for a permanent conversion: set clear_project_fields=True (mimics the app's Edit Settings path — a bug in their tracker; also clears firstScheduled, which that path otherwise leaves behind) and receive the values in removed_project_fields. Note: the app's correct path (right-click/hover) is not in the menu by default — it is added via the gear icon directly in the right-click menu → Add action (app-verified 2026-08-31), so unmodified apps only show the buggy path. Do NOT convert a category that contains subcategories into a project — projects cannot contain categories (risk of orphans/cycles; check get_children first). |
| list_habitsA | Get all habits as full documents incl. title, settings and history ([time1, value1, time2, value2, ...], unix ms). Requires the Full Access Token (the raw variant of /habits). Important (verified live 2026-08-19): non-raw /habits would be wrong here — it reads the server's tracking registry, which is created lazily on the first recording, so never-recorded habits are missing entirely, and the responses lack titles. |
| get_habitA | Get the server's tracking record for a single habit (habitId + full history — the source of truth for recordings). Note: the response lacks title and settings; those are in list_habits. |
| record_habitA | Record (or undo) a habit. Also updates the sync database (updateDB=true) so the Marvin app shows the change immediately. |
| get_today_time_blocksA | Get today's time blocks. The API response lacks the category link (known limitation, MarvinAPI issue #65); the mapping is therefore fetched separately from the profile setting plannerSmartLists (key = normalized block title). |
| create_time_blockA | EXPERIMENTAL: Create a time block via /doc/create (db='PlannerItems', Full Access Token). No official endpoint exists. Verify in the app that the block looks right. |
| get_tracked_itemA | Show which task is currently being time-tracked (if any). |
| start_trackingB | Start time tracking for a task. |
| stop_trackingA | Stop time tracking for a task. Note (documented API limitation, confirmed live 2026-09-02): the task's own times/duration fields are not updated by /track STOP — the tracking only lands in /tracks (get_time_tracks). Exception: mark_done during active tracking now writes task.times (see mark_done). |
| get_time_tracksA | Get time-tracking history for the given tasks (the source of truth, max 100 per call). |
| get_kudosA | Get kudos, level and kudosRemaining (Marvin's XP system). Note: kudos is separate from reward points (the reward currency) — the point balance is in get_account_info. nextMultiplier only exists in /me, not here (known limitation, MarvinAPI issue #5). |
| claim_reward_pointsA | Award reward points for a completed task (or a manual celebration). Note: mark_done does not award a task's rewardPoints automatically through the API (cf. issue #6 about kudos) — call this tool separately afterwards. WARNING: a MANUAL award CANNOT be undone through the API (verified live 2026-08-19: unclaim returns 404, negative points are rejected with 400). The only compensation is spend_reward_points for the same amount (which however inflates the spent statistics) — award MANUAL points thoughtfully. |
| unclaim_reward_pointsA | Undo a point award (e.g. after a misclick, or when the task was un-completed with unmark_done). Only works for awards tied to a real task ID: Marvin's server stores no entry for MANUAL awards (verified live 2026-08-19, /unclaimRewardPoints responds 404 'No such entry'). Compensate a MANUAL award with spend_reward_points for the same amount instead. |
| spend_reward_pointsA | Spend reward points on a reward. Note (verified live): the API responds 500 Internal Server Error if the balance would go negative — check the balance (get_account_info) before large purchases. |
| reset_reward_pointsA | Reset reward points PERMANENTLY: deletes the whole earn/spend history and sets the balance to 0 (Full Access Token). CANNOT be undone — only use when the user explicitly asks for it. |
| get_labelsA | Get all labels (for label_ids when creating/filtering). |
| get_goalsA | Get all goals with status and check-in data. |
| get_remindersA | Get all server-side reminders (push notifications to the phone). Requires the Full Access Token. |
| set_reminderA | Set a standalone push reminder (type 'M', requires the Marvin mobile app to be logged in). WARNING — data integrity: a task reminder in Marvin consists of TWO writes that only the app keeps in sync — reminder fields on the task document itself (taskTime, reminderTime, reminderOffset, snooze, autoSnooze) AND a server-side entry via /reminder/set. This tool only writes the server-side entry. Setting reminder_id to a task ID therefore does NOT link the reminder to the task in the app's UI, and risks an orphaned/inconsistent server-side entry (only visible through get_reminders). Task-linked reminders are set in the Marvin app; use this tool for standalone reminders only. Facts about time on tasks (live data 2026-09-02): the Time field in the app (taskTime) is a clock time that — with auto-created reminders enabled in the user's settings — automatically becomes a reminder at the same time (reminderTime = the clock time, offset 0); Time and reminder are in practice the same thing there. That this MCP does not set times on tasks is therefore an MCP limitation, never a Marvin limitation. |
| delete_reminderA | Delete one or more server-side reminders. Note: for a reminder that belongs to a task (set in the app), only the server-side entry is removed — the task document's reminder fields are not cleared, so the app may show it as active and recreate it. Prefer using this against standalone reminders (type 'M') or to clean up orphaned entries from get_reminders. |
| create_eventA | EXPERIMENTAL: Create a calendar event. Calendar sync happens in the client — the Marvin app must be running on some device for the event to sync onwards to an external calendar. |
| get_account_infoA | Get account info (/me): email, tracking status, etc. |
| get_rate_limit_statusA | Show how many Marvin API calls have been made today (budget 1440/day, shared by all tools). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 37 tools
Most tools have clear distinct purposes, but there is semantic overlap: update_task vs set_priority (explicitly warns to use set_priority for priority), mark_done vs update_task, and create_category_or_project vs convert_category_or_project. The descriptions are exceptionally detailed and often clarify boundaries, preventing lower scoring, but an agent must read carefully to avoid misselection.
The vast majority follow a consistent snake_case verb_noun pattern (get_*, create_*, update_*, delete_*, mark_done, unmark_done, start_tracking, stop_tracking). A couple of deviations like 'mark_done' (verb without explicit object) and 'test_connection' are minor and readable.
37 tools is heavy for a task-management API integration. While the domain is broad (tasks, projects, categories, habits, rewards, time tracking, calendar, reminders), many tools could be consolidated (e.g., separate getters for today, due, done, children), and the count strains the 'well-scoped' ideal.
The surface covers a large portion of the domain with CRUD for tasks, categories/projects, time tracking, rewards, reminders, habits, and read operations for various views. Some gaps exist (e.g., no dedicated tool to set task time/reminder fields, no batch operations), but agents can work around most missing operations via update_task or other tools.