storebridge-mcp
A remote MCP (Model Context Protocol) connector for StoreBridge API — the unified Apple App Store + Google Play data API (search, app details, reviews, similar apps, charts, categories, developer portfolios, autocomplete, and a directional ASO keyword/rank suite).
Live: https://storebridge-mcp.vercel.app/mcp (Vercel project storebridge-mcp, team isaiahduprees-projects) — 13 tools, verified against real production data. Since the upstream StoreBridge deployment is metered (RapidAPI/Apify), this connector authenticates its own outbound calls with the same Apify-actor bearer (STOREBRIDGE_APIFY_BEARER) and applies a soft per-IP rate limit (STOREBRIDGE_MCP_RATE_LIMIT, default 30 tool-calls/hour, in-memory) so the free MCP tier stays a discovery channel rather than an unmetered bypass of the paid listing — see lib/ratelimit.js.
What this is, and why it's a separate connector
StoreBridge API is a plain REST API. Any HTTP client can already call it directly. This repo exists because MCP clients (Claude, ChatGPT, and other MCP-aware agents) don't consume arbitrary REST APIs — they consume MCP tools. storebridge-mcp is a thin adapter layer that:
- Exposes each StoreBridge endpoint as a discoverable, typed MCP tool (name, description, zod input schema, annotations) that an LLM can reason about and call directly, instead of having to be taught the REST surface out-of-band.
- Speaks the MCP streamable-HTTP transport at a single
/mcp endpoint, so it can be registered as a connector in Claude, ChatGPT, or any other MCP client with one URL.
- Does nothing else. It has no business logic of its own — every tool call is a pass-through
fetch to StoreBridge, and the JSON response StoreBridge returns is handed back verbatim as the tool result.
Authentication: None (deliberate)
Unlike this org's other MCP connectors (NotesBridge, GapRadar, EtsyOps, etc.), which require OAuth because they act on a signed-in user's private Mac/shop/account data, StoreBridge's data has no per-user dimension at all — it's public app-store metadata (listings, reviews, charts, developer pages). There is nothing to gate per-caller, so this connector intentionally ships with:
- No OAuth, no login, no bearer tokens
- No Supabase / database
- No billing, no plans, no usage metering
- No demo-vs-real account split — every caller gets the same real, live data
This makes the connector dramatically simpler than the org's OAuth-based connectors: api/mcp.js builds a fresh, stateless McpServer per request and serves it with zero auth checks.
Known caveat (see below): the production StoreBridge API deployment (https://storebridge-api.vercel.app) currently sits behind a RapidAPI proxy-secret guard on /v1/* (see "Upstream auth caveat"). That's an upstream deployment/monetization detail, not a reason to add auth to this connector — it just means the upstream base URL needs to be pointed at an open deployment (or the guard needs to be relaxed / the proxy secret injected server-side) before this connector's default config serves real production traffic end-to-end.
One tool per StoreBridge endpoint (from storebridge-api/openapi.yaml):
| Tool | StoreBridge endpoint | Description |
|---|
search_apps | GET /v1/search | Search apps on Apple App Store, Google Play, or both. |
get_apps_batch | GET /v1/apps | Resolve an Apple app by bundle id, or batch-fetch many apps by comma-separated ids. |
get_app | GET /v1/apps/{id} | Full app details (description, version, rating histogram, screenshots, size, installs, etc). |
get_app_reviews | GET /v1/apps/{id}/reviews | Paginated reviews for an app. |
get_similar_apps | GET /v1/apps/{id}/similar | "Customers also bought" / related apps. |
get_app_permissions | GET /v1/apps/{id}/permissions | Google Play declared permissions (Google only). |
get_app_datasafety | GET /v1/apps/{id}/datasafety | Google Play "Data safety" section (Google only). |
get_charts | GET /v1/charts | Top-chart rankings (free/paid/grossing, by category). |
get_categories | GET /v1/categories | Category / genre list for a store. |
get_developer | GET /v1/developers/{id} | A developer's record plus their published apps. |
autocomplete_suggest | GET /v1/suggest | Autocomplete completions for a partial query. |
get_aso_keywords | GET /v1/aso/keywords | Directional keyword ideas + difficulty (estimated, from live search — not panel data). |
get_aso_rank | GET /v1/aso/rank | Point-in-time rank of an app across up to 20 keywords (estimated). |
All 13 tools are read-only and annotated { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true } — none of them write anything, and all of them reflect live, externally-changing app-store data.
(The build brief sketched ~9-10 illustrative tool names; StoreBridge's actual verified openapi.yaml surface has 13 GET endpoints, so this build maps 1:1 to all 13 rather than dropping three real ones to hit a round number.)
How it wraps storebridge-api
Each tool handler does a plain fetch(\${STOREBRIDGE_API_BASE_URL}${path}`, ...)` against the real StoreBridge REST API and returns the parsed JSON as MCP tool-result content:
{ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }
Upstream HTTP errors (4xx/5xx) are caught and surfaced as a typed MCP error result via an asError helper rather than crashing the request.
STOREBRIDGE_API_BASE_URL (env var) controls the upstream base URL. It defaults to https://storebridge-api.vercel.app.
Project layout
api/mcp.js MCP endpoint (StreamableHTTPServerTransport, stateless, no auth)
api/health.js GET /api/health
lib/tools.js All 13 tool definitions (zod schemas + fetch-and-forward handlers)
local-server.js Plain-Node http server for local dev / smoke testing (not deployed)
test/smoke.mjs Real end-to-end smoke test (initialize, tools/list, tools/call)
vercel.json Routes /mcp -> api/mcp.js, /health -> api/health.js
There is no .well-known / OAuth-metadata surface in this repo on purpose: the 401 + WWW-Authenticate: Bearer resource_metadata=... dance and /.well-known/oauth-protected-resource / /.well-known/oauth-authorization-server endpoints in this org's other connectors exist purely to support the OAuth discovery flow. An MCP streamable-HTTP server with no auth has nothing for a client to discover or authorize — it just accepts POST requests. Skipping OAuth metadata entirely is correct here, not an oversight.
Local development
Endpoints locally: POST http://localhost:3900/mcp, GET http://localhost:3900/health.
To point at a self-hosted / open StoreBridge instance instead of production (useful while the production RapidAPI guard is active — see below):
STOREBRIDGE_API_BASE_URL=http://localhost:8080 npm run dev
Smoke test
npm run dev &
npm run smoke
test/smoke.mjs drives the running server over real HTTP/JSON-RPC and verifies:
GET /health returns { ok: true, ... }
initialize succeeds and reports serverInfo.name === "storebridge"
tools/list returns all 13 tools with their zod-derived JSON schemas
tools/call for search_apps with { term: "notes", store: "apple", limit: 3 } returns real app results fetched live (not mocked)
Upstream auth caveat (read before deploying)
While building this, I read storebridge-api's own server.js / src/guard.js: the production deployment gates every /v1/* route behind a RapidAPI proxy-secret (rapidApiGuard), and only opens up when RAPIDAPI_PROXY_SECRET is unset (self-host/dev mode). That means, as currently deployed, https://storebridge-api.vercel.app/v1/search?... returns 403 forbidden without a valid X-RapidAPI-Proxy-Secret header — it is not actually open on the live URL today, even though the data itself is public information (app-store listings) and the long-term intent (per the org's product line) is a fully public, keyless API.
This doesn't change the architecture of this connector — storebridge-mcp still has zero auth of its own, by design, because there's no per-caller state to protect. It does mean that before storebridge-mcp's default STOREBRIDGE_API_BASE_URL (the production URL) will serve real traffic end-to-end, one of the following needs to happen upstream:
- Deploy an open (no
RAPIDAPI_PROXY_SECRET) StoreBridge instance for this connector to point at, or
- Relax the guard for a
/v1/* traffic class that isn't going through RapidAPI, or
- Have this connector inject a server-side RapidAPI proxy secret / Apify bearer on outbound requests (would need
RAPIDAPI_PROXY_SECRET or APIFY_BEARER added as an env var here and forwarded as a header in lib/tools.js's callStoreBridge).
The smoke test in this repo proves the MCP protocol plumbing and tool-calling mechanics end-to-end against a real, live, self-hosted StoreBridge instance (node server.js in the storebridge-api repo with no RAPIDAPI_PROXY_SECRET set — its guard is explicitly inert in that mode) fetching real Apple App Store data — see the smoke test output in the build report for the exact live response.
Deploy
Not deployed yet (by design — verify first). Once verified:
cd /Users/isaiahdupree/Software/storebridge-mcp
npx vercel --yes --prod
After deploy, the MCP connector URL to register in Claude/ChatGPT/any MCP client is:
https://<deployment-domain>/mcp