Visitar URL original
feat: discover the config file in predefined locations by Lightning00Blade · Pull Request #2876 · ChromeDevTools/chrome-devtools-mcp · GitHub
Skip to content

feat: discover the config file in predefined locations - #2876

Merged
Lightning00Blade merged 4 commits into
mainfrom
cd4a-config/3-config-discovery
Sep 30, 2026
Merged

Lightning00Blade merged 4 commits into
mainfrom
cd4a-config/3-config-discovery

Conversation

@Lightning00Blade

Copy link
Copy Markdown
Collaborator

The config file is searched for in the following locations, the first
existing file wins and files are not merged:

  1. --config
  2. ${CWD}/cd4a.config.json
  3. ${PLUGIN_DATA}/cd4a.config.json
  4. $XDG_CONFIG_HOME/cd4a/config.json on macOS and Linux,
    %LOCALAPPDATA%/Google/cd4a/config.json on Windows, with a fallback to
    ~/.config/cd4a/config.json.

Discovery is only enabled when a ConfigLocator is passed to ConfigParser,
which the entry points do. Setting CHROME_DEVTOOLS_MCP_NO_CONFIG_DISCOVERY
turns it off, the test runner sets it so tests never pick up a developer's
config file.


Stack created with GitHub Stacks CLI • Give Feedback 💬

@Lightning00Blade
Lightning00Blade force-pushed the cd4a-config/2-option-groups branch from 7da87b3 to c4b8dc3 Compare September 30, 2026 08:13
@Lightning00Blade
Lightning00Blade force-pushed the cd4a-config/3-config-discovery branch from 9c6f634 to d57b0d1 Compare September 30, 2026 08:13
@Lightning00Blade
Lightning00Blade force-pushed the cd4a-config/2-option-groups branch from c4b8dc3 to 628508c Compare September 30, 2026 08:23
@Lightning00Blade
Lightning00Blade force-pushed the cd4a-config/3-config-discovery branch from d57b0d1 to 72caad5 Compare September 30, 2026 08:23
@Lightning00Blade
Lightning00Blade force-pushed the cd4a-config/2-option-groups branch from 628508c to e44d630 Compare September 30, 2026 08:28
@Lightning00Blade
Lightning00Blade force-pushed the cd4a-config/3-config-discovery branch from 72caad5 to 058953c Compare September 30, 2026 08:28
@Lightning00Blade
Lightning00Blade removed this pull request from stack #2879 September 30, 2026 08:32
@Lightning00Blade
Lightning00Blade force-pushed the cd4a-config/2-option-groups branch from e44d630 to 60f0a06 Compare September 30, 2026 09:54
@Lightning00Blade
Lightning00Blade force-pushed the cd4a-config/3-config-discovery branch from 058953c to 7253d9b Compare September 30, 2026 09:54
Comment thread src/config/ConfigParser.ts Resolved
Base automatically changed from cd4a-config/2-option-groups to main September 30, 2026 11:15
Comment thread src/config/ConfigParser.ts Resolved
Comment thread src/config/ConfigLocator.ts Resolved
Comment thread tests/config/ConfigLocator.test.ts Resolved
@Lightning00Blade
Lightning00Blade force-pushed the cd4a-config/3-config-discovery branch from 7253d9b to 88700a0 Compare September 30, 2026 11:52
@Lightning00Blade
Lightning00Blade marked this pull request as ready for review September 30, 2026 11:52

@OrKoN OrKoN left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the following:

  1. In src/config/ConfigParser.ts (ConfigParser.parse), pass this.env when calling this.configLocator?.locate(this.env). Calling locate() without arguments causes it to fall back to process.env, ignoring any custom environment variables (such as CHROME_DEVTOOLS_MCP_NO_CONFIG_DISCOVERY or custom PLUGIN_DATA / XDG_CONFIG_HOME) passed into the ConfigParser constructor.

  2. In src/config/ConfigParser.ts, move configLocator?: ConfigLocator to the end of the ConfigParser constructor parameter list (or accept it via an options object) instead of the second position. Placing an optional parameter before argv and env breaks existing constructor call sites and causes unnecessary churn across dozens of unrelated test files and build scripts just to pass undefined.

@Lightning00Blade
Lightning00Blade added this pull request to the merge queue Sep 30, 2026
Merged via the queue into main with commit 02c0112 Sep 30, 2026
23 checks passed
@Lightning00Blade
Lightning00Blade deleted the cd4a-config/3-config-discovery branch September 30, 2026 13:11
OrKoN added a commit that referenced this pull request Oct 15, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.11.0](chrome-devtools-mcp-v1.10.1...chrome-devtools-mcp-v1.11.0)
(2026-10-15)


