AI & Automation · Guide

Your AI Agent Built Your Website. Here Is How to Make Its Images Fast (and Strip the GPS)

33 min read · Published October 31, 2026 · Mochify Engineering Team

If an AI agent built your website, there is a good chance nobody has looked at the images. Not you, because you asked for a site and got one. Not the agent, because you did not ask it to. The photos went into the repo at whatever size they arrived, the agent wrote <img src="/hero.jpg"> around each one, and the deploy shipped the lot. Simon Willison found this on a conference-schedule app he had built in an afternoon with an agent: "it turns out those speaker avatar images are 1MB+ PNGs! And there are 170 of them." He fixed it the same way he built it, by asking the agent.

That is the whole shape of this guide. An agent-built site has heavy images because image work was never on the list, and the same agent will do that work well if you know what to ask for. The difference from a site builder is that your agent controls the markup, so it can do more than squeeze the files: it can write the <picture> element, set the width and height, decide what loads first, and keep doing all of it on every image you add later, because you can write the rule into the file it reads at the start of every session.

Two things make the job urgent rather than nice-to-have. The first is speed. Images are the biggest thing on most pages (the median home page sends about a megabyte of them) and the largest element on 73% of mobile pages is an image, so the hero your agent dropped in at 4,000 pixels is usually the single reason the page feels slow. The second is one you may not have thought about. We ran six photos from an iPhone through the workflow below as a test. Every one of the 23 photos in that folder carried the latitude and longitude of where it was taken. A site that publishes supplied photos as they arrived publishes where they were taken, and anyone can read it.

The guide is written as prompts. You paste them into the agent you already use, in whichever seat you sit in: a chat assistant with the hosted Mochify MCP server, Claude Code or Cursor with the local one, or a script that calls the API. If you have never opened a terminal, start with the six words below and use the chat seat; the rest of the guide assumes only those six words.

Published October 31, 2026 by the Mochify Engineering Team. Written as six prompts for the person whose site an agent built, with every number from our own six-photo run on October 29, 2026.

Six words this guide uses

  • Agent: the AI that wrote your site and can still change it. Lovable, Bolt, v0 and Replit Agent build and host the site for you; Claude Code, Cursor and Codex work in a folder of code on your computer. All of them read and write files and can call tools.
  • Repo: the folder of files that is your website, usually kept on GitHub. The images your agent used live in it, often in a folder called public or assets. The deploy copies that folder to the server, so whatever is in the repo is what visitors download.
  • Original: the image file as it arrived: the 6 MB phone photo, the 4,000-pixel stock download, the PNG export from a design tool. An original is almost always far bigger than any screen will show it at.
  • Format: the kind of image file. JPEG and PNG are the old universal ones. WebP and AVIF store the same picture in a much smaller file and now work for over 96% of visitors, which is why speed tests ask for them.
  • Metadata (EXIF): text stored inside a photo that is not the picture: camera model, lens, date, and on phone photos usually the GPS coordinates of where you stood. It travels with the file unless something removes it.
  • MCP: the Model Context Protocol, the standard way an agent calls an outside tool. Mochify is an MCP server, so once it is connected your agent can compress, resize and convert images as a tool call, the same way it edits a file. There are two Mochify servers: the hosted MCP server, which you connect from a chat app with nothing installed, and the local MCP server, a small program on your machine for coding agents.

Why an AI-built website ships heavy images, and why the platform does not fix it

An agent writes the simplest code that makes the picture appear, and the simplest code is <img src="/photo.jpg"> pointing at the file you gave it. Nothing in that line resizes the file, converts it or removes its metadata, and nothing in a typical deploy does either. The slowness people notice on "vibe-coded" sites is mostly this. A web designer who audits them put it as "4K hero images served at 80% quality with no responsive variants"; an analysis of 100 sites built with Lovable, v0 and Bolt found "large hero images and uncompressed assets were particularly common issues".

The platforms are clear that this is your job, when they say anything. Lovable's documentation tells you to "Compress images and use efficient formats like WebP or SVG", says files you upload to the connected repo go in the public folder and are referenced by path, and notes that its own SEO review "no longer runs Lighthouse audits, so it no longer reports page speed scores": you are sent to PageSpeed Insights to find out. Bolt's publish troubleshooting page says projects must stay under 100 MB and that "most commonly, projects hit this limit because they have large media files", with the remedy being to delete media or move it to a CDN. Vercel, which hosts a great many agent-built Next.js and v0 sites, states the rule for the plain tag exactly: "If you use a standard HTML img element, the browser will be instructed to bypass optimization and serve the image directly from its source."

Compare a hosted site builder, which resizes what you upload (imperfectly, with no say over the format or what loads first). An agent-built site does nothing unless asked, and then can do it better, because the agent owns the markup. The gap is the whole opportunity, and closing it takes six prompts.

What a speed test will tell you, if you run one before you start: in PageSpeed Insights and Lighthouse 13 the image findings are now gathered under one insight called "Improve image delivery", which flags images with "unnecessarily large download sizes" (older reports split the same problem into "Serve images in next-gen formats", "Properly size images" and "Efficiently encode images"). If that insight is at the top of your report with a large number next to it, this guide is the fix.

Prompt 1: the audit (find every image and what it costs)

Start by making the agent look at its own output. You want a table, not a fix, because the table tells you which case you are in (next section) and how many images you are dealing with (which decides the allowance you need, later). Paste this into the agent that has access to the repo:

audit-prompt.txt
Audit every image on this site. For each image file in the repo (public/, assets/, src/, and anything referenced from HTML, JSX, CSS or Markdown), list: file path, pixel width x height, file size in KB, format, every place it is referenced, the largest width it is ever displayed at (read the CSS, the layout and any max-width), and whether the reference is a plain <img>, a CSS background-image, or a framework image component (next/image, Astro <Image>, or similar). Then tell me: the total image bytes, the ten largest files, every image displayed at less than half its pixel width, every image over 300 KB, and which image is likely the largest element on the home page's first screen. Do not change anything yet.

Three things to read in the result. The total image bytes are your before number; write it down. The displayed-at-less-than-half-width list is where resizing alone will do most of the work: a 5,712-pixel phone photo shown in a 1,200-pixel column is sending visitors twenty times the pixels they can see. The largest element on the first screen is your LCP image, the one Google's Core Web Vitals score is measured on; it is the first file to fix and the one to treat with care (no lazy loading on it, which Prompt 4 covers).

If the agent is a chat assistant without access to the repo (you build in Lovable or Bolt and talk to it in the browser), ask the same question in the platform's chat; it can read its own project. If it cannot give you dimensions, the published site can: open the page, right-click an image, choose "Open image in new tab", and Chrome's tab title shows the pixel size next to the file name.

A metadata check belongs in the audit too, because the agent can do it in one line where you have a shell:

metadata-check-prompt.txt
For every JPEG and HEIC in the repo, report whether it carries EXIF metadata and specifically whether it has GPS coordinates. Use exiftool if it is installed (exiftool -gps:all -n <file>), otherwise read the EXIF with any library you have. List every file with a GPSLatitude value.

On a site built from your own phone photos, expect that list to be most of them.

Prompt 2: which case are you in? Plain img, framework component, or builder

The honest premise of this guide is only half true, and the half that is false matters: some agent-built sites already have an image pipeline, because the framework the agent chose has one built in. You need to know which case you are in before you fix anything, and the audit table tells you.

Case A: plain <img> tags (and CSS backgrounds) pointing at files in public/. This is most Lovable, Bolt and Replit sites, most static sites, and any Next.js or Astro site where the agent used the ordinary tag instead of the framework component. Nothing touches the file between the repo and the visitor. Astro's documentation says it plainly: "Files in the public/ directory are always served or copied into the build folder as-is, with no processing." The whole job is yours, and it has two halves: shrink the files, and write the markup (Prompts 3 and 4).

Case B: a framework image component. If the audit shows next/image (Next.js, which is typically what a v0 project is) or Astro's <Image />, the serving side is handled: the component resizes the image to the sizes it needs, converts it to WebP or AVIF for browsers that can take it, and sets the width and height. What it does not do is change the file in your repo. Next.js optimizes on request, through an endpoint on your own site, and caches the results on disk; the original stays exactly where it was and is still downloadable at its original path. Three consequences follow. The repo and every deploy still carry the 6 MB file. Anyone who wants the original, metadata included, can fetch it. And on Vercel, every size and format the optimizer makes from it is a transformation that counts against a quota (the Hobby plan includes 5,000 a month; past the limit "new images will fail to optimize and instead return a runtime error response with 402 status code" and visitors see the alt text). A smaller, cleaner source means a smaller cache, cheaper transformations and nothing embarrassing at the original URL. So in Case B you still run Prompt 3 to shrink the originals and strip the metadata; you skip most of Prompt 4 because the component writes the markup for you, and you check two settings instead: that sizes is set on any image that is not full width (Next.js assumes full width without it, "which can cause unnecessarily large images to be downloaded"), and that the first-screen image has preload (or priority on versions before Next.js 16).

