MCP / Tools / Story Graph / story_mutate

story_mutate

writebetaauth: project:writeapproval: requiredstatus: v1

Create agreed story cards or scenes, or make exact updates, reordering and deletions to story entities. Card creation requires card_code, name and stage_id; copy the stage's id and card_template.card_type from beatbandit://templates/{project_mode}. For scene creation, use entity_type=scene and operation=create with scene_data and an observed after_scene_id. This saves outline content, not generated screenplay pages.

When to use

  • When the writer accepts a developed scene and asks to add it, read the scene list with `story_entity_query`, identify placement, then create that scene using its agreed content. Ask only if placement or content is genuinely unresolved.
  • For scene creation, pass a flat `scene_data` object with `title`, `summary`, `arena` (location) and any developed planning fields. Use `after_scene_id` from the scene-list read; omitting placement appends to the end.
  • Use when you already know the exact project id, entity_type, and entity fields you want to mutate.
  • Use `entity_type=card` with top-level `operation`, numeric `project_id`, `card_code`, and object `fields` for card-family CRUD.
  • For card creation, also supply `name` and `stage_id`. Read `beatbandit://templates/{project_mode}` and use the matching `stages[].id` and `card_template.card_type`. Micro Drama Chapters use `stage_id=season_movements`, `card_type=SEASON_CHAPTER` and `card_code=movement_*`.
  • Use `entity_type=scene` with top-level `operation`, numeric `project_id`, `scene_id`, and object `fields_patch` / `scene_data` for scene-family CRUD and ordering.
  • Use `entity_type=graph` for episodes, arcs, and relationships.

When not to use

  • Novel Chapter insertion/deletion/reordering/split/merge and manuscript/Voice saves use `novel_mutate`; generic CHAPTER create/delete are rejected.
  • Do not use for open-ended generation of structural changes or coordinated dependent pages; use `story_revision_run(workflow=scene_list_revision)`. A new scene inside an existing outline is a structural addition, not a reason to replace the list with Scene Wizard.
  • To write screenplay prose for a saved scene, use `screenplay_generation_run(workflow=scene_screenplay)` after creation returns its scene identity.
  • Do not use for screenplay block edits; use `screenplay_edit_*` for natural-language edits or `screenplay_snapshot_apply` for direct snapshot block mutations.
  • Do not start here when the user only has a raw story idea; prefer `story_development_run`.
  • Do not use for image, visual reference, storyboard, moodboard, recurring-image, shot, shot-element, or media-asset work; use `project_assets_query` / `shot_list_query` for reads, `shot_mutate` for shot or recurring-element mutations, and `image_generate` for still-image generation.

Examples

  • “"Add the scene we just discussed after the control room." After reading the scene list, use entity_type=scene, operation=create, after_scene_id=<observed id>, scene_data={"title":"The hidden file","summary":"Elli finds evidence of targeted recruitment and uses it to challenge Heino.","arena":"UFO records room"}.”
  • “Update one protagonist card summary.”
  • “Create an agreed Micro Drama Chapter with entity_type=card, operation=create, project_id=1041, card_code=movement_06, name="Losing the Women", stage_id=season_movements, card_type=SEASON_CHAPTER, position=6, fields={"title":"Losing the Women","objective":"...","episode_count":7}, after confirming the template stage and that the code is unused.”
  • “Update treatment card 50.10.10 with `entity_type=card`, `operation=update`, `project_id=1041`, `card_code=50.10.10`, and `fields={"Treatment - Act 1":"..."}`.”
  • “Reorder scenes inside an existing outline.”
  • “Link a scene to a storyline arc.”

Anti-examples

  • "Develop a new scene and restructure the surrounding sequence, including affected pages." Use `story_revision_run(workflow=scene_list_revision)`.
  • Generate a complete new scene list from story beats; use `story_development_run(workflow=scene_wizard)`.
  • Rewrite selected screenplay dialogue.
  • Update a card with `code` or `entity_id` instead of `card_code`; use the schema field names exactly.
  • Do not invent a stage key from a label or card type: `beats` is not the Micro Drama Chapter stage. Read the template manifest and use `season_movements`.
  • Create a recurring element for Anna or prepare character reference images; use `shot_mutate(entity_type=element)` and `image_generate(workflow=generate_element)`.

Workflows

Switch behavior by setting the entity_type input field.

WorkflowPhasesCalls
cardstory.card_mutate
scenestory.scene_mutate
graphstory.graph_mutate

Input schema

story_mutate input
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": [
    "entity_type",
    "operation",
    "project_id"
  ],
  "properties": {
    "entity_type": {
      "type": "string",
      "enum": [
        "card",
        "scene",
        "graph"
      ],
      "description": "Choose which story graph family to mutate. This schema intentionally exposes all variant fields at top level so MCP clients do not need to resolve nested oneOf refs."
    },
    "operation": {
      "type": "string",
      "enum": [
        "create",
        "update",
        "delete",
        "update_fields",
        "reorder",
        "update_position",
        "update_beats",
        "relationship_upsert",
        "relationship_delete",
        "episode_create",
        "episode_update",
        "episode_delete",
        "episode_reorder",
        "storyline_arc_create",
        "storyline_arc_update",
        "storyline_arc_delete"
      ],
      "description": "Operation for the selected entity_type. Card operations: create/update/delete. Scene operations: create/update_fields/delete/reorder/update_position/update_beats. Graph operations: relationship_*, episode_*, storyline_arc_*."
    },
    "project_id": {
      "type": "integer",
      "description": "Numeric BeatBandit project id. Pass as a JSON number, not a string."
    },
    "if_match_updated_at": {
      "type": "string"
    },
    "card_code": {
      "type": "string",
      "description": "Required for card create, update and delete. For create, choose an unused code matching the template, such as movement_06 for a Micro Drama Chapter; otherwise copy the exact existing card code. Use card_code, not code or entity_id."
    },
    "name": {
      "type": "string",
      "description": "Required for card creation. The card name is separate from fields; fields.title alone does not supply name."
    },
    "card_type": {
      "type": "string",
      "description": "For card creation, copy the selected template stage's card_template.card_type. Micro Drama Chapters use SEASON_CHAPTER."
    },
    "stage_id": {
      "type": "string",
      "description": "Required for card creation. Exact template stage key from stages[].id in beatbandit://templates/{project_mode}; not a display label or numeric database ID. Micro Drama Chapters use season_movements, not beats."
    },
    "fields": {
      "type": "object",
      "description": "For entity_type=card, object of card field updates. Pass as a JSON object, not a stringified JSON blob."
    },
    "position": {
      "type": "integer"
    },
    "info": {
      "type": "string"
    },
    "scene_id": {
      "type": "string",
      "description": "For entity_type=scene, exact scene card id/code to update."
    },
    "scene_data": {
      "type": "object",
      "description": "For operation=create, a flat scene-outline object, not screenplay prose or a nested fields object. Use title, summary and arena (location); optional planning fields include focal_character, goal, subtext, turning_point, climax, fallout, push_forward, dramatic_function, turn_type, intensity, sequence and key_beats. Preserve the agreed content and template-specific fields. Scene identity is assigned by BeatBandit.",
      "examples": [
        {
          "title": "The hidden file",
          "summary": "Elli uses evidence of targeted recruitment to confront Heino.",
          "arena": "UFO records room"
        }
      ]
    },
    "after_scene_id": {
      "type": "string",
      "description": "For scene creation, insert after this existing scene id/code from story_entity_query. Omit to append at the end of the current scene list. Do not invent an anchor or use a scene title as its identity."
    },
    "fields_patch": {
      "type": "object",
      "description": "For entity_type=scene, object of scene field updates. Pass as a JSON object, not a stringified JSON blob."
    },
    "scene_order": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "beat_codes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "source_card_code": {
      "type": "string"
    },
    "target_card_code": {
      "type": "string"
    },
    "relationship_type": {
      "type": "string"
    },
    "strength": {
      "type": "number",
      "minimum": 0,
      "maximum": 1
    },
    "notes": {
      "type": "string"
    },
    "episode_id": {
      "type": "string"
    },
    "episode_name": {
      "type": "string"
    },
    "episode_fields": {
      "type": "object"
    },
    "episode_order": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "arc_code": {
      "type": "string"
    },
    "arc_name": {
      "type": "string"
    },
    "arc_fields": {
      "type": "object"
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "entity_type": {
            "const": "card"
          }
        }
      },
      "then": {
        "properties": {
          "operation": {
            "enum": [
              "create",
              "update",
              "delete"
            ]
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "entity_type": {
            "const": "scene"
          }
        }
      },
      "then": {
        "properties": {
          "operation": {
            "enum": [
              "create",
              "update_fields",
              "delete",
              "reorder",
              "update_position",
              "update_beats"
            ]
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "entity_type": {
            "const": "graph"
          }
        }
      },
      "then": {
        "properties": {
          "operation": {
            "enum": [
              "relationship_upsert",
              "relationship_delete",
              "episode_create",
              "episode_update",
              "episode_delete",
              "episode_reorder",
              "storyline_arc_create",
              "storyline_arc_update",
              "storyline_arc_delete"
            ]
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "operation": {
            "const": "create"
          },
          "entity_type": {
            "const": "scene"
          }
        },
        "required": [
          "operation",
          "entity_type"
        ]
      },
      "then": {
        "required": [
          "scene_data"
        ]
      }
    }
  ],
  "additionalProperties": false
}

Output schema

story_mutate output
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": [
    "entity_type",
    "result"
  ],
  "properties": {
    "entity_type": {
      "type": "string",
      "enum": [
        "card",
        "scene",
        "graph"
      ]
    },
    "result": {
      "type": "object"
    }
  },
  "additionalProperties": true
}
← All toolsv1 · discriminated_mutate_tool