Environment

Updating .wp-env.json and Local Environments for Core Abilities

⏱ 11 min

Removing the archived Composer package doesn’t help you if your local environment is still running a WordPress core version older than 6.9. This lesson updates .wp-env.json, the config file wp-env (WordPress’s official local environment tool, introduced back in Course 1) reads to decide which WordPress core version to spin up.

What you'll learn in this lesson
How .wp-env.json pins a core version
The core key, and the difference between a version pin and "always latest."
Pinning to 6.9 versus 7.0
Matching your environment to whichever core features your code actually uses.
Rebuilding after a config change
wp-env config changes don't apply until you destroy and restart.
Confirming the version that actually loaded
Because a stale Docker volume can silently keep an old core version around.
Prerequisites

A working wp-env install from Course 1’s environment setup lesson. Lesson 2’s Composer package removal, so you’re not fighting two problems at once.

Step 1: Find your current pin

Open .wp-env.json at your project root and look at the core key:

// File: .wp-env.json
{
	"core": null,
	"plugins": [ "." ],
	"config": {
		"WP_DEBUG": true
	}
}

A core value of null tells wp-env to use whatever WordPress version ships with the installed @wordpress/env package itself, which tracks recent stable releases but is not a version guarantee. If your code specifically needs 6.9 or 7.0 behavior, null isn’t precise enough to trust for migration testing, pin it explicitly instead.

Step 2: Pin to a specific WordPress release

wp-env accepts a direct WordPress.org release archive URL as the core value, which is the most reliable way to pin an exact version:

// File: .wp-env.json
{
	"core": "https://wordpress.org/wordpress-6.9.zip",
	"plugins": [ ".", "https://github.com/WordPress/mcp-adapter/releases/latest/download/mcp-adapter.zip" ],
	"config": {
		"WP_DEBUG": true
	},
	"phpVersion": "8.1"
}

Two things to notice here beyond the core key. First, the MCP Adapter plugin is listed explicitly under plugins, since, as covered in Lessons 1 and 2, it’s a separate install regardless of your core version, wp-env won’t add it for you. Second, phpVersion is worth pinning too if your production hosting runs a specific PHP version, so your local environment and production stay aligned.

If you’re testing against 7.0 to exercise the PHP AI Client instead, change only the core value:

// File: .wp-env.json
{
	"core": "https://wordpress.org/wordpress-7.0.zip"
}
Use a second config file to test both versions

wp-env supports a .wp-env.override.json file for local, uncommitted overrides, and you can also keep entirely separate config files (for example .wp-env.6-9.json and .wp-env.7-0.json) and point the CLI at whichever one you need with the --config flag wp-env start --config .wp-env.7-0.json. This is the cleanest way to run the version-matrix testing covered in Lesson 6 without editing one file back and forth.

Step 3: Rebuild the environment

Config file changes to .wp-env.json are read on start, not live-applied to a running environment, and a version change specifically requires tearing down the existing Docker volume, since that volume already has an older WordPress core installed inside it:

wp-env destroy
wp-env start

wp-env destroy removes the environment’s containers and volumes entirely, this is safe for a local dev environment but is exactly the kind of command you do not want to run against anything holding data you care about. If you have local content you need to keep, export it first with wp export before destroying.

Step 4: Confirm the version that actually loaded

Don’t assume the config change took, verify it:

wp-env run cli wp core version
What you should see
Matches your pinned core value
If you pinned 6.9, this should print 6.9.x, not an older or newer version.
Abilities API functions present on 6.9+
wp eval 'var_dump( function_exists( "wp_register_ability" ) );' should print bool(true).
PHP AI Client only present on 7.0+
wp eval 'var_dump( function_exists( "wp_ai_client_prompt" ) );' should print bool(false) on a 6.9 pin, bool(true) on 7.0.

Test it: full environment sanity check

wp-env run cli wp core version
wp-env run cli wp plugin list --status=active
wp-env run cli wp eval 'var_dump( function_exists( "wp_register_ability" ) );'

The plugin list should include mcp-adapter as active if you listed it in .wp-env.json’s plugins array and it’s not disabled. If it’s missing, wp-env will have silently skipped a plugin source it couldn’t resolve (a typo in the URL is the usual cause), check the startup log output for a download failure.

A stale Docker volume keeps the old core version

Editing .wp-env.json’s core value and running wp-env start without first running wp-env destroy is the single most common mistake here. wp-env start reuses an existing environment if one is already running, it does not re-provision WordPress core just because the config file changed underneath it. If wp core version still shows your old version after editing the config, you skipped the destroy step.

Recap

.wp-env.json’s core key controls exactly which WordPress core version your local environment runs, and pinning it to a specific WordPress.org release URL (rather than leaving it null) gives you a reliable target for migration testing. Remember that the MCP Adapter still needs its own entry in the plugins array on every version, core never provides it. Any change to core requires wp-env destroy followed by wp-env start before it takes effect, and wp core version is your ground truth for confirming it actually did.

Resources & further reading

← Dropping the Archived abilities-api Composer Package The meta.mcp.public Requirement: Why Your Tools Aren't Showing Up →