# MCP Setup & Agent Guide

MakeFX exposes a remote Streamable HTTP MCP server at
`https://makefx.app/mcp`. It operates on the same Spaces, Assets, Variants,
Recipes, References, Collections, Drafts, Bindings, canvas
organization, and permissions as the web app.

Use MCP for structured agent work. Use the MakeFX CLI when an operation needs a
caller-local file.

## Connect

```bash
claude mcp add --transport http makefx https://makefx.app/mcp
```

Complete browser OAuth when prompted. MCP uses `makefx:read`, `makefx:write`,
`makefx:generate`, and `makefx:delete`; Space roles independently authorize the
selected Space. Connectors initially request `makefx:read`; selected write,
generation, or deletion tools request their action scope as a step-up. Existing
tokens with all four scopes remain valid, and omitted action scopes are never
silently granted.

OAuth discovery is `/.well-known/oauth-protected-resource`; the `/mcp`-suffixed
path is an identical compatibility alias.

After connecting, call `tools/list`. Its live schemas are authoritative. Use
`list_models` and `get_model` to choose a public model and read the typed inputs
available for the intended operation.

## Protocol negotiation

The same URL supports legacy `2025-06-18` and stateless `2026-07-28`. Modern
clients use `server/discover`; clients declaring `io.modelcontextprotocol/tasks`
receive a durable Task and poll `tasks/get` using `pollIntervalMs`. Other clients
receive ordinary `variant_ref`, `asset_ref`, and `status` results and continue
with `get_variant`. Polling cadence is server-owned.

## Product references

An Asset reference identifies the durable creative object. A Variant reference
identifies one exact result:

```text
asset:name~prefix
asset:name~prefix@variant
```

Use exact Variant references for regeneration, activation, completed media,
and generation inputs. Current `get_asset` also returns legacy Lineage
compatibility; only Recipe References define inputs.

## Agent workflow

1. Discover the live tool and model schemas.
2. Find or create a Space.
3. Inspect existing Assets and exact Variants.
4. Generate an Asset, regenerate a completed Variant, or retry a failed Variant.
5. Read the returned Variant until it is completed or failed.
6. Inspect the result and activate the chosen Variant.
7. Organize the Asset or exact Variant in Collections.

Without the negotiated Tasks extension, every generation, regeneration, and
retry tool returns the same durable resume fields: `variant_ref`, `asset_ref`,
and `status`. A queued or running response also includes the server-owned
`next_poll_seconds` hint. MCP clients should wait for that interval and call
`get_variant` with the returned reference.

Example:

```text
list_models({media_kind: "image", operation: "generate", available_only: true})
get_model({model: "pro"})
generate_image({
  space_id: "<space-id>",
  name: "Market",
  asset_type: "scene",
  prompt: "A painted market at dusk",
  model: "pro"
})
get_variant({space_id: "<space-id>", variant_ref: "<returned-variant-ref>"})
activate_variant({space_id: "<space-id>", variant_ref: "<chosen-variant-ref>"})
```

The live schema, not this example, owns optional fields and current limits.

`drafts_create` accepts optional `bindings` without running. Pass a completed
exact `from_variant_ref` to map its Recipe and references into exact-Variant
Bindings; `name` and `destination_kind` override mapped defaults.
`drafts_get` reads one Draft with Binding `broken`/`broken_reason` and latest
run Variant.

Call `drafts_run` with stable `request_id`. If `queued`/`running`, wait
`next_poll_seconds` and replay the same pair; it returns current status and
Variant without another run.

## Graph approvals

Set `require_approval: true` with a stable caller-owned `request_id`:

```text
graph_run({
  space_id: "<space-id>",
  draft_refs: ["<draft-ref>", "<downstream-draft-ref>"],
  request_id: "dialogue-scene-07",
  include_upstream: true,
  require_approval: true
})
```

No generation starts yet. The call returns `status: "pending_approval"` and an
`approval_ref`. Poll it with the read-only `graph_approval_status`, waiting for
`next_poll_seconds` while its status is `pending`:

```text
graph_approval_status({
  space_id: "<space-id>",
  approval_ref: "<returned-approval-ref>"
})
```

Only a human in the web Space can approve or reject the exact request.
Rejection returns `rejected` and starts nothing. Approval returns `approved`
with a `run_ref`; poll that run to a terminal status:

```text
graph_run_status({
  space_id: "<space-id>",
  run_ref: "<returned-run-ref>"
})
```

If launch fails, approval polling returns `failed` without a run reference.
Reusing the `request_id` is idempotent, not a substitute for polling: it
returns the same approval reference while waiting or the existing successful
run.

`graph_cancel`: pending/blocked only; no in-flight abort.

## Regenerate and Retry

Regenerate when a completed result should be different. The typed
media-family operation starts from an exact completed Variant, inherits its
Recipe, applies supplied changes, and creates a sibling Variant. The sibling is
activated on success by default; set `activate: false` to keep the current
selection.

Retry only a failed Variant when its Recipe should remain unchanged. Retry keeps
the Variant identity.

## Activation, organization, and deletion

Activation is first-class because choosing the result that represents an Asset
is a deliberate product decision.

The public guides to [Variant comparison](https://makefx.app/docs/ai-media-variants.md)
and [reproducible media records](https://makefx.app/docs/reproducible-ai-media.md)
show how that decision connects to Recipes and References.

Collections support ordinary create, read, update, and delete behavior plus
ordered Asset or exact-Variant membership. Moving work between Collections is
expressed by removing one membership and adding another.

Deletion is permanent. Owners may delete Spaces, Assets, and eligible terminal
Variants. Activate another Variant before deleting the current one; delete the
Asset to remove its only Variant.

## Local files

MCP does not read caller-local paths. Upload with:

```bash
makefx assets upload <file> --name "<name>" --type <type>
```

Call `get_variant` to obtain a fresh authenticated link and `resource_link` for
a completed Variant. Call `get_variant` again when the link expires; do not
repeat media creation.

## Recovery

- Correct invalid inputs rather than repeating them unchanged.
- Refresh `tools/list`, `list_models`, and `get_model` when remembered schemas
  disagree with the server.
- Read an accepted Variant again after disconnect.
- Use Retry only for an unchanged failed Variant.
- Use typed Regenerate operations for a new creative direction.

Errors include stable codes, safe messages, and retryability where applicable.
Provider credentials, storage details, raw upstream responses, and internal
identifiers never appear in public output.
