Working in ClaudeAdd images, logos & favicons

Add images, logos & favicons

Re-host any image from a URL onto the Productised CDN, or upload reusable brand images as variables to drop into any page.

There are two ways to get images into your products: upload_image (re-host an image from a URL, great for scraping a customer's logo) and image variables (upload reusable brand assets in the app and reference them anywhere as {{ custom:key }}). This page covers both.


Why re-host?

You could embed a third-party URL directly (<img src="https://customer-site.com/logo.png">), but it's fragile:

  • The customer redesigns their site — the URL 404s, your branding breaks
  • The host blocks hotlinking — the image silently stops loading
  • A swapped source could inject something unexpected into your product

Re-hosting snapshots the asset onto your CDN: durable, owned, optimisable, served from Productised's domain. The customer's site can change without affecting your product.


The tool: upload_image

upload_image accepts an image two ways:

Supported types: jpeg, png, gif, webp, svg, ico. Max 10 MB via the connector (the in-app uploader caps at 5 MB). For a logo, a square PNG or SVG at least 256×256px renders crisply everywhere it's used — chat header, footer badge, and social share cards.


The canonical "brand my product from a website" flow

"Take the logo from acme.com, set it as the branding for my AI Readiness Scorecard, and use the favicon for the page SEO."

Claude does this:

Web fetch acme.com

Claude's built-in web fetch reads the homepage, locates the <img class="logo"> and <link rel="icon"> URLs.

Re-host the logo

Claude calls upload_image({ source_url: "https://acme.com/logo.png", filename: "acme-logo.png", product_id: "..." }). The connector downloads, validates, re-hosts. Returns: https://assets.productised.ai/<tenant>/product-assets/<product>/<ts>-acme-logo.png.

Re-host the favicon

Same call for the favicon (often .ico, also supported).

Apply

Claude calls update_branding({ logo_url: "..." }) and update_seo({ favicon: "..." }) with the new CDN URLs. Branding applied.

All four steps happen in one round-trip. The customer never uploads anything.


Reusable brand images (image variables)

For images you'll use across many pages — your logo, headshot, product photos — upload them once as image variables in the app (Settings → Variables, switch the type to Image). Each becomes a named {{ custom:key }} token. See Variables for the full walkthrough.

When you build a page in Claude, the connector sees your uploaded images (via get_variables, which returns an images list) and offers them — you don't have to recall the key:

"Design my results page and put my logo in the header."

Claude drops the token straight into the tag:

<img src="{{ custom:brand_logo }}" alt="Logo" />

Because the page uses the token (not a baked-in URL), swapping the image in Settings updates every page at once. This is the recommended way to put your own files on a page — see the limitation below.


Where to use the returned URL

The CDN URL upload_image returns can be used anywhere an image URL is accepted:

ToolFieldUse case
update_brandinglogo_urlThe logo in the chat header
update_seofaviconThe browser tab icon
update_seoog_imageSocial share card image
update_page / set_welcome_html<img src> in HTMLInline images in result or landing pages

Security guards

The connector's image fetch isn't a wide-open proxy. It enforces:

  • HTTPS / HTTP only. No file://, data:, or javascript: URLs.
  • No internal addresses. Loopback (127.0.0.1, localhost), private ranges (10.*, 192.168.*, 172.16-31.*), and cloud metadata (169.254.169.254) are blocked — a standard SSRF guard.
  • Size cap. Anything over 10 MB is rejected.
  • Content-type validation. The fetched response must be one of the allowed image types, sniffed from the response header or URL extension.
  • Timeout. The fetch aborts after 12s so a slow source can't hang the conversation.

The download and re-host happen on the Productised side (via the app's storage credentials), so the MCP server itself never touches storage directly — single source of truth, one credential set.


Limitations

  • No binary upload from the Claude chat. You can't drag a file into Claude and have it arrive at Productised — MCP is a text/JSON protocol. To use your own image on a page, either upload it as an image variable in the app and reference {{ custom:key }}, or give Claude a public URL for upload_image.
  • No transformations. The image is stored as-fetched. If you need a resize, crop, or format conversion, do it before uploading (or ask Claude to fetch a specific size from the source site if it offers multiple).
  • No deletion via the connector. Old uploads stay on the CDN until you remove them via the app. They're scoped to your tenant/product folder.

Common asks

Brand a product from a customer's site:

"Use the branding from beautifulagency.com — logo, favicon, og image, and pick the brand colour from their site."

Pull a single asset:

"Re-host the image at https://example.com/hero.jpg and use it as the landing page banner."

Use your own uploaded logo on a page:

"Use my logo from Settings in the result page header."

Update branding on every product in my workspace:

"Apply the logo I just uploaded to all my products."

Claude calls list_products, iterates, calls update_branding for each. Done in one message.