External Agent (MCP)
Expose your app's AI capabilities to an external agent (the user's own Claude Code or Codex) over an OAuth-authenticated MCP server, with the same capability set the in-app assistant has.
The external agent server turns your app's capability layer into an authenticated Model Context Protocol (MCP) server. An always-on external agent connects to it, signs in once with OAuth, and calls the same capabilities your in-app assistant uses - on that user's behalf, with no app UI open.
The server is off by default: it mounts only when config.mcpServer.enabled is true. With it off, the MCP endpoint and its discovery routes do not exist and no OAuth provider is registered.
Connect an agent
The agent needs one thing - your backend origin plus /api/mcp:
https://your-app.com/api/mcpAuthentication
Access is gated by OAuth 2.1: your app issues the token, validates it on every request, and ties each call to a user. An unauthenticated, invalid, or expired token is rejected before any tool runs.
| Discovery document | Path | What it tells the agent |
|---|---|---|
| Protected-resource metadata | /.well-known/oauth-protected-resource | That the MCP endpoint requires a token, and which authorization server issues it |
| Authorization-server metadata | /.well-known/oauth-authorization-server | Where to run the OAuth flow (authorize, token, and registration endpoints) |
A compliant agent reads these itself and registers dynamically, so you hand-configure no client IDs, endpoints, or app registrations. A fullstack project forwards those two root paths to the co-hosted Hono app; with a standalone backend the agent resolves them against the backend origin directly, so no forwarder routes ship.
What the agent can do
The agent acts on the user's behalf, so it gets the same full capability set the in-app assistant does, automations included.
- Discover and call. It lists the tools available to it with each input schema, calls any of them, and receives the result as text. It has no shell, file, or network access of its own, and no secret is returned to it.
- Nothing MCP-specific to write. The agent is served the same capability registry the rest of your AI surface uses, so adding a capability once reaches the in-app assistant, the external agent, and automations at the same time.
- Web research too.
web_searchandweb_extractappear whenever a vendor key is set andconfig.ai.webSearchis notfalse. There is no per-request toggle here, so those two are the whole gate.
Those calls cost money, billed to the token's user. Each search or page read is a credits line item under the ai.mcp feature tag, priced through your pricingConfig.credits markup like every other metered call. An empty balance refuses the call before the vendor is reached, and a project with credits disabled meters nothing. An identical call repeated within 15 minutes bills once, so an agent that retries a call it timed out on cannot charge the user twice. The endpoint's AI rate limiter bounds how fast an agent can drive any of this.
The external agent runs at the chat surface, like the in-app assistant, because both are USER-DRIVEN. Restricting a capability to chat (via surfaces) therefore keeps it available to both while withholding it from unattended automation runs - the loop-guard that stops an automated run from managing automations.
Under the hood
- Engine: Mastra's
MCPServer. It takes your capability toolset (AI SDKtool()objects) as-is and does the tool-to-MCP conversion -tools/listschemas andtools/callargument validation - via@mastra/schema-compat. - Transport: the MCP SDK's web-standard streamable HTTP, stateless JSON-response mode. Mastra's own HTTP serving is Node-bound, so the route connects this transport to Mastra's underlying MCP server instead, keeping
@repo/apideployable to Node, serverless, and edge-style runtimes alike. - The other direction - your agent consuming external MCP servers - uses
MCPClientfrom the same@mastra/mcppackage; see Agents.
Enabling it
config.mcpServer.enabled to true. That mounts /api/mcp and its OAuth discovery routes, registers your app as the OAuth provider, and shows the MCP settings tab. config.ai.enabled gates none of it.config.ai.enabled still matters for part of the surface, because the registry is shared: a capability that runs a model on your server - an automation the agent creates, say - never runs while the AI product is off. Account capabilities work either way; integration capabilities run too, but integrations are connected from the AI-gated Integrations tab.
Affiliate tracking
Credit referral partners for signups and purchases with the anonymous, browser-side Refgrow, Affonso, and PromoteKit pixels under config.affiliate.
Runner Daemon
Let your users run their own coding-CLI subscriptions for your app 24/7 from hardware they control, by installing AgentRunner - the daemon we publish and maintain.