Set up your coding assistant with the Chrome Web Store Policy MCP
AI coding assistants are powerful but have limitations — training data cuts off at a specific date, missing recent Chrome Web Store policy revisions and the precise wording reviewers use to reject extensions. Without that context, agents tend to suggest generic patterns that pass technically but get flagged at review.
To keep your coding assistant current with the evolving Chrome Web Store program policies and their on-the-ground enforcement, we recommend setting up the Chrome Web Store Policy MCP. The server runs policy validation against your extension's manifest, permissions, privacy policy, and source code, and exposes a structured remediation report your agent can act on without leaving the editor.
Connect the Chrome Web Store Policy MCP #
The MCP is hosted as a public server at
https://chrome-web-store-policy-mcp.dev.
Connecting your coding agent to this server gives every query
access to the latest policy rules, deterministic checks for
manifest and permissions, and LLM-assist prompts for code-quality
and single-purpose review.
Run the following command in your agent's terminal or project root to install the server:
npx add-mcp "https://chrome-web-store-policy-mcp.dev"
The installer auto-detects which MCP-compatible clients you have (Claude Code, Cursor, Antigravity, Codex CLI, Gemini CLI, Copilot, Claude Desktop) and writes the correct configuration block for each. You can also install manually — see Manual installation below.
Once connected, your agent gains seven new tools that follow the
mcp__chrome-web-store-policy__*
namespace:
-
validate_manifest— manifest version, required fields, content security policy -
validate_permissions— broad host patterns, sensitive permissions, MV3-disallowed APIs -
check_privacy_policy— HTTPS, fetched URL or text, standard disclosure sections -
scan_code_quality— eval, Function constructor, remote code, obfuscation -
validate_single_purpose— description vs. manifest surface area -
get_policy_details— look up policies by category or keyword with source URLs -
generate_remediation_report— end-to-end report aggregating all checks
Policies covered #
The bundled rule set mirrors Google's official 27-violation
taxonomy from
Troubleshooting Chrome Web Store violations. Each card shows the official notification ID(s) reviewers
cite in rejection emails — paste a codename like
Red Magnesium here to look up exactly
what it means. Click Why it's rejected & how to fix
on any card to expand the full description, common rejection
reasons, and concrete fix steps.
AUTO detected by the deterministic validators · LLM evaluated by the calling agent via a structured prompt · MANUAL reference-only; reviewers check this by hand.
Blue — Manifest / API / Prohibited / Enforcement #
Why it's rejected & how to fix
MV3 extensions must not include remotely hosted code. Full functionality must be discernible from the submitted package; logic must be self-contained.
Common reasons for rejection
- Including a <script> tag that points to a resource outside the extension's package.
- Using JavaScript's eval() or other mechanisms to execute a string fetched from a remote source.
- Building an interpreter to run complex commands fetched from a remote source, even if those commands are fetched as data.
How to fix
- Double-check all code for references to external JavaScript files; replace them with internal extension files.
- Review the Manifest V3 migration guide on improving extension security for alternatives to executing arbitrary strings and remotely hosted code.
Why it's rejected & how to fix
Extensions must not provide access to content behind paywalls or login restrictions, facilitate downloads of YouTube videos, or download content that violates intellectual property rights.
Common reasons for rejection
- Providing access to content behind a paywall.
- Providing access to content behind login restrictions.
- Facilitating download of YouTube videos.
- Facilitating download of content that violates intellectual property rights.
How to fix
- If this is the primary functionality — unpublish.
- If unintended — remove the violating content/services and resubmit.
Why it's rejected & how to fix
Modifying the Chrome New Tab Page or Omnibox Search without using the Overrides API.
Common reasons for rejection
- Modifying the Chrome New Tab Page without using the Overrides API.
- Modifying the Omnibox Search without using the Overrides API.
How to fix
- Don't modify the Chrome New Tab Page (or do so via the Overrides API).
- Don't modify the Omnibox Search (or do so via the Overrides API).
Why it's rejected & how to fix
Manipulating store state, listings, or update distribution to evade reviews, evade enforcement actions, or keep users on previous violating versions.
Common reasons for rejection
- Manipulating store state or extension listings to evade reviews or enforcement actions.
- Manipulating update distribution to keep users on previous, violating versions.
How to fix
- Stop. Don't take any further actions to circumvent intended limitations or enforcement.
- Continued attempts will result in suspension of your developer account.
Amber — Quality / Metadata / Spam #
Why it's rejected & how to fix
The extension does not function as described in its listing. Common causes: missing files in the package, broken paths, server-side issues, or the item simply doesn't do what the description claims.
Common reasons for rejection
- Packaging errors: files referenced in the manifest are not present in the package, or the paths/names are wrong.
- Functionality is broken at review time due to a server-side issue.
- The item simply does not function as described in the listing.
How to fix
- Test the exact files you submit to the Web Store locally — pack the extension and test the .crx, not just the dev build.
- Verify every file referenced in manifest.json exists in the package with the correct path and name.
- Check for case-sensitivity bugs (e.g., Background.js vs background.js).
- Make sure the extension clearly communicates error conditions to the user.
- If the extension requires an account or special network environment, communicate that requirement.
- Test on unreliable connections; gracefully handle timeouts and HTTP 4xx/5xx errors.
- If the rejection reason is unclear, contact developer support.
Why it's rejected & how to fix
Users must understand what an item provides before installing. Missing icon, title, screenshots, or description — or a misleading title — will cause rejection.
Common reasons for rejection
- Missing icon, title, screenshots, or description.
- The title is not meaningful or is misleading.
- Screenshots or description don't adequately explain the functionality.
How to fix
- Provide a meaningful icon, title, screenshots, and description.
- Clearly explain the extension's functionality in the description and screenshots.
- List all major features so users know what they're installing.
Why it's rejected & how to fix
Excessive, irrelevant, or unnaturally repeated keywords in metadata (especially the description), brand/site lists without added value, regional location lists, or unattributed user testimonials.
Common reasons for rejection
- Excessive, irrelevant, or inappropriate keywords in metadata — most commonly the description.
- Lists of sites/brands/keywords without substantial added value.
- Lists of regional locations.
- Unnatural repetition of the same keyword more than 5 times.
- Unattributed or anonymous user testimonials in the product description.
How to fix
- Remove the violating keywords/content.
- Write a clear, well-formatted description that uses keywords in context.
Why it's rejected & how to fix
The only purpose of the extension is to launch another app, theme, webpage, or extension. Includes opening a website on action click and showing a promo page on install.
Common reasons for rejection
- The only functionality is launching another app, theme, webpage, or extension.
- Displaying a website in a new tab/popup when the action is clicked.
- Showing a promotional page for another product immediately upon installation.
How to fix
- Such extensions are not allowed — unpublish them and rebuild as something that provides standalone value.
Why it's rejected & how to fix
Multiple extensions providing duplicate experiences, manipulation of reviews / ratings / installs, disruptive notifications, or sending messages on behalf of the user without consent.
Common reasons for rejection
- Submitting multiple extensions (or affiliate-related submissions) that provide duplicate experiences/functionality.
- Manipulating reviews, ratings, or installs.
- Disruptive or harmful notifications to users.
- Sending messages on behalf of the user without consent.
How to fix
- Don't submit duplicate extensions.
- Don't try to manipulate user-generated content on your listing.
- Don't harm the browsing experience.
Why it's rejected & how to fix
Extension contains only a manifest, provides no discernible value, links to an external service for its claimed feature, uses click-bait metadata, or is one of many near-duplicate template extensions.
Common reasons for rejection
- The submitted extension contained only a manifest.
- The extension provides no discernible value or utility.
- A described feature is not provided directly by the extension and instead links to an external service.
- Click-baity content in metadata designed to attract installs.
- Click-baity template extensions varying only slightly (e.g., 'Word of the Day' vs 'Daily Inspirational Quotes' using the same template).
How to fix
- Ensure the extension has a defined functionality that provides real value.
- Ensure all claimed functionality is performed directly by the item, not by linking to an external source.
Purple — User data privacy #
Why it's rejected & how to fix
The extension requests permissions broader than what its functionality requires, or requests permissions it never uses.
Common reasons for rejection
- The extension requests a permission but never uses it.
- The extension requests a permission that is not required for its functionality.
- Commonly misunderstood permissions are requested when not strictly required (activeTab, tabs, cookies, storage).
How to fix
- Review the commonly misunderstood permissions documentation to verify which ones you actually need.
- Request only the narrowest permission required for the feature.
- Remove every unused entry from permissions, optional_permissions, and host_permissions.
- If the rejection message lacks detail, contact developer support.
- If you believe the permission is necessary, use the Appeal button with a detailed justification.
Why it's rejected & how to fix
Users must be aware of what data is collected and how it's collected, used, and shared. Common cause: no privacy policy, or the policy URL is broken / not in the designated dashboard field.
Common reasons for rejection
- Collecting user data with no privacy policy at all.
- Privacy policy not provided in the designated dashboard field — commonly placed in the description by mistake.
- Privacy policy URL doesn't work or is not accessible.
- The URL doesn't actually point to a privacy policy.
- The privacy policy doesn't address user-data collection, usage, handling, or sharing.
How to fix
- Add a valid, working, accessible privacy policy URL in the designated field on the Privacy tab.
- Verify the link appears in the 'Privacy Policy' box on the Privacy tab.
- Make sure the policy explicitly addresses data collection, usage, handling, and sharing.
- If problems persist, use the Appeal button with details about your privacy practices.
Why it's rejected & how to fix
Data collection and consent must be prominently disclosed. Data may only be collected in direct support of the extension's single purpose.
Common reasons for rejection
- The extension is not prominently disclosing how user data is being used.
- User consent is not obtained before data collection.
How to fix
- Prominently disclose what data is collected and how it will be handled — in the privacy policy and elsewhere.
- Only collect data after the user consents.
- Prominent disclosure of data collection in the Chrome Web Store listing is sufficient.
- Provide opt-out controls in the options page.
- Consider an 'offline mode' that stores user data locally only.
Why it's rejected & how to fix
User data must be transmitted securely. HTTP transmission, or encoding sensitive data in URL query strings even over HTTPS, is prohibited (query strings appear in server logs).
Common reasons for rejection
- The extension is not transmitting user data securely.
- Data is being transmitted to an unsecure (HTTP) domain.
How to fix
- Don't transmit user data over HTTP. Use secure (HTTPS) protocols.
- Don't encode data in request headers or query parameters, even over HTTPS — they often appear in server logs.
- Use Chrome DevTools or other network monitoring tools to inspect the actual requests your extension makes.
Why it's rejected & how to fix
Sensitive information must not be collected unnecessarily, and must never be publicly disclosed. Web Browsing Activity may only be collected in support of a user-facing feature.
Common reasons for rejection
- Collecting Web Browsing Activity when not needed for a user-facing feature.
- Publicly disclosing sensitive user information collected by the extension.
How to fix
- Don't collect Web Browsing Activity unless required for a user-facing feature.
- Ensure user information is never publicly disclosed.
Red — Deceptive / Single purpose / Obfuscation #
Why it's rejected & how to fix
The extension does not provide the functionality described, performs undisclosed actions, impersonates another entity, or copies another extension.
Common reasons for rejection
- The extension does not provide the functionality described in metadata.
- The extension provides different functionality than described.
- The extension performs actions not mentioned in the metadata.
- The extension impersonates another entity.
- The extension copies, or is copied from, another entity.
- The extension pretends to be authorized by another entity.
How to fix
- Ensure promised functionality works as intended.
- Clearly state functionality in the metadata.
- Do not perform actions not mentioned in the metadata.
- Do not pretend to be another entity or claim endorsement that doesn't exist.
- Do not copy another extension.
Why it's rejected & how to fix
Extensions must serve a single, narrowly defined purpose. Common violations: bundling unrelated features, exposing unrelated functionality through the action icon, modifying new-tab search without using the Search API, injecting ads alongside other features.
Common reasons for rejection
- The extension provides two or more unrelated purposes (e.g., image conversion plus bibliography generation).
- Unrelated functionality is exposed via the extension's action icon.
- A modified search experience on a new tab page does not respect the user's chosen search provider.
- Distinct features are bundled together that may not be combined: replacing any single override page; using override settings to replace the default search provider; injecting ads into web pages.
How to fix
- Narrow the functionality to a single, well-defined purpose and clearly describe it in metadata.
- If you inject ads, either stop injecting ads or remove all other functionality besides ad injection.
- Chrome does not support optional new tab pages — split into a separate extension if needed.
- Don't expose unrelated functionality through the extension's action icon.
- Use the chrome.search API so a new-tab-page search respects the user's chosen search provider.
Why it's rejected & how to fix
Unclear install disclosures, misleading CTAs/forms, hidden listing metadata, bundling other extensions/offers, or requiring unrelated user actions to access advertised functionality.
Common reasons for rejection
- Unclear or inconspicuous disclosures on marketing collateral preceding the listing.
- Misleading interactive elements (CTAs, forms) that imply an outcome other than installing an extension.
- Adjusting the listing window to withhold or hide extension metadata from the user.
- Bundling other extensions or offers within the same installation flow.
- Requiring unrelated user action to access the advertised functionality.
How to fix
- Publish a new extension that does not employ deceptive marketing or user-acquisition methods.
Why it's rejected & how to fix
Code that conceals functionality from review. Examples: base64-encoded code strings, character-encoded identifiers, or any technique designed to make the source unreadable. Minification (whitespace removal, identifier shortening, file collapsing) is allowed.
Common reasons for rejection
- Using obfuscated code in the extension package.
- Examples: Base 64 encoding (e.g., 'SSdtIGluIHVyIGJhc2U=').
- Examples: Character encoding (e.g., '\u{68}ack\x69ng...').
How to fix
- Publish a new extension without obfuscated code.
- Minification — whitespace removal, shortening identifier names, collapsing files — is allowed. Obfuscation is not.
Grey — Content policies #
Why it's rejected & how to fix
The extension promotes or facilitates anything illegal.
Common reasons for rejection
- The extension promotes or facilitates anything illegal.
How to fix
- If illegal activity is the primary functionality — unpublish.
- If unintended — remove the violating content/services and resubmit.
- Contact developer support for clarification on the verdict.
Why it's rejected & how to fix
Extensions that facilitate online gambling — including odds calculation for betting sites, links to gambling sites, or skill-games offering cash prizes — are prohibited.
Common reasons for rejection
- Providing online gambling within the extension.
- Facilitating online gambling on other sites (e.g., calculating odds for a betting site).
- Directing users to online gambling sites.
- Providing games of skill that offer prizes of cash or other value.
How to fix
- If gambling is the primary functionality — unpublish.
- If unintended — remove the violating content/services and resubmit.
Why it's rejected & how to fix
The extension contains, displays, or directs users to sexually explicit material.
Common reasons for rejection
- The extension contains sexually explicit material.
- The extension displays or provides sexually explicit material.
- The extension directs users to pornographic sites.
- The extension primarily enhances pornographic sites.
How to fix
- If pornography is the primary purpose — unpublish.
- If unintended — remove the violating content and resubmit.
- For integrations with adult-oriented sites, enable the 'Mature content' flag in the developer dashboard.
Why it's rejected & how to fix
The extension provides, links to, or amplifies hate-speech content.
Common reasons for rejection
- Providing or directing users to content considered hate speech.
How to fix
- If hate-speech distribution is a primary feature — unpublish.
- For user-generated content, implement content moderation.
- Remove functionality intended to draw negative attention to a person's group identity.
Why it's rejected & how to fix
Content is not suitable for all ages, but the extension is not flagged as 'Mature content'.
Common reasons for rejection
- Content is not suitable for all ages, but the extension is not flagged as 'Mature content'.
How to fix
- Either remove the content, or mark the extension 'Mature content' in the developer dashboard and resubmit.
Why it's rejected & how to fix
The extension contains, or directs users to, gratuitous violence, harassment, threats, or bullying.
Common reasons for rejection
- Content (or directing users to content) that includes gratuitous violence, harassment, threats, or bullying.
How to fix
- If violent/bullying content is a primary feature — unpublish.
- If unintended — remove the violating content and resubmit.
Why it's rejected & how to fix
Extensions that mine cryptocurrencies on user machines, or provide functionality to do so, are prohibited.
Common reasons for rejection
- The extension mines cryptocurrencies on user machines.
- The extension provides functionality to mine cryptocurrencies.
How to fix
- If mining is the primary functionality — unpublish.
- If unintended — remove the violating content/services and resubmit.
Why it's rejected & how to fix
Use of affiliate links / codes / cookies without clear disclosure in the description and UI, or without a related user action that a reasonable user would understand and consent to.
Common reasons for rejection
- Using affiliate marketing links/codes/cookies without disclosure in the description and UI.
- No related user action required before inclusion of affiliate codes/links/cookies.
- Examples: silently updating shopping cookies; appending or replacing affiliate codes in URLs without user knowledge; applying or replacing affiliate promo codes without user knowledge.
How to fix
- Update the description and UI to clearly inform users that affiliate programs are in use.
- Require a relevant user action before each inclusion of an affiliate code/link/cookie — one that a reasonable user would understand and consent to.
Verify installation #
After installing, confirm that your coding assistant can connect to the Chrome Web Store Policy MCP server and call its tools.
1. Verify agent behavior #
The most reliable way to verify the connection is to ask your agent a policy question that requires the MCP to answer accurately.
Test prompt:
Validate this manifest.json against Chrome Web Store policy and tell me which permissions will trigger reviewer pushback.
The response should:
-
Cite specific policy IDs (e.g.
overly-broad-host-permissions,sensitive-permissions-need-justification) with links back to developer.chrome.com. - Show that the MCP tool was called — most clients display a "Using tool: validate_manifest" or similar indicator.
- Return concrete remediation steps, not generic advice ("consider narrowing your permissions").
2. Verify the server is loaded #
If the agent gives a generic answer or doesn't seem to call any tool, use the discovery command for your environment to confirm the MCP is registered.
| Environment | MCP verification | Expected output |
|---|---|---|
| Claude Code |
Type /mcp in the terminal.
|
chrome-web-store-policy shown
as connected; the seven tools listed
under it.
|
| Cursor | Open Settings → Features → MCP. | Server status is Connected; tools enumerated in the panel. |
| Antigravity | Customizations → Connections sidebar. | Entry visible with green status indicator. |
| Gemini CLI |
Run gemini mcp list or
/mcp list in-session.
|
✓ chrome-web-store-policy: ... - Connected
|
| Copilot |
Type @policy /mcp in chat to
list active connectors.
|
Server listed under data connectors with available tools. |
| Codex CLI |
Type /mcp in the TUI, or
run codex mcp list.
|
chrome-web-store-policy shown
with status ready and the seven tools
enumerated underneath.
|
| Claude Desktop | Click the ⚙ icon in the prompt bar → MCP servers. | Server listed with green status; tools selectable. |
Manual installation #
If you'd rather not run npx add-mcp,
add the server to your client's MCP config file directly. Most
clients use the same JSON shape:
{
"mcpServers": {
"chrome-web-store-policy": {
"serverUrl": "https://chrome-web-store-policy-mcp.dev"
}
}
}
Place that block in:
-
Claude Code:
.mcp.jsonat the project root, or~/.claude/mcp_servers.jsonuser-wide. -
Claude Desktop:
~/Library/Application Support/Claude/claude_desktop_config.json(macOS) or%APPDATA%\Claude\claude_desktop_config.json(Windows). -
Cursor:
~/.cursor/mcp.json. -
Gemini CLI:
~/.gemini/settings.jsonor project-scoped.gemini/settings.json.
Codex CLI #
Codex CLI uses TOML. Append the following block to
~/.codex/config.toml (or
project-scoped .codex/config.toml in
a trusted project):
[mcp_servers.chrome-web-store-policy] url = "https://chrome-web-store-policy-mcp.dev"
Or use the CLI directly — this writes the same block for you:
codex mcp add chrome-web-store-policy --url https://chrome-web-store-policy-mcp.dev
Restart your client after editing the config file.
Troubleshooting #
If your agent provides only general policy advice or doesn't recognize the seven tools, check the following:
Agent didn't discover the MCP #
Most clients query MCP servers only at startup. After running
npx add-mcp or editing the config
manually, completely restart your IDE (Cursor, Antigravity, VS
Code) or exit and relaunch your terminal-based agent (Claude
Code, Gemini CLI). A reload-window command is usually not enough.
Tools list is stale #
If the server was updated after your client connected, force a reload so the client re-queries the tool list:
-
Gemini CLI:
/mcp reload -
Claude Code:
/mcp→ refresh the server entry - Cursor: toggle the server off and on
Corporate network blocks the endpoint #
If your network blocks
https://chrome-web-store-policy-mcp.dev,
run the server locally instead. Clone the source repository, run
npm install && npm run build,
and configure the MCP entry to point at the local
dist/index.js over stdio:
{
"mcpServers": {
"chrome-web-store-policy": {
"command": "node",
"args": ["/absolute/path/to/dist/index.js"]
}
}
}
Resources #
- Chrome Web Store Policy MCP source on GitHub
- Chrome Web Store program policies (developer.chrome.com)
- Model Context Protocol specification
- Rule set changelog — what's new in each policy database release
- Report a missed policy — help us cover more rejection reasons