APKCube

Android APK intelligence over MCP: search apps, versions and downloads, run security scans, detect SDKs and trackers, inspect permissions and signing history, look up hashes and certificates, and fetch Google Play details. Remote Streamable HTTP with OAuth 2.1 or API key.

Hosted MCP Server

npx add-mcp 'https://apkcube.com/api/mcp'

Installs into Claude Code, Codex, Cursor and more

Documentation

Connect

  1. Add the server to your client

    The quickest way is a one-click install, which opens your client with the server filled in. To add it to Claude by hand: Settings → Connectors → Add custom connector. Or add it by hand. Any client that speaks MCP over HTTP and supports OAuth will work; only the file and its shape differ.
    claude mcp add --transport http apkcube https://apkcube.com/api/mcp
    
    Cursor ~/.cursor/mcp.json VS Code .vscode/mcp.json OpenCode ~/.config/opencode/opencode.json
  2. Ask in plain language

    The agent picks the tools itself. A few things to try:
    • “Is this APK safe to install? Check the scan, the permissions and the signing key.”
    • “What versions of Signal do you have, and which is the newest arm64 build?”
    • “Download the latest WhatsApp APK, then tell me its sha256 so I can verify it.”
    • “What changed between the last two builds of com.spotify.music? Any new permissions?”
    • “Has this package ever changed its signing key?”
    • “Find me a torch app with more than 10 million installs and a rating above 4.5.”

Tools

36 tools. Each catalogue tool runs the same code as its REST endpoint, linked under its row, so prices, responses and takedowns are always identical. Every tool declares an outputSchema and returns structured content plus the same JSON as text.

31 of the 36 are marked readOnlyHint, so a client that auto-approves reads can run them without asking. The ones marked catalog:download spend credits on a download, a fetch or a variant build, or change your app's public page, so a client that confirms writes will ask you first.

Find apps

Start here when you have a name or a phrase and need a package id.

ToolCreditsWhat it does
search_apps1Search by app name, publisher or package id.GET /apps?q=
get_app5The full listing for one app, including whether it can be downloaded.GET /apps/{pkg}
get_apps1 / appSummary rows for up to 100 apps in one call. Charged per app.POST /apps/batch
list_developer_apps1All apps from one publisher, most installed first.GET /developers/{slug}
list_similar_apps1Apps related to one app, as its page on the site shows them.GET /apps/{pkg}/similar
list_chart1Charts: hot, top grossing, latest, new, Editors' Choice, and what's popular or freshly updated here.GET /charts
list_categoriesfreeThe category list used to filter searches.GET /categories

Builds and downloads

List what we hold, get a file, or ask for one we don't have yet.

ToolCreditsWhat it does
check_availabilityfreeFree. Whether we have a build of up to 100 apps, each one's newest version, and every version we have by code and name. For update checks.POST /apps/availability
list_versions5All builds we have for an app, newest first, with checksums.GET /apps/{pkg}/versions
get_download_url catalog:download10Get a signed download URL for one build. Expires after about 5 minutes.POST /apps/{pkg}/download
request_fetch catalog:download10Ask us to fetch an app from Google Play when list_versions comes back empty.POST /apps/{pkg}/fetch
get_fetch_status1Whether a fetch you started is still running, ready, or failed.GET /apps/{pkg}/fetch
request_variant catalog:download10Ask for a build the default download doesn't include: every language, 32-bit ARM, universal, an older Android version or a specific device.POST /apps/{pkg}/variants
get_variant_status1Whether a variant build is ready, still building, failed, or not requested yet.GET /apps/{pkg}/variants

Security and integrity

What is inside a build, who signed it, and what changed between releases.

ToolCreditsWhat it does
get_version_security5Checksum, antivirus result, signing certificates, permissions and findings for one build.GET /apps/{pkg}/security
list_permissions5Permissions a build declares, with plain descriptions. Sensitive ones first.GET /apps/{pkg}/permissions
list_sdks5Third-party libraries detected in a build, and how much of the code we could read.GET /apps/{pkg}/sdks
list_trackers5Only the advertising, analytics and tracking libraries in a build.GET /apps/{pkg}/trackers
get_protection5Whether a build is packed or protected, and how that limits the other checks.GET /apps/{pkg}/protection
get_manifest5Manifest settings, native libraries and the findings we flag from them.GET /apps/{pkg}/manifest
get_signing_history5Which key signed each release, and whether the key was ever replaced.GET /apps/{pkg}/signing
compare_versions1Differences between two releases: permissions, signing key, size, min Android.GET /apps/{pkg}/compare
get_raw_scan10The raw scan record, for when you want to apply your own rules.GET /apps/{pkg}/raw

Reverse lookups

Start from a file you already have rather than an app name.

ToolCreditsWhat it does
lookup_hash5Find the build that matches an MD5, SHA-1 or SHA-256 checksum.GET /lookup/hash/{hash}
lookup_certificate5Find all packages we have that were signed by a given certificate.GET /lookup/certificate/{fp}
list_developer_certificates5Every signing key behind one publisher's apps, and whether each also signs anyone else's.GET /developers/{slug}/certificates

Google Play

The live store listing and its reviews, in any country.

ToolCreditsWhat it does
get_play_details5Google Play's full store listing in any country: rating histogram, installs, in-app prices, release date.GET /apps/{pkg}/play
list_reviews5One page of Google Play user reviews, with the developer's replies.GET /apps/{pkg}/reviews

Account

Free, so an agent can check before it spends.

ToolCreditsWhat it does
get_accountfreeYour remaining credits and which key or connected client is calling.GET /me

Developers Console

Free, for your own apps. Needs a signed-in user on a verified developer's team: OAuth, not an API key.

ToolCreditsWhat it does
console_list_appsfreeThe apps you manage, with your role on each.
console_app_statsfreeDaily downloads of one of your apps over 30 days, the lifetime total and top countries.
console_list_uploadsfreeBuilds you submitted, newest first, with each one's status and any hold or rejection reason.
console_upload_statusfreeWhere one upload stands, with its scan summary once it has one.
console_security_reportfreeEvery stored build of your app with its scan verdict, signing check and any notice on it.
console_update_listing catalog:downloadfreeChange the description, what's new and video on your app's page. Live immediately.
console_set_version_notice catalog:downloadfreeMark one build vulnerable or withdrawn, optionally blocking its download, or lift the mark.

Credits

Every tool result reports what the call cost and what's left, in _meta under com.apkcube/credits. That includes tool errors: a charged failure is still a charge, and a refunded one reports a cost of 0.

Running out comes back as a tool error that says what the call costs and where to top up, not as a server failure, so the agent stops instead of retrying.

To check the balance up front, call get_account. It's free, and worth doing before a 10-credit download. It returns the key, the balance and when the account was created, never a name or email. It is the same as GET /me.

get_apps is priced per package (1 credit each) and returns summary rows, not the full listing get_app returns for 5 credits.

A tools/call result

{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "resultType": "complete",
    "structuredContent": {
      "packageName": "org.thoughtcrime.securesms",
      "versions": [ … ]
    },
    "content": [
      { "type": "text", "text": "{\"packageName\":…}" }
    ],
    "isError": false,
    "_meta": {
      "com.apkcube/credits": {
        "cost": 5,
        "remaining": 245
      }
    }
  }
}

Without an account (x402)

https://apkcube.com/api/mcp/x402 serves the paid tools with no sign-in at all: each call is paid for by the call itself over x402, in USDC on Base or Solana, at $0.01 per credit. An unpaid call returns a tool error whose structuredContent is the x402 PaymentRequired; an x402-aware client (such as @x402/mcp 's) pays it and repeats the call with the payment in _meta["x402/payment"], and the receipt comes back in _meta["x402/payment-response"].

Payments settle by the credit rules: an empty answer or a failure on our side moves no money. get_account and the free tools are not served there — they need an account — and neither are prompts.

Prompts

8 ready-made prompts, which most clients offer as slash commands. Each walks the agent through a multi-step task and carries the rules that don't fit in one tool description: check the signing key before recommending an install, don't read a missing scan as a clean one, and pick builds by versionCode, not by version name. Prompts cost nothing; the tools they call are charged as usual.

PromptArgumentsWhat it does
vet_apppackageNameDecide whether a package is safe to install and explain why, using the listing, scan verdict, permissions and signing key.
find_and_downloadquery requirements?Find an app by name, pick the right build and mint a download URL, checking first so you don't pay for the wrong file.
whats_changedpackageName from?``to?Compare two builds of a package and report new permissions and any change of signing key.
audit_sdkspackageNameList the third-party code inside an app (ads, analytics, attribution, crash reporting) and say how much of the build we could actually read.
trace_artifactartifactStart from a checksum or a signing-key fingerprint and find out what it is, who signed it, and what else that key signs.
privacy_reportpackageNameSay what an app can reach and who it reports to: its trackers, its sensitive permissions and the manifest settings that expose data, with how much of the build we could read.
compare_appsa bPut two apps side by side — rating, installs, trackers and sensitive permissions — so you can choose between alternatives.
vet_developerslugCheck whether a publisher signs its apps consistently, and whether any of its keys also signs somebody else's packages.

name? marks an optional argument.

Protocol

Streamable HTTP, MCP revision 2026-07-28. Each request carries its own protocol version, so there is no handshake and no session. Clients on an older revision still connect: we answer their initialize without issuing a session. You only need this if you're writing a client; any MCP client does it for you.

The method, tool name and version are mirrored into headers, and the server rejects a request whose headers and body disagree.

A raw tools/call

curl -sS https://apkcube.com/api/mcp \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/call" \
  -H "Mcp-Name: list_versions" \
  -d '{
    "jsonrpc": "2.0",
    "id": 7,
    "method": "tools/call",
    "params": {
      "name": "list_versions",
      "arguments": {
        "packageName": "org.thoughtcrime.securesms"
      },
      "_meta": {
        "io.modelcontextprotocol/protocolVersion": "2026-07-28"
      }
    }
  }'
TransportStreamable HTTP. POST only, with a body of at most 256 KiB (413 otherwise); GET and DELETE return 405.
Version2026-07-28, or 2025-11-25 or 2025-06-18 after an initialize. Any other gets a 400 with error -32022 and the list of supported versions.
HeadersMCP-Protocol-Version and Mcp-Method on every 2026-07-28 request, plus Mcp-Name on tools/call and prompts/get. A mismatch with the body is a 400 with -32020.
ResponseA single application/json object. No streaming, no SSE. A notification (no id) gets an empty 202.
SessionsNone, in either era. Mcp-Session-Id is never issued and is ignored if sent.
Sign-inNot needed for initialize, server/discover, the two lists or ping, so you can see every tool before connecting. tools/call and prompts/get need a credential.
Methodsserver/discover, initialize, tools/list, tools/call, prompts/list, prompts/get, ping. Anything else is a 404 with -32601.
Cachingserver/discover, tools/list and prompts/list are the same for every caller and cacheable for 5 minutes.
OriginA request with an Origin header is accepted only from our own site, against DNS rebinding. Desktop and CLI clients send none.

Errors follow the spec. An unknown tool or malformed arguments is a JSON-RPC protocol error. Problems the agent can act on, like “package not found”, “app taken down” or “out of credits”, come back as ordinary results with isError: true and a sentence saying what to do.

Authorization

OAuth 2.1, as the MCP spec requires over HTTP. We run both the authorization server and the resource server, so an account here is all you need. Clients discover all of this on their own from the first 401, which comes at the first tool call: listing tools needs no sign-in.

Protected resourcehttps://apkcube.com/api/mcp
Resource metadatahttps://apkcube.com/.well-known/oauth-protected-resource/api/mcp
Issuerhttps://apkcube.com
Server metadatahttps://apkcube.com/.well-known/oauth-authorization-server
RegistrationDynamic (RFC 7591), open to anyone, rate limited.
FlowAuthorization code with PKCE (S256). Refresh tokens issued.
Token bindingTokens are bound to the resource above. A token issued for anything else is rejected.

Scopes

Reading costs between 0 and 10 credits a call (get_apps is 1 per package). A download costs 10 and is recorded on your account, a fetch 10, and a variant build 10. Those three sit behind their own scope, with the two console tools that change your app's public page, so a client that only looks things up never has to be trusted to spend or publish.

ScopeGrants
catalog:readEvery tool except get_download_url, request_fetch, request_variant, console_update_listing, and console_set_version_notice (31 of 36). Required for every call.
catalog:downloadget_download_url, request_fetch, request_variant, console_update_listing, and console_set_version_notice: a download, a fetch of an app we don't have yet, a variant the default download doesn't include, or a change to your own app's page on the Developers Console.
offline_accessA refresh token, so you don't sign in again every hour.

A token missing the scope a tool needs gets a 403 with an RFC 6750 insufficient_scope challenge naming the scope, which a client can use to ask you for it.

API keys

For an agent that has no browser to sign in with, the server also accepts the same akc_ key the REST API takes. Send it as a bearer token on every request, in place of the access token in the example above. Most clients have a headers field for this.

{
  "Authorization": "Bearer akc_9f3Ka2Lp_xxxxxxxxxxxxxxxxxxxx"
}

A key has no scopes. It can do everything your account can, downloads included, except the Developers Console tools, which need a signed-in user over OAuth. Keep it on a server and never in client-side code. Until your first top-up an account can hold 1 active key; after it, 10. You can revoke a key from your account at any time.

Troubleshooting

What you seeWhyWhat to do
401 on every tool callThe client didn't sign in with OAuth, or its API key is wrong or revoked.Use a client with OAuth support, or send an API key as a bearer token.
400, error -32022The client asked for a revision we don't speak (older than 2025-06-18, or not yet released).Update the client. The error's data lists the versions we support.
400, error -32020A mirrored header doesn't match the request body.A bug in a hand-written client: send the headers shown under Protocol.
403 insufficient_scopeThe client was authorized without catalog:download and called get_download_url, request_fetch, request_variant, console_update_listing or console_set_version_notice.Re-authorize from the client, asking for catalog:download.
429 Too many requestsToo many calls from your address in a short time, before any credential is checked.Wait for the Retry-After header, then retry.
403 Origin not allowedA browser page on another site called the server directly.Make the call from that site's backend.
405A GET or DELETE, usually a client probing for SSE.POST only. Use a client that supports this revision.
Tool error: Out of creditsThe balance is below the call's price. Nothing was charged.Top up on billing, then retry.