GhostfeedGhostfeed MCPv8.1.0
REST API

Media

Upload original media and extract precise source frames.

POST /api/v2/media/uploads

WRITE

MCP twin: request_media_upload

Request an upload URL for original image, video, or audio bytes. PUT the bytes to the URL, then complete_media_upload. No generation is started.

Workspace-scoped writes name workspace in the body (or as a ?workspace= query param on a bodyless DELETE); the X-Workspace-Id header is for reads only.

Request body
{
  "type": "object",
  "properties": {
    "workspace": {
      "type": "string",
      "minLength": 1,
      "description": "Required write target: a workspace slug or id from list_workspaces. Writes never inherit the connection default."
    },
    "uploadId": {
      "description": "Optional stable request ID. Repeat it with identical metadata when retrying.",
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]{8,64}$"
    },
    "contentType": {
      "type": "string",
      "enum": [
        "image/jpeg",
        "image/png",
        "image/webp",
        "video/mp4",
        "video/webm",
        "video/quicktime",
        "audio/mpeg",
        "audio/mp4",
        "audio/wav",
        "audio/x-wav",
        "audio/ogg",
        "audio/webm",
        "audio/aac"
      ]
    },
    "byteLength": {
      "type": "integer",
      "minimum": 1,
      "maximum": 209715200
    },
    "filename": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255
    }
  },
  "required": [
    "workspace",
    "contentType",
    "byteLength",
    "filename"
  ],
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Example response
{
  "success": true,
  "data": {
    "uploadId": "upload-example",
    "uploadUrl": "https://upload.example.com/signed",
    "completed": false,
    "contentType": "image/png",
    "expiresInSeconds": 900,
    "maxBytes": 10485760
  }
}

POST /api/v2/media/uploads/complete

WRITE

MCP twin: complete_media_upload

Validate and save uploaded original media. Returns mediaId for generation references. Retrying the same upload is safe.

Workspace-scoped writes name workspace in the body (or as a ?workspace= query param on a bodyless DELETE); the X-Workspace-Id header is for reads only.

Request body
{
  "type": "object",
  "properties": {
    "workspace": {
      "type": "string",
      "minLength": 1,
      "description": "Required write target: a workspace slug or id from list_workspaces. Writes never inherit the connection default."
    },
    "uploadId": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]{8,64}$"
    }
  },
  "required": [
    "workspace",
    "uploadId"
  ],
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Example response
{
  "success": true,
  "data": {
    "media": {
      "mediaId": "upload-example",
      "uploadId": "upload-example",
      "mediaKind": "image",
      "url": "https://media.example.com/original.png"
    }
  }
}

POST /api/v2/media/source-frame

WRITE

MCP twin: get_source_frame

Extract and save a frame at a timestamp from an accessible source template or uploaded video. Use it to inspect sections or choose the exact image to recreate.

Workspace-scoped writes name workspace in the body (or as a ?workspace= query param on a bodyless DELETE); the X-Workspace-Id header is for reads only.

Request body
{
  "type": "object",
  "properties": {
    "workspace": {
      "type": "string",
      "minLength": 1,
      "description": "Required write target: a workspace slug or id from list_workspaces. Writes never inherit the connection default."
    },
    "source": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "templateId": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            }
          },
          "required": [
            "templateId"
          ],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {
            "mediaId": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            }
          },
          "required": [
            "mediaId"
          ],
          "additionalProperties": false
        }
      ],
      "description": "Exactly one ready accessible templateId or completed uploaded video mediaId. Audio and image uploads cannot supply a video frame."
    },
    "timestampSeconds": {
      "type": "number",
      "minimum": 0,
      "maximum": 3600,
      "multipleOf": 0.001,
      "description": "Source timestamp in seconds, to millisecond precision; must be before the end."
    }
  },
  "required": [
    "workspace",
    "source",
    "timestampSeconds"
  ],
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Example response
{
  "success": true,
  "data": {
    "frameId": "source-example",
    "imageUrl": "https://media.example.com/frame.png",
    "templateId": "template-example",
    "timestampSeconds": 1,
    "sourceKind": "template"
  }
}