Case C: a hosted builder with its own image handling. We looked for a statement from Lovable, Bolt, v0 or Replit that uploaded images are resized or re-encoded on publish and found none; their documentation tells you to compress your own. Treat a builder site as Case A unless you can prove otherwise, and the proof is one minute's work: open the published site, open an image in its own tab, and compare the pixel size and file size with the original you uploaded. Same numbers, same file.

The test that settles any case, and the one to show a client: download an image from the live site and read its metadata. On a Mac, open it in Preview, then Tools > Show Inspector and look for a GPS tab. In a shell, exiftool -gps:all photo.jpg. If coordinates come back, the live site is serving the original.

When you do not need this guide: a site whose images are all SVG logos and icons, or screenshots already exported at the size they display, or a Case B site whose originals are already small and clean. Run the audit anyway; it is one prompt and it tells you.

What the fix is worth: our six-photo run, 96% smaller, zero GPS

We tested the workflow on six photographs straight from an iPhone 15, the kind of file a client sends over WhatsApp for the "About us" page: 5,712 x 4,284 pixels, 3.6 to 6.3 MB each, 26.2 MB for the six. Each went through Mochify once per output format, resized to 1,600 pixels wide (a sensible ceiling for a full-width photo on a laptop screen) with the web-delivery setting on and everything else at automatic quality.

Output (1,600 px wide)Six files inSix files outSmaller byPer-file range
AVIF26.2 MB1.04 MB96.1%95 to 380 KB
WebP26.2 MB0.92 MB96.5%77 to 415 KB
JPEG (jpegli)26.2 MB1.08 MB95.9%129 to 368 KB

Each call took about a second from a laptop; the engine itself reported 217 to 792 milliseconds. Three things in the result are worth more than the headline number.

The resize did most of the work. At 1,600 pixels wide, all three formats landed within a few percent of each other. On a 24-megapixel phone photo, choosing the right pixel size is the big lever and the format is the last few percent, which is why Prompt 1 asks for the displayed width. (At automatic quality WebP came out smaller than AVIF on five of the six, an observation about these photos at these settings, not a format ranking; AVIF still wins on most detailed images, and the <picture> element lets you ship both.)

Every output came back with no metadata at all. We did not ask for that; it is the default. Every one of the source photos carried the full iPhone block, including the GPS coordinates of a real location. The outputs carried none, and they still came back the right way up: the resize applies the orientation stored in the metadata before discarding it, so a portrait phone photo stays portrait.

The same engine answers every door. We ran one of the files twice, once through the hosted MCP server from a chat and once through the REST API from a script, with the same settings. The two outputs were byte for byte identical. Whichever seat you use below, you get the same file.

Prompt 3: have the agent do it, from whichever seat you sit in

The agent does the work by calling Mochify as a tool: it decides the width, format and name from your words, Mochify does the pixel work on its servers, and the file comes back. Which seat you are in decides how the file travels, so the prompt changes slightly. Mochify's servers hold nothing: an image is streamed into memory, encoded, and wiped, with no copy written to disk and no log that contains it (the privacy notes under each seat say exactly what differs).

Seat 1: a chat assistant with the hosted MCP server (no install)

This is the seat for the person who builds in a browser and does not want to install anything, and for the content person on a team who is given a folder of photos and asked to "make these web-ready". Connect the hosted server once from the chat app's connectors or integrations screen (the steps for the common chat apps and editors are on the MCP server page; you sign in to a Mochify account, free or paid). Then, in a chat, attach the photo and say what you want:

chat-prompt.txt
Here is the hero photo for the home page. Make three versions at 1,600 pixels wide for the web: AVIF, WebP and JPEG, metadata stripped. Name them hero-1600.avif, hero-1600.webp and hero-1600.jpg and give me the download links.

