Acme
MCP Server

Setup

Configure OAuth and run the MCP Server.

The MCP Server runs alongside your SaaS application and API. It uses the existing database and auth configuration, and does not require an AI provider or agent storage bucket.

Configure the server

Set the following values in .env.local:

MCP_ENABLED=true
MCP_PORT=3005
MCP_SERVER_URL=http://localhost:3005/mcp

MCP_SERVER_URL is the canonical protected resource and must include /mcp. Use HTTPS outside local development.

The authorization server uses your existing SaaS URL and /api/auth base path. The provider is configured in packages/auth/lib/mcp.ts.

Start the server

After applying the database migration, run:

pnpm --filter @repo/mcp-app dev

The local endpoint is http://localhost:3005/mcp.

Connect a client

Use a client that supports the MCP 2026-07-28 profile and CIMD. Host the client's metadata document at a public HTTPS URL and include client_id, client_name, and redirect_uris.

An SDK connection looks like this:

import { Client, StreamableHTTPClientTransport } from "@modelcontextprotocol/client";

const client = new Client(
	{ name: "my-client", version: "1.0.0" },
	{ versionNegotiation: { mode: { pin: "2026-07-28" } } },
);

await client.connect(
	new StreamableHTTPClientTransport(new URL(mcpServerUrl), {
		requestInit: { headers: { Authorization: `Bearer ${accessToken}` } },
	}),
);

Never replace the OAuth access token with a Better Auth login-session token.

Deploy

pnpm --filter @repo/mcp-app build
pnpm --filter @repo/mcp-app start

The build bundles the server into apps/mcp/dist/index.mjs. Deploy that output with installed production dependencies.

Verify the provider

Application-tool failures and Code Mode failures are logged in the MCP process terminal or deployment logs. Shared application invocation records the original procedure error before MCP maps it to a client-safe message. Logs use the same bounded, credential-redacted diagnostics as the embedded agent; submitted code, tool arguments, and authorization headers are not logged. Logging does not roll back completed mutations or retry a failed call.

With local PostgreSQL running:

pnpm exec dotenv -e .env.local -- pnpm --filter @repo/auth test:mcp

For the full transport and browser workflow:

pnpm exec dotenv -e .env.local -- pnpm --filter @repo/mcp-app test:integration
pnpm --filter saas e2e:mcp

On this page