AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Marvin Mcp

mcp-recon2026-marvin-mcp · by Recon2026

An MCP server for the Amazing Marvin task manager — read and write tasks, projects, and time tracking from any MCP-compatible AI assistant.

No reviews yet
0 installs
21 views
0.0% view→install

Install

$ agentstack add mcp-recon2026-marvin-mcp

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-recon2026-marvin-mcp)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Marvin Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Marvin MCP

SPDX-License-Identifier: MIT — see [LICENSE](LICENSE).

An MCP server putting Claude in front of Amazing Marvin — see [docs/SPEC.md](docs/SPEC.md) for the full design (start there, not here, if you're implementing or reviewing behavior). This file is a macOS/Claude quickstart; see [docs/SETUP.md](docs/SETUP.md) for every platform and MCP client this project documents, including what's not yet verified.

Not affiliated with, endorsed by, or sponsored by Amazing Marvin. This project uses Amazing Marvin's public API; "Marvin" and "Amazing Marvin" appear here only to describe compatibility, not as an endorsement or as this project's own branding — no logo, wordmark, or other visual identity is borrowed, and the name is used descriptively only. Behavior documented in this repo was verified against the live API as of August 2026 and may drift as Marvin changes. Provided with no warranty of any kind — see [LICENSE](LICENSE).

19 tools, matching SPEC.md §4 in full: 10 reads, 9 writes.

Recurring tasks are read-only. This server reads and reasons about recurring tasks and their generated instances correctly (SPEC.md §3.12) but never writes recurrence: it never creates, edits, or deletes a RecurringTasks generator document, and never creates or deletes a generated instance. Set up and manage recurrence in the Marvin app — see CONTEXT.md for why this is a deliberate scope boundary rather than an unimplemented feature.

This server never writes reminders, habits, goals, events, or time blocks. Set them up, change them, or remove them in the Marvin app. Reminders were probed live and found to need two independent writes (a task-document field cluster plus a separate server-side record via POST /api/reminder/set) that only the app's own UI keeps in sync — see SPEC.md §3.13 for the reproduced failure mode, including an orphaned server-side reminder that reading (not writing) reminders was the only way to find. Habits and Goals are strategies this account has disabled entirely (SPEC.md §7, Appendix B). Events (calendar items, a separate document type from tasks) are readable only by an already-known ID — nothing in the live API enumerates them — so a write there could never be verified through this server; see SPEC.md §3.14. Time blocks are unbuilt for the same reason as Habits/Goals: the strategy is disabled, so the endpoint has nothing to return.

What it looks like

One realistic session — invented tasks, not anything from a real account:

> You: dump these before I forget — call the dentist, order more > filter cartridges, look into the co-op board election, and text Priya > back about Saturday > > Claude: Captured 4 to Inbox. > · call the dentist > · order more filter cartridges > · look into the co-op board election > · text Priya back about Saturday > > You: what should I do today > > Claude: Proposing three, not the full list: > > 1. Finish Q3 budget review (due today, ~45m) — the only hard > deadline today. > 2. Call the dentist (from this morning) — quick, keeps it from > aging into next week. > 3. Draft the co-op board election writeup (~30m) — no due date, > but it's been sitting a while and blocks two other people. > > Excluded on purpose: 6 recurring daily-checklist instances (filtered > by default — say the word to see them); order filter cartridges > (no urgency); renew passport (due in 11 weeks, not today's > problem). > > Estimated load: ~1h15m against your usual free time today. > Comfortable. > > You: anything stale I should deal with? > > Claude: One: "Draft the co-op board election writeup" — first > scheduled 23 days ago, still open. Break it down, backburner it, or > drop it? > > You: backburner it > > Claude: Done — backburnered and moved into your Backburner > project.

How the documentation fits together

