Summary
On Apple Silicon macOS, neither documented-ish install path works out of the box — and they fail for different reasons:
npx / npm fails during install: a transitive sharp falls back to a source build that errors out, so the server never starts.
pnpm dlx installs and starts fine, but the server then throws mobilecli is not available or not working properly on the first device call, because under pnpm's strict node_modules the binary isn't where the resolver looks.
The net effect is that there's no clean install path on Apple Silicon: one tool breaks on sharp, the other on mobilecli.
Environment
|
|
@mobilenext/mobile-mcp |
0.0.59 |
mobilecli (transitive, via mobilewright) |
0.3.79 |
sharp (transitive) |
0.34.5 |
| OS |
macOS 26.4.1, Apple Silicon (arm64) |
| Node |
v24.8.0 |
| npm |
11.6.0 |
| pnpm |
10.15.1 |
Path A — npx / npm: sharp source build fails
$ npm install @mobilenext/mobile-mcp@latest
npm error code 1
npm error path .../node_modules/sharp
npm error command sh -c node install/check.js || npm run build
npm error > sharp@0.34.5 build
npm error sharp: Attempting to build from source via node-gyp
npm error sharp: See https://sharp.pixelplumbing.com/install#building-from-source
npm error sharp: Please add node-addon-api to your dependencies
The platform prebuilt that should avoid the source build is not installed:
$ ls node_modules/@img/
ls: node_modules/@img/: No such file or directory # @img/sharp-darwin-arm64 missing
$ npm config get omit
# empty — optional deps are NOT opted out
So npm (11.6.0) does not install @img/sharp-darwin-arm64, sharp falls back to a node-gyp source build, and the whole install (and therefore npx -y @mobilenext/mobile-mcp@latest) hard-fails. This appears to be the well-known npm optional-dependencies resolution bug, but the result is that the documented npx install does not work on Apple Silicon.
Note: with --ignore-scripts the install completes and mobilecli is correctly hoisted to the top level — i.e. Path A's only blocker is sharp:
$ npm install --ignore-scripts @mobilenext/mobile-mcp@latest # exit 0
$ ls node_modules/mobilecli/bin/mobilecli-darwin-arm64 # present ✓
Path B — pnpm dlx: mobilecli is not available
pnpm installs sharp from its prebuilt fine, so the server starts. But the first tool call fails:
mobilecli is not available or not working properly. Please review the documentation
at https://github.com/mobile-next/mobile-mcp/wiki for installation instructions
Root cause
mobilecli is not a direct dependency of @mobilenext/mobile-mcp — it's pulled in transitively via mobilewright. src/mobilecli.ts (getMobilecliPath) resolves the binary with a manual node_modules path join off __filename, not require.resolve:
// after the MOBILECLI_PATH env check:
const mobilecliPath = join(lastNodeModulesPath, "mobilecli", "bin", binaryName);
if (existsSync(mobilecliPath)) { return mobilecliPath; }
- Under npm's flat/hoisted layout, the transitive
mobilecli lands at the top-level node_modules/mobilecli, so the join resolves. ✅ (This is why most users — npx on Intel/Linux where sharp's prebuilt installs — never see this.)
- Under pnpm's strict, symlinked layout,
mobilecli lives only in the virtual store and is symlinked under mobilewright's subtree — never as a sibling of @mobilenext/mobile-mcp. The manual join (which doesn't follow pnpm's structure, unlike require.resolve) misses it, the version check throws, and the server reports "mobilecli is not available".
Verified the binary is present-but-unreachable in a pnpm dlx tree:
# .pnpm/mobilecli@0.3.79/.../bin/mobilecli-darwin-arm64 → exists and runs ('mobilecli version 0.3.79')
# .pnpm/@mobilenext+mobile-mcp@0.0.59/node_modules/ → mobilewright, zod, express… but NO mobilecli sibling
Why this is an Apple-Silicon trap
The two failures compound: on Apple Silicon you can't use npx (sharp source build fails), so you reach for pnpm — which then can't resolve mobilecli. There's no out-of-the-box combination that works.
Suggested fixes
- Declare
mobilecli as a direct dependency of @mobilenext/mobile-mcp. Then pnpm symlinks it as a sibling and the existing path-join resolves (npm already hoists it). This is the smallest fix for Path B.
- Resolve via
require.resolve("mobilecli/package.json") instead of hand-rolling the node_modules path — robust across npm/pnpm/yarn layouts (still needs (1) so it's resolvable under pnpm).
- Document
MOBILECLI_PATH as a supported escape hatch in the README/wiki (it's honored first, but undocumented).
- Path A: ensure the
@img/sharp-<platform> prebuilt installs on Node 24 / npm 11 (pin a sharp with working prebuilts, or add node-addon-api), or document that pnpm is required and why.
Current workaround
Install the mobilecli binary out-of-band and point MOBILECLI_PATH at it; the server then skips its broken lookup and works under pnpm dlx.
Summary
On Apple Silicon macOS, neither documented-ish install path works out of the box — and they fail for different reasons:
npx/ npm fails during install: a transitivesharpfalls back to a source build that errors out, so the server never starts.pnpm dlxinstalls and starts fine, but the server then throwsmobilecli is not available or not working properlyon the first device call, because under pnpm's strictnode_modulesthe binary isn't where the resolver looks.The net effect is that there's no clean install path on Apple Silicon: one tool breaks on
sharp, the other onmobilecli.Environment
@mobilenext/mobile-mcpmobilecli(transitive, viamobilewright)sharp(transitive)arm64)Path A —
npx/ npm:sharpsource build failsThe platform prebuilt that should avoid the source build is not installed:
So npm (11.6.0) does not install
@img/sharp-darwin-arm64,sharpfalls back to a node-gyp source build, and the whole install (and thereforenpx -y @mobilenext/mobile-mcp@latest) hard-fails. This appears to be the well-known npm optional-dependencies resolution bug, but the result is that the documentednpxinstall does not work on Apple Silicon.Note: with
--ignore-scriptsthe install completes andmobilecliis correctly hoisted to the top level — i.e. Path A's only blocker issharp:Path B —
pnpm dlx:mobilecli is not availablepnpminstallssharpfrom its prebuilt fine, so the server starts. But the first tool call fails:Root cause
mobilecliis not a direct dependency of@mobilenext/mobile-mcp— it's pulled in transitively viamobilewright.src/mobilecli.ts(getMobilecliPath) resolves the binary with a manualnode_modulespath join off__filename, notrequire.resolve:mobileclilands at the top-levelnode_modules/mobilecli, so the join resolves. ✅ (This is why most users —npxon Intel/Linux wheresharp's prebuilt installs — never see this.)mobileclilives only in the virtual store and is symlinked undermobilewright's subtree — never as a sibling of@mobilenext/mobile-mcp. The manual join (which doesn't follow pnpm's structure, unlikerequire.resolve) misses it, the version check throws, and the server reports "mobilecli is not available".Verified the binary is present-but-unreachable in a
pnpm dlxtree:Why this is an Apple-Silicon trap
The two failures compound: on Apple Silicon you can't use
npx(sharp source build fails), so you reach forpnpm— which then can't resolvemobilecli. There's no out-of-the-box combination that works.Suggested fixes
mobileclias a direct dependency of@mobilenext/mobile-mcp. Then pnpm symlinks it as a sibling and the existing path-join resolves (npm already hoists it). This is the smallest fix for Path B.require.resolve("mobilecli/package.json")instead of hand-rolling thenode_modulespath — robust across npm/pnpm/yarn layouts (still needs (1) so it's resolvable under pnpm).MOBILECLI_PATHas a supported escape hatch in the README/wiki (it's honored first, but undocumented).@img/sharp-<platform>prebuilt installs on Node 24 / npm 11 (pin asharpwith working prebuilts, or addnode-addon-api), or document thatpnpmis required and why.Current workaround
Install the
mobileclibinary out-of-band and pointMOBILECLI_PATHat it; the server then skips its broken lookup and works underpnpm dlx.