Agents trained on years of Manifest V2 tutorials will happily write background pages, remote code and "<all_urls>" permissions — all of which either break in Manifest V3 or get you rejected from the Chrome Web Store. This loadout keeps your agent on MV3, keeps permissions tight, and walks through store submission so the review goes smoothly first time.
What's in it
- Service worker lifecycle rules (no global state, use chrome.storage and alarms)
- Least-privilege permissions with activeTab and optional host permissions
- Clear message-passing pattern between content scripts, popup and service worker
- Store-prep skill: permission justifications, privacy disclosures, zip packaging
You'll need
- Tools:
node,chrome
Verification
| Check | Result | What we found |
|---|---|---|
| Listinglisting.yaml matches the schema and declares every file in the folder. | Pass | Schema valid; 5 files declared, none missing or extra
|
| Files parseJSON parses; SKILL.md and .mdc front matter is valid YAML with the fields each agent needs; code fences are closed. | Pass | All 5 files parse; front matter valid |
| AdaptersCLAUDE.md imports @AGENTS.md, GEMINI.md imports @./AGENTS.md, and both match the generator. | Pass | CLAUDE.md and GEMINI.md import AGENTS.md and are up to date
|
| Install pathsEvery file lands where each agent documents it, with no collisions, and the laid-out project is re-discovered correctly. | Pass | Correct paths for all 5 agents; layouts re-discovered
|
| MCP configmcp.json is structurally valid, converts to each agent's format, declares no literal secrets, and referenced packages exist on npm/PyPI. | Not applicable | No MCP servers in this loadout |
| Safety scanThe intake scanner finds no credentials, risky shell, hidden Unicode or prompt-injection wording, and the listing's network flag is honest. | Pass | Clean: no credentials, risky shell or hidden text
|
| ReferencesLinks and file paths between the loadout's files resolve, including for each agent's installed layout. | Pass | No cross-file references to check |
| Size limitsFile count and sizes are within the submission limits; SKILL.md bodies stay under 500 lines. | Pass | 5 files, 7.0 KB total; largest AGENTS.md 3.2 KB
|
| LicenceA recognised SPDX licence, with the licence text available. | Pass | MIT, by Agent Loadout; text in the repository LICENSE |
| Starter buildA minimal fixture project with the loadout applied installs and builds or type-checks, and the loadout's own code examples compile. | Pass | Manifest V3 extension in the loadout's layout type-checks against @types/chrome, builds, and passes the loadout's manifest and remote-code rules
|
What this means: a script checked the files themselves: they parse, they install where each agent looks, any MCP config is sound, the safety scan is clean, references between files resolve, and, where a free and repeatable fixture exists, a small starter project builds with the loadout applied. No AI agent was run. Per-agent results ("tested with agent") are separate and stay untested until an agent actually runs.
Install
Choose your agent. Run the commands from your project root, or download a zip already laid out in the right folders.
Claude Code reads CLAUDE.md (imports AGENTS.md with @AGENTS.md) and skills from .claude/skills/.
curl -fsSL --create-dirs -o AGENTS.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/AGENTS.md curl -fsSL --create-dirs -o CLAUDE.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/CLAUDE.md curl -fsSL --create-dirs -o .claude/skills/extension-store-prep/SKILL.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/skills/extension-store-prep/SKILL.md
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
CLAUDE.md | CLAUDE.md |
skills/extension-store-prep/SKILL.md | .claude/skills/extension-store-prep/SKILL.md |
Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.
Codex CLI reads AGENTS.md and skills from .agents/skills/.
curl -fsSL --create-dirs -o AGENTS.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/AGENTS.md curl -fsSL --create-dirs -o .agents/skills/extension-store-prep/SKILL.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/skills/extension-store-prep/SKILL.md
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
skills/extension-store-prep/SKILL.md | .agents/skills/extension-store-prep/SKILL.md |
Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.
Cursor reads AGENTS.md + .cursor/rules/*.mdc and skills from .agents/skills/.
curl -fsSL --create-dirs -o AGENTS.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/AGENTS.md curl -fsSL --create-dirs -o .cursor/rules/manifest.mdc https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/.cursor/rules/manifest.mdc curl -fsSL --create-dirs -o .agents/skills/extension-store-prep/SKILL.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/skills/extension-store-prep/SKILL.md
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
.cursor/rules/manifest.mdc | .cursor/rules/manifest.mdc |
skills/extension-store-prep/SKILL.md | .agents/skills/extension-store-prep/SKILL.md |
Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.
Gemini CLI reads GEMINI.md (imports AGENTS.md with @./AGENTS.md) and skills from .agents/skills/.
curl -fsSL --create-dirs -o AGENTS.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/AGENTS.md curl -fsSL --create-dirs -o GEMINI.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/GEMINI.md curl -fsSL --create-dirs -o .agents/skills/extension-store-prep/SKILL.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/skills/extension-store-prep/SKILL.md
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
GEMINI.md | GEMINI.md |
skills/extension-store-prep/SKILL.md | .agents/skills/extension-store-prep/SKILL.md |
Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.
GitHub Copilot reads AGENTS.md and skills from .agents/skills/.
curl -fsSL --create-dirs -o AGENTS.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/AGENTS.md curl -fsSL --create-dirs -o .agents/skills/extension-store-prep/SKILL.md https://loadout.jnw-it.com/raw/chrome-extension-mv3/1.0.0/skills/extension-store-prep/SKILL.md
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
skills/extension-store-prep/SKILL.md | .agents/skills/extension-store-prep/SKILL.md |
Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.
Files
Rules AGENTS.md Manifest V3 extension project rules. 51 lines
# AGENTS.md: Chrome extension (Manifest V3)
## Ground rules
- This is a **Manifest V3** extension (`"manifest_version": 3`). Do not use MV2 APIs: no `background.page`,
no `background.persistent`, no `chrome.browserAction`/`pageAction` (use `chrome.action`), no blocking `webRequest` (use `declarativeNetRequest`).
- **No remotely hosted code.** Every script the extension runs ships in the package. No `eval`, no `new Function`,
no `<script src="https://...">`, no loading JS from a CDN. Fetching *data* (JSON) is fine.
## Layout
```
manifest.json
src/background.ts service worker
src/content/*.ts content scripts (run in web pages, isolated world)
src/popup/ popup UI (popup.html + script)
src/options/ options page
icons/ 16, 32, 48, 128 px PNGs
```
## Service worker lifecycle
- The service worker stops when idle (after about 30 seconds) and restarts on events. **Global variables are lost.**
Persist state in `chrome.storage.local` (or `session` for per-browser-session data).
- Register all event listeners synchronously at the top level of the worker, not inside `await`s or callbacks,
or they will be missed when the worker wakes.
- Use `chrome.alarms` instead of `setInterval`/`setTimeout` for anything longer than a few seconds.
- No DOM in the service worker (`document`, `window`, `localStorage` do not exist). Use an offscreen document if you truly need DOM APIs.
## Permissions (least privilege — reviewers check this)
- Prefer `activeTab` + `scripting` over broad host permissions: the extension gets access to the current tab only when the user clicks it.
- If host access is needed, list specific origins, and prefer `optional_host_permissions` requested at the moment of use
with `chrome.permissions.request`.
- Never add `<all_urls>`, `tabs`, `history`, `cookies` or `webRequest` "just in case". Every permission needs a one-line reason in `PERMISSIONS.md`.
## Messaging
- Content script ↔ service worker: `chrome.runtime.sendMessage` / `chrome.runtime.onMessage`. Popup → tab: `chrome.tabs.sendMessage(tabId, ...)`.
- Messages are typed objects with a `type` field. Validate the shape on receipt; treat messages from content scripts as untrusted
(web pages can influence them).
- To respond asynchronously from `onMessage`, `return true` from the listener and call `sendResponse` later.
## Content scripts
- Do not trust page data. Never insert page-controlled strings with `innerHTML`; use `textContent` or build elements.
- Scope `matches` as narrowly as possible. Avoid running on every page if the feature is for one site.
- Style injected UI in a Shadow DOM so page CSS cannot break it (and vice versa).
## Dev loop
- `npm run build` outputs to `dist/`. The human loads it at `chrome://extensions` → Developer mode → Load unpacked → `dist/`.
- After changing `manifest.json` or the service worker, the extension must be reloaded on that page. Remind the human.
- Debug the worker from `chrome://extensions` → "service worker" link; debug content scripts in the page's DevTools.
## Before you say "done"
`npm run build` passes, `manifest.json` is valid JSON with no new permissions you have not justified, and you have said what to reload and test. Adapter CLAUDE.md Imports AGENTS.md for Claude Code. 10 lines
# CLAUDE.md
@AGENTS.md
## Claude Code notes
- Skills from this loadout live in `.claude/skills/`: `extension-store-prep`. Use them when their description matches the task.
- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.
<!-- From the Agent Loadout "Chrome extension (Manifest V3)" v1.0.0 — https://loadout.jnw-it.com/loadouts/chrome-extension-mv3/ --> Adapter GEMINI.md Imports AGENTS.md for Gemini CLI. 10 lines
# GEMINI.md
@./AGENTS.md
## Gemini CLI notes
- Skills from this loadout live in `.agents/skills/`: `extension-store-prep`. Use them when their description matches the task.
- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.
<!-- From the Agent Loadout "Chrome extension (Manifest V3)" v1.0.0 — https://loadout.jnw-it.com/loadouts/chrome-extension-mv3/ --> Cursor rule .cursor/rules/manifest.mdc Rule applied when editing manifest.json. 15 lines
---
description: Manifest V3 manifest.json rules
globs: "**/manifest.json"
alwaysApply: false
---
- `"manifest_version": 3`. Background is `{ "service_worker": "background.js", "type": "module" }` — never `scripts` or `page`.
- Use `"action"` for the toolbar button, not `browser_action`/`page_action`.
- Adding any entry to `permissions` or `host_permissions` requires a justification line in `PERMISSIONS.md`. Prefer `activeTab`.
- Prefer `optional_host_permissions` for sites the user opts into.
- No remote URLs in `content_security_policy`. Do not loosen the default extension CSP.
- `web_accessible_resources` lists only files a page genuinely needs, with narrow `matches`.
- Bump `version` (dot-separated integers, e.g. `1.2.0`) on every store upload.
- Keep `description` under 132 characters; it is shown in the store. Skill skills/extension-store-prep/SKILL.md Prepares a Chrome Web Store submission. 38 lines
---
name: extension-store-prep
description: Prepare a Manifest V3 Chrome extension for Chrome Web Store submission. Use when the user wants to publish, submit, package or release their extension.
---
# Chrome Web Store prep
## 1. Audit the manifest
- `manifest_version` is 3, `version` is bumped since the last upload, `name` and `description` (≤132 chars) are final.
- Icons: 16, 32, 48 and 128 px PNGs exist and are referenced.
- For each permission and host permission, write a one-sentence justification describing the user-facing feature that needs it.
If you cannot, recommend removing it. `activeTab` is preferred over host permissions; broad host permissions slow review.
## 2. Check for common rejection reasons
- **Remote code:** search the build for `eval(`, `new Function(`, remote `<script src=`, and imports from `http`. Any hit is a blocker.
- **Single purpose:** the extension does one clearly described thing. Flag unrelated features.
- **Obfuscation:** minified is fine, obfuscated is not. Do not enable obfuscating build plugins.
- **Data use:** list every piece of user data the extension reads, stores or sends anywhere.
## 3. Write the listing material into `store/`
- `store/description.md`: what it does in the first sentence, then features, then a privacy line.
- `store/permissions.md`: each permission with its justification (pasted into the dashboard's Privacy tab).
- `store/privacy.md`: data collected, why, where it goes, retention. If nothing leaves the device, say so plainly.
A privacy policy URL is required if the extension handles personal or sensitive data — the human must host it somewhere.
- Screenshot list: tell the human to capture at least one 1280×800 (or 640×400) screenshot, plus a 440×280 small promo tile.
## 4. Package
```sh
npm run build
cd dist && zip -r ../extension-$(node -p "require('./manifest.json').version").zip . -x "*.map" && cd ..
```
`manifest.json` must be at the root of the zip. Exclude source maps and dev files.
## 5. Hand over
Tell the human the zip path, then the dashboard steps they must do themselves: upload at the Chrome Web Store Developer
Dashboard, fill in Store listing and Privacy tabs from the `store/` files, choose visibility, submit for review.
A one-off developer registration fee applies to new accounts. Do not claim the extension has been submitted. All files: source zip · Licence MIT · By Agent Loadout · First listed
Installing and testing
How do I install Chrome extension (Manifest V3) in Claude Code?
From your project root, put AGENTS.md, CLAUDE.md, skills/extension-store-prep/SKILL.md at .claude/skills/extension-store-prep/SKILL.md. The "Claude Code" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/chrome-extension-mv3/claude-code.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.
How do I install Chrome extension (Manifest V3) in Codex CLI?
From your project root, put AGENTS.md, skills/extension-store-prep/SKILL.md at .agents/skills/extension-store-prep/SKILL.md. The "Codex CLI" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/chrome-extension-mv3/codex.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.
How do I install Chrome extension (Manifest V3) in Cursor?
From your project root, put AGENTS.md, .cursor/rules/manifest.mdc, skills/extension-store-prep/SKILL.md at .agents/skills/extension-store-prep/SKILL.md. The "Cursor" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/chrome-extension-mv3/cursor.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.
How do I install Chrome extension (Manifest V3) in Gemini CLI?
From your project root, put AGENTS.md, GEMINI.md, skills/extension-store-prep/SKILL.md at .agents/skills/extension-store-prep/SKILL.md. The "Gemini CLI" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/chrome-extension-mv3/gemini-cli.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.
How do I install Chrome extension (Manifest V3) in GitHub Copilot?
From your project root, put AGENTS.md, skills/extension-store-prep/SKILL.md at .agents/skills/extension-store-prep/SKILL.md. The "GitHub Copilot" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/chrome-extension-mv3/copilot.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.
Has Chrome extension (Manifest V3) been tested?
It passed the Level 1 automated install checks on 2026-10-16: the files parse, install to each agent's documented paths, and pass the safety scan. No AI agent has run it yet, so no agent pass or fail is claimed.
More for Claude Code, Codex, Cursor, Gemini CLI and GitHub Copilot.