| File | What it's for | Claude Code | Claude Desktop | |---|---|---|---| | [docs/SETUP.md](docs/SETUP.md) | Install, per-platform/per-client config, troubleshooting with exact error text | — | — | | [docs/SPEC.md](docs/SPEC.md) | Index into the full design (spec/*.md) — data model, tool surface, guardrails, decisions already settled (§11) | Read the index at session start; read a specific spec/*.md file when the work touches it | Not visible at all | | [CONTEXT.md](CONTEXT.md) | Why the non-obvious choices were made — read before "fixing" anything that looks like a bug | Read in full at session start | Not visible at all | | [WORKFLOWS.md](WORKFLOWS.md) | The seven workflow patterns (§6) — single canonical copy, self-contained (no § references, no file paths) | Read in full — nothing about workflows lives in CLAUDE.md anymore | Visible only if you paste it into that client's system prompt / project / custom instructions field — see docs/SETUP.md §4 | | [CLAUDE.md](CLAUDE.md) | Claude-Code-specific session behavior (read SPEC/CONTEXT first, ask before editing, venv test rule) — points to WORKFLOWS.md for everything else | Read as project instructions at session start | Not visible at all | | [DESKTOPINSTRUCTIONS.md](DESKTOPINSTRUCTIONS.md) | One-line stub — WORKFLOWS.md is the canonical text now, this file only exists so old links don't break | Can open it, but it's not one of Code's own session-start files | Not needed — paste [WORKFLOWS.md](WORKFLOWS.md) instead | | CONVENTIONS.md (gitignored — copy from [CONVENTIONS.example.md](CONVENTIONS.example.md)) | User-specific preferences that accumulate over time (§9.3) — empty on a fresh install | Read at session start | Not visible unless pasted | | logs/decisions.jsonl | Append-only decision log (§9.2) — most recent 100 lines read back in each session | Read at session start | Not visible — Desktop has no file access, so there's nothing to paste even if you wanted to |

The critical asymmetry: a Claude Desktop chat sees none of this repository — only the 19 tools' names, schemas, and descriptions over MCP, plus whatever text you've manually pasted into that client's instructions field. That's why §4.4 requires every behavioral constraint that must hold in daily use to be written into the tool description strings themselves, not just documented here. If a rule only exists in SPEC.md or CLAUDE.md, Claude Code will follow it and a Desktop session never will.

Safety notice

This server writes to your real Marvin task database. There is no delete tool and no rollback built into this project — a bad write has no undo path here beyond what you can fix by hand in the app. Take a manual backup in Marvin (Settings → Backup, or your own export routine) before first use, and again before trying anything unfamiliar or run at scale, like a large Inbox consolidation.

Both MARVIN_API_TOKEN and MARVIN_FULL_ACCESS_TOKEN grant broad account access — they are not scoped to read-only or to specific data. Keep them only in your gitignored .env; never commit them, paste them into a chat, or share them anywhere.

Quickstart (macOS, Claude)

Check your Python version before anything else:

python3 --version

You need 3.10 or newer — macOS ships 3.9 by default, which is too old. The MCP SDK requires 3.10+; that's the binding constraint, not this codebase. If yours is older:

brew install python@3.12

Skip this check and you won't get a clean error — you'll get a confusing one, later. Creating the venv with an old python3 succeeds without complaint. The failure shows up one step later, at pip install -r requirements.txt, as:

ERROR: Could not find a version that satisfies the requirement mcp[cli]==2.0.0

That's a Python-version problem, not a broken package or a network issue — nothing in that message says so. If you searched for that exact text and landed here, this is why: rerun python3 --version first.

git clone 
cd marvin-mcp

python3.12 -m venv .venv
.venv/bin/pip install --upgrade pip
.venv/bin/pip install -r requirements.txt

cp .env.example .env

Edit .env — both API tokens (Marvin → Strategies → API → Settings → View credentials) and MARVIN_TZ are required; everything else is optional and only gates the one feature it belongs to. See .env.example's own comments, or [docs/SETUP.md](docs/SETUP.md) §3 for the full walkthrough.

Verify:

.venv/bin/python src/client.py

Then connect a client — Claude Code or Claude Desktop on macOS are the two verified paths, in [docs/SETUP.md](docs/SETUP.md) §4, which also covers Windows/Linux and other MCP clients with an honest verified/ unverified marking for each. For any client other than Claude Code, paste [WORKFLOWS.md](WORKFLOWS.md) into its instructions field — without it, the assistant has the tools but none of the judgment for combining them (docs/SETUP.md §4 explains why in full).

Hit an error? [docs/SETUP.md](docs/SETUP.md) §5 has the exact text every config failure produces and where it shows up.

Requirements

  • Python 3.10+. The MCP SDK requires it; the rest of the codebase

targets 3.9 syntax but the SDK is the binding constraint. macOS ships 3.9 by default — see [docs/SETUP.md](docs/SETUP.md) §2 for install commands per platform.

  • A Marvin account with API access (Marvin → Strategies → API).

Running tests

.venv/bin/python -m unittest discover tests

Use the venv's Python, not a bare python3. tests/test_server.py needs the mcp package to import at all — under a system Python that doesn't have it, all of its tests are silently skipped, not run, and the suite still reports green. server.py's own wiring (tool signatures, delegation to src/tools/*) is exactly what that file covers, so a skip-and-pass run gives no coverage of the one layer most likely to drift when a tool's signature changes — confirmed 2026-08-11, when a stale test_server.py assertion sat silently skipped through several unrelated commits until a venv run finally caught it. python3 -m unittest discover tests still works and is useful for a fast partial check, but treat it as partial, not as "tests pass" — run the venv before reporting results.