### 🎉 Features

* add --file-navigations flag to reject file: URL navigations
([#2853](#2853))
([54cae57](54cae57))
* Add analyze_heapsnapshot_contexts MCP tool
([#2791](#2791))
([190aeee](190aeee))
* add ignoreCache option to performance_start_trace
([#2931](#2931))
([3467d40](3467d40))
* add maxNameLength truncation option to compare_heapsnapshots
([#3098](#3098))
([1e1c53e](1e1c53e))
* Add pagination to compare_heapsnapshots
([#3140](#3140))
([daebfd1](daebfd1))
* **config:** add ConfigWatcher to watch config file changes
([#3139](#3139))
([9171f77](9171f77))
* discover the config file in predefined locations
([#2876](#2876))
([02c0112](02c0112))
* implement ffmpeg-free screencast tools enabled by default
([#3123](#3123))
([8953ea5](8953ea5))
* reduce StaticText noise in text snapshots
([#2895](#2895))
([4441325](4441325))
* report pages opened by input actions
([#2679](#2679))
([28fb230](28fb230))
* resolve config defaults after merging CLI and config file
([#2849](#2849))
([bdeb70d](bdeb70d))
* return failing audits and DOM nodes inline from lighthouse_audit
([#2930](#2930))
([241fba5](241fba5))
* skip more redundant data in text snapshots
([#2896](#2896))
([b2f522c](b2f522c))
* support debugging WebMCP tools in third-party developer tools
([#2900](#2900))
([0db519f](0db519f))
* support emulating additional CSS media features
([#2929](#2929))
([69524f0](69524f0))
* support evaluating scripts from local files
([#2606](#2606))
([9cf47a4](9cf47a4))
* Support truncation in get_heapsnapshot_details
([#3137](#3137))
([f827e06](f827e06))
* Truncate long names by default to 100 characters
([#2893](#2893))
([5ddb0a3](5ddb0a3))


### 🛠️ Fixes

* account for scroll offsets in downscaled screenshots
([#2685](#2685))
([830c693](830c693))
* allow --categoryExtensions when connecting to an existing browser
([#3041](#3041))
([d250bc5](d250bc5))
* allow stopping the CLI if command fails
([#3088](#3088))
([77e238e](77e238e)),
closes
[#2982](#2982)
* avoid runtime title fetches
([#2883](#2883))
([04195d1](04195d1))
* better config support for chrome-devtools CLI
([#2819](#2819))
([9624e64](9624e64))
* clamp async stack trace separator repeat count
([#3035](#3035))
([93e06ab](93e06ab)),
closes
[#3031](#3031)
* **cli:** pass positional values starting with `-` through to tools
([#3084](#3084))
([9de05ae](9de05ae)),
closes
[#2984](#2984)
* **collectors:** ignore transient target errors when subscribing to
service workers
([#2888](#2888))
([551dd6c](551dd6c))
* **daemon:** bound browser shutdown and avoid watchFile timeout on stop
([#2887](#2887))
([f3db5e7](f3db5e7))
* **daemon:** keep fallback socket in private runtime dir
([#2766](#2766))
([871a37e](871a37e))
* **daemon:** verify process identity before treating PID file as active
([#3109](#3109))
([b608bed](b608bed))
* do not close a healthy browser when a tool call outlasts 60s
([#3149](#3149))
([39c7db1](39c7db1))
* ensure aggregate IDs in heap snapshots are deterministic
([#2923](#2923))
([e918c47](e918c47))
* escape client-supplied values in McpContext logs and errors
([#2832](#2832))
([efb0d02](efb0d02)),
closes
[#2831](#2831)
* fail fast on tool calls stuck after a dead browser connection
([#2699](#2699))
([2a7ef50](2a7ef50))
* harden third-party tool result serialization
([#2892](#2892))
([4418a7b](4418a7b))
* honor explicit --allowUnrestrictedPaths=false in CLI mode
([#3040](#3040))
([61fc362](61fc362))
* include errors in slim responses
([#3085](#3085))
([ee38097](ee38097))
* **input:** reject multiple file paths on single-file input in
upload_file
([#2995](#2995))
([#3135](#3135))
([e650843](e650843))
* list fresh page titles
([#3103](#3103))
([e717082](e717082))
* **memory:** reject contradictory pagination options in
take_heapsnapshot
([#3002](#3002))
([#3131](#3131))
([508126c](508126c))
* **network:** enforce URL policy across redirects
([#2767](#2767))
([274cd4c](274cd4c))
* pass categoryExtensions to the target filter when connecting
([#3047](#3047))
([4e90238](4e90238))
* **performance:** report an error when performance_stop_trace is called
with no active trace
([#3001](#3001))
([#3126](#3126))
([e170384](e170384))
* preserve HeapSnapshotManager across browser reconnects
([#3025](#3025))
([64388c6](64388c6))
* propagate failed responseFilePath write error instead of reporting
body unavailable
([#2957](#2957))
([#3119](#3119))
([3cee3bd](3cee3bd))
* **pwa:** wait for initial navigation on launch and retry transient
install error
([#2889](#2889))
([63010cb](63010cb))
* record screencast at the page's device pixel size
([#3155](#3155))
([62e2aa4](62e2aa4))
* reject --blockedUrlPattern/--allowedUrlPattern hostname regexp groups
([#2796](#2796))
([ae0aaef](ae0aaef))
* reject JSON arrays as 3p and WebMCP tool params
([#2785](#2785))
([c14e616](c14e616))
* reject named groups in URL patterns
([#2857](#2857))
([5b2c6f9](5b2c6f9))
* reject non-positive --viewport dimensions
([#2781](#2781))
([0ef528a](0ef528a))
* reject non-positive resize_page dimensions
([#2784](#2784))
([6ab6d35](6ab6d35))
* reject unrestricted paths with an explicit workspace
([#2858](#2858))
([45c1c6c](45c1c6c))
* report unknown page id before last-page guard in close_page
([#3042](#3042))
([bdc7e24](bdc7e24))
* round lighthouse category scores and show unscored categories as n/a
([#2924](#2924))
([7007680](7007680)),
closes
[#2915](#2915)
[#2916](#2916)
* set empty filePath to undefined instead of empty string
([#2836](#2836))
([adfc1ff](adfc1ff)),
closes
[#2825](#2825)
* surface WebMCP tool exceptions in execute_webmcp_tool
([#3107](#3107))
([d80d22e](d80d22e)),
closes
[#2975](#2975)
* url pattern partial ipv4
([#2859](#2859))
([c87d190](c87d190))


### 📄 Documentation

* clarify Antigravity MCP setup for VS Code extension
([#2855](#2855))
([12e13ca](12e13ca))
* clarify scope of --no-javascript-evaluation
([#3100](#3100))
([0c67cd5](0c67cd5))
* correct link to configuration
([#3086](#3086))
([bbb1e36](bbb1e36))
* document trusted host environment in SECURITY.md
([#3125](#3125))
([1352207](1352207))
* fix inaccurate examples in skills and CLI docs
([#2922](#2922))
([ec372b0](ec372b0)),
closes
[#2906](#2906)
[#2907](#2907)
[#2908](#2908)
[#2910](#2910)
[#2912](#2912)
[#2913](#2913)
[#2918](#2918)
[#2919](#2919)
[#2920](#2920)
[#2921](#2921)
* fix some reported issues
([#3099](#3099))
([d5d2f08](d5d2f08))
* include serviceWorkerId parameter for evaluate_script
([#3015](#3015))
([#3129](#3129))
([0623434](0623434))
* mention heapsnapshot being cached between runs
([#3045](#3045))
([f08dbe1](f08dbe1)),
closes
[#2976](#2976)
* **skills:** remove invalid outputDir flag from lighthouse_audit calls
([#3013](#3013))
([#3130](#3130))
([7754226](7754226))
* update documentation and SKILL for get_css_styles tool
([#2824](#2824))
([3c12a91](3c12a91))


### ⚡ Performance

* **cli:** re-use MCPServer.from helpers for daemon
([#2804](#2804))
([89eb3d5](89eb3d5))
* Load heap snapshots in parallel in compare_heapsnapshots
([#3023](#3023))
([20c1391](20c1391))


### 🏗️ Refactor

* centralize config defaults and conflict checks
([#2753](#2753))
([a739ba8](a739ba8))
* create all tools and register per slim mode
([#2874](#2874))
([99847a7](99847a7))
* enable categories by default
([#2811](#2811))
([e33ee48](e33ee48))
* extract CLI examples and conflict list in mcp-options
([#2848](#2848))
([45000d9](45000d9))
* extract config parsing logic in a class
([#2861](#2861))
([e4168d0](e4168d0))
* extract worker logic into McpWorker
([#2800](#2800))
([77165c6](77165c6))
* group Puppeteer and tool options
([#2875](#2875))
([699c4d5](699c4d5))
* lazily initialize McpPage from Target and enumerate targets in
McpContext
([#2812](#2812))
([545cbe3](545cbe3))
* use default Error for toolSchema
([#2822](#2822))
([8b2768d](8b2768d))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: Alex Rudenko <OrKoN@users.noreply.github.com>
nattallius pushed a commit to divya0795/chrome-devtools-mcp that referenced this pull request Nov 13, 2026
…ls#3474)

Fixes ChromeDevTools#3038

Renames the root Agent Plugins manifest (`plugin.json`) from
`chrome-devtools` to `chrome-devtools-mcp`. That matches
`.claude-plugin/plugin.json`, `.github/plugin/plugin.json`, and the
plugin's entry in `claude-plugins-official`. The diff is one line.

## Problem

Codex installs this plugin from the `claude-plugins-official`
marketplace, where the entry is `chrome-devtools-mcp`, but it validates
the plugin against the root `plugin.json`, whose name was
`chrome-devtools`. The names don't match, so `codex plugin add
chrome-devtools-mcp@claude-plugins-official` fails. So does `codex
plugin marketplace upgrade` for the whole marketplace:

```
plugin.json name `chrome-devtools` does not match marketplace plugin name `chrome-devtools-mcp`
```

From the Codex source (`openai/codex` `main`, 2026-11-12):

- `find_plugin_manifest_path`
(`codex-rs/utils/plugins/src/plugin_namespace.rs`) returns the root
`plugin.json` whenever it declares a supported agent-plugins.org
`$schema`. It only falls back to vendor manifests when the root file is
missing or has no `$schema`.
- `install_with_version_and_manifest`
(`codex-rs/core-plugins/src/store.rs`) compares the resolved manifest
name with the marketplace entry name and rejects the plugin if they
differ.

## Alternatives considered

- **Add .codex-plugin/plugin.json.** Doesn't work. Codex reads it only
as an overlay (apps, hooks, onboarding_skill, interface), and the name
still comes from the root file.
- **Rename the marketplace entry and Claude manifest to
chrome-devtools.** Matches the long-term name from the issue. It needs a
coordinated change in claude-plugins-official and renames the plugin for
existing Claude Code installs. It can still be done later as a separate
PR.

## Impact on other harnesses

The rename only affects clients that read the root `plugin.json`. Claude
Code, Cursor, Kimi, and Gemini read their own manifests and don't
change.

| Client | Reads root `plugin.json`? | Effect of this PR |
|---|---|---|
| Codex (via `claude-plugins-official`) | Yes | Install and upgrade work
again. There are no existing installs to break, because this path
currently fails. |
| GitHub Copilot CLI, marketplace install
(`chrome-devtools-mcp@chrome-devtools-plugins`) | Uses the marketplace
entry name | No change. Verified on 1.0.109: it installs as
`chrome-devtools-mcp` both before and after this PR. |
| GitHub Copilot CLI, direct install (`copilot plugin install
ChromeDevTools/chrome-devtools-mcp`) | Yes | The name changes from
`chrome-devtools` to `chrome-devtools-mcp`, so marketplace and direct
installs now match. Verified on 1.0.109 that direct installs currently
report `chrome-devtools`. Copilot prints a warning that direct installs
are deprecated in favor of `plugin@marketplace`. |
| Other harnesses that read the root plugin.json | Expected to, per the
Agent Plugins spec. | The plugin name changes. Existing installs may
need a reinstall. |

### `$PLUGIN_DATA` config

Since v1.11.0 (ChromeDevTools#2876), the server loads `cd4a.config.json` from
`$PLUGIN_DATA` before falling back to the global config. Clients derive
`$PLUGIN_DATA` from the plugin name: Codex keys it by plugin and
marketplace name, and the spec's example is
`~/.agents/plugins/data/<name>`. If a user installed the plugin through
a client that reads the root manifest under the old name and placed
`cd4a.config.json` in that plugin data directory, the server won't find
the file after the rename. It falls back to the global config without an
error. The fix is to move the file into the new plugin data directory.
This affects few users, because it needs both a root-manifest install
and a hand-placed per-plugin config. The npx cache in that directory is
downloaded again, which is harmless.

Users who define the server directly in their own MCP config are not
affected, because the server key in `mcp.json` (`chrome-devtools`) is
unchanged, and a hand-written entry never reads the root `plugin.json`.

Clients that read the root manifest and build tool names or permission
scopes from the plugin name may see those identifiers change. Allowlist
entries for the old name would need updating.

## Verification

- The new name matches the `.claude-plugin/marketplace.json` entry and
the Agent Plugins name rules (lowercase, at most 64 characters, no
`--`).
- I verified the Copilot CLI behavior above on 1.0.109. I verified the
Codex behavior by reading the source, not by running Codex against this
branch.
- `npm run format` and `npm run test` handled by CI.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants