Files
supabase/apps/ui-library/content/docs/tanstack/headless-app.mdx
19d7233580 feat(ui-library): add headless app block for TanStack Start (#49579)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Feature — a new UI Library block. Stacked on #49573 (already in main)

Fixes AI-1064

## What is the new behavior?

Adds `headless-app-tanstack`: customers sign in, authorize an MCP
client, and use the product through agent tool calls. It composes the
existing Password-Based Auth, OAuth Consent, and MCP Server blocks.

- `/agents` provides a copyable connection prompt, lists OAuth
authorizations, and lets customers revoke access.
- The shared MCP runtime exposes `whoami` plus example task CRUD tools.
Tools use the caller's Supabase client, with database grants and RLS
enforcing ownership.
- A root-level `supabase/` directory supplies local Auth/OAuth
configuration, a declarative tasks schema, and Edge Function files,
including `.env.example`.
- Docs cover local setup, signing keys, migrations, environment
configuration, deployment, and extending the tools.
`/example/headless-app` previews the sign-in, consent, connect, and
connected states.

Shared block fixes make a fresh install work:

- Explicit public URL resolution fixes OAuth discovery in local Edge
Runtime when middleware runtime detection fails. Both external OAuth
access tokens and ordinary authenticated app session tokens remain
supported; embedded agents do not need an additional consent flow.
- Registry targets keep backend files outside `src/`, and generated
consumer routes omit source-only TypeScript suppressions.
- Signup respects `auth.email.enable_confirmations`; sign-in/signup
preserve the return destination. Missing consent IDs retain the existing
error state without serializing `null` into the URL.

## How to test

Use the UI Library on **staging** and follow the block pages'
instructions.

1. Open the **Headless App** block page for TanStack Start. Install it
into a fresh app and follow the setup instructions through connecting an
MCP client.
2. Sign up, open `/agents`, and use the connection prompt to authorize a
client. Call `whoami`, then create, list, update, and delete a task.
3. Confirm the client appears on `/agents`. Revoke access and verify it
disappears and token refresh fails. An existing access token can
continue working until it expires.
4. Follow the **MCP Server** block page's embedded-agent instructions
using an authenticated app session. Confirm tools work without another
OAuth consent flow and `whoami` returns `client_id: null`.
5. With a second user, confirm each user can only access their own
tasks. Check that signup behaves correctly for the configured
email-confirmation setting.
6. Check the Headless App preview states and run the installed app's
typecheck and production build.

## Validation performed

Fresh local installation and browser/SDK verification passed: 26 live
MCP/Data API checks, 10 Deno tests, and 7 connection-page component
tests. Also passed UI Library typecheck, targeted lint,
registry/Markdown builds, and fresh consumer typecheck/production build.
Both OAuth and ordinary app session authentication were exercised.

Hosted deployment and consuming the confirmation-email link were not
tested.



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a TanStack Headless App example with sign-in, OAuth consent, MCP
connection, and connected-agent screens.
- Added task management tools for listing, creating, updating, and
deleting tasks through MCP.
- Added connected-agent management, including server URL and prompt
copying, refresh, and access revocation.
  - Added a new Headless App registry block and documentation.

- **Bug Fixes**
- Preserved intended destinations through sign-up, email confirmation,
and protected-route login redirects.
- Improved OAuth discovery URL handling across forwarded-host
deployments.

- **Documentation**
- Updated setup, environment, deployment, and Supabase CLI guidance for
headless apps and MCP servers.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Saxon Fletcher <SaxonF@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: repro <repro@local>
Co-authored-by: Raúl Barroso <code@raulb.dev>
2026-09-14 10:30:26 +10:00

83 lines
2.7 KiB
Plaintext

---
title: Headless App
description: A backend with an agent as the primary interface
---
A headless app uses an AI agent as its primary interface. Users sign in and
approve access in the browser, then work through their agent using MCP tools.
This starter includes task tools and a database with Row Level Security (RLS)
that limits each user to their own data.
<BlockPreview name="headless-app" />
## Installation
Create a TanStack Start app:
```bash
pnpm dlx shadcn@latest init --template start --name my-app
cd my-app
```
Install the headless app:
<BlockItem name="headless-app-tanstack" showOpenInV0={false} />
Merge `supabase/config.toml` if you already have project settings. Add
`"supabase/functions/**"` to your app's `tsconfig.json` exclusions.
## Customize
- Set `VITE_PRODUCT_NAME` in `.env.local` and edit the generated pages and components.
- Define your tables, grants, and RLS policies in `supabase/schemas/`.
- Replace `supabase/functions/mcp-server/tools/tasks.ts` with your app's operations
and register them in `tools/index.ts`. Use the supplied user-scoped `supabase` client.
- Set `MCP_SERVER_NAME` and `MCP_SERVER_DESCRIPTION` with `supabase secrets set`.
## Deploy
Deploy the frontend using a [TanStack Start hosting adapter](https://tanstack.com/start/latest/docs/framework/react/guide/hosting).
Set these environment variables in your hosting provider before building:
```env
VITE_SUPABASE_URL=https://<project-ref>.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=<publishable-key>
VITE_PRODUCT_NAME="Your app"
```
In `supabase/config.toml`, set `auth.site_url` to your deployed HTTPS origin,
update `auth.additional_redirect_urls` for your app's destinations, and set
`auth.email.enable_confirmations = true`. Keep the supplied OAuth and function settings.
Use an ES256 or RS256 signing key in your project's
[JWT Keys](https://supabase.com/dashboard/project/_/settings/jwt).
In [Email Templates](https://supabase.com/dashboard/project/_/auth/templates),
use this confirmation link for sign-up and change `type=email` to `type=recovery`
for password reset:
```html
<a
href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email&next={{ .RedirectTo | urlquery }}"
>Confirm email</a
>
```
With the [Supabase CLI](https://supabase.com/docs/guides/local-development/cli/getting-started)
(2.117.0 or later) and Docker installed, generate a migration:
```bash
supabase db diff -f create_tasks
```
Review the migration, including grants and RLS policies, then deploy:
```bash
supabase link --project-ref <project-ref>
supabase db push
supabase config push
supabase functions deploy mcp-server
```
Open `/agents` on your deployed app, sign in, and copy the server URL into an
MCP client that supports HTTP and OAuth. Approve access to start using your tools.