How to Upload Local Assets to a Stitch Project: A Complete Guide

The Stitch Design plugin provides a reusable upload-to-stitch skill that sends local images, HTML, and Markdown files directly to a Stitch project via the BatchCreateScreens API, bypassing model token limits through base-64 encoding and direct REST calls.

The google-labs-code/stitch-skills repository delivers a token‑efficient workflow for uploading local design assets to Stitch projects. Instead of passing file contents through the LLM context window, the upload-to-stitch skill validates, encodes, and transmits assets directly to the Stitch backend, making screenshots, HTML prototypes, and Markdown documentation immediately available for downstream processing.

The Three-Layer Upload Architecture

The upload process follows a logical three‑layer pattern defined in plugins/stitch-design/skills/upload-to-stitch/SKILL.md (lines 28‑38).

Project Identification

First, locate the target Stitch project by running any MCP‑compatible list‑projects command and extracting the projectId. The skill assumes you have already provisioned a project within the Stitch ecosystem.

Credential Discovery

Next, retrieve the Stitch API key from local Gemini or Claude configuration files. The skill searches standard locations such as ~/.gemini/settings.json or .gemini/antigravity/mcp_config.json (lines 32‑38 in SKILL.md). You may also pass the key explicitly via the --api-key flag.

Upload Execution

Finally, invoke the helper script plugins/stitch-design/skills/upload-to-stitch/scripts/upload_to_stitch.py. This script orchestrates file validation, base‑64 encoding, and the HTTP POST to Stitch’s BatchCreateScreens endpoint.

How the Upload Script Works

The core implementation in upload_to_stitch.py handles five distinct responsibilities:

MIME-Type Validation

A static _MIME_TYPES dictionary (lines 48‑57) maps file extensions to their correct MIME types. Supported formats include PNG, JPG, WEBP, HTML, and Markdown.

Base-64 Encoding

The encode_file() function (lines 60‑64) reads the asset in binary mode and returns a base‑64 encoded string suitable for JSON transmission.

Screen Request Construction

The build_screen_request() function (lines 29‑77) constructs the CreateScreenRequest payload. It distinguishes between two screen types:

  • IMAGE screens use the screenshot field for PNG/JPG/WEBP assets.
  • DOCUMENT screens use the htmlCode field for HTML or Markdown content, optionally appending a generatedBy tag.

HTTP API Call

The call_batch_create_screens() function (lines 66‑87) assembles the POST request to /v1/projects/<projectId>/screens:batchCreate, attaches the X‑Goog‑Api‑Key header, and uses an SSL‑aware context when certifi is present. Errors trigger a graceful sys.exit(1) after printing diagnostics.

Command-Line Interface

The parse_args() function (lines 81‑67) defines required flags (--project-id, --file-path, --api-key) and optional parameters (--api-url, --title, --generated-by, --create-screen-instances). The main() routine validates inputs, executes the encoding, and prints the formatted JSON response.

Step-by-Step Workflow

Follow this sequence to upload assets from your local machine:

  1. Find the project – Run stitch list_projects and copy the projectId.

  2. Locate your API key – Inspect ~/.gemini/settings.json or similar configuration files, or request the key from the user.

  3. Confirm assets – The skill pauses before execution to display the file path, size, and type. You must obtain explicit user approval (see the "Checkpoint" note in SKILL.md, lines 49‑53).

  4. Run the upload – Execute the command block, which expands to:

    python3 <SKILL_DIR>/scripts/upload_to_stitch.py \
      --project-id <PROJECT_ID> \
      --file-path <PATH_TO_ASSET> \
      --api-key <API_KEY> \
      [--api-url <STITCH_API_URL>] \
      [--title <SCREEN_TITLE>] \
      [--generated-by <GENERATED_BY>]
  5. Verify the response – A successful upload returns a JSON object containing screenId under responses[0].screen.id.

SSL Troubleshooting on macOS

If you encounter ssl.SSLCertVerificationError, the script automatically falls back to the certifi bundle (lines 40‑45). You may also manually set the SSL_CERT_FILE environment variable as documented in SKILL.md (lines 67‑80).

Code Examples

Use the script programmatically from Python:

from pathlib import Path
import subprocess, shlex

project_id = "1234567890"
api_key    = "AIzaSy...."
file_path  = Path("assets/logo.png")

cmd = f"""python3 upload_to_stitch.py \\
  --project-id {project_id} \\
  --file-path {file_path} \\
  --api-key {api_key} \\
  --title "Brand Logo"
"""
subprocess.run(shlex.split(cmd), check=True)

Or invoke directly from the terminal:

python3 upload_to_stitch.py \
  --project-id 1234567890 \
  --file-path ./designs/homepage.html \
  --api-key AIzaSy... \
  --title "Homepage Mockup" \
  --generated-by "stitch::extract-static-html"

Summary

  • The upload-to-stitch skill bypasses LLM token limits by uploading assets directly to the Stitch API.
  • The process requires three inputs: a valid projectId, a Stitch API key, and the local file path.
  • The script upload_to_stitch.py handles MIME detection, base‑64 encoding, and the BatchCreateScreens REST call.
  • Supported formats include IMAGE screens (PNG, JPG, WEBP) and DOCUMENT screens (HTML, Markdown).
  • Execution requires user confirmation before transmission, with full JSON response logging for verification.

Frequently Asked Questions

What file types are supported when uploading local assets to a Stitch project?

The upload_to_stitch.py script accepts PNG, JPG, and WEBP files as IMAGE screens, and HTML or Markdown files as DOCUMENT screens. The _MIME_TYPES dictionary (lines 48‑57) maps extensions to MIME types, ensuring the correct protobuf structure is sent to the Stitch API.

How do I find my Stitch API key for the upload script?

According to the skill documentation in SKILL.md (lines 32‑38), the API key is typically stored in local configuration files such as ~/.gemini/settings.json or .gemini/antigravity/mcp_config.json. You may also provide it directly via the --api-key command-line argument.

What is the difference between IMAGE and DOCUMENT screens in Stitch?

IMAGE screens store base‑64 encoded image data in the screenshot field, suitable for design mockups and screenshots. DOCUMENT screens store text content in the htmlCode field, used for HTML prototypes or Markdown documentation, and can include a generatedBy metadata tag to track the source of the asset.

How do I handle SSL certificate errors when uploading to Stitch?

If you encounter ssl.SSLCertVerificationError on macOS, the script automatically attempts to use the certifi certificate bundle (lines 40‑45). Alternatively, set the SSL_CERT_FILE environment variable to point to a valid PEM file before running the upload command, as noted in the skill documentation (lines 67‑80).

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →