Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ jobs:
unzip -q "$RELEASE_ARCHIVE" -d "$RUNNER_TEMP/mobile-dev-release"
npm run test:package -- "$RUNNER_TEMP/mobile-dev-release"

- name: Package and check the Claude plugin
run: |
npm run package:claude -- --release
npm run test:claude
tar -czf release/mobile-dev-claude-plugin.tar.gz -C release/claude-plugin mobile-dev

- name: Save Claude plugin
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: mobile-dev-${{ steps.release.outputs.version }}-claude-plugin
path: release/mobile-dev-claude-plugin.tar.gz
if-no-files-found: error
compression-level: 0
retention-days: 30

- name: Upload Sentry source maps and native symbols
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
Expand Down Expand Up @@ -249,3 +264,38 @@ jobs:
mkdir "$RUNNER_TEMP/mobile-dev-marketplace"
unzip -q "release/mobile-dev-$RELEASE_VERSION-darwin-arm64.zip" -d "$RUNNER_TEMP/mobile-dev-marketplace"
node apps/codex-plugin/tooling/publish-release.mjs "$RUNNER_TEMP/mobile-dev-marketplace"

publish-claude:
needs: [build, release]
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write
concurrency:
group: release-claude
cancel-in-progress: false
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: refs/tags/${{ needs.build.outputs.tag }}
persist-credentials: false

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: '22.23.2'

- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: mobile-dev-${{ needs.build.outputs.version }}-claude-plugin
path: release

# The directory submission and Claude Code marketplace both track release/claude.
- name: Publish the Claude plugin branch
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ needs.build.outputs.tag }}
RELEASE_REPOSITORY_URL: ${{ github.server_url }}/${{ github.repository }}.git
run: |
mkdir "$RUNNER_TEMP/mobile-dev-claude"
tar -xzf release/mobile-dev-claude-plugin.tar.gz -C "$RUNNER_TEMP/mobile-dev-claude"
node apps/claude/tooling/publish-release.mjs "$RUNNER_TEMP/mobile-dev-claude/mobile-dev"
62 changes: 29 additions & 33 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ host as an argument.
| `packages/runtimes` | Pinned Node runtimes bundled into the server (agent-device, serve-emu). |
| `packages/skills` | Agent skills for the shared tools; each host's package step includes the ones its host supports. |
| `apps/codex-plugin` | Codex: manifest, launcher, assets, and its own server (`server/`, the self-updater) and panel (`ui/`, the update banner). |
| `apps/claude` | Claude: the Claude Desktop extension (`manifest.json`, MCPB) and the Claude Code plugin (`.claude-plugin/plugin.json`). Both run the shared server and panel unchanged. |
| `apps/claude` | Claude: the Claude Code plugin manifest (`.claude-plugin/plugin.json`), its Node launcher (`scripts/`), Node check hook (`hooks/`), README and setup-skill overrides, and the `release/claude` publisher (`tooling/`). It runs the shared server and panel unchanged. |
| `apps/cursor` | Cursor: the Cursor plugin manifest (`.cursor-plugin/plugin.json`). It runs the shared server and panel unchanged. |
| `apps/mac` | The Mac app: a SwiftUI shell (`Sources/`), the page it hosts (`web/`) and its server (`server/`). |
| `packages/test-support` | Fixtures shared by tests across packages and apps. |
Expand Down Expand Up @@ -267,49 +267,45 @@ Open a new chat after installing, then open Mobile Dev from the sidebar.

`npm run package` writes the local ZIP to `release/mobile-dev-<version>-darwin-arm64.zip`. Install through the local marketplace above. The New Plugin archive dialog uploads to the workspace plugin service; it is a separate install route. This package has not gone through public directory review or publication.

### Claude Desktop local development
### Claude local development

Complete the first-time runtime and native-helper setup under [Build and package](#build-and-package),
then run from this checkout with Node.js 22.19 or later:
then build and package the plugin with Node.js 22.19 or later:

```sh
npm run build
npm run claude:config
```

1. Open Claude Desktop **Settings > Developer > Edit Config**. On macOS, this is
`~/Library/Application Support/Claude/claude_desktop_config.json`.
2. Merge the `mobile-dev` entry from `.local-dev/claude-desktop-config.json` into
the existing `mcpServers` object, preserving other servers and settings. The
snippet uses absolute paths to this checkout and the Node executable running
the generator.
3. Fully quit and reopen Claude, start a new conversation, and ask **“Open Mobile Dev.”**
Approve the connector when prompted; use **Expand** when available.

After UI or server edits, run `npm run build` and fully restart Claude. This
workflow uses the checkout directly and needs no repackaging. Regenerate the
config if the checkout or Node path changes. For connection failures, check
**Settings > Developer** for the server status and logs.

To create and check a bundle for manual installation instead:

```sh
npm run package:claude
npm run test:claude
claude plugin validate --strict ./release/claude-plugin/mobile-dev
claude --plugin-dir ./release/claude-plugin/mobile-dev
```

This writes `release/mobile-dev-<version>-claude-desktop-darwin-arm64.mcpb` and
the Claude plugin folder `release/claude-plugin/mobile-dev`. The plugin folder
uses `apps/claude/.claude-plugin/plugin.json`, which starts `dist/server.mjs` with Node.js
22.19 or later from `PATH`, and leaves out the Codex manifest, `.mcp.json`, and
launcher. Check it with `claude plugin validate ./release/claude-plugin/mobile-dev`,
or load it with `claude --plugin-dir ./release/claude-plugin/mobile-dev`.
Follow the [manual installation steps](README.md#claude-desktop-manual-installation).
Remove the `mobile-dev` development entry before installing the bundle to avoid
duplicate servers. Rebuild, repackage, and reinstall to update a bundled copy.
`package:claude` writes the plugin folder `release/claude-plugin/mobile-dev` from
`apps/claude`: the manifest, `scripts/launch-node.sh`, `hooks/hooks.json`, the
Claude README, and the shared skills with `apps/claude/skills` files replacing
theirs. It leaves out the Codex manifest, `.mcp.json`, launcher, and skill
metadata, and npm's `.bin` symlinks. The manifest starts the server through
`launch-node.sh`, which finds Node.js 22.19 or later on `PATH` or in Homebrew, nvm,
fnm, Volta, mise, and asdf locations, because Claude opened from the Dock does not
inherit the shell's `PATH`. The SessionStart hook runs the same script with
`--check` and tells the user and Claude when no usable Node is found.
`test:claude` copies the folder to a path with spaces, runs the hook, and starts
the server through the launcher. Repackage after UI or server edits and restart
the Claude Code session.

To use a checkout directly in Claude Desktop's chat instead, run `npm run claude:config`
and merge the `mobile-dev` entry from `.local-dev/claude-desktop-config.json` into
**Settings > Developer > Edit Config** (`~/Library/Application Support/Claude/claude_desktop_config.json`),
preserving other servers. Fully quit and reopen Claude, then ask **“Open Mobile Dev.”**
Run `npm run build` and restart Claude after edits.

Local builds retain the `development` telemetry environment. Public releases use
`npm run build:release` and `npm run package:claude -- --release`.
`npm run build:release` and `npm run package:claude -- --release`. The release
workflow then makes the `release/claude` branch hold only the plugin, in
`plugins/mobile-dev`, and a root marketplace that lists it, and tags it
`claude-v<version>`. Users add it with
`claude plugin marketplace add callstackincubator/codex-mobile-dev-plugin@release/claude`,
and the Claude directory submission tracks `plugins/mobile-dev` on the same branch.

### Cursor local development

Expand Down
34 changes: 16 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,21 @@ from the plugin directory, then open a new chat.
To install the prebuilt plugin from this repository instead, see
[Install from the GitHub marketplace](CONTRIBUTING.md#install-from-the-github-marketplace).

### Claude Desktop: manual installation
### Claude

On an Apple Silicon Mac, obtain a `mobile-dev-<version>-claude-desktop-darwin-arm64.mcpb`
bundle from the person sharing the preview, or [build one locally](CONTRIBUTING.md#claude-desktop-local-development).
The Claude bundle is not yet published through this repository's release workflow.
On an Apple Silicon Mac with Node.js 22.19 or later, add the prebuilt plugin from
this repository's `release/claude` branch in Claude Code:

1. Open Claude Desktop **Settings > Extensions > Advanced settings**.
2. Under **Extension Developer**, click **Install Extension…**, select the `.mcpb`
file, and confirm installation. You can also open the file with Claude Desktop.
3. Fully quit and reopen Claude, then start a new conversation and ask **"Open Mobile Dev."**
4. Approve the connector when prompted. Click **Expand** to use the larger view
when available; Mobile Dev does not add a permanent Claude sidebar entry.
```sh
claude plugin marketplace add callstackincubator/codex-mobile-dev-plugin@release/claude
claude plugin install mobile-dev@mobile-dev
```

The bundle includes the plugin and native helpers; Claude supplies Node, so no
`npm install` is needed. Install a newer `.mcpb` manually to update. Use either
the bundle or the [local development connection](CONTRIBUTING.md#claude-desktop-local-development)
to avoid duplicate Mobile Dev servers. See [Claude's installation guide](https://support.claude.com/en/articles/10949351-getting-started-with-local-mcp-servers-on-claude-desktop).
Start a new session and ask **"Open Mobile Dev."** Approve the tool calls when
prompted. Run `claude plugin update mobile-dev@mobile-dev` to update. Mobile Dev
finds Node on `PATH` or in the usual Homebrew, nvm, fnm, Volta, mise, and asdf
locations, and Claude tells you at the start of a session if none is usable. To
work on the plugin itself, see [Claude local development](CONTRIBUTING.md#claude-local-development).

### Cursor: manual installation

Expand Down Expand Up @@ -130,8 +128,8 @@ See [storage privacy and review checks](docs/storage-privacy.md).

Mobile Dev runs on an Apple Silicon Mac. In Codex desktop, the prebuilt plugin
uses Codex's bundled Node runtime from its workspace dependency cache; the Claude
Desktop bundle uses Claude's Node runtime, the Cursor plugin uses Node.js from
`PATH`, and the Mac app bundles its own. Install the tools for the platforms you use:
plugin finds Node.js 22.19 or later on `PATH` or in common install locations, the
Cursor plugin uses Node.js from `PATH`, and the Mac app bundles its own. Install the tools for the platforms you use:

| Platform or feature | Requirements |
| --- | --- |
Expand Down Expand Up @@ -191,12 +189,12 @@ product in `apps/`:
| --- | --- |
| `packages/core` | The MCP server, device runtimes, and tool handlers |
| `packages/ui` | The device panels and tools every host shows |
| `packages/mcp-app` | The MCP Apps panel that Codex and Claude Desktop load |
| `packages/mcp-app` | The MCP Apps panel that Codex and Claude load |
| `packages/shared` | Types and logic the server and UI both use |
| `packages/skills` | Agent skills for the shared tools |
| `packages/native`, `packages/runtimes` | Native helpers and bundled Node runtimes |
| `apps/codex-plugin` | The Codex plugin: manifest, updater, and update banner |
| `apps/claude` | Claude: the Claude Desktop extension and Claude Code plugin manifests |
| `apps/claude` | Claude: the Claude Code plugin manifest, Node launcher and release branch publisher |
| `apps/cursor` | Cursor: the Cursor plugin manifest |
| `apps/mac` | The Mac app: SwiftUI window and its page |

Expand Down
15 changes: 8 additions & 7 deletions apps/claude/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"name": "Callstack",
"email": "hello@callstack.com"
},
"homepage": "https://github.com/callstackincubator/mobile-dev",
"repository": "https://github.com/callstackincubator/mobile-dev",
"homepage": "https://github.com/callstackincubator/codex-mobile-dev-plugin",
"repository": "https://github.com/callstackincubator/codex-mobile-dev-plugin",
"license": "MIT",
"keywords": [
"ios",
Expand All @@ -20,14 +20,15 @@
"performance"
],
"icon": "./assets/icon.svg",
"documentationUrl": "https://github.com/callstackincubator/mobile-dev#readme",
"supportUrl": "https://github.com/callstackincubator/mobile-dev/blob/main/SUPPORT.md",
"privacyPolicyUrl": "https://github.com/callstackincubator/mobile-dev/blob/main/PRIVACY.md",
"termsOfServiceUrl": "https://github.com/callstackincubator/mobile-dev/blob/main/TERMS.md",
"documentationUrl": "https://github.com/callstackincubator/codex-mobile-dev-plugin/tree/release/claude/plugins/mobile-dev#readme",
"supportUrl": "https://github.com/callstackincubator/codex-mobile-dev-plugin/blob/main/SUPPORT.md",
"privacyPolicyUrl": "https://github.com/callstackincubator/codex-mobile-dev-plugin/blob/main/PRIVACY.md",
"termsOfServiceUrl": "https://github.com/callstackincubator/codex-mobile-dev-plugin/blob/main/TERMS.md",
"mcpServers": {
"mobile-dev": {
"command": "node",
"command": "/bin/sh",
"args": [
"${CLAUDE_PLUGIN_ROOT}/scripts/launch-node.sh",
"${CLAUDE_PLUGIN_ROOT}/dist/server.mjs"
]
}
Expand Down
64 changes: 64 additions & 0 deletions apps/claude/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Mobile Dev for Claude

Build, run, and debug iOS and Android apps without leaving Claude. Mobile Dev
streams simulators, emulators, and connected devices into the chat and gives
Claude tools to see and control them. It works with Expo, React Native, SwiftUI,
and other native mobile projects.

- **Live devices beside your chat:** stream iOS simulators, Android emulators,
and connected iPhones, iPads, and Android devices.
- **Device control and inspection:** let Claude tap, type, scroll, and read the
accessibility tree, and annotate elements with instructions for it.
- **App control:** install, launch, and stop apps, open deep links, send test
pushes, and set permissions and languages.
- **Device settings:** appearance, text size, rotation, location, status bar,
and slow or offline networks.
- **Logs:** iOS unified logs, Android logcat, and Metro console messages in one
filterable view.
- **Performance:** CPU, memory, and FPS charts, with recordings Claude can analyze
and compare.
- **App storage:** browse and watch what your app saves, without adding code to it.

## Install

In Claude Code:

```sh
claude plugin marketplace add callstackincubator/codex-mobile-dev-plugin@release/claude
claude plugin install mobile-dev@mobile-dev
```

Start a new session and ask **"Open Mobile Dev."** Approve the tool calls when
prompted. Run `claude plugin update mobile-dev@mobile-dev` to update.

## Requirements

- An Apple Silicon Mac.
- **Node.js 22.19 or later.** Mobile Dev looks for it on `PATH` and in the usual
Homebrew, nvm, fnm, Volta, mise, and asdf locations. If none is found, Claude
tells you at the start of a session; install it with `brew install node` or
from [nodejs.org](https://nodejs.org), then restart Claude.
- **iOS:** Xcode 26 or later with an installed simulator runtime. Physical
devices need Xcode 27 or later and Developer Mode.
- **Android:** Android SDK platform-tools and emulator, and an AVD or a device
with USB or wireless debugging authorized.

The plugin bundles its device backends and native helpers, so no `npm install`,
account, or hosted service is needed. Your project's own tools build the app;
Mobile Dev supplies the device panel, inspection, logs, and performance tools.

## Privacy and support

Mobile Dev reports plugin errors, crashes, usage counters, and aggregate plugin
performance measurements to Sentry. App logs, screenshots, input content, tool
payloads, app storage contents, profiles, and performance recordings are never
included. Set `MOBILE_DEV_TELEMETRY=off` in the environment Claude starts from
to turn reporting off. Read the [Privacy Policy](PRIVACY.md) and
[Terms of Service](TERMS.md).

For help, email [hello@callstack.com](mailto:hello@callstack.com) or see
[Support](SUPPORT.md).

## License

MIT. See [LICENSE](LICENSE) and [third-party notices](THIRD_PARTY_NOTICES.md).
17 changes: 17 additions & 0 deletions apps/claude/hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"description": "Tells the user and Claude when Node.js 22.19 or later, which the Mobile Dev server needs, is missing.",
"hooks": {
"SessionStart": [
{
"matcher": "startup",
"hooks": [
{
"type": "command",
"command": "/bin/sh \"${CLAUDE_PLUGIN_ROOT}/scripts/launch-node.sh\" --check",
"timeout": 10
}
]
}
]
}
}
28 changes: 0 additions & 28 deletions apps/claude/manifest.json

This file was deleted.

2 changes: 1 addition & 1 deletion apps/claude/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
"version": "0.0.0",
"private": true,
"type": "module",
"description": "Claude: the Claude Desktop extension (MCPB) and Claude Code plugin manifests for the shared server and MCP Apps panel."
"description": "Claude: the Claude Code plugin manifest, Node launcher and README for the shared server and MCP Apps panel."
}
1 change: 0 additions & 1 deletion apps/claude/plugin-host.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"label": "Claude",
"manifest": ".claude-plugin",
"root": "CLAUDE_PLUGIN_ROOT",
"desktopBundle": "manifest.json",
"config": {
"file": "claude-desktop-config.json",
"server": {},
Expand Down
Loading
Loading