Kalpana Docs
Batch MCP

Workspace and templates

Find the connected workspace and its templates, and read the inputs a template takes.

get_workspace

Returns the one workspace this connection covers (titled "The connected workspace"): the user's role, what it allows, and the domains upload_images may fetch image URLs from. A missing permission explains a 403 from another tool. Needs workspaces:read.

  • Annotations: readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false

  • Input Parameters: None ({})

  • Output Schema:

    {
      id: string;               // Workspace ID
      name: string;             // Workspace display name
      slug: string;             // URL slug
      role: string;             // User's workspace role, such as "Owner", "Manager" or "Designer"
      allowedImageDomains: string[]; // Hosts upload_images fetches image URLs from, subdomains included
      permissions: Array<       // Granted by both the role and the connection
        | "templates:read"      // search_templates, get_template_inputs, validate_batch
        | "assets:read"         // search_assets
        | "assets:create"       // upload_images
        | "batches:read"        // get_batch, list_batches, get_batch_jobs
        | "batches:create"      // with templates:read: create_batch, update_batch, update_job, create_job
        | "renders:create"      // with batches:create: run_batch, cancel_batch, cancel_job, run_job, create_job with run
        | "renders:read"        // with batches:read and creatives:read: get_batch_outputs, get_job
        | "creatives:read"
      >;
    }

    The text result also spells out the abilities and domains, for example Shop (id: …, role: Designer): can find templates, find images, add images, view batches, create and edit batches, render batches (spends credits); cannot download rendered images. Image URLs may come from: kalpana.one, cdn.shopify.com. An image URL on another host is refused until an admin adds the domain in Workspace Settings > Domain Whitelisting.


search_templates

Search for templates by name, campaign topic, or description, or look up a specific template by its exact ID. Supports filtering by dimensions and preview availability. Animated templates are included and marked isAnimated: rendered as images, each shows one moment of the motion (see stillTime on create_batch); rendered as a video (mp4 or gif), each row is a video of the whole motion.

  • Annotations: readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false

  • Input Parameters:

    ParameterTypeRequiredDefaultDescription
    querystringNo—Search term (min 3 chars) or exact template ID. Omit to browse recently updated templates.
    hasPreviewbooleanNo—When true, returns only templates with preview URLs.
    widthnumberNo—Filter by exact pixel width.
    heightnumberNo—Filter by exact pixel height.
    pagenumberNo1Page number.
    limitnumberNo10Results per page (capped at 20).
  • Output Schema:

    {
      items: Array<{
        id: string;             // Template ID
        name: string;           // Display name
        description: string | null;
        workspaceId: string;
        workspaceName: string;
        width: number | null;
        height: number | null;
        previewUrl: string | null;
        openUrl: string | null;
        variableCount: number;
        isAnimated: boolean;    // True when the template moves; its images show one moment of the motion
      }>;
      total: number;
      page: number;
      limit: number;
    }

get_template_inputs

Retrieves all customizable inputs exposed by a template without exposing private layer hierarchies or internal vector scene nodes. Inputs the author turned off or placed on hidden layers are left out unless requested, and omittedInputs names them: their template text still renders, so check them (dates, terms, links) when the copy changes theme. An animated template also gives its duration in seconds and, when its designer set one, its stillTime.

  • Annotations: readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false

  • Input Parameters:

    ParameterTypeRequiredDefaultDescription
    templateIdstringYes—ID of the template (a whole template, not a page or flow).
    flowIdstringNo—One video of the template (an id from flows) instead of a page: its inputs, one per layer name across its pages.
    pageIdstringNoFirst pageOne page of the template. A template's pages are separate designs, each with its own inputs. Take the id from pages in a previous result.
    includeDisabledbooleanNofalseInclude inputs currently disabled in template settings.
    includeHiddenbooleanNofalseInclude inputs marked as hidden in template settings.
  • Output Schema:

    {
      id: string;
      name: string;
      description: string | null;
      width: number | null;
      height: number | null;
      pageId?: string | null;   // The page these inputs are from
      pages?: Array<{           // The template's pages
        id: string;             // Pass in pages to the batch tools, or as pageId here
        name: string;
        width: number | null;
        height: number | null;
      }>;
      inputs: Array<{
        id: string;             // The layer's id; rows may key the input by it
        key: string;            // What rows key this input by: the layer name, or the id when another layer has the same name. A video's inputs are keyed by page, as <pageId>@title; a plain title fills every page without its own
        sharedName?: boolean;   // True when another layer has the same name, so rows use the id; tell the user so they can rename one
        styles?: Record<string, { font: string; size: number; color?: string; sample: string }>; // A text input's styles when it has several: s1, s2, ... (s1 is the first run's)
        label: string;          // Human-friendly label
        type: "text" | "image";
        required: boolean;
        description: string | null;
        dimensions?: {          // Target layer dimensions in pixels (for image inputs)
          width: number;
          height: number;
        };
        defaultValue?: string;  // A text input's own text, kept when a row omits it
        fit?: string;           // An image input's current fit: Fill, Fit or Stretch
        defaultImage?: {        // The image an image input keeps when a row omits it
          assetId: string;      // Its asset id, in the form batch rows take
          previewUrl: string;   // A preview; inspect_image shows it
        };
        valueExample: unknown;  // A value in the shape rows give it: "the default text" or "Your text" for text, { asset: "an asset id or file name" } for images
      }>;
      omittedInputs?: Array<{   // Inputs left out of `inputs`; their template text still renders unless a row fills them by key
        key: string;
        label: string;
        type: "text" | "image";
        reason: "disabled" | "hidden"; // disabled: the author turned it off; hidden: its layer is hidden
        defaultValue?: string;
      }>;
      rowExample: Record<string, unknown>; // Ready modifications keyed by each input's key: copy and edit them
      isAnimated?: boolean;     // True when the template moves
      duration?: number;        // An animated template's timeline length in seconds
      stillTime?: number;       // The second the page's still image shows, set by its designer
      flowId?: string;          // The video these inputs are from, when flowId was given
      flows?: Array<{           // The template's videos. Pass an id as flowId here for its inputs, and as flow to the batch tools or a job to render it
        id: string;
        name: string;
        description: string | null;
        duration: number;
        pageIds: string[];
      }>;
      openUrl: string | null;
    }
Was this page helpful?

Updated 9 Nov 2026

On this page