You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: show_build_settings and list_schemes ignore derivedDataPath (BUILD_DIR mismatch, extra package checkout) #547
Disclosure: This issue was generated by Claude Code, operating fully autonomously in the research and drafting of this issue. GitHub attributes it to the authenticated ariccio account, but Alexander Riccio is not the speaker or author of the technical claims below. His role is to provide the quoted prompts, choose the publication scope, and explicitly approve the exact text after preview.
Bug Description
show_build_settings and list_schemes run xcodebuild without the DerivedData location that the build tools use. The build tools, the test tools' build step and the app-path lookups always pass -derivedDataPath (an explicit derivedDataPath, else a per-project folder under the server's own workspace tree). Both discovery tools pass the project or workspace path; show_build_settings also passes the scheme. Neither accepts derivedDataPath or extraArgs, so session defaults for those fields are filtered out. Reproduced on 2.7.1 with this repository's own example projects:
In the calculator example, show_build_settings reports a BUILD_DIR the server's builds do not use. In example_projects/iOS_Calculator, whose config sets derivedDataPath: ./.build/DerivedData, get_sim_app_path resolves the app path under .build/DerivedData/Build/Products/ (no build is needed; it reads build settings with -derivedDataPath), while show_build_settings returns BUILD_DIR under Xcode's own DerivedData for the workspace. An agent that takes product paths from show_build_settings looks in the wrong folder.
With fresh DerivedData, the first call can create another package checkout. In example_projects/spm, whose config enables project-discovery, a first list_schemes checked out the fixture's one remote dependency, swift-argument-parser, into Xcode's DerivedData for the workspace instead of the derivedDataPath set for the run: 9.4 MiB on this fixture. In a private app with many Swift packages on 2.7.0, the same step left 1.9 GB (7,736 files) of SourcePackages in a fresh DerivedData folder.
Both tools are annotated readOnlyHint: true and openWorldHint: false. #341 (9600359d) already gave the app-path lookups the builds' DerivedData "so follow-up commands inspect the same build location"; these two tools were not part of it. Suggested changes for each tool, supported by command-line experiments, are in fold 3: xcodebuild -list rejects -derivedDataPath but honours -clonedSourcePackagesDirPath.
Debug Output
Doctor output (2.7.1, CLI, redacted mode; process tree, local paths and PATH replaced before posting)
⚙️ MobileBuildMCP Doctor
Generated: 2026-10-05T19:42:18.596Z
Server Version: 2.7.1
Output Mode: Redacted (default)
System Information
platform: darwin
release: 25.4.0
arch: arm64
cpus: 8 x Apple M2
memory: 24 GB
hostname: <redacted>
username: <redacted>
homedir: (replaced before posting: local path or process detail)
tmpdir: (replaced before posting: local path or process detail)
Node.js Information
version: v24.10.0
execPath: (replaced before posting: local path or process detail)
pid: 60200
ppid: 60194
platform: darwin
arch: arm64
cwd: (replaced before posting: local path or process detail)
argv: (replaced before posting: local path or process detail)
Process Tree
(replaced before posting: local path or process detail)
Xcode Information
version: Xcode 26.6 - Build version 17F113
path: /Applications/Xcode.app/Contents/Developer
selectedXcode: /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
xcrunVersion: xcrun version 72.
Dependencies
axe: 1.8.0
mise: Not found
Environment Variables
INCREMENTAL_BUILDS_ENABLED: (not set)
DEVELOPER_DIR: (not set)
HOME: (replaced before posting: local path or process detail)
USER: <redacted>
TMPDIR: (replaced before posting: local path or process detail)
NODE_ENV: (not set)
SENTRY_DISABLED: (not set)
AXE_PATH: (not set)
MOBILEBUILDMCP_LAUNCH_JSON_WAIT_MS: (not set)
MOBILEBUILDMCP_DEBUGGER_BACKEND: (not set)
MOBILEBUILDMCP_UI_DEBUGGER_GUARD_MODE: (not set)
MOBILEBUILDMCP_SENTRY_DISABLED: true
MOBILEBUILDMCP_RUNTIME: cli
MOBILEBUILDMCP_SILENCE_LOGS: true
PATH
(replaced before posting: local path or process detail)
UI Automation (axe)
Available: Yes
UI Automation Supported: Yes
Simulator Video Capture Supported (AXe >= 1.1.0): Yes
UI-Debugger Guard Mode: error
Incremental Builds
Enabled: No
xcodemake Binary Available: No
Makefile exists (cwd): (not checked: incremental builds disabled)
Mise Integration
Running under mise: No
Mise available: No
Debugger Backend (DAP)
lldb-dap available: Yes
Selected backend: dap
Manifest Tool Inventory
Total Unique Tools: 82
Workflow Count: 15
coverage: 2 tools
debugging: 8 tools
device: 15 tools
doctor: 1 tools
macos: 13 tools
project-discovery: 5 tools
project-scaffolding: 2 tools
session-management: 5 tools
simulator-management: 10 tools
simulator: 20 tools
swift-package: 8 tools
ui-automation: 14 tools
utilities: 1 tools
workflow-discovery: 1 tools
xcode-ide: 5 tools
Runtime Tool Registration
Enabled Workflows: 0
Registered Tools: 0
Note: Runtime registry unavailable.
Xcode IDE Bridge (mcpbridge)
Workflow enabled: No
mcpbridge path: /Applications/Xcode.app/Contents/Developer/usr/bin/mcpbridge
Xcode running: (unknown)
Connected: No
Bridge PID: (none)
Proxied tools: 0
Last error: (none)
Note: Bridge debug tools (status/sync/disconnect) are only registered when debug: true
Tool Availability Summary
Build Tools: Available
UI Automation Tools: Available
Incremental Build Support: Not available
Sentry
Sentry enabled: Yes
Troubleshooting Tips
If UI automation tools are not available, install axe: brew tap cameroncooke/axe && brew install axe
If incremental build support is not available, install xcodemake (https://github.com/cameroncooke/xcodemake) and ensure it is executable and available in your PATH
To enable xcodemake, set environment variable: export INCREMENTAL_BUILDS_ENABLED=1
For mise integration, follow instructions in the README.md file
✅ Doctor diagnostics complete
The doctor ran with MOBILEBUILDMCP_SENTRY_DISABLED=true. Its "Sentry enabled: Yes" line reads only SENTRY_DISABLED (doctor.ts#L713), while the runtime gate also reads MOBILEBUILDMCP_SENTRY_DISABLED (sentry.ts#L155-L159).
Editor/Client
MobileBuildMCP CLI 2.7.1 for the reproduction below; first seen through Claude Code (MCP over stdio) on 2.7.0.
MCP Server Version
2.7.1 (main is identical to v2.7.1 on 2026-10-05); first seen on 2.7.0.
LLM
No LLM in the 2.7.1 CLI reproduction; the earlier MCP observation was through Claude Code.
MCP Configuration
None beyond each example project's own .mobilebuildmcp/config.yaml, unmodified, plus MOBILEBUILDMCP_SENTRY_DISABLED=true. Step 3 (run B1 in fold 1) also sets MOBILEBUILDMCP_DERIVED_DATA_PATH, because the spm example's config sets no derivedDataPath.
Steps to Reproduce
In example_projects/iOS_Calculator, run mobilebuildmcp simulator get-app-path --platform 'iOS Simulator' --simulator-name '<an installed simulator>' (or node build/cli.js … from a checkout).
In the same folder, run mobilebuildmcp project-discovery show-build-settings --output json and compare its BUILD_DIR with step 1's appPath.
In a fresh copy of example_projects/spm, create the package workspace its config names (workspacePath: .swiftpm/xcode/package.xcworkspace; the example's .gitignore excludes its contents.xcworkspacedata): a contents.xcworkspacedata holding one <FileRef location = "self:">. Do not open the package in Xcode first, since that can resolve its packages. Then, with no DerivedData yet for that workspace, run MOBILEBUILDMCP_DERIVED_DATA_PATH=<lab>/mcp-dd mobilebuildmcp project-discovery list-schemes; the variable supplies the derivedDataPath that the example's config does not set.
Look for SourcePackages/checkouts/swift-argument-parser in Xcode's DerivedData for that workspace, and under <lab>/mcp-dd.
The runs below also gave each copy a per-user Xcode workspace setting (WorkspaceSettings.xcsettings with DerivedDataLocationStyle = WorkspaceRelativePath and DerivedDataCustomLocation = DerivedData), so Xcode's DerivedData stayed inside the copy. That is Xcode configuration, not MobileBuildMCP configuration; without it, Xcode uses its default DerivedData location.
Expected Behavior
BUILD_DIR points under the .build/DerivedData that get_sim_app_path uses. list_schemes and show_build_settings use the builds' package checkout, creating it there if it is missing, instead of a second one elsewhere.
Step 2: BUILD_DIR = <copy>/DerivedData/CalculatorApp/Build/Products, Xcode's DerivedData location for CalculatorApp.xcworkspace. The default would be ~/Library/Developer/Xcode/DerivedData/CalculatorApp-<hash>/; here a per-user workspace-relative setting kept it inside the copy.
Step 3: 4 schemes listed in 7 s, and a new SourcePackages folder (9.4 MiB, 307 files) appeared in Xcode's DerivedData location for the workspace. Nothing appeared under <lab>/mcp-dd, the derivedDataPath set for the run.
For step 3's package workspace, xcodebuild prints no build settings, so show_build_settings returns only xcodebuild's preamble, which names the invocation: xcodebuild -showBuildSettings -workspace <copy>/.swiftpm/xcode/package.xcworkspace -scheme spm-Package, followed by Resolve Package Graph.
Each run used a fresh copy of the example project unless it says otherwise. A per-user WorkspaceSettings.xcsettings (DerivedDataLocationStyle = WorkspaceRelativePath) kept Xcode's DerivedData inside each copy, so nothing was written to ~/Library/Developer/Xcode/DerivedData. Sizes in runs A to C are du -k totals of allocated space in this lab. Row D quotes the earlier clone-aware census of a private project, with the scope of each total.
Run
Command
Result
A1
get-app-path, iOS_Calculator, its config (derivedDataPath: ./.build/DerivedData)
appPath under <copy>/.build/DerivedData/Build/Products/
A2
show-build-settings --output json, same copy and config
exit 0; Fetching from https://github.com/apple/swift-argument-parser.git (cached), Checking out 1.5.1: a full checkout was still created
C4
xcodebuild -showBuildSettings -workspace … -scheme spm-Package -derivedDataPath <dd>, run twice
first run: checkout in <dd>/SourcePackages; the shared SwiftPM cache's FETCH_HEAD timestamp advanced during the run and named the GitHub remote (network transfer was not directly observed); second run: 2 s, no fetch or checkout messages logged, +4 KiB
C5
xcodebuild -list -workspace … -clonedSourcePackagesDirPath <dd>/SourcePackages, after C4
2 s, no fetch or checkout messages logged, no growth
D
2.7.0 through the MCP server, 2026-10-02, a private app with many Swift packages
list_schemes: 11 s, 1,909,944,320 bytes (7,736 files) of SourcePackages in the workspace's DerivedData; show_build_settings returned a BUILD_DIR there, while the builds used -derivedDataPath <checkout>/<App-dir>/DerivedData. The same -showBuildSettings argv run by hand in a checkout with no per-user DerivedData setting created a new ~/Library/Developer/Xcode/DerivedData/<App>-<hash>/ folder of 1,910,665,216 bytes in total, SourcePackages included (no separate SourcePackages total was taken), even with -disableAutomaticPackageResolution.
If the project is also open in Xcode.app, Xcode's DerivedData for the workspace is Xcode.app's own folder, so the extra checkout is shared with Xcode.app (the sharing #525 asks for, there for the build tools). The BUILD_DIR mismatch and the extra checkout relative to the server's builds remain unless the server's builds are pointed at that same folder, as #525's workaround does by rewriting each build and test call's derivedDataPath.
2. Where the argv is built (v2.7.1)
show_build_settings: show_build_settings.ts#L123-L133 builds ['xcodebuild', '-showBuildSettings'], then -project or -workspace, then -scheme, and nothing else. Its schema has projectPath, workspacePath and scheme only (#L18-L21).
list_schemes: list_schemes.ts#L48-L56 builds ['xcodebuild', '-list'], then -project or -workspace. Its schema has projectPath and workspacePath only (#L18-L21).
Session defaults are filtered to the tool's schema keys (typed-tool-factory.ts#L118-L136, applied at #L251), so the derivedDataPath and extraArgs defaults never reach these two tools.
The Xcode-state watcher's bundle-id lookup runs xcodebuild -showBuildSettings -scheme <s> -skipPackageUpdates without -derivedDataPath (xcode-state-watcher.ts#L53); run C3 shows -skipPackageUpdates does not prevent a first checkout.
Between v2.7.0 and v2.7.1 each of the two tool files changes one line, the structured-output schema id.
3. Suggested changes, supported by command-line experiments
Runs C1 to C5 were plain xcodebuild commands, not a modified MobileBuildMCP.
show_build_settings: resolve resolveEffectiveDerivedDataPath({ derivedDataPath, workspacePath, projectPath }) and push -derivedDataPath, as app-path-resolver.ts does. Run C4 (xcodebuild -showBuildSettings … -derivedDataPath <dd>, run twice): the checkout lands in <dd>/SourcePackages, and the second query reuses it. Reuse after an actual build is expected, since the build uses the same path, but was not measured here.
list_schemes: -list rejects -derivedDataPath without a scheme (run C1), but honours -clonedSourcePackagesDirPath (run C2). Passing -clonedSourcePackagesDirPath <effective DerivedData>/SourcePackages reused the checkout that C4's query had made (run C5); reuse of a build's checkout is likewise expected, not measured.
Required for 1 and 2 to honour configuration: add an optional derivedDataPath field to each tool's internal schema and forward it to the resolver. Session defaults are filtered to the internal schema's keys (typed-tool-factory.ts#L118-L136, #L251), and resolveEffectiveDerivedDataPath uses only the value passed to it (derived-data-path.ts#L33-L47). Without the field, 1 and 2 would fall back to the per-project default and still miss a configured path such as the calculator example's ./.build/DerivedData. Per-call overrides are a separate, public-schema choice: the build tools leave derivedDataPath out of their session-aware public schema and include it in the legacy schema used when disableSessionDefaults is set (build_sim.ts#L190-L200, #L297-L300, typed-tool-factory.ts#L154-L159).
The MCP specification (2026-07-28 schema, unchanged from 2025-06-18 here) defines readOnlyHint as "If true, the tool does not modify its environment", destructiveHint: false as "the tool performs only additive updates", and openWorldHint as "If true, this tool may interact with an "open world" of external entities."
A first list_schemes call wrote a package checkout (B1). Separately, a plain xcodebuild query (C4) logged a cached fetch of the package URL and advanced the shared cache's FETCH_HEAD; remote network exchange was not observed. The write matches readOnlyHint: false and destructiveHint: false; whether openWorldHint should also be true is a question about what a first call does with an uncached dependency, which may reach the network (not observed here). After the changes in fold 3, a first call on a checkout that has never been built would still resolve packages and write a checkout, only into the builds' folder. Whether the hints should change then is your call. fix(mcp): make tool approval annotations explicit #297 notes that "Codex now treats missing MCP approval hints as risky defaults", so clients do act on them.
5. Why this looks like an oversight rather than a design choice
feat(session): auto-scope DerivedData per workspace/project path #341 ("auto-scope DerivedData per workspace/project path"; 108 changed files, and its commit 9600359d, "fix(build): Scope DerivedData by invocation context", touches 109) propagated derivedDataPath "through app-path lookups and generated next steps so follow-up commands inspect the same build location". It changed app-path-resolver.ts, build-utils.ts and derived-data-path.ts; neither discovery tool appears in its file list or in any of its eight commits.
The session-default field is described as the "Default DerivedData path for Xcode build/test/clean tools." (session-defaults-schema.ts#L54-L56); no comment, changelog entry or doc page says the discovery tools should skip it.
None of the 21 commits in git log --follow of show_build_settings.ts mentions DerivedData or package resolution.
6. Related issues (no obvious duplicate found in a scan of 210 issue titles on 2026-10-05)
#525 (build tools reusing Xcode.app's DerivedData), #526 (orphaned workspaces never swept), #524 (test-product retention), #340 (closed by #341), #173 (derivedDataPath as a session default).
7. Prompt and publication control
The account owner's instruction for this draft, verbatim: "Draft it and hold it for my review." Publication requires the account owner's explicit approval of the exact final text after preview. The 2.7.0 measurements come from a private project; its paths and names are replaced with placeholders. The 2.7.1 runs used copies of this repository's example projects.
Disclosure: This issue was generated by Claude Code, operating fully autonomously in the research and drafting of this issue. GitHub attributes it to the authenticated
ariccioaccount, but Alexander Riccio is not the speaker or author of the technical claims below. His role is to provide the quoted prompts, choose the publication scope, and explicitly approve the exact text after preview.Bug Description
show_build_settingsandlist_schemesrunxcodebuildwithout the DerivedData location that the build tools use. The build tools, the test tools' build step and the app-path lookups always pass-derivedDataPath(an explicitderivedDataPath, else a per-project folder under the server's own workspace tree). Both discovery tools pass the project or workspace path;show_build_settingsalso passes the scheme. Neither acceptsderivedDataPathorextraArgs, so session defaults for those fields are filtered out. Reproduced on 2.7.1 with this repository's own example projects:show_build_settingsreports aBUILD_DIRthe server's builds do not use. Inexample_projects/iOS_Calculator, whose config setsderivedDataPath: ./.build/DerivedData,get_sim_app_pathresolves the app path under.build/DerivedData/Build/Products/(no build is needed; it reads build settings with-derivedDataPath), whileshow_build_settingsreturnsBUILD_DIRunder Xcode's own DerivedData for the workspace. An agent that takes product paths fromshow_build_settingslooks in the wrong folder.example_projects/spm, whose config enablesproject-discovery, a firstlist_schemeschecked out the fixture's one remote dependency,swift-argument-parser, into Xcode's DerivedData for the workspace instead of thederivedDataPathset for the run: 9.4 MiB on this fixture. In a private app with many Swift packages on 2.7.0, the same step left 1.9 GB (7,736 files) ofSourcePackagesin a fresh DerivedData folder.Both tools are annotated
readOnlyHint: trueandopenWorldHint: false. #341 (9600359d) already gave the app-path lookups the builds' DerivedData "so follow-up commands inspect the same build location"; these two tools were not part of it. Suggested changes for each tool, supported by command-line experiments, are in fold 3:xcodebuild -listrejects-derivedDataPathbut honours-clonedSourcePackagesDirPath.Debug Output
Doctor output (2.7.1, CLI, redacted mode; process tree, local paths and PATH replaced before posting)
The doctor ran with
MOBILEBUILDMCP_SENTRY_DISABLED=true. Its "Sentry enabled: Yes" line reads onlySENTRY_DISABLED(doctor.ts#L713), while the runtime gate also readsMOBILEBUILDMCP_SENTRY_DISABLED(sentry.ts#L155-L159).Editor/Client
MobileBuildMCP CLI 2.7.1 for the reproduction below; first seen through Claude Code (MCP over stdio) on 2.7.0.
MCP Server Version
2.7.1 (
mainis identical tov2.7.1on 2026-10-05); first seen on 2.7.0.LLM
No LLM in the 2.7.1 CLI reproduction; the earlier MCP observation was through Claude Code.
MCP Configuration
None beyond each example project's own
.mobilebuildmcp/config.yaml, unmodified, plusMOBILEBUILDMCP_SENTRY_DISABLED=true. Step 3 (run B1 in fold 1) also setsMOBILEBUILDMCP_DERIVED_DATA_PATH, because the spm example's config sets noderivedDataPath.Steps to Reproduce
example_projects/iOS_Calculator, runmobilebuildmcp simulator get-app-path --platform 'iOS Simulator' --simulator-name '<an installed simulator>'(ornode build/cli.js …from a checkout).mobilebuildmcp project-discovery show-build-settings --output jsonand compare itsBUILD_DIRwith step 1'sappPath.example_projects/spm, create the package workspace its config names (workspacePath: .swiftpm/xcode/package.xcworkspace; the example's.gitignoreexcludes itscontents.xcworkspacedata): acontents.xcworkspacedataholding one<FileRef location = "self:">. Do not open the package in Xcode first, since that can resolve its packages. Then, with no DerivedData yet for that workspace, runMOBILEBUILDMCP_DERIVED_DATA_PATH=<lab>/mcp-dd mobilebuildmcp project-discovery list-schemes; the variable supplies thederivedDataPaththat the example's config does not set.SourcePackages/checkouts/swift-argument-parserin Xcode's DerivedData for that workspace, and under<lab>/mcp-dd.The runs below also gave each copy a per-user Xcode workspace setting (
WorkspaceSettings.xcsettingswithDerivedDataLocationStyle = WorkspaceRelativePathandDerivedDataCustomLocation = DerivedData), so Xcode's DerivedData stayed inside the copy. That is Xcode configuration, not MobileBuildMCP configuration; without it, Xcode uses its default DerivedData location.Expected Behavior
BUILD_DIRpoints under the.build/DerivedDatathatget_sim_app_pathuses.list_schemesandshow_build_settingsuse the builds' package checkout, creating it there if it is missing, instead of a second one elsewhere.Actual Behavior
appPath=<copy>/.build/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app.BUILD_DIR=<copy>/DerivedData/CalculatorApp/Build/Products, Xcode's DerivedData location forCalculatorApp.xcworkspace. The default would be~/Library/Developer/Xcode/DerivedData/CalculatorApp-<hash>/; here a per-user workspace-relative setting kept it inside the copy.SourcePackagesfolder (9.4 MiB, 307 files) appeared in Xcode's DerivedData location for the workspace. Nothing appeared under<lab>/mcp-dd, thederivedDataPathset for the run.show_build_settingsreturns only xcodebuild's preamble, which names the invocation:xcodebuild -showBuildSettings -workspace <copy>/.swiftpm/xcode/package.xcworkspace -scheme spm-Package, followed byResolve Package Graph.Error Messages
None; every command above exits 0.
1. Measurements (2.7.1 CLI, Xcode 26.6 (17F113), macOS 26.4)
Each run used a fresh copy of the example project unless it says otherwise. A per-user
WorkspaceSettings.xcsettings(DerivedDataLocationStyle = WorkspaceRelativePath) kept Xcode's DerivedData inside each copy, so nothing was written to~/Library/Developer/Xcode/DerivedData. Sizes in runs A to C aredu -ktotals of allocated space in this lab. Row D quotes the earlier clone-aware census of a private project, with the scope of each total.get-app-path, iOS_Calculator, its config (derivedDataPath: ./.build/DerivedData)appPathunder<copy>/.build/DerivedData/Build/Products/show-build-settings --output json, same copy and configBUILD_DIR = <copy>/DerivedData/CalculatorApp/Build/Productslist-schemes, spm,MOBILEBUILDMCP_DERIVED_DATA_PATH=<lab>/mcp-dd<copy>/DerivedData/spm/SourcePackagescreated, 9,668 KiB, 307 files;<lab>/mcp-ddnever createdshow-build-settings, same copy-showBuildSettings -workspace … -scheme spm-Package, no-derivedDataPathxcodebuild -list -workspace … -derivedDataPath <dd>xcodebuild: error: The flag -scheme, -testProductsPath, or -xctestrun is required when specifying -derivedDataPath.xcodebuild -list -workspace … -clonedSourcePackagesDirPath <dir><dir>(9,668 KiB); DerivedData got only 28 KiB of logsxcodebuild -showBuildSettings -workspace … -scheme spm-Package -skipPackageUpdatesFetching from https://github.com/apple/swift-argument-parser.git (cached),Checking out 1.5.1: a full checkout was still createdxcodebuild -showBuildSettings -workspace … -scheme spm-Package -derivedDataPath <dd>, run twice<dd>/SourcePackages; the shared SwiftPM cache'sFETCH_HEADtimestamp advanced during the run and named the GitHub remote (network transfer was not directly observed); second run: 2 s, no fetch or checkout messages logged, +4 KiBxcodebuild -list -workspace … -clonedSourcePackagesDirPath <dd>/SourcePackages, after C4list_schemes: 11 s, 1,909,944,320 bytes (7,736 files) ofSourcePackagesin the workspace's DerivedData;show_build_settingsreturned aBUILD_DIRthere, while the builds used-derivedDataPath <checkout>/<App-dir>/DerivedData. The same-showBuildSettingsargv run by hand in a checkout with no per-user DerivedData setting created a new~/Library/Developer/Xcode/DerivedData/<App>-<hash>/folder of 1,910,665,216 bytes in total,SourcePackagesincluded (no separateSourcePackagestotal was taken), even with-disableAutomaticPackageResolution.If the project is also open in Xcode.app, Xcode's DerivedData for the workspace is Xcode.app's own folder, so the extra checkout is shared with Xcode.app (the sharing #525 asks for, there for the build tools). The
BUILD_DIRmismatch and the extra checkout relative to the server's builds remain unless the server's builds are pointed at that same folder, as #525's workaround does by rewriting each build and test call'sderivedDataPath.2. Where the argv is built (v2.7.1)
show_build_settings:show_build_settings.ts#L123-L133builds['xcodebuild', '-showBuildSettings'], then-projector-workspace, then-scheme, and nothing else. Its schema hasprojectPath,workspacePathandschemeonly (#L18-L21).list_schemes:list_schemes.ts#L48-L56builds['xcodebuild', '-list'], then-projector-workspace. Its schema hasprojectPathandworkspacePathonly (#L18-L21).typed-tool-factory.ts#L118-L136, applied at #L251), so thederivedDataPathandextraArgsdefaults never reach these two tools.-derivedDataPath(build-utils.ts#L79, #L170); the test tools build through it (test-common.ts#L272) before running the prepared products. So does the internal-showBuildSettingsbehind the app-path lookups (app-path-resolver.ts#L51, #L76). With noderivedDataPathconfigured, that path is a per-project folder under the server's workspace tree (derived-data-path.ts#L33-L51). These discovery calls leave the location to Xcode, so the two match only when they are deliberately made the same, for example aderivedDataPathset to Xcode's own folder for the workspace (Allow reusing Xcode.app's per-workspace DerivedData (avoid duplicate builds); static XCODEBUILDMCP_DERIVED_DATA_PATH can't map per workspace #525's workaround). They differed in both reproductions above, each of which set aderivedDataPath.xcodebuild -showBuildSettings -scheme <s> -skipPackageUpdateswithout-derivedDataPath(xcode-state-watcher.ts#L53); run C3 shows-skipPackageUpdatesdoes not prevent a first checkout.v2.7.0andv2.7.1each of the two tool files changes one line, the structured-output schema id.3. Suggested changes, supported by command-line experiments
Runs C1 to C5 were plain
xcodebuildcommands, not a modified MobileBuildMCP.show_build_settings: resolveresolveEffectiveDerivedDataPath({ derivedDataPath, workspacePath, projectPath })and push-derivedDataPath, asapp-path-resolver.tsdoes. Run C4 (xcodebuild -showBuildSettings … -derivedDataPath <dd>, run twice): the checkout lands in<dd>/SourcePackages, and the second query reuses it. Reuse after an actual build is expected, since the build uses the same path, but was not measured here.list_schemes:-listrejects-derivedDataPathwithout a scheme (run C1), but honours-clonedSourcePackagesDirPath(run C2). Passing-clonedSourcePackagesDirPath <effective DerivedData>/SourcePackagesreused the checkout that C4's query had made (run C5); reuse of a build's checkout is likewise expected, not measured.derivedDataPathfield to each tool's internal schema and forward it to the resolver. Session defaults are filtered to the internal schema's keys (typed-tool-factory.ts#L118-L136, #L251), andresolveEffectiveDerivedDataPathuses only the value passed to it (derived-data-path.ts#L33-L47). Without the field, 1 and 2 would fall back to the per-project default and still miss a configured path such as the calculator example's./.build/DerivedData. Per-call overrides are a separate, public-schema choice: the build tools leavederivedDataPathout of their session-aware public schema and include it in the legacy schema used whendisableSessionDefaultsis set (build_sim.ts#L190-L200, #L297-L300,typed-tool-factory.ts#L154-L159).4. Annotations: a question rather than a claim
show_build_settings.yaml#L12-L16andlist_schemes.yaml#L10-L14declarereadOnlyHint: true,destructiveHint: false,openWorldHint: false.readOnlyHintas "If true, the tool does not modify its environment",destructiveHint: falseas "the tool performs only additive updates", andopenWorldHintas "If true, this tool may interact with an "open world" of external entities."list_schemescall wrote a package checkout (B1). Separately, a plainxcodebuildquery (C4) logged a cached fetch of the package URL and advanced the shared cache'sFETCH_HEAD; remote network exchange was not observed. The write matchesreadOnlyHint: falseanddestructiveHint: false; whetheropenWorldHintshould also betrueis a question about what a first call does with an uncached dependency, which may reach the network (not observed here). After the changes in fold 3, a first call on a checkout that has never been built would still resolve packages and write a checkout, only into the builds' folder. Whether the hints should change then is your call. fix(mcp): make tool approval annotations explicit #297 notes that "Codex now treats missing MCP approval hints as risky defaults", so clients do act on them.5. Why this looks like an oversight rather than a design choice
9600359d, "fix(build): Scope DerivedData by invocation context", touches 109) propagatedderivedDataPath"through app-path lookups and generated next steps so follow-up commands inspect the same build location". It changedapp-path-resolver.ts,build-utils.tsandderived-data-path.ts; neither discovery tool appears in its file list or in any of its eight commits.session-defaults-schema.ts#L54-L56); no comment, changelog entry or doc page says the discovery tools should skip it.git log --followofshow_build_settings.tsmentions DerivedData or package resolution.6. Related issues (no obvious duplicate found in a scan of 210 issue titles on 2026-10-05)
#525 (build tools reusing Xcode.app's DerivedData), #526 (orphaned workspaces never swept), #524 (test-product retention), #340 (closed by #341), #173 (
derivedDataPathas a session default).7. Prompt and publication control
The account owner's instruction for this draft, verbatim: "Draft it and hold it for my review." Publication requires the account owner's explicit approval of the exact final text after preview. The 2.7.0 measurements come from a private project; its paths and names are replaced with placeholders. The 2.7.1 runs used copies of this repository's example projects.