Stdlib unittest, not pytest — kept the dependency list to exactly what the MCP SDK needs. Unit tests run against a mocked HTTP boundary and synthetic fixtures (§12.1); they don't touch the network or your Marvin data. Live verification against the real API happens by hand, per §12.2's zzz--prefixed convention — there's no doc/delete tool, so anything created that way needs manual cleanup in the app.

Project layout

src/
├── server.py     # MCP server, tool registration — thin wiring only
├── client.py     # HTTP layer: token routing, timezone, rate limiting, retries
├── project.py    # §4.0 projection levels, applied to every read
├── fields.py     # whitelist, pairing, emptiness helpers — pure logic, no I/O
├── create.py     # two-phase creation (§4.3) + the shared existing-document write primitive
├── backup.py     # §9.4 local backup archive reader — independent of client.py, no network
├── drafts.py     # resolve_path + format_ms_as_human (§6.2) — Claude Code only, not an MCP tool
├── timeutil.py   # the one clock read every write module needs
└── tools/        # one module per write tool, plus reads.py for the remaining read tools

CONVENTIONS.md accumulates user-specific preferences over time (§9.3) — empty on a fresh install, and that's expected. Gitignored, since it fills with your own real preferences; copy [CONVENTIONS.example.md](CONVENTIONS.example.md) to get started.

What's untested

Everything below is unit-tested against mocked HTTP or synthetic fixtures, but has never fired against the live API or real account data. Not a defect list — most of these need a real-world state this account doesn't currently have (a recurring task, a task with a clock time set through the app's own UI, an actual rate-limit response). Listed so a future reader doesn't mistake "passes the test suite" for "confirmed against reality."

  • The clock_time disagreement states (fields.parse_title_time_prefix

and its use in update_item/project.py) are unit-tested against synthetic documents covering all three states — prefix and taskTime agreeing, prefix present with taskTime empty, taskTime set with no prefix — but never against a document the Marvin app itself produced. All real clock_time writes in this account so far went through this server, which always keeps both fields in sync; whether the app's own UI actually produces the "prefix present, taskTime empty" or "taskTime set, no prefix" states the way Finding 2's live probing suggested is unconfirmed against a document this server didn't write itself.

  • The §4.9 recurring-task refusal's primary path is live-confirmed

(2026-08-11, once real recurring tasks existed in the account — see §3.12): calling mark_done on a generated instance refused correctly, citing both recurring: true and the matching recurringTaskId, with no write attempted. The fallback pathrecurringTaskId present without recurring: true — is unit-tested only, not live-fired: every generated instance actually observed carries both signals together, so there's no real document to exercise the fallback against without fabricating one, which would test this server's handling against a state Marvin itself doesn't produce. The non-refusal path (a normal task with recurringTaskId: "") remains live-confirmed too.

  • **get_inbox/get_today/get_due's recurring-instance filter is

live-confirmed for the response shape and two of its three paths, not the third. Live-confirmed: include_recurring=True returning real generated instances with excludedRecurringCount: 0 (the bypass path), and the default call returning excludedRecurringCount: 0 when no recurring instances exist (the nothing-to-exclude path) — both against the real account. Not live-fired: the default call actually excluding a nonzero count while recurring instances exist.** The window to check this closed mid-session — by the time the bypass path had been exercised, the account's recurring-task instances were cleaned up (§3.12.3), leaving nothing left to filter for the third check. Unit-tested only (TestRecurringFilter in test_reads.py).

  • 429/5xx retry-with-backoff has never been exercised — every real

call this session either succeeded or failed with a definitive 4xx. The retry loop's behavior under an actual rate limit or server error is unverified in practice.

  • MarvinNoResponseError (no response received, don't retry) has

never been triggered by a real network failure. fast_capture's handling of it is unit-tested with a simulated exception, not a real dropped connection.

  • MarvinSessionCeilingWarning firing mid-create was verified with

the real client.py and create.py working together, but with the call counter fast-forwarded to 800 and only the network layer mocked — not by actually making 800 live calls in one session.

  • **get_children, get_item, get_today, get_due, get_labels, and

get_time_tracks's own wrapper functions** (in src/tools/reads.py) have had their underlying endpoints verified live (correct query params, correct response shape), but the wrapper functions themselves — with projection, caching, or chunking applied — were mostly exercised via raw client calls during endpoint discovery, not by calling the actual tool. get_tree's caching is the one exception: it was explicitly instrumented and verified end-to-end, including invalidation.

  • **read_backup's summary, completion_history, project_trajectory,

and extract_subtree operations** are unit-tested against synthetic snapshots only. Only delta has been run against the real backup archive — the account's actual archive is

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.