# Deploy it and connect Claude (/docs/guides/connect-an-agent/deploy-for-claude)

---
title: Deploy it and connect Claude
description: Claude's remote connectors run from Anthropic's cloud, so they cannot reach localhost. This is the public deployment they need and the checks that prove it works before you add the connector.
kind: guide
package: "@questpie/mcp"
---

The editor worked because it runs on the same machine as the dev server. A
remote connector does not, so `http://localhost:3000/api/mcp` is unreachable to
it. The desktop app is no exception. Everything below is the same app, on a real
domain.

## Set the deployed origin

```bash title="Production environment"
APP_URL=https://cms.example.com
BETTER_AUTH_SECRET=<a-strong-production-secret>
DATABASE_URL=<production-postgres-url>
```

`APP_URL` has to match the public origin exactly. Access tokens carry
`<APP_URL>/api/mcp` as their audience, and verification rejects a token whose
audience does not match. `BETTER_AUTH_SECRET` has a default in the starter's env
schema. That default is for your laptop, not for a server.

## Ship the schema as migrations

Fix the starter's migration path first. Codegen only discovers migrations in
`src/questpie/server/migrations`, and `questpie migrate` runs only what codegen
found. The starter's `cli.migrations.directory` sends new files to
`src/migrations` instead, where nothing reads them. Delete that line from
`src/questpie/server/questpie.config.ts`.

Then write the migration in development, read it, and commit it:

```bash
bun run migrate:create
```

Apply only committed files at deploy time:

```bash
bun run migrate
```

<Callout type="warn" title="`migrate`, never `push`">
	`questpie push` writes the schema straight to whatever database it is pointed
	at. Keep it out of container commands, init containers, CI deploy steps and
	runbooks. `--force` does not make it safer.
</Callout>

## Prove the endpoint before you connect

Discovery sits under the handler's base path, which is `/api` in the starters:

```bash
curl https://cms.example.com/api/.well-known/oauth-protected-resource
curl https://cms.example.com/api/.well-known/oauth-authorization-server
```

Both return JSON. Then check the endpoint itself:

```bash
curl -i -X POST https://cms.example.com/api/mcp
```

It must answer `401` with a `WWW-Authenticate: Bearer resource_metadata="..."`
header. That header is what starts the OAuth flow in a compliant client. Use
`POST`. A `GET` on `/api/mcp` returns `405` and tells you nothing.

<Callout type="warn" title="A `200` there is a hole">
	`POST /api/mcp` with no session and no token must never succeed. If it does,
	the endpoint is answering unauthenticated callers and every tool you exposed
	is public.
</Callout>

Also confirm that `/api/auth/oauth2/register`, `/admin/login` and
`/admin/oauth/consent` all resolve on the same deployment. A client walks
through all three during its first connection.

## Add the connector

Claude's remote connectors speak Streamable HTTP, run OAuth, and register
themselves. So the endpoint URL is the whole configuration. Add
`https://cms.example.com/api/mcp` as a custom connector and leave the advanced
client ID and secret fields empty. Anthropic documents the individual and
organization flows in
[Get started with custom connectors using remote MCP](https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp).

Then connect it. You sign in with a real account from this app and approve the
scopes on your own consent screen. Nothing about that step is Anthropic's.

Do not put this server in `claude_desktop_config.json`. That file is for local
stdio servers. This one is remote.

## What the client can ask for

Of your resource scopes, the authorization server metadata lists only the coarse
umbrellas, such as `collections:read` and `collections:write`. The granular
per-resource scopes stay grantable but unlisted. Discovery does not enumerate
your data model.

Consent can only narrow. The signed-in user's `.access()` rules run unchanged
underneath, so the effective permission is the intersection of the two.

## Next

Back to [Connect an AI agent](/docs/guides/connect-an-agent) for the config and
the custom tool. [MCP over OAuth 2.1](/docs/agents/mcp-oauth) covers
registration, consent and token verification in full.
