App Dropper

MCP server reference

Last updated 1 October 2026

@appdropper/mcp is a Model Context Protocol server. It lets a coding agent upload a local .apk or .ipa to App Dropper and get back the tester install link. It runs on your machine over stdio, because the build it uploads is on your machine. It uses the same REST API and the same upload code as the CLI.

Version 0.1.0. Requires Node.js 20 or newer. For what it’s for and what a session looks like, see the MCP overview.

Setup

Sign in once

This opens a browser page where you approve the machine. The token is saved to ~/.appdropper/config, and the MCP server reads it from there.

bash
npx appdropper login

Add the server to your editor

Use the config for your client below.

Ask for an upload

“Upload the latest Android release build to App Dropper and give me the install link.”

Client configuration

Claude Code

bash
claude mcp add appdropper -s user -- npx -y @appdropper/mcp

-s user makes it available in every project. Leave it out to add the server to the current project only. On native Windows, npx needs a wrapper: -- cmd /c npx -y @appdropper/mcp.

Cursor

Add this to ~/.cursor/mcp.json for every project, or to .cursor/mcp.json for one.

~/.cursor/mcp.json
{
  "mcpServers": {
    "appdropper": {
      "command": "npx",
      "args": ["-y", "@appdropper/mcp"]
    }
  }
}

VS Code with GitHub Copilot

VS Code’s own format uses a top-level servers key, not mcpServers. Put it in .vscode/mcp.json for a workspace, or run MCP: Open User Configuration from the command palette to add it for every workspace.

.vscode/mcp.json
{
  "servers": {
    "appdropper": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@appdropper/mcp"]
    }
  }
}

Or add it to your user profile from a terminal:

bash
code --add-mcp '{"name":"appdropper","command":"npx","args":["-y","@appdropper/mcp"]}'

GitHub Copilot CLI

bash
copilot mcp add appdropper -- npx -y @appdropper/mcp

This writes to ~/.copilot/mcp-config.json. Copilot CLI passes only PATH through to MCP servers, not the rest of your shell environment, so sign in with appdropper login rather than relying on an exported APPDROPPER_TOKEN.

Claude Desktop and other clients

Any client that can launch a local stdio MCP server works. Point it at the command npx with the arguments -y @appdropper/mcp. Clients that use an mcpServers JSON file, Claude Desktop’s claude_desktop_config.json among them, take the same block as Cursor. Remote (HTTP) MCP isn’t offered: the server has to run where your build files are.

Authentication

The server looks for a token in this order, the same order the CLI uses:

  1. APPDROPPER_TOKEN in the server’s environment
  2. The saved login from appdropper login

It reads the credential on every tool call, so signing in after the editor started needs no restart.

appdropper login covers all your apps by default, including new ones. The first upload of a bundle ID you haven’t used before creates its app, the same as dropping the build on the dashboard, within your plan’s app limit. You can limit a login to selected apps on the approval page, or later under Settings → API tokens.

Using an API token instead

Generate one under Settings → API tokens. Choose only selected apps if it should reach just the apps you work on from this machine. Then make it available to the server without writing it into a file you commit:

.cursor/mcp.json or .vscode/mcp.json
"appdropper": {
  "command": "npx",
  "args": ["-y", "@appdropper/mcp"],
  "env": { "APPDROPPER_TOKEN": "${env:APPDROPPER_TOKEN}" }
}

That reads APPDROPPER_TOKEN from the environment the editor was started in. In a Claude Code .mcp.json the syntax is "${APPDROPPER_TOKEN}". VS Code can also prompt for the token once and store it securely, using an inputs entry with "password": true.

Never commit a token

A token in a committed mcp.json is a token you have to rotate. Use a variable reference, or the saved login.

Tools

Six tools. Only upload_build changes anything. Every tool returns a short readable summary for the agent plus structured data matching its output schema.

upload_build

Uploads a local .apk or .ipa, waits for App Dropper to process it, then returns the tester install link. The build becomes the newest build of its app (matched by bundle ID), and the app’s testers get an email and a push notification.

InputRequiredNotes
file_pathYesPath to the .apk or .ipa. Relative paths resolve against the project directory. URLs are rejected.
release_notesNoUp to 4,000 characters. Shown on the install page and in the email.
tagNoUp to 40 characters, e.g. qa or nightly. Defaults to beta.

Returns app_name, app_id, platform, version, build_number, bundle_id, build_id, install_url, qr_url, expires_at (when the build expires), file_name and size_bytes.

text
Upload build/app/outputs/flutter-apk/app-release.apk and use the last commit message as release notes.

find_builds

Lists .apk and .ipa files in a project, newest first, with size, modification time, platform, and release/debug/profile when the path says so. Read-only: it never uploads anything.

Inputs: directory (defaults to the project the editor opened), platform (android, ios or any), and limit (1–50, default 10). It skips node_modules, Pods, DerivedData, Gradle intermediates and every hidden folder (.git, .dart_tool, .gradle…). It never follows a symlink, and stops after 8,000 folders. When no directory is given and the server was started in your home directory or the filesystem root, it asks for a directory instead of scanning.

text
Send the latest release build to App Dropper.

list_apps

The apps the credential can upload to, with app_id, app_name, bundle_id and the app’s public install page. all_apps is true when it also covers apps created later.

text
Which App Dropper apps can this token access?

list_builds

An app’s recent builds, newest first: version, build number, platform, tag, status, upload and expiry dates, install count and install URL. Inputs: app_id (optional when the credential covers exactly one app) and limit (1–50, default 10).

text
Show me the last 5 builds of this app.

get_build

One build by build_id, with its release notes, minimum OS version, install count, install URL and QR code URL. app_id is optional and narrows the lookup.

text
Show me the install link for the latest build.

whoami

Whether the server is signed in, where the credential came from (APPDROPPER_TOKEN or saved login), its name and masked hint, its expiry, and the apps it covers. It never returns the token. It reports a missing or rejected credential as authenticated: false with the fix, rather than as an error.

Errors

A failed call comes back as a tool error. The agent reads it and can explain it or recover. The text starts with what happened, then the next step, and ends with a stable code:

text
Upload failed: This build is 620 MB. Your plan allows up to 500 MB per build. Upgrade to Studio at https://appdropper.io/pricing
Upgrade: https://appdropper.io/pricing
(error code: plan_limit, HTTP 402)
CodeMeaning
not_authenticatedNo credential. Run appdropper login or set APPDROPPER_TOKEN.
unauthorized (401)The token was revoked, has expired, or is incomplete.
plan_limit (402)Build size, storage or app count is over the plan’s limit. Includes the upgrade link.
forbidden (403)The token can’t reach that app, or you no longer manage it.
not_found (404)No such app or build, or it’s outside the token’s apps.
rate_limited (429)Too many requests or uploads this hour. The message says how long to wait.
server_error (5xx)A temporary problem on our side. Retry, or check system status.
network_errorApp Dropper couldn’t be reached from this machine.
upload_interruptedThe transfer to storage dropped and couldn’t be resumed.
invalid_buildThe file arrived but isn’t a readable, complete app.
processing_timeoutUploaded, but still processing when the wait ran out. Nothing is lost: it shows up in list_builds shortly.
file_not_found, not_a_file, unsupported_file_type, empty_file, invalid_pathThe path was wrong. Nothing was sent.
cancelledThe client cancelled the call; the transfer was stopped.

Security

  • upload_build uploads exactly the path it is given. It accepts only .apk and .ipa and refuses URLs. For a symlink, the type check applies to the target.
  • find_builds only lists files. It never reads file contents, never uploads, and never leaves the directory it was given.
  • The token is never returned by a tool, never written to logs, and never sent anywhere but App Dropper’s API. The binary itself goes straight to Google Cloud Storage over a one-off upload session, and the token isn’t sent there.
  • Editor uploads don’t send CI metadata. The notification email doesn’t claim a pipeline built them.
  • Uploads count against your plan exactly like dashboard uploads.

Large builds

Builds stream from disk, so even the largest build your plan allows uploads in a small, flat amount of memory. A dropped connection resumes from the last byte storage received. Processing waits up to 10 minutes; set APPDROPPER_MCP_TIMEOUT (seconds) to change that. Clients that support MCP progress notifications show upload progress.

iOS builds

App Dropper doesn’t sign or re-sign apps, and an upload doesn’t change what iOS allows. An .ipa has to be exported with an ad hoc or enterprise profile, and ad hoc builds install only on devices in that profile. See registering tester UDIDs.

Troubleshooting

The editor says the server failed to start

Run npx -y @appdropper/mcp --version in a terminal. It should print the version. If npx isn’t found, the editor isn’t seeing your Node install: check node --version is 20 or newer, and on Windows use the cmd /c form.

“App Dropper isn’t signed in on this machine”

Run npx appdropper login, then try again. No restart needed. Ask the agent to run whoami to confirm.

The token is rejected

It was revoked, has expired, or APPDROPPER_TOKEN holds an old value. APPDROPPER_TOKEN takes priority over the saved login, so unset it if you meant to use your login.

“This token isn’t allowed to upload to …”

The token is limited to selected apps. Often the cause is a debug flavour with a suffixed bundle ID, which counts as a separate app. The error links to the token: add the app or switch to all apps.

find_builds says the directory is too broad

Your editor started the server in your home directory. Ask with the project path, or tell the agent the path of the build.

Logs

The server writes logs to stderr and nothing but protocol messages to stdout. Claude Code shows them with claude --debug. Cursor and VS Code show them in the output panel for MCP servers.

Ready to try it?

Drop an .apk or .ipa and get a shareable install link in seconds.

Upload a build