Doramagic Project Pack · Human Manual

marvin

an ambient intelligence library

Marvin Overview and Architecture

Related topics: Core Abstractions: Tasks, Agents, and Threads

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Tasks

Continue reading this section for the full explanation and source context.

Section Agents

Continue reading this section for the full explanation and source context.

Section Threads

Continue reading this section for the full explanation and source context.

Related topics: Core Abstractions: Tasks, Agents, and Threads

Marvin Overview and Architecture

Marvin is a Python framework for producing structured outputs and building agentic AI workflows. It provides an intuitive API for defining workflows and delegating work to LLMs, including utilities for casting, classifying, extracting, and generating structured data; discrete observable tasks; specialized agents; and threads for orchestrating complex behaviors. Source: README.md:1-15

Purpose and Scope

Marvin sits at the intersection of two audiences: users coming from Marvin 2.x who want familiar structured-output helpers, and former ControlFlow users who want a powerful agentic engine. Marvin 3.0 unifies both by combining the DX of Marvin 2.0 with the engine previously shipped as ControlFlow, and it uses Pydantic AI as its underlying LLM runtime, supporting the full range of providers that Pydantic AI supports. Source: README.md:130-150

The framework's high-level role is to give developers a type-safe, task-centric model for AI work: rather than hand-rolling prompt chains, users express work as Task and Agent objects and let Marvin's orchestrator manage dependencies, tool calls, memory, and state. Source: src/marvin/engine/CLAUDE.md:1-12

Core Abstractions

Tasks

Tasks are the fundamental unit of work in Marvin. Each task represents a clear objective that an AI agent can accomplish. The simplest invocation is marvin.run("Write a haiku about coding"), which returns a string. Source: README.md:175-200

Tasks can also be defined explicitly via marvin.Task(...) with a result_type for type-safe returns, and they can be chained so that earlier outputs flow into later context:

with marvin.Thread() as thread:
    research = marvin.run("Research recent AI developments")
    outline = marvin.run("Create an outline", context={"research": research})
    draft = marvin.run("Write the first draft", context={"outline": outline})

Source: README.md:80-95

For complex objectives, marvin.plan(...) returns a list of dependent Task objects that can then be executed with marvin.run_tasks(tasks), providing smart planning and progress tracking. Source: src/marvin/fns/plan.py:1-30

Agents

An Agent is a stateful, autonomous AI entity that can use tools, maintain memory, and chain tool calls to accomplish a task. Agents are configured with instructions, a name, optional tools, and an optional Model. They extend the lower-level Actor concept and integrate with Pydantic AI for model access. Source: src/marvin/agents/agent.py:1-30, src/marvin/agents/CLAUDE.md:1-25

Memory is automatically managed and persisted across calls, and the agent's loop is driven by the orchestrator rather than by a single LLM invocation. Source: src/marvin/agents/CLAUDE.md:20-30

Threads

Threads replace the older "Flow" concept. They act as a context manager that maintains a shared conversation history across multiple marvin.run calls. Thread/message history is persisted in SQLite, and an explicit id can be supplied for later recovery. Source: README.md:155-170

with marvin.Thread(id="optional-id-for-recovery"):
    marvin.run("do something")
    marvin.run("do another thing")

Source: README.md:155-168

Engine and Orchestration

The Marvin engine is the task orchestration layer that coordinates actors, conversations, and tool calls. Its key files are orchestrator.py, streaming.py, end_turn.py, events.py, and llm.py. Source: src/marvin/engine/CLAUDE.md:1-20

The orchestrator's high-level flow is:

  1. Task Collection via get_all_tasks() to gather ready tasks and dependencies.
  2. Tool Assembly that combines regular tools with end-turn tools (e.g., MarkTaskSuccessful, DelegateToActor, PostMessage) from tasks and actors.
  3. Memory Integration that auto-searches memories based on recent messages.
  4. System Prompt built from the actor, instructions, and assigned tasks via the SystemPrompt Jinja template.
  5. Agent Execution that runs a Pydantic AI agent with streaming event handling.
  6. Turn Management that processes end-turn tools and updates task states.

Source: src/marvin/engine/CLAUDE.md:15-30

flowchart TD
    A[Collect ready tasks] --> B[Assemble tools + end-turn tools]
    B --> C[Search memory for context]
    C --> D[Build system prompt]
    D --> E[Run Pydantic AI agent with streaming]
    E --> F[Process end-turn tools]
    F --> G[Update task states]
    G --> A

Structured-Output Utilities

In addition to the task/agent model, Marvin exposes top-level helpers that wrap a single LLM call into a typed operation:

UtilityPurpose
marvin.runExecute a task with an AI agent
marvin.summarizeConcise summary of text via a language model
marvin.classifyCategorize data into predefined classes
marvin.extractPull structured information from text
marvin.castTransform data into a different type
marvin.generateCreate structured data from a description

Source: README.md:110-125, src/marvin/fns/summarize.py:1-25, src/marvin/fns/generate.py:1-30

All of these helpers accept an optional agent, thread, context, and prompt, and they build a marvin.Task[...] internally to drive execution. Source: src/marvin/fns/summarize.py:50-75

CLI, Integrations, and Known Issues

Marvin ships a small CLI surface. marvin config view prints the current settings tree, and marvin config get <key> retrieves a single setting. Source: src/marvin/cli/config.py:1-18 The dev CLI includes marvin dev docs to launch the Mintlify documentation locally. Source: src/marvin/cli/dev.py:9-25

For external tooling, Marvin integrates with FastMCP servers via a lazy-loading adapter in _internal/integrations/fastmcp.py that uses duck typing and _FastMCPImportState to manage optional dependencies. Source: src/marvin/_internal/integrations/README.md:1-30 The MCP lifecycle is managed by the orchestrator so that servers stay alive for the session rather than being restarted on every agent.run(). Source: release notes for v3.2.5

A real-world deployment example is the Marvin Slackbot, which uses GPT-5 or Claude, persists memories in TurboPuffer, and is configured via Prefect Secrets/Variables and a MARVIN_SLACKBOT_* env namespace. Source: examples/slackbot/README.md:1-40

Several known limitations are worth noting:

  • Passing a pydantic_ai.messages.BinaryImage to marvin.cast() can blow past token limits for moderate images. Source: issue #1246
  • Bare typing.List (without a type parameter) crashes is_classifier/as_classifier with IndexError. Source: issue #1355
  • from __future__ import annotations can cause AI functions to fall back to string returns when type resolution is deferred. Source: issue #950
  • schema_to_type() in src/marvin/utilities/jsonschema.py raises IndexError for {"type": ["null"]} and TypeError for {"type": "array", "items": []}. Source: issues #1351, #1353
  • A defense for OWASP ASI06 (memory poisoning) has been requested for AI functions. Source: issue #1347

See Also

Source: https://github.com/PrefectHQ/marvin / Human Manual

Core Abstractions: Tasks, Agents, and Threads

Related topics: Marvin Overview and Architecture, Structured-Output Functions and JSON Schema Utilities, Memory Providers, Tools, and MCP Integration

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Marvin Overview and Architecture, Structured-Output Functions and JSON Schema Utilities, Memory Providers, Tools, and MCP Integration

Core Abstractions: Tasks, Agents, and Threads

Marvin is built around three cooperating abstractions that together turn LLM calls into inspectable, composable workflows. Tasks describe what should be done, Agents are the entities that actually do the work, and Threads are the conversation/session container that connects them. All higher-level helpers (marvin.run, marvin.classify, marvin.extract, marvin.summarize, marvin.cast, marvin.generate, marvin.plan) are thin façades that construct a Task and route it through the same engine (Source: README.md).

flowchart LR
    User[User Code] -->|runs| Task[Task<br/>instructions + result_type]
    Task -->|assigned to| Agent[Agent<br/>name + instructions + tools]
    Agent -->|executes via| Orch[Orchestrator]
    Thread[Thread<br/>shared history + memory] --- Orch
    Orch -->|end_turn tools| Result[Typed Result]
    MCP[MCP Servers] -.->|tools| Agent
    Memory[Memory] -.->|context| Orch

Tasks

A Task is the unit of work. It is a generic, type-parameterized class — marvin.Task[T] — where T is the Python type the model is expected to produce (Source: src/marvin/tasks/task.py). Tasks carry instructions, an optional context dict, a list of tools, and a result_type. When a task is executed, the orchestrator sends the system prompt plus tools to the model and validates the response against result_type before returning it (Source: src/marvin/engine/CLAUDE.md).

Tasks are observable and stateful: they progress through states tracked by the engine and are persisted alongside the thread. The simplest usage is marvin.run("Write a haiku about coding"), but explicit construction lets you tune the result type, agents, and dependencies:

import marvin
from pydantic import BaseModel

class Article(BaseModel):
    title: str
    content: str
    key_points: list[str]

article = marvin.run(
    "Write an article using the research",
    result_type=Article,
    context={"research": research},
)

Tasks can also be planned. marvin.plan(...) internally constructs marvin.Task[list[PlanTask]], asks the LLM to decompose an objective, then expands that into a list of real Task objects that marvin.run_tasks will execute in dependency order (Source: src/marvin/fns/plan.py).

Common pitfall: Putting from __future__ import annotations at the top of a module turns all type hints into strings, which breaks Marvin's runtime type resolution and causes AI functions to return str instead of structured objects. See issue #950.

Agents

An Agent is a stateful actor that can use tools and maintain memory (Source: src/marvin/agents/CLAUDE.md). Concretely, Agent is a dataclass subclass of Actor that adds tool orchestration, model configuration, and event handling (Source: src/marvin/agents/agent.py). Agents are specialized (via instructions), portable (reusable across tasks), collaborative (Team lets multiple agents be assigned to a single task), and customizable (model, temperature, etc.) (Source: README.md).

from marvin import Agent

writer = Agent(
    name="Writer",
    instructions="Write clear, engaging content for a technical audience",
)
marvin.run("Write an article", agent=writer)

Under the hood, agents integrate with Pydantic AI for model invocation, support MCP servers as tool sources, and stream events through registered handlers. The agent class also dispatches handle_event callbacks to both sync and async handler lists (Source: src/marvin/agents/agent.py). Lazy-loaded FastMCP support lets agents transparently use tools exposed by a FastMCP server without making fastmcp a hard dependency (Source: src/marvin/_internal/integrations/README.md).

MCP lifecycle note: In v3.2.5 the engine was changed so that MCP server subprocesses are started once per session rather than for every agent.run() call. Earlier versions repeatedly spawned and tore down the server, which caused both latency and intermittent TimeoutErrors during initialization (Source: release v3.2.5). v3.2.7 additionally merges user-specified env vars on top of os.environ so essential variables like PATH and HOME are no longer dropped when configuring MCPServerStdio (Source: release v3.2.7).

Threads

A Thread is the conversation/session container — the Marvin 3.0 replacement for ControlFlow's Flow. It is used as a context manager and may carry an optional id for later recovery:

import marvin

with marvin.Thread(id="optional-id-for-recovery"):
    marvin.run("do something")
    marvin.run("do another thing")

(Source: README.md; src/marvin/thread.py).

Threads are what give Marvin its stateful character. They:

  • Persist message history in SQLite (no migration tooling yet — expect to reset data during upgrades) (Source: README.md).
  • Share context and history between tasks executed inside the same with block (Source: README.md).
  • Auto-search memories based on recent messages before each model call (Source: src/marvin/engine/CLAUDE.md).
  • Act as the unit of recovery: passing thread="some-id" reattaches new tasks to a prior conversation.

Because every high-level helper is a task, and every task runs inside the active thread, threads are also the natural boundary for memory poisoning defenses (OWASP ASI06) — adversarial content embedded in one task's output should be validated before being written into the thread's persisted memory (Source: issue #1347).

The Engine: How the Three Connect

The Orchestrator is what actually drives execution. Per the engine module's own documentation, the flow is: collect ready tasks → assemble tools (regular + end-turn tools from tasks/agents) → integrate memory → build a system prompt from the actor, instructions, and tasks → run the Pydantic AI agent with streaming events → process EndTurn subclasses (MarkTaskSuccessful, DelegateToActor, PostMessage, etc.) to update task state (Source: src/marvin/engine/CLAUDE.md). Tools are wrapped with wrap_tool_errors so a tool failure surfaces as a recoverable model message rather than a hard crash (Source: src/marvin/agents/agent.py).

For workloads that need true concurrency, v3.2.1 enabled parallel execution of independent tasks within a thread, and v3.2.2 fixed Optional result types returning None (Source: releases v3.2.1, v3.2.2).

See Also

  • Engine and Orchestrator — deep dive into the execution loop
  • Structured-Output Helpers — cast, classify, extract, generate, summarize
  • Planning and Threads — marvin.plan and thread persistence
  • MCP and Tool Integration — wiring external tool servers into agents

Source: https://github.com/PrefectHQ/marvin / Human Manual

Structured-Output Functions and JSON Schema Utilities

Related topics: Core Abstractions: Tasks, Agents, and Threads

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Cast, Classify, Extract, Generate

Continue reading this section for the full explanation and source context.

Section Plan and Thread Orchestration

Continue reading this section for the full explanation and source context.

Related topics: Core Abstractions: Tasks, Agents, and Threads

Structured-Output Functions and JSON Schema Utilities

Overview and Scope

Marvin is a Python framework for producing structured outputs and building agentic AI workflows. At the core of its "structured output" promise sits a collection of high-level functions (marvin.cast, marvin.classify, marvin.extract, marvin.generate, marvin.summarize, marvin.plan) plus a dedicated JSON Schema-to-Python-type converter that bridges raw JSON Schema documents with Pydantic-validated Python types. Source: README.md.

The structured-output functions are designed to be composable. Each function wraps a marvin.Task and delegates LLM interaction to Pydantic AI, then validates the model's reply against a target Python type. The pipeline is:

  1. The user supplies a target type (Python class, dataclass, or JSON Schema).
  2. The framework constructs a Task with that result_type.
  3. The LLM is instructed to emit JSON matching the type's schema.
  4. The response is parsed and validated through Pydantic.

This same pipeline is reused inside the src/marvin/fns/generate.py module, where generate_schema_async() instructs the model to produce a JSONSchema document, illustrating the round-trip capability between Python types and JSON Schema.

High-Level Functions

Cast, Classify, Extract, Generate

The README documents five "keep-it-simple" utilities:

FunctionPurpose
marvin.runExecute any task with an AI agent
marvin.summarizeGet a quick summary of a text
marvin.classifyCategorize data into predefined classes
marvin.extractPull structured information from text
marvin.castTransform data into a different type
marvin.generateCreate structured data from a description

All of these accept an optional agent, thread, context, handlers, and prompt, and return through a common run_sync wrapper. Source: src/marvin/fns/summarize.pysummarize_async() shows the canonical pattern: build a task_context dict, optionally append user instructions to the default prompt, then call marvin.Taskstr.run_async(thread=thread, handlers=handlers).

Plan and Thread Orchestration

marvin.plan() returns a list of marvin.Task objects that together satisfy a high-level objective; marvin.run_tasks() executes them. Source: src/marvin/fns/plan.py. Threads act as context managers that share message history between tasks, defined in marvin.Thread(). Each Agent participating in a task is a dataclass that owns its own Model, instructions, and optional MCP servers. Source: src/marvin/agents/agent.py.

JSON Schema Utilities

The most relevant implementation file is src/marvin/utilities/jsonschema.py. Its top-level docstring lists the supported conversions:

  • Basic types: string, number, integer, boolean, null
  • Complex types: arrays, objects
  • Format constraints: date-time, email, uri
  • Numeric constraints: minimum, maximum, multipleOf
  • String constraints: minLength, maxLength, pattern
  • Array constraints: minItems, maxItems, uniqueItems
  • Object properties with defaults, recursive references, enums, constants, unions

The module constructs Pydantic-friendly types via several helpers: create_numeric_type, create_enum, create_array_type, and create_object_type. These produce either plain Python classes, dataclasses via make_dataclass, Enum subclasses, or Annotated types with Field/StringConstraints. The create_numeric_type helper, for example, returns a Literal[schema["const"]] when the schema declares a constant, otherwise an Annotated[int|float, Field(...)] with the relevant constraints. Source: src/marvin/utilities/jsonschema.py.

The companion jsonschema_to_type() function enables arbitrary JSON Schema documents to drive Marvin's structured-output pipeline, allowing users to supply schemas that were not authored in Python.

flowchart LR
    A[User Input / Python Type] --> B{Structured Function}
    B -->|marvin.cast| C[Construct Task]
    B -->|marvin.extract| C
    B -->|marvin.generate| C
    C --> D[Pydantic AI Model]
    D --> E[Raw JSON]
    E --> F[JSON Schema Validator]
    F --> G[Pydantic-Validated Result]
    G --> H[Return Value]

Known Issues and Community-Reported Limitations

The community has surfaced several failure modes that practitioners should be aware of:

  • Token explosion with binary inputs — Passing a pydantic_ai.messages.BinaryImage to marvin.cast() can blow past model token limits even for moderately sized images (e.g., a 200 KB PNG). See issue #1246.
  • Bare typing.List crashesis_classifier() and as_classifier() call get_args(typ)[0] without checking that get_args() is non-empty, so a parameter typed List (without a type argument) raises IndexError. See issue #1355.
  • schema_to_type IndexError on ["null"] — A schema whose type field is the list ["null"] raises IndexError: list index out of range at line 302 of src/marvin/utilities/jsonschema.py. See issue #1353.
  • create_array_type TypeError on empty items — A schema like {"type": "array", "items": []} (valid JSON Schema for a zero-element tuple) raises TypeError: Cannot take a Union of no types.. See issue #1351.
  • from __future__ import annotations returns strings — AI functions declared under PEP 563 postponed annotations may return raw strings rather than structured types because annotations become strings at runtime. See issue #950.
  • OWASP ASI06 memory poisoning — External content processed by Marvin functions can poison downstream memory; the project has an open feature request for mitigations. See issue #1347.

To inspect the active configuration that drives model selection for these utilities, use marvin config view or marvin config get <key>, which read from marvin.settings. Source: src/marvin/cli/config.py and src/marvin/cli/main.py.

See Also

  • Marvin README — high-level overview and installation
  • Agents — marvin.Agent and team composition
  • Threads — orchestrating multi-task workflows
  • MCP Integrations — MCPServerStdio lifecycle (v3.2.5, v3.2.7)
  • Release Notes — v3.2.1 through v3.2.7 covering concurrency, optional results, and observability

Source: https://github.com/PrefectHQ/marvin / Human Manual

Memory Providers, Tools, and MCP Integration

Related topics: Core Abstractions: Tasks, Agents, and Threads

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Security Note: Memory Poisoning (OWASP ASI06)

Continue reading this section for the full explanation and source context.

Section Design Decisions

Continue reading this section for the full explanation and source context.

Section Lifecycle and Recent Fixes

Continue reading this section for the full explanation and source context.

Related topics: Core Abstractions: Tasks, Agents, and Threads

Memory Providers, Tools, and MCP Integration

Marvin's agent runtime is built around three interlocking extension points: a Memory abstraction backed by pluggable vector-database providers, a Tools layer that promotes regular Python functions into LLM-callable tools, and an MCP (Model Context Protocol) integration that lets an agent reach external tool servers. This page describes how those pieces fit together and how to use them safely.

Overview and High-Level Architecture

Marvin's runtime coordinates actors (LLM-driven agents) over an Orchestrator that runs each task turn, assembles available tools, queries memory, builds a system prompt, and dispatches the resulting call to a Pydantic AI agent. Source: src/marvin/engine/CLAUDE.md. The orchestrator flow is summarized below.

flowchart TD
    A[Orchestrator.run] --> B[Collect ready tasks]
    B --> C[Assemble regular + end-turn tools]
    C --> D[Query Memory providers for context]
    D --> E[Build SystemPrompt<br/>actor + tasks + memory]
    E --> F[Run pydantic-ai agent<br/>with streaming events]
    F --> G{End-turn tool fired?}
    G -- MarkTaskSuccessful --> H[Task SUCCESS]
    G -- DelegateToActor --> I[Hand off to another agent]
    G -- PostMessage --> J[Continue turn]
    G -- none --> K[Continue tool loop]
    H --> L[Persist to thread DB]
    I --> L
    J --> L
    K --> F

Agents are stateful, expose typed Python tools, automatically persist conversation history, and can chain tool calls across turns. Source: src/marvin/agents/CLAUDE.md. MCP servers extend the same tool model by importing remote tools into the agent's available toolset at run time.

Memory: `Memory` Class and Providers

The Memory class models a partitioned collection of memories that is stored in a vector database configured by a MemoryProvider. Source: src/marvin/memory/memory.py. Its most important fields are:

FieldTypePurpose
keystrAlphanumeric/underscore identifier; sanitized in __post_init__.
instructions`str \None`Tells the agent when/how the memory should be used.
providerMemoryProviderBacking vector store (resolved from string via get_memory_provider).
auto_useboolIf true, the orchestrator queries the memory before each agent run using the most recent messages.
prompt`str \Path`Jinja template for the memory's prompt (defaults to memory.jinja).

Construction validates the key (alphanumerics and underscores only) and ensures a provider is configured, otherwise the post-init raises a ValueError directing users to configure a default provider. Source: src/marvin/memory/memory.py. The class exposes add, delete, search, and get_tools, where get_tools() converts the memory's own CRUD methods into agent-callable tools prefixed add_memory__{key} (and equivalents). Source: src/marvin/memory/memory.py.

Each Memory is hashed by id(self), so a memory is identity-stable across calls. The __post_init__ also calls provider.configure(key) to initialize the underlying store partition. Source: src/marvin/memory/memory.py.

The slackbot example wires memory to a vector store using the tpuf-api-key secret for TurboPuffer and overrides the memory-synthesis model via marvin_memory_synthesis_model (default claude-haiku-4-5-20251001). Source: examples/slackbot/README.md.

Security Note: Memory Poisoning (OWASP ASI06)

Because memory content is fed back into the LLM, untrusted external data that ends up in a memory can poison later outputs (OWASP ASI06). When designing memory flows, sanitize inputs before await memory.add(content) and review instructions text that influences recall. Source: community issue #1347.

Tools: From Python Functions to LLM-Callable Tools

Marvin agents accept ordinary Python functions as tools; type hints drive schema generation. Source: src/marvin/agents/CLAUDE.md. A minimal example:

from marvin import Agent

def write_file(path: str, contents: str) -> str:
    "Write the given contents to path."
    ...

agent = Agent(tools=[write_file])
result = agent.run("how to use pydantic? write to docs.md")

Source: README.md.

Internally, the orchestrator collects two categories of tools: regular tools (user-supplied or memory-derived) and end-turn tools such as MarkTaskSuccessful, MarkTaskFailed, MarkTaskSkipped, DelegateToActor, and PostMessage. Source: src/marvin/engine/CLAUDE.md. These end-turn tools are how an agent terminates its turn, escalates, or hands work to another agent — they are not user-defined but are appended by the engine on each run. Source: src/marvin/engine/CLAUDE.md.

Higher-level helpers (marvin.summarize, marvin.generate, marvin.plan) compile down to the same marvin.Task[str], marvin.Task[list[T]], and marvin.run_tasks(tasks) primitives, all of which share the agent's tool surface. Source: src/marvin/fns/summarize.py, src/marvin/fns/generate.py, src/marvin/fns/plan.py.

MCP Integration and FastMCP Adapter

Marvin's MCP integration lives under src/marvin/_internal/integrations/ and exposes an adapter that lets a Marvin Agent consume tools from a FastMCP server via the mcp_servers=[...] argument. Source: src/marvin/_internal/integrations/README.md.

Design Decisions

DecisionRationale
Lazy import of FastMCPKeeps FastMCP an optional dependency (marvin[mcp]); not pulled in for users who do not need it.
Duck typing over isinstanceTolerates FastMCP variants by checking for name, list_tools / _mcp_list_tools; avoids tight coupling to a specific release.
_FastMCPImportStateEncapsulates import state to avoid repeated attempts and keep global namespace clean.
Multi-heuristic detectionClass-name contains "FastMCP" and presence of required methods — belt-and-suspenders for compatibility.
Diagnostics + error messagesLogs each step and produces clear errors when FastMCP is missing.

Source: src/marvin/_internal/integrations/README.md.

Lifecycle and Recent Fixes

  • v3.2.5: MCP server subprocesses were being restarted on every agent.run(), which broke tool-heavy agents. The lifecycle fix keeps servers alive for the session. Source: release v3.2.5.
  • v3.2.7: MCPServerStdio was launched with only user-supplied env=..., dropping PATH, HOME, etc., and causing TimeoutError during server init. The fix merges user env on top of os.environ. Source: release v3.2.7.

Usage

from fastmcp.server import FastMCP
import marvin

server = FastMCP("My Server")

@server.tool()
def hello_world() -> str:
    return "Hello, world!"

agent = marvin.Agent(mcp_servers=[server])
result = agent.run("Please say hello to the world")

Source: src/marvin/_internal/integrations/README.md.

Configuration and CLI Inspection

Settings can be inspected at runtime through the CLI:

marvin config view          # Show all settings
marvin config get <key>     # Show a specific setting

Source: src/marvin/cli/config.py. Defaults such as the memory provider, default model, and thread database live on marvin.settings; marvin.defaults.memory_provider is consulted when a Memory is constructed without an explicit provider. Source: src/marvin/memory/memory.py.

Common Failure Modes

SymptomLikely causeReference
TimeoutError initializing an MCP stdio serverenv on MCPServerStdio overrode os.environ instead of mergingv3.2.7 fix
Agent re-spawns MCP server every runPre-v3.2.5 lifecycle bugv3.2.5 fix
ValueError: Memory modules require a MemoryProvider...No default provider configuredsrc/marvin/memory/memory.py
ai_fn returns a string instead of structured datafrom __future__ import annotations stripped type infoissue #950
Out-of-memory token explosion in marvin.cast on imagesBinaryImage data bloatissue #1246
Persisted memory causes downstream model to misbehaveExternal content written into memory without sanitization (ASI06)issue #1347

See Also

Source: https://github.com/PrefectHQ/marvin / Human Manual

Doramagic Pitfall Log

Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.

high Maintenance risk requires verification

May increase setup, validation, or first-run risk for the user.

high Security or permission risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

Doramagic Pitfall Log

Found 12 structured pitfall item(s), including 2 high/blocking item(s). Top priority: Maintenance risk - Maintenance risk requires verification.

1. Maintenance risk: Maintenance risk requires verification

  • Severity: high
  • Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/PrefectHQ/marvin/issues/950

2. Security or permission risk: Security or permission risk requires verification

  • Severity: high
  • Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/PrefectHQ/marvin/issues/1246

3. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/PrefectHQ/marvin/issues/1351

4. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/PrefectHQ/marvin/issues/1347

5. Configuration risk: Configuration risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/PrefectHQ/marvin/issues/1353

6. Capability evidence risk: Capability evidence risk requires verification

  • Severity: medium
  • Finding: README/documentation is current enough for a first validation pass.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: capability.assumptions | https://github.com/PrefectHQ/marvin

7. Runtime risk: Runtime risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a runtime risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/PrefectHQ/marvin/issues/1355

8. Maintenance risk: Maintenance risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/PrefectHQ/marvin

9. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: downstream_validation.risk_items | https://github.com/PrefectHQ/marvin

10. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: risks.scoring_risks | https://github.com/PrefectHQ/marvin

11. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: issue_or_pr_quality=unknown。
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/PrefectHQ/marvin

12. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: release_recency=unknown。
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/PrefectHQ/marvin

Source: Doramagic discovery, validation, and Project Pack records

Community Discussion Evidence

These external discussion links are review inputs, not standalone proof that the project is production-ready.

Sources 12

Count of project-level external discussion links exposed on this manual page.

Use Review before install

Open the linked issues or discussions before treating the pack as ready for your environment.

Community Discussion Evidence

Doramagic exposes project-level community discussion separately from official documentation. Review these links before using marvin with real data or production workflows.

Source: Project Pack community evidence and pitfall evidence