
Your agent needs to drive an Expo project. Check whether the production iOS build passed, pull the failing job's logs, trigger a rebuild, then triage the TestFlight crashes that followed. Expo ships both a hosted MCP server and an HTTP surface, and here the usual assumption breaks down: the REST API is not the superset. Most of what an Expo release agent wants to do has an MCP tool and no documented endpoint anywhere else. This is where each path ends, and what that means for how you authenticate.
These two paths are not two views of the same platform. They were built for different consumers, and the capability gap between them runs in the opposite direction to most tools in this series.
Expo MCP Server is a remote server hosted by Expo at https://mcp.expo.dev/mcp, running Streamable HTTP with OAuth authentication. It launched in preview in October 2025 for paid plans and opened to Free accounts in May 2026 with a monthly usage allowance.
Its capabilities split into two classes. Server capabilities work with the remote connection alone. Local capabilities require the expo-mcp package in your project and a dev server started with EXPO_UNSTABLE_MCP_SERVER=1, and they are only available on SDK 54 and later.
Expo's own MCP documentation lists the tools and carries an explicit caveat that the list may change with expo-mcp package updates or server changes. Treat it as a moving target, not a contract.
There is no single Expo REST API in the way Slack or GitHub ship one. What exists is a small set of separately documented HTTP surfaces.
The EAS Workflows REST API documents two endpoints under https://api.expo.dev: POST /v2/workflows/dispatch to trigger a run and GET /v2/workflows/runs/:workflowRunId to read its status and jobs. Both take a bearer EXPO_TOKEN.
Alongside that sit the Expo Push Service API at exp.host, EAS webhooks for BUILD and SUBMIT completion, and the EAS Simulator REST API, which is a limited-access preview available only to selected partners. The api.expo.dev/graphql endpoint that EAS CLI talks to is not documented as a public integration surface, and Expo publishes no schema reference for it.
Four dimensions decide this for a production agent: what it can do, how it authenticates, what breaks in production, and which workloads fit each path.
At the time of writing, Expo's docs list 25 server tools and 6 local tools. The documented HTTP surface covers workflow dispatch, workflow run status, push notifications and two webhook event types. Everything else in the table below has an MCP tool and no published endpoint.
The gap is not the usual one. If your agent needs build history, build logs, store crash data or review replies, MCP is the only documented path. Going around it means either shelling out to EAS CLI or calling an undocumented GraphQL endpoint whose shape can change without notice.
Two things the MCP server does not do. It has no event subscription model, so a build-completion trigger has to come from an EAS webhook. And it has no push notification tool, so anything that ends in a user-facing notification goes through the Push Service API.
The credential model differs more than the transport does, and the difference decides what your audit trail is worth.
The current docs describe a single flow: sign in with your Expo account in the browser when prompted, and the server generates an access token. The agent then sees what that Expo account can see across its projects and organizations.
For an interactive coding agent this is the right default. Each developer authorizes once, and every build triggered through the agent is attributable to that developer's Expo identity rather than to shared infrastructure.
The HTTP surface takes Authorization: Bearer <EXPO_TOKEN>, and the token type matters. A personal access token can perform actions on your behalf across your personal account and every organization you have been granted access to. That is a wide blast radius for an automated caller.
A robot user token is the alternative Expo recommends for production integrations. Robot users can be assigned a role, cannot sign in to Expo products, cannot own projects and authenticate only through their token, so revoking one does not disturb any human account.
Both paths hand you a credential per identity and nothing else. MCP's OAuth flow produces a token per user. The HTTP path produces a token per robot or per person. Neither path gives you storage, rotation, revocation or tenant isolation. Those remain infrastructure problems no matter which one you pick, and the difference between single and multi-tenant tool calling auth shows up the moment a second team or a second customer org enters the picture.
Choosing a path decides which class of failure lands in your on-call rotation.
Expo owns the server, the tool schemas and the underlying calls into EAS. You own the OAuth token per user, plus one thing that catches teams out: MCP usage is metered. Free accounts get a monthly allowance counted at the billing account level and shared across organization members, and requests fail with an error once it is exhausted.
You also own the consequences of a changing tool list. Expo states plainly that capabilities may change with package or server updates. An agent with hardcoded tool names needs a check on startup, not a stack trace at 3am. That is the same class of silent breakage covered in tool call failures in production.
Six of the tools need a local dev server. They also come with hard limits: one dev server connection at a time, iOS support restricted to simulators, and iOS local capabilities only on macOS hosts. Restarting the dev server requires reconnecting the MCP client.
None of that survives a hosted or scheduled agent. Treat local capabilities as developer-workstation features, not production ones, and design your agent so it never plans around a tool that will not exist on your server.
You own polling. The workflow run endpoint returns a status you read in a loop until it reaches success, failure or canceled. You own webhook verification too: EAS sends an expo-signature header containing a hex-encoded HMAC-SHA1 digest of the body, keyed on a secret at least 16 characters long, with exponential backoff retries on any non-2xx or non-3xx response.
You also own one ceiling that has no workaround. Anything outside workflows, push and webhooks means driving EAS CLI in a subprocess, with all the process management, non-interactive flags and project-linking prerequisites that implies.
The two lists below are Expo-specific. They are not general MCP advice.
Scalekit ships an Expo MCP connector that fronts the hosted Expo MCP Server, runs the authorization handshake, stores the resulting credential per user and resolves it at call time. The connector page lists 24 tools, covering the server-capability surface except search_documentation, which Expo gates behind an EAS paid plan.
There is no separate Expo API connector in the catalog today, which is consistent with how small the documented HTTP surface is. If you need POST /v2/workflows/dispatch alongside the MCP tools, add it through bring your own connector and it inherits the same vault and audit chain.
Install the SDK and set three environment variables from your Scalekit dashboard, then create the connected account.
Before handing anything to a model, call one read-only tool directly. If this returns builds, your connector, credential and project linkage are all correct.
Note the expomcp_ prefix. Scalekit namespaces tool names per connector, so build_list on Expo's server is expomcp_build_list here. Use the exact names from the connector's tool list rather than Expo's unprefixed table.
actions.langchain.get_tools() returns native StructuredTool objects, so there is no schema reshaping. Set page_size above the default so a connector with two dozen tools is not silently truncated.
The instruction not to trigger a build is a prompt, and prompts are not a control. The next section replaces it with something enforced.
A triage agent does not need build_run, build_submit or the review-reply tools. A Virtual MCP server declares which tools exist for that agent role, so the excluded ones are never offered to the model and calls to them are blocked. As covered in agent tool observability, knowing exactly which tools an agent can reach is the first step to meaningful monitoring.
The token cost matters here too. Every tool definition sits in every context window, so a five-tool triage server costs roughly a fifth of what the full connector costs per run. At CI volume that is a real line item.
The server URL is static and safe to share. The session token carries the identity, so mint one per user before each run and never put it in client-side code.
Set expiry longer than the expected run. There is no refresh endpoint; create_session_token is the remint call, and a host holding an expired bearer fails at its next tool call rather than at startup.
Mastra has native MCP support, so it discovers the scoped tool list and schemas straight from the Virtual MCP server. Pass the URL and the user's session token as bearer auth.
If you prefer direct tool calling over MCP in Node, scalekit.tools.listScopedTools() returns Anthropic-shaped schemas with input_schema, and scalekit.actions.executeTool() runs them.
Both paths hand you a token and stop. No vault, no rotation logic, no revocation flow, no tenant boundary. That gap is identical whether you chose MCP or the workflow endpoints.
A single robot user token looks correct in a demo. Every workflow dispatches, every build triggers, everything works. In production it collapses attribution: the EAS activity log shows one robot user for every action, with no link back to the engineer, the Slack thread or the incident that caused it.
That is tolerable for a nightly build. It is not tolerable for build_submit, which pushes a binary to the App Store or Google Play. This is exactly the kind of credential ownership pattern that breaks down at scale when multiple agents share a single identity.
Expo MCP's review tools sharpen this. appstore_reply_review and playstore_reply_review post text that is publicly visible on the store listing, and each review holds exactly one developer reply, so replying again overwrites the previous one.
An agent posting under a shared credential means a public statement from your company with no recorded author. When someone asks who approved the wording, the answer needs to be a name, not a service account. The case for an audit trail in agent auth is rarely this concrete.
Multiply by headcount. Fifty engineers using a release assistant means fifty Expo credentials to store, refresh and revoke. Offboarding is where this breaks: the SSO account is disabled on Friday, and a personal access token minted eight months ago still works on Monday. The agent does not decide to keep using it. It simply does.
Scalekit's Expo MCP connector resolves the right per-user credential on every tool call from an AES-256 encrypted, per-tenant vault. The token never enters your prompt, your model context or your logs, and revoking one user's connected account stops their agent without touching anyone else's.
The same infrastructure serves both paths. If you later add the workflow dispatch endpoint as a custom connector, it uses the same vault and the same audit chain, so the MCP decision never becomes an auth migration. Secure token management for AI agents covers the storage and rotation mechanics in full.
Three things matter specifically for agents that touch mobile release infrastructure.
Every call through the connector is logged with full attribution: who authorized it, which agent ran it, which tool, what scope and what came back. Logs are queryable, exportable to Datadog, Splunk or any SIEM, and retained 90 days by default.
For Expo this is not a compliance checkbox. When a build gets cancelled or a store reply gets overwritten, the log tells you which agent run did it and which engineer's credential it used. Failures are separated by source, so an Expo MCP quota error reads differently from an expired credential.
Real release agents are not Expo-only. A useful one reads the failing EAS build, finds the commit, opens the GitHub PR, files the Linear issue and posts to Slack. That is four connectors and potentially a hundred tools in one context window.
A Virtual MCP server declares the five or six tools that agent role actually needs across all of those connectors, behind one endpoint and one session token per user. One definition serves every user, and each run resolves to that user's own connected accounts.
If you ship agents to other companies, each customer has their own Expo organization, their own builds and their own store listings. One connection definition serves all of them; each tenant's tokens sit in a separate vault namespace and resolve at request time.
The blast radius of a misbehaving run is one user's scoped session token, not a platform credential. Access control for multi-tenant AI agents covers the model in full.
For Expo the answer is less balanced than usual. If your agent reads or acts on build health, workflow logs, store crashes or store reviews, build against Expo MCP. The documented HTTP surface covers none of it, and EAS CLI in a subprocess is not an integration strategy.
Reach for the HTTP surface for what it was built for: dispatching and polling a workflow, receiving build and submit completion events, sending push notifications. Most production Expo agents use both, with MCP reading and reasoning while webhooks provide the trigger.
The credential layer does not change either way. Per-user isolation, rotation, revocation and an attributable record for every public write action are infrastructure requirements, not path-dependent ones.
Browse the Scalekit Expo MCP connector or read the connector setup docs to get a first authenticated build call running.
If you are building release automation, crash triage or store feedback agents on Expo, join the Scalekit Slack community and compare notes with other agent builders. For architecture questions that need a faster answer, talk to our team directly.