{"name":"io.github.extensiondev/mcp","slug":"extensiondev-mcp","title":null,"description":"Build, run, inspect, and publish browser extensions from any MCP client. 30 tools, 11 browsers.","url":"https://mcp.market/server/extensiondev-mcp","rating":null,"grade":"A","score":94,"certified":false,"status":"active","category":"scraping","tags":["scraping"],"presence":{"score":35,"stars":3,"forks":0,"downloads_week":143,"last_push_at":"2026-09-21T11:32:44.000Z","license":"Apache-2.0"},"uptime":null,"claimed":false,"transport":"npm","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/extensiondev/mcp","website":"https://extension.dev","version":"10.9.0","remotes":[],"packages":[{"registryType":"npm","registryBaseUrl":"https://registry.npmjs.org","identifier":"@extension.dev/mcp","version":"10.9.0","runtimeHint":"npx","transport":{"type":"stdio"}}],"tools":[{"name":"extension_add_feature","description":"Plan a new feature surface for an existing extension. This returns step-by-step instructions, the manifest additions to make, and reference templates from the extension.dev catalog. It modifies no files: apply the returned plan yourself.","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_analyze","description":"Analyze a BUILT extension on disk: file sizes, declared entry points, permissions, bundle composition, and store-readiness checks. This is static only: it reads dist/<browser> from the filesystem and never touches a browser, so build first with extension_build. Use extension_inspect for a running extension's live DOM and console.","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_auth","description":"Sign this machine in to extension.dev, report that login, or clear it. Pass action:'status' (the default) to name the workspace and project the stored token is scoped to and when it expires, never the token itself; that identity comes from the stored token alone, and does not change with the current working directory or whichever project folder you are in. Status also asks the platform's whoami en","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_browsers","description":"Find, install and remove the browsers Extension.js tooling can launch. Pass action:'detect' (the default) to scan both system-installed and managed browsers, and report each one's binary path, version, engine and debugger support. Pass action:'list' for the managed cache this tool downloads into, with sizes on disk. Pass action:'install' to download a managed binary: 580 to 625 MB in one blocking ","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_build","description":"Build a browser extension for production. The output lands in dist/<browser>/. Pass zip:true to also package a .zip for store submission. With browser:'safari' the build converts the extension into a macOS app through Xcode, and bundleId sets the identifier it ships under. The build refuses a manifest with build-blocking errors unless you pass skipValidation:true, because such a manifest yields a ","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_create","description":"Create a browser extension project from a template in the extension.dev catalog. Call extension_templates first to see what is available. The scaffolder may initialize a git repository in the new project. Read the result's defaultsApplied block for that, and for every other decision made without being asked.","write_action":true,"price_micros":0,"input_schema":null},{"name":"extension_dev","description":"Run the extension while you edit it: dev build, hot module replacement, and a browser with the extension loaded. Reach for this first when the ask is \"run my extension\". ONLY this tool unlocks the control channel that extension_storage, extension_reload, extension_open and extension_dom_snapshot need (allowControl:true) and the eval channel that extension_eval needs (allowEval:true, which implies ","write_action":true,"price_micros":0,"input_schema":null},{"name":"extension_doctor","description":"Diagnose a dev session end to end: ready contract, dev-server process, control-port agreement, control channel, eval token, executor, browser liveness. This returns one {check, status, detail, remediation?} per leg, in dependency order. Read a 'skip' as blocked, not as a pass: it names the check that blocked it. A session started without allowControl comes back ok:true with status 'read-only', not","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_dom_snapshot","description":"Take a shallow structured DOM snapshot of one chosen surface through the agent bridge (localhost only; the snapshot itself needs no CDP, but listTargets and `tabUrl` resolution ask the browser directly and need the session's debug port: CDP page targets on Chromium, RDP tab descriptors on Firefox): element counts, extension roots, open shadow roots, optional byte-capped HTML, and optional recent c","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_eval","description":"Evaluate an expression in a running extension context. Start the session with allowEval:true (extension_dev), which writes a 0600 session token. Context defaults to 'background', except on a Chromium MV3 session (the default template) where it defaults to 'page', the active tab, because the MV3 service worker CSP blocks eval; pass context:'background' to target the worker anyway and get that expla","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_inspect","description":"Inspect a running extension deeply over the browser's debugger protocol: full HTML including shadow DOM, DOM structure, content-script injection, console messages, and CSS selector queries through `probe`. This is the ONLY tool that pierces closed shadow roots (deepDom), runs selector probes, and navigates a tab to `url` before reading it. It reads a web or override page and picks the first inspec","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_list_extensions","description":"List the extensions in the running dev browser: id, name, version, and, on Chromium, live contexts. This session's own extension carries ownExtension:true, with name and version from the ready contract even when the browser exposes no identity. Chromium rides the Chrome DevTools Protocol, so an entry needs at least one live context, and a dormant MV3 service worker may be absent until it wakes. Fi","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_logs","description":"Read or stream logs from every context of a running dev session (service worker, content scripts, popup, options, sidebar, devtools, pages) in one ordered timeline. This reads the same agent-bridge plane as the `extension logs` CLI: a one-shot returns the most recent matching lines from logs.ndjson, and follow:true collects from the live control channel for a bounded window. This requires an activ","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_manifest_validate","description":"Validate a manifest.json across browsers. This reports missing fields, invalid permissions, dangling file references, and cross-browser compatibility issues. Read buildBlocking for the errors that make extension_build refuse.","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_open","description":"Open an extension surface, or replay an event, in a running session. Pass surface:'popup', 'options' or 'sidebar' to open a UI surface, or 'newtab', 'history' or 'bookmarks' to open the matching chrome_url_overrides page in a tab. Pass surface:'action' to trigger the toolbar action, which opens its popup or replays chrome.action.onClicked when there is none. Pass surface:'command' with `name` to r","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_preview_web","description":"Preview an in-progress extension in the web emulator, with no real browser. This builds the project (unless build:false) and previews dist/<browser>. Pass share:true unless you are working inside the extension.dev monorepo: it uploads the build and returns a link anyone can open, with no install, sign-in or dev server, and it is the only lane that works from an npm install of this server. Sharing ","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_project_create","description":"Create an extension.dev project for an extension that does not have one yet, without opening the console. Use it right after extension_create and extension_build, once the extension's source is pushed to a GitHub repository, and BEFORE extension_auth: extension_auth can only log in to a project that already exists, and this tool is what brings that project into existence. Ask for nothing but the p","write_action":true,"price_micros":0,"input_schema":null},{"name":"extension_publish","description":"Publish the project your stored token is scoped to (extension_auth, or EXTENSION_DEV_TOKEN) to extension.dev, and return its shareable URL. This is what \"deploy\" or \"ship\" an extension usually means; extension_submit is the separate store-review path. The target is the token's project: there is no projectPath, and no local file is uploaded. For a public project the URL is the canonical public page","write_action":true,"price_micros":0,"input_schema":null},{"name":"extension_release_promote","description":"Promote a built extension to a release channel (stable, preview, beta, …) on extension.dev, headless. This WRITES: it is the only verb that changes what a channel points at. It is auth-gated by your stored login (extension_auth) or a release token in EXTENSION_DEV_TOKEN, minted and revoked under project settings, Access tokens. Tokens live at most 7 days, so CI must re-mint before expiry. The proj","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_release_status","description":"Read where a project stands on extension.dev, from the public registry (registry.extension.land). This is read-only: it dispatches nothing and promotes nothing. Pass include:'releases' for the release channels (channel to promoted build sha), recent builds, and a public build-page URL for each, which is how you find a valid sha for extension_release_promote, extension_submit or extension_publish. ","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_reload","description":"Reload a running extension's background context, or a tab. Start the session with allowControl:true (extension_dev).","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_shares","description":"List and revoke the public preview links this token has shared, which is what extension_preview_web share:true hands out. Pass action:'list' (the default) for every artifact the logged-in project owns, with its artifactId, name, version, live or dead state, createdAt, expiresAt, revokedAt, size, previewUrl, zipUrl and revokeUrl, so a link whose response you lost is findable again. Each row carries","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_start","description":"Run the PRODUCTION build in a browser: build the project, serve it, and launch. There is no hot module replacement and no control channel, so your edits are not picked up and extension_eval, extension_storage, extension_reload, extension_open and extension_dom_snapshot cannot attach to this session. Use extension_dev while writing code, and this to check what actually ships. Pass build:false to la","write_action":true,"price_micros":0,"input_schema":null},{"name":"extension_stop","description":"Stop a session that extension_dev or extension_start is running: terminate the server and the browser it launched, and remove the live-preview carrier if extension_dev placed one. This covers extension_start build:false too, which the registry records as a preview session. Call it when you are done verifying, so sessions do not accumulate.","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_storage","description":"Read or write chrome.storage in a running extension. Start the session with allowControl:true (extension_dev). Set one key per call: there is no bulk-object set.","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_submit","description":"Submit a built extension for store REVIEW through extension.dev, which holds your store credentials and dispatches from your project's mirror CI: the Chrome Web Store, Firefox AMO, Edge Add-ons and the App Store (Safari). This is store review only. It does not push a build to the extension.dev platform, and it does not make a shareable link: that is extension_publish, which is what \"deploy\" or \"sh","write_action":true,"price_micros":0,"input_schema":null},{"name":"extension_templates","description":"Browse the extension.dev template catalog. Pass action:'list' (the default) to search and filter it and get metadata per template. Pass action:'source' with a `slug` to read one template's files, for learning a pattern before building something similar. Read `framework` as the UI framework only, never the language: TypeScript and JavaScript templates live under slugs ('typescript', 'content-typesc","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_theme_verify","description":"Verify a Chrome theme manifest before it ships. This settles the four-leg WYSIWYG contract (app-shows == manifest-says == chrome-paints, plus chrome-accepts) as far as is possible headless: it derives every color current Chrome would paint from the manifest through the transcribed Chromium resolver, and classifies each problem as D1 fabrication, D3 parity gap, or D4 acceptance gap (keys Chrome sil","write_action":false,"price_micros":0,"input_schema":null},{"name":"extension_wait","description":"Wait for a running dev or start session to be ready. This polls the ready.json contract and reports compiled (the compiler finished), browserAttached (the runtime executor connected), and guestLoaded (the browser's own target list shows your extension). Read guestLoaded as the trustworthy load signal: it catches a silently rejected --load-extension that leaves ready.json stamped attached with empt","write_action":false,"price_micros":0,"input_schema":null}],"scan":{"score":94,"grade":"A","scanned_at":"2026-09-21T22:10:13.616Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-21T22:10:13.585Z","components":{"code":{"score":25,"max":25,"notes":["109 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":12,"max":15,"notes":["local package, no credentials required"]},"maintenance":{"score":15,"max":15,"notes":["last push 0 days ago"]},"identity":{"score":9,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[],"inputs":{"packages":[{"registryType":"npm","identifier":"@extension.dev/mcp","version":"10.9.0","found":true,"license":"Apache-2.0","hasInstallScripts":false,"dependencyCount":8,"publishedAt":"2026-08-21T18:56:27.664Z","repositoryUrl":"git+https://github.com/extensiondev/mcp.git","weeklyDownloads":143}],"repo":{"found":true,"owner":"extensiondev","repo":"mcp","archived":false,"pushedAt":"2026-09-21T11:32:44Z","stars":3,"forks":0,"openIssues":2,"ownerType":"Organization","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/106714027?v=4","ownerCreatedAt":"2022-06-02T00:30:04Z","license":"Apache-2.0"},"icon":{"url":"https://avatars.githubusercontent.com/u/106714027?v=4&s=128","source":"github"},"presence":{"stars":3,"forks":0,"downloadsWeek":143,"license":"Apache-2.0","lastPushAt":"2026-09-21T11:32:44.000Z","score":35}}}},"grade_history":[],"reviews":[]}