Publish iOS and Android builds to testers and manage share links from an AI coding agent.
"Publish this build and send me the install link." Say that to your AI assistant and a tester can be installing the app thirty seconds later.
BetaDrop puts an iOS .ipa or Android .apk behind an over-the-air install
link: testers open the link on their phone and install straight from the browser — no TestFlight
review wait, no Play track, no tester accounts. If you have used Diawi or Firebase App Distribution,
it does the same job.
BetaDrop MCP moves that step to the other side of your AI assistant. Claude, Cursor, Copilot, Windsurf, Zed and Antigravity can publish builds, look up release history and manage API tokens through ordinary prompts — no browser tab, no CLI, no leaving the editor.
claude mcp add betadrop -s user -- npx -y @betadrop/mcp
11 tools. One npx command. No build step. Your assistant already knows how to use them — you never type a tool name.
"My IDE"), and copy the tokenbd_live_... — save it somewhere safe, it's shown only once!)[!TIP] 🤖 AI-Native Installation (Easiest) Since you are already using an AI assistant (like Cursor Composer, Claude, Copilot, or Antigravity), you don't need to edit configuration files manually! Just paste one of the following prompts directly into your AI chat:
- Cursor:
"Add the @betadrop/mcp server to my global Cursor mcp.json config"- Antigravity:
"Add the @betadrop/mcp server to my Antigravity mcp_config.json"- VS Code (Copilot):
"Add the @betadrop/mcp server to my workspace .vscode/mcp.json"- Claude Desktop:
"Add the @betadrop/mcp server to my Claude Desktop config"The AI will automatically locate, create, or update the configuration file for you. Once it is done, simply refresh/restart your editor.
Otherwise, pick your editor below to configure it manually.
Run one command in your terminal:
claude mcp add betadrop -s user -- npx -y @betadrop/mcp
This installs BetaDrop globally across all your Claude Code projects.
For a single project only, drop the-s userflag.
Verify it worked:
claude mcp list
Start a new Claude Code session and type /mcp to confirm the connection.
Open your config file:
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
Add this inside the file:
{
"mcpServers": {
"betadrop": {
"command": "npx",
"args": ["-y", "@betadrop/mcp"]
}
}
}
Restart Claude Desktop. BetaDrop tools will appear in the 🔧 tools panel.
Create .cursor/mcp.json in your project root:
{
"mcpServers": {
"betadrop": {
"command": "npx",
"args": ["-y", "@betadrop/mcp"]
}
}
}
Or for global access, create/edit ~/.cursor/mcp.json with the same content.
Go to Settings → MCP and click Refresh to pick up the new server.
Create .vscode/mcp.json in your project root:
{
"servers": {
"betadrop": {
"command": "npx",
"args": ["-y", "@betadrop/mcp"]
}
}
}
Or add it globally:
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/Code/User/mcp.json |
| Windows | %APPDATA%\Code\User\mcp.json |
| Linux | ~/.config/Code/User/mcp.json |
Use Copilot in Agent mode to access BetaDrop tools.
Edit ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"betadrop": {
"command": "npx",
"args": ["-y", "@betadrop/mcp"]
}
}
}
Add to your Zed settings file:
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/Zed/settings.json |
| Linux | ~/.config/zed/settings.json |
{
"context_servers": {
"betadrop": {
"command": {
"path": "npx",
"args": ["-y", "@betadrop/mcp"]
}
}
}
}
Open MCP settings from Settings → MCP Servers or edit the config file directly:
| OS | Path |
|---|---|
| macOS | ~/.gemini/antigravity-ide/mcp_config.json |
| Windows | %USERPROFILE%\.gemini\antigravity-ide\mcp_config.json |
{
"mcpServers": {
"betadrop": {
"command": "npx",
"args": ["-y", "@betadrop/mcp"]
}
}
}
Restart Antigravity to pick up the new server.
After adding the MCP server, authenticate with your BetaDrop API token. Open your AI assistant and type:
"Log me in to BetaDrop with token bd_live_xxxxxxxx"
Your credentials are saved to $XDG_CONFIG_HOME/betadrop/config.json when that variable is set, otherwise ~/.betadrop/config.json, with 0600 permissions (owner-read only). On logout, the token is revoked on the server and the config file is removed.
✅ You're all set! Now try any of these prompts 👇
You don't need to memorize any tool names — just talk to your AI assistant naturally:
| Prompt | What Happens |
|---|---|
"Publish ./build/MyApp.ipa to BetaDrop" | Uploads the IPA and returns an install link |
"Upload MyApp.apk with notes 'Fixed login crash on Android 14'" | Publishes with release notes visible to testers |
"Push the latest IPA to BetaDrop, expire after 7 days" | Sets a time-based expiry on the build |
"Upload MyApp.ipa and send me the install link" | Returns a shareable OTA install URL |
| Prompt | What Happens |
|---|---|
"Show my recent BetaDrop builds" | Lists your latest builds across both platforms |
"List my iOS builds" | Filters to iOS only |
"Show all expired builds on BetaDrop" | Lists builds that have hit their expiry limit |
"Any expired Android builds?" | Expired builds filtered by platform |
"Get the install link for my last build" | Retrieves the shareable URL |
| Prompt | What Happens |
|---|---|
"Show my BetaDrop API tokens" | Lists all active tokens with abilities and expiry |
"Create a BetaDrop token for CI called 'GitHub Actions'" | Creates a new token scoped for CI |
"Make a read-only token called 'QA Team'" | Creates a token whose abilities are recorded as read only |
"Create a token that expires in 30 days" | Auto-expiring token for temporary access |
"Revoke BetaDrop token abc-123" | Permanently revokes a token |
| Prompt | What Happens |
|---|---|
"Am I logged in to BetaDrop?" | Shows your email, token details, and API URL |
"Log out of BetaDrop" | Revokes the token server-side and clears local config |
Because these are tools and not a chat bot, your assistant can string them together:
"Build the release APK, publish it to BetaDrop with the last commit message as the notes, and give me the install link."
The build runs in your terminal, betadrop_publish uploads the artifact, and the link comes back
in the same reply.
Eleven tools across four areas. You never call these by name — the assistant picks them.
| Tool | What It Does |
|---|---|
betadrop_login | Save and validate your API token |
betadrop_logout | Revoke the token on the server and clear local credentials |
betadrop_whoami | Show your account email, token name, and expiry |
| Tool | What It Does |
|---|---|
betadrop_publish | Upload an .ipa or .apk and get a shareable install link |
betadrop_upload_status | Get the result (install link) of the most recent betadrop_publish upload. Takes no parameters — called automatically when a large build outruns the 90-second publish window |
betadrop_publish parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
filePath | string | ✅ | Absolute path to the .ipa or .apk file |
name | string | Override the app display name | |
version | string | Override the version string (e.g. 1.2.3) | |
buildNumber | string | Override the build number | |
bundleId | string | Override the bundle / package ID | |
notes | string | Release notes shown on the install page | |
expiryType | string | none · time · downloads · devices · combined. none (a permanent link) requires a paid plan — see below | |
expiryTimeDays | number | Expire after N days (use with time or combined). Clamped to your plan's maximum build retention | |
expiryDownloadLimit | number | Expire after N downloads (use with downloads or combined) | |
expiryDeviceLimit | number | Expire after N unique devices (use with devices or combined) |
Expiry is capped by your plan.
none— a permanent link — is a paid-plan feature; on a plan without it the build is stored as a dated one instead of being rejected.expiryTimeDaysis clamped to your plan's maximum build retention on every plan. When either happens the server returns aretentionClampobject (requestedDays,appliedDays,maxDays,permanentDenied,message) and the tool result appends a ⚠️ line explaining what was applied. Note it is reported only when the plan actually shortened something you asked for: send noexpiryTimeDaysand it stays null even if your account default was clamped down. Current per-plan day ceilings live insrc/lib/limits.jsonrather than being restated here.
How uploads work: The file is validated locally (ZIP magic bytes check) and uploaded, with progress notifications streamed to your AI client in 5% increments. The install link comes back in the tool result. Builds that take longer than 90 seconds keep uploading in the background so the tool call does not time out — the assistant then calls
betadrop_upload_statusto fetch the link. A status file at~/.betadrop/upload_status.jsontracks the upload in real time.
| Tool | What It Does |
|---|---|
betadrop_list_builds | List recent builds, with optional filters |
betadrop_list_expired_builds | List only expired builds (convenience shortcut) |
betadrop_list_builds parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
platform | string | ios or android — omit to list all | |
status | string | active · expired · disabled · deprecated · latest | |
page | number | Page number (default: 1) | |
perPage | number | Results per page (default: 20, max: 100) |
betadrop_list_expired_builds parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
platform | string | ios or android — omit to list all | |
page | number | Page number (default: 1) | |
perPage | number | Results per page (default: 20, max: 100) |
Each result includes the build name, version, platform, file size, status, dates, and a shareable install link.
| Tool | What It Does |
|---|---|
betadrop_token_list | List all your active (non-revoked) API tokens |
betadrop_token_create | Create a new scoped token (plaintext shown only once!) |
betadrop_token_delete | Permanently revoke a token by ID |
betadrop_token_create parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Label for the token (max 100 chars) |
abilities | string[] | ["publish"], ["read"], or ["*"] (default: all) | |
expiresInDays | number | Token lifetime in days (1–365). Omit for no expiry |
Abilities are recorded on the token and shown by
betadrop_token_list; publishing builds requires thepublishability. Do not treat areadtoken as a hard security boundary across every endpoint — scope it to a plan, and revoke tokens you no longer hand out.
⚠️ The plaintext token is shown exactly once at creation. Copy it immediately!
| Tool | What It Does |
|---|---|
betadrop_help | Show a full offline reference of all tools and example prompts |
Set these environment variables to override the defaults:
| Variable | Default | Description |
|---|---|---|
BETADROP_API_URL | https://api.betadrop.app | API server URL (for self-hosted) |
BETADROP_APP_URL | https://betadrop.app | Frontend URL for install links |
BETADROP_TOKEN | (none) | Token for CI — skips the local config file |
To set them for the MCP server, add an env block alongside command and args in the editor
config from Step 2:
{
"mcpServers": {
"betadrop": {
"command": "npx",
"args": ["-y", "@betadrop/mcp"],
"env": { "BETADROP_TOKEN": "bd_live_xxx" }
}
}
}
With BETADROP_TOKEN set there is no need to log in — the server uses it directly:
BETADROP_TOKEN=bd_live_xxx betadrop-mcp
"Tool not found" or no BetaDrop tools showing up?
node --version/mcp to check the server status"You are not logged in"?
"Log me in to BetaDrop with token bd_live_..."BETADROP_TOKEN env variable in your MCP config — see ConfigurationUpload seems stuck?
betadrop_upload_status) — that returns the install link once the upload lands~/.betadrop/upload_status.json directlyToken expired or revoked?
The iOS build downloads on the phone but will not open?
.ipa only installs on devices that were in the provisioning profile when it was signed — publishing it does not change that. Send the tester the UDID checker, add the device in the Apple Developer portal, and re-sign.The same publish step, on the other two surfaces — one account, one set of API tokens:
@betadrop/clisource | betadrop publish app.ipa from your terminal. Prints the install link and a scannable QR code. |
betadrop-app/upload-action | Publish from a GitHub Actions workflow. The install link lands on the run summary and, optionally, in a pull-request comment that updates itself on every push. |
Issues and pull requests: https://github.com/betadrop-app/betadrop-mcp. If this saved you a trip to the browser, a ⭐ helps other mobile teams find it.
MIT
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y @betadrop/mcpMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-betadrop-app-betadrop-mcp": {
"command": "npx",
"args": [
"-y",
"@betadrop/mcp"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceBetaDrop works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.