What happens: the assistant cannot read the bytes of an attached image, so it asks Mochify for a one-time upload link and shows it to you; you drop the original onto that page; the assistant then calls the squish tool once per output format and comes back with three download links. The links live for about five minutes, so save the files straight away, then hand them to whoever commits them (or drop them into the builder's chat with "replace the hero with these three"). If the photo is already on a public HTTPS address, give the assistant the URL instead and skip the upload step; the address must be HTTPS, and Mochify's own pages are not accepted as a source.

Two limits to know. The hosted server takes one image per call, so this seat is for the hero, the team photos and the dozen product shots, not a hundred-image sweep; for that, use the web app's batch (up to 25 at a time on paid plans, 3 on Free) or Seat 3. And the privacy model here has one extra step: the original is wiped as soon as it is processed, and the finished file waits in a pickup store for up to five minutes so your link works, then is deleted whether or not you fetched it.

Seat 2: Claude Code or Cursor with the local MCP server (files in, files out)

This is the seat for anyone working in the repo. The local server is the mochify command run as mochify serve; the agent calls its squish tool with a file path and gets a file path back, so no image bytes ever enter the conversation and nothing is uploaded by hand. Install and register it once (a few commands; our Claude Code image compression guide walks through brew install mochify, mochify auth login and claude mcp add; Cursor and other MCP clients register the same mochify serve command in their MCP settings), then give the agent the audit table and this:

claude-code-prompt.txt
Using the Mochify squish tool, process every image in the audit that is a photo or a raster graphic. For each one: resize to the largest width it is displayed at, rounded up to the next of 640, 1024, 1600 or 2048 pixels, never larger than the original; write an AVIF, a WebP and a JPEG into the same folder as the original, named <name>-<width>.<ext>; strip the metadata. Do not touch SVGs or files under 30 KB. When all of them are done, report the before and after sizes per file and the totals, and list every original you processed so I can decide what to delete.

The agent calls the tool once per output file; each call returns a path and the new size, which is why it can write the report without you opening anything. Mochify never upscales (an image displayed wider than its pixels comes back at its own size), and the local tool never overwrites: a name that already exists gets a numeric suffix, so the originals are safe until you delete them in the next step.

Privacy on this seat: the bytes travel from your disk to api.mochify.app over HTTPS, are encoded in memory and wiped, and the result is written straight back to your disk. There is no pickup store and nothing is held, which is as close to zero retention as a cloud encoder gets. The file does leave your machine for the encoding; we do not claim otherwise.

If you are in Claude Code but cannot install the binary (a locked-down machine, a cloud sandbox), the hosted server still works from a shell: the agent asks for an upload link, uploads with curl -T, calls squish, and fetches the result link with curl. It is four steps per image instead of one, and the allowance cost is the same, so install the local server where you can.

Seat 3: the bulk sweep, from the CLI or the API in a script

For a site with hundreds of images, or a deploy step that should run without an agent in the loop, the same engine is one command or one HTTP call per image. The mochify command takes a glob and an output folder:

sweep.sh
mochify ./public/photos/*.jpg -t avif -w 1600 -o ./public/photos/web
mochify ./public/photos/*.jpg -t webp -w 1600 -o ./public/photos/web

The REST API is the same thing from any language. Our test script was a loop around a single call:

squish.sh
curl -X POST "https://api.mochify.app/v1/squish?type=avif&width=1600&optimizeForWeb=1" \
  -H "Content-Type: image/jpeg" \
  -H "Authorization: Bearer $KEY" \
  --data-binary @IMG_4601.JPG --output IMG_4601-1600.avif

On the API, metadata is stripped unless the call says stripExif=false, which is the one setting a photographer's portfolio might want and a company site never does. The key ($KEY above) comes from your Mochify dashboard; an agent can write this loop for you ("write a script that runs this call for every JPEG in public/photos, for avif and webp, and prints a size table"), and our guide to converting a whole site's images to WebP and AVIF has the version that only converts files that do not have a .webp and .avif beside them yet, so it can run on every deploy for nothing.

Prompt 4: the markup the agent should write back

New files do nothing until the page points at them, and this is where an agent-built site can end up better than a builder's: the agent can write the markup a builder will not let you touch. In Case B the framework component does this for you and you skip to the two settings named earlier. In Case A, give the agent this:

markup-prompt.txt
For every image you processed, replace the plain <img> with a <picture> element: an AVIF <source>, a WebP <source>, and the JPEG as the <img> fallback, keeping the existing alt text. Set width and height on the <img> to the new file's pixel size. Add loading="lazy" and decoding="async" to every image except the one that is the largest element on the home page's first screen; give that one fetchpriority="high" and no lazy loading. Where an image is a CSS background-image, use image-set() with the AVIF and WebP and the JPEG as the fallback. Then delete the originals you listed, unless I kept any for the metadata, and make sure nothing still references them.

The result for one image looks like this:

hero.html
<picture>
  <source srcset="/photos/web/hero-1600.avif" type="image/avif">
  <source srcset="/photos/web/hero-1600.webp" type="image/webp">
  <img src="/photos/web/hero-1600.jpg" alt="The workshop at dawn"
       width="1600" height="1200" fetchpriority="high">
</picture>

Why each part is there, briefly: the browser takes the first <source> it can decode and downloads only that one, so an AVIF-capable visitor never fetches the JPEG; the width and height let the page reserve the space before the file arrives, which is what stops the layout jumping; loading="lazy" holds back images below the fold until they are needed, and must not go on the first-screen image because it would delay the thing the page is judged on. The order of the sources, the art-direction tricks and the four rules that make the element render are in our picture tag guide, and the CSS half is in the background-image fallback answer; point the agent at either if it gets a detail wrong.

Verify it the way a visitor's browser would: open the live page, right-click, Inspect, open the Network tab, filter to Img, reload. Each picture should show one request, with an .avif name in Chrome, Firefox or Safari 16 or later. Then run PageSpeed Insights again and read the "Improve image delivery" line.

Prompt 5: keep it fixed with one line in the rules file

A one-off clean-up lasts until the next photo. The durable fix is to make image processing the agent's default, and every coding agent now reads a plain-text file of standing instructions at the start of a session: CLAUDE.md for Claude Code, AGENTS.md for Codex, Cursor, Copilot's coding agent, Gemini CLI, Windsurf and most of the rest (an open format now stewarded under the Linux Foundation and "used by over 60k open-source projects"), and .cursor/rules/*.mdc for Cursor's own rule files. Claude Code reads AGENTS.md in place of CLAUDE.md if that is what the repo has, and Cursor reads AGENTS.md too, so one file usually covers everyone. Add this to it:

AGENTS.md
## Images
Every raster image that enters this repo goes through the Mochify squish tool
before it is committed: resized to its largest displayed width (640, 1024,
1600 or 2048, never upscaled), saved as AVIF + WebP + JPEG named <name>-<width>,
metadata stripped. Reference them with <picture>, width and
height set, loading="lazy" on everything except the first-screen image.
Never commit an original photo or a file over 300 KB.

Ask the agent to add it and to confirm it applies to the right scope: "Add this Images section to the project's CLAUDE.md (or AGENTS.md), and tell me which file you read on startup." In Cursor, the equivalent is a rule with alwaysApply: true.

Be honest with yourself about what a rules file is. Claude Code's own documentation says it treats these files as "context, not enforced configuration": the line makes processing the default, and a determined prompt or a distracted session can still skip it. For enforcement, add the same check as a pre-commit hook that rejects any image over your size limit or with a GPS tag, and have the agent write it ("add a pre-commit hook that fails if any staged image is over 300 KB or carries GPSLatitude"). The rule makes it happen by default; the hook makes it impossible to forget.

Prompt 6: count the images against an allowance before you start

Every output file is one operation against a Mochify allowance, so three formats for 100 images is 300 operations, and the agent can count that for you before it spends anything. The hosted MCP server exposes a check_usage tool, and the API has the same read at GET /v1/checkTokens, which a coding agent can call with the key from your dashboard:

allowance-prompt.txt
Before processing anything, call check_usage (or GET https://api.mochify.app/v1/checkTokens with my key) and tell me how many operations are left on this account this month. From the audit, count the images we will process and multiply by the number of formats. If the total is more than what is left, stop and tell me which plan would cover it; do not start a partial run.

The tiers, by what they allow rather than what they cost: a free account gets 25 operations a month with a batch of 3 and a 20 MB file limit, enough to test on the hero and a handful of photos. Seller gives 300 a month, Pro 1,200 and Growth 5,000, all with 75 MB files and batches of 25, and all three include the MCP servers and the API; Seller is the right size for one site that gets new photos every week. A Day Pass is $2 for 100 operations in 24 hours with no signup, which covers a one-off pass over a small site from the web app; used from an assistant it needs a free account you are signed in with, and for those 24 hours it replaces the account's monthly 25 rather than adding to it. The agent reports the number; a person decides and pays. Current limits are on the pricing page.

For agencies: the same six prompts per client

If you build sites for clients with an agent, this is a repeatable service rather than a one-time fix, and it maps onto how a team already splits the work. The content person works in the chat seat: they receive the client's photos, run them through the hosted MCP server, and hand over clean, sized files with the location data already gone, which matters when the client is a clinic, a school or anyone whose photos were taken at a home address. The developer works in the local seat: the rules file is in the project template, so every new client repo starts with the image policy in place, and the pre-commit hook catches the one time someone pastes a photo straight in. The allowance question becomes a per-client line item: run Prompt 6 against the audit at kickoff, and put the operations count in the proposal next to the page count.

The handoff between the two seats is the part teams skip. Make it a file: the audit table from Prompt 1, with a column for "processed by" and "committed in", lives in the repo next to the images. It is the before-and-after the client sees, and the record of who stripped what from which photo. (For an agency, that record is also the answer to a data-protection question; Mochify's data processing agreement and the architecture page describe the in-memory model if a client asks where the photos went.)

Mochify Workflow: optimize an agent-built site's images

The same job, step by step, whichever seat you are in. The natural-language layer runs through all of them: in the web app and on the command line you describe the result and Magic Flow turns the words into settings; in an agent, your words go to the agent, which picks the settings and calls the tool.

  1. Run the audit (Prompt 1)

    Write down the total image bytes and the largest first-screen image.

  2. Decide the case (Prompt 2)

    Plain <img> means you do files and markup; a framework component means files only plus the sizes and preload checks.

  3. Try it on one image first

    Drop the hero on mochify.app/flow and type "convert to AVIF, 1,600 pixels wide, for the web"; or on the command line, mochify hero.jpg -p "convert to avif, 1600px wide". Open the result, check it is upright and looks right, and read the size. That is the number you will get for every image.

  4. Process the set (Prompt 3)

    From the chat seat for a handful, the local server for a repo, or the CLI/API for hundreds. Mochify never upscales and the local tool never overwrites.

  5. Write the markup (Prompt 4)

    The <picture> element, width and height, lazy loading below the fold, priority on the first-screen image. Delete the originals the audit listed.

  6. Add the rules-file line and the hook (Prompt 5)

    So the next photo is handled the same way without being asked.

  7. Verify

    The Network tab filtered to Img shows one small request per picture; a downloaded image from the live site has no GPS tab; PageSpeed Insights' "Improve image delivery" line is gone or small.

Privacy, stated for each surface because they differ: on the local server, the CLI and the API, the image is streamed into memory at api.mochify.app, encoded, wiped, and the result comes straight back to your disk with nothing held; on the hosted server the original is wiped the same way and the finished file waits in a five-minute pickup store so your link resolves, then is deleted. Images and PDFs are never used to train anything. They do travel to the API for the encoding; the one Mochify surface that never leaves the device is video, in the web app, which is not part of this workflow.

Cheat Sheet

You want toSeatPrompt or command
Know how bad it isAny agent with the repoPrompt 1 (audit table: path, pixels, KB, displayed width, reference type, GPS)
Know whether anything already optimizesAudit resultPlain <img> in public/ = Case A, do files and markup; next/image or Astro <Image> = Case B, do files, check sizes and preload
Fix a few images with nothing installedChat + hosted MCP serverAttach photo: "three versions at 1,600 wide, AVIF, WebP, JPEG, metadata stripped"; one image per call, links last ~5 min
Fix a repo's imagesClaude Code / Cursor + local MCP serverPrompt 3: largest displayed width from 640/1024/1600/2048, three formats, <name>-<width>, report sizes
Fix hundredsCLI or APImochify ./public/photos/*.jpg -t avif -w 1600 -o ./public/photos/web or POST /v1/squish?type=avif&width=1600&optimizeForWeb=1
Keep metadata on purposeAPI, or an assistant on the hosted MCP serverstripExif=false (the default strips, GPS included)
Point the page at the new filesAgent with the repoPrompt 4: <picture> with AVIF, WebP, JPEG; width and height; lazy below the fold; fetchpriority="high" on the first-screen image
Make it the default foreverRules fileThe Images section in CLAUDE.md / AGENTS.md / .cursor/rules, plus a pre-commit hook on size and GPS
Know what it will cost in operationsAny agentPrompt 6: check_usage (hosted MCP server) or GET /v1/checkTokens (API); images x formats
Prove it workedBrowserNetwork tab, Img filter, one .avif per picture; downloaded image has no GPS; "Improve image delivery" gone

What our run measured: six iPhone photos, 26.2 MB, to 1.04 MB AVIF, 0.92 MB WebP, 1.08 MB JPEG at 1,600 wide (about 96% smaller each way); every output free of metadata; 23 of 23 source photos had carried GPS coordinates; hosted MCP and API outputs byte-identical.

FAQ

Does Lovable optimize images automatically?

Nothing in Lovable's documentation says uploaded images are resized or re-encoded on publish; its advice is to "Compress images and use efficient formats like WebP or SVG" yourself, images you upload to the connected repo go in the public folder as they are, and its SEO review no longer reports page speed, so Lovable SEO advice that stops at meta tags, sitemaps and rendering misses the weight of the page. Treat a Lovable site as a plain-<img> site: process the files with the prompts above and have Lovable's chat replace the references. Then confirm by opening a published image in its own tab and comparing its pixel size with what you uploaded.

My Lovable site is slow. Is it the images?

"Lovable is slow" means two different things, and the forums mix them: the editor and preview being slow to respond, which is on Lovable's side and shows up on its status page, and the published site loading slowly for visitors, which is almost always weight, and the heaviest weight on a new site is images. Run PageSpeed Insights on the published URL; if "Improve image delivery" is the top finding, the images are the reason, and Prompt 1 will tell you how much.

I use next/image. Does Next.js image optimization mean I can skip this?

For the serving side, no: next/image resizes and converts on request and writes the markup. For the files, yes. It does not change the originals in your repo, so every deploy carries them, anyone can download one at its original path with its metadata intact, and on Vercel every size it generates from a large source is a transformation against your quota. Shrink and clean the originals with Prompt 3, then check that sizes is set on images that are not full width and that the first-screen image has preload (or priority before Next.js 16).

Will stripping the metadata rotate my phone photos sideways?

Not through Mochify. A phone stores a portrait photo as landscape pixels plus an orientation flag in the metadata; a careless tool that discards the metadata leaves the picture on its side. Mochify applies the orientation during the resize and then writes the output upright with no metadata, which is what our six-photo run showed: 5,712 x 4,284 in, 1,600 x 2,133 out, the right way up.

How do I get Claude Code or Cursor to optimize the images in my repo?

Install the mochify binary, run mochify auth login once, and register mochify serve as a local MCP server (in Claude Code, claude mcp add --transport stdio mochify -- mochify serve; in Cursor, the same command in its MCP settings). Then paste Prompt 3: the agent calls the squish tool with each file path and gets a path back, so no image bytes enter the session. To keep the metadata on a particular photo, say so in the prompt; the API option behind it is stripExif=false. Add the Images section from Prompt 5 to CLAUDE.md or AGENTS.md so the next photo is handled the same way without being asked.

How many operations will a whole site take, and which plan covers it?

Count the images you will process and multiply by the formats you want: 40 photos in AVIF, WebP and JPEG is 120 operations. A free account has 25 a month; a Day Pass is 100 in 24 hours for $2 with no signup; Seller is 300 a month, Pro 1,200, Growth 5,000, and all three include the MCP servers and the API. Prompt 6 has the agent read the remaining allowance with check_usage before it starts, so a sweep never stops halfway.

Does the agent see my photos, and does Mochify keep them?

With the local MCP server the agent sees a file path and a result path, never the image bytes, and Mochify encodes the image in memory and wipes it, with the result written straight back to your disk. With the hosted server the agent sees a download link, the original is wiped the same way, and the finished file waits in a pickup store for up to five minutes so the link works. Neither route stores your photos, and nothing is used to train anything. The photo does travel to Mochify's servers for the encoding; it is not processed on your machine.

Can the rules-file line replace a build step?

It replaces the forgetting, not the enforcement. The line makes the agent process images by default in every session that reads it, and Claude Code and Cursor both read AGENTS.md or their own file at startup; Claude Code's documentation is clear that such files are "context, not enforced configuration". Keep the line, and add a pre-commit hook or a deploy-time script (the only-new-files version in our whole-site conversion guide) for the case where a human or a hurried agent skips it.

Connect the hosted server from the MCP server page and run Prompt 1 on your own site, or try a single photo at mochify.app/flow with the prompt "convert to AVIF, 1,600 pixels wide, for the web". Twenty-five images a month are free with an account.