> ## Documentation Index
> Fetch the complete documentation index at: https://docs.magichour.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# CrewAI

> Retrieve an existing Magic Hour image project's status with native CrewAI MCP tools, without a model call.

Use CrewAI's `MCPServerAdapter` to authenticate and retrieve an image project you
already created. This example calls native `BaseTool.run` methods directly. It
requires no Agent, Crew, language model or model-provider key, and starts no new
generation or media download.

## Install and configure

Use Python 3.12. Download [recover-image.py](https://raw.githubusercontent.com/magichourhq/docs/main/examples/crewai/recover-image.py)
and [requirements.txt](https://raw.githubusercontent.com/magichourhq/docs/main/examples/crewai/requirements.txt)
into the same private directory, then install the normal declared dependencies:

```bash theme={null}
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
python -m pip check
```

The example pins `crewai==1.15.22` and `crewai-tools[mcp]==1.15.22`, matching the
existing [upstream quickstart PR](https://github.com/crewAIInc/crewAI-quickstarts/pull/8).
These are the full released packages; the example does not remove their dependencies.

Provide a [Magic Hour API key](https://magichour.ai/developer?tab=api-keys) through
your normal private process environment or secret manager. Keep it out of source,
notebook cells, prompts and shared logs. Select an image project owned by that account:

```bash theme={null}
export MAGIC_HOUR_IMAGE_PROJECT_ID="YOUR_EXISTING_IMAGE_PROJECT_ID"
python recover-image.py
```

The script reads `MAGIC_HOUR_API_KEY` from its own environment. No model-provider
credentials are needed for direct tool invocation.

## Retrieve a status snapshot

The adapter connects to `https://mcp.magichour.ai/` using Streamable HTTP and bearer
authorization. It admits only `account_retrieve` and `image_projects_retrieve_details`.
The account call verifies field types before printing an authorization marker; account
values are not printed. The project call supplies only the saved `id` and checks that
the response contains that exact ID and a string status.

The runnable example is:

```python theme={null}
import json
import os

os.environ["OTEL_SDK_DISABLED"] = "true"
os.environ["CREWAI_DISABLE_TELEMETRY"] = "true"

def recover_image() -> dict[str, str]:
    from crewai_tools import MCPServerAdapter

    api_key = os.environ["MAGIC_HOUR_API_KEY"]
    project_id = os.environ["MAGIC_HOUR_IMAGE_PROJECT_ID"]
    server_params = {
        "url": "https://mcp.magichour.ai/",
        "transport": "streamable-http",
        "headers": {"Authorization": f"Bearer {api_key}"},
    }
    with MCPServerAdapter(
        server_params,
        "account_retrieve",
        "image_projects_retrieve_details",
        connect_timeout=60,
    ) as tools:
        if len(tools) != 2:
            raise ValueError("Required tools unavailable")
        account = json.loads(tools["account_retrieve"].run())
        if (
            not isinstance(account, dict)
            or not isinstance(account.get("id"), str)
            or not isinstance(account.get("credits"), (int, float))
            or isinstance(account.get("credits"), bool)
        ):
            raise ValueError("Unexpected account metadata")
        project = json.loads(
            tools["image_projects_retrieve_details"].run(id=project_id)
        )
        if (
            not isinstance(project, dict)
            or project.get("id") != project_id
            or not isinstance(project.get("status"), str)
        ):
            raise ValueError("Unexpected project metadata")
        print({"filtered_tools": len(tools), "authenticated_account": True})
        return {"id": project["id"], "status": project["status"]}


if __name__ == "__main__":
    try:
        result = recover_image()
    except Exception:
        print({"error": "Magic Hour recovery failed; keep the saved project ID."})
        raise SystemExit(1)
    print(result)
```

The final output contains the two-tool count, the authorization marker, and your
requested project ID/status. A successful retrieval does not mean generation has
completed. If status is pending, keep the same ID and retrieve it later; do not create
a replacement project to recover existing work.

This is one status snapshot, without a wait helper, polling loop or application retry.
The extended wait helper has a multi-text presentation; it is outside this strict
JSON metadata example. No fallback parser or schema patch is used.

## Connection lifecycle and privacy

The released adapter passes a single MCP text block through as text. The example
parses the API-backed tools' JSON response and validates its shape before reporting
success. Any failure produces a static message without a raw response, account values
or temporary download URL.

`MCPServerAdapter` connects during construction. Its context manager disconnects after
the calls, including when validation fails; do not call `start()` again inside it.
The script sets supported `OTEL_SDK_DISABLED` and `CREWAI_DISABLE_TELEMETRY` flags
before importing CrewAI. Keep verbose tool/response logging and tracing off when
handling private metadata. Use a dedicated working directory and preserve any existing
CrewAI storage when cleaning up your own disposable run.

## Verification scope

The exact example ran with CrewAI and CrewAI Tools 1.15.22, MCP 1.28.1 and MCPAdapt
0.1.20 on Python 3.12 with all normal declared dependencies. Its two filtered native
tools verified account field types and retrieved an existing image project with the
requested ID and `complete` status. The process exited successfully with no stderr;
neither the key nor private response data appeared in captured output. The context
closed, and the owned process and private runtime state were cleaned up.

This verifies native direct tool invocation and saved-project metadata retrieval.
It does not verify a model-driven Crew, image/video creation or media preservation.
The optional Crew branch in the existing upstream notebook remains separately
unverified; an open PR does not imply upstream acceptance.

See [Magic Hour MCP](https://docs.magichour.ai/integration/model-context-protocol.md),
[image-project retrieval](https://docs.magichour.ai/api-reference/image-projects/get-image-details.md), and the
[released CrewAI MCP adapter](https://github.com/crewAIInc/crewAI/blob/1.15.22/lib/crewai-tools/src/crewai_tools/adapters/mcp_adapter.py).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.