mirror of
https://github.com/supabase/server.git
synced 2026-09-14 15:28:52 +08:00
docs: add MCP server guide and surface the OAuth entry point in the skill (#154)
* docs: add MCP server guide and surface the OAuth entry point in the skill docs/mcp.md explains the pipeline form for MCP servers (withOAuthProtectedResource before the withSupabase gate), how the public URLs are derived on Edge Functions and configured elsewhere, the Supabase Auth prerequisites, the inline-handler inference gotcha, and the stateless limits. The agent skill gains the @supabase/server/oauth-protected-resource entry point and a docs-table row pointing at the new page. docs(mcp): drop the private sandbox link, match the guide title docs(mcp): address review on the MCP guide - CLI 2.117.0 injects SUPABASE_FUNCTION_SLUG only; SUPABASE_PUBLIC_URL is honored when set but not set by the CLI. - The asymmetric-key requirement comes from withSupabase verifying user JWTs against the JWKS, not from OAuth 2.1. - Document OAuthProtectedResourceConfig, UrlOption, fromSupabaseUrl and the escape hatches in api-reference.md, and link there. - Show withSupabase<Database> and a writing tool, the onerror hook for factory errors, the OPTIONS preflight row, the root-path-without-slug case, and that the one-shot limits belong to the handler, not the library. * docs: list mcp.md in README and complete the metadata row --------- Co-authored-by: Katerina Skroumpelou <sk.katherine@gmail.com>
This commit is contained in:
@@ -531,42 +531,43 @@ No. `@supabase/ssr` handles cookie-based session management for frameworks like
|
||||
|
||||
## Exports
|
||||
|
||||
| Export | What's in it |
|
||||
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
||||
| `@supabase/server` | `withSupabase`, `createSupabaseContext` |
|
||||
| `@supabase/server/core` | `verifyAuth`, `verifyCredentials`, `extractCredentials`, `createContextClient`, `createAdminClient`, `resolveEnv` |
|
||||
| `@supabase/server/adapters/hono` | `withSupabase` (Hono middleware) |
|
||||
| `@supabase/server/adapters/h3` | `withSupabase` (H3 / Nuxt middleware) |
|
||||
| `@supabase/server/adapters/elysia` | `withSupabase` (Elysia plugin) |
|
||||
| `@supabase/server/adapters/nestjs` | `withSupabase` (NestJS guard), `SupabaseCtx` (param decorator) |
|
||||
| `@supabase/server/middleware/client` | **Alpha.** `withSupabaseClient` (RLS-scoped `ctx.supabase` client) |
|
||||
| `@supabase/server/middleware/admin-client` | **Alpha.** `withSupabaseAdminClient` (`ctx.supabaseAdmin`, bypasses RLS) |
|
||||
| `@supabase/server/middleware/claims` | **Alpha.** `withClaims` (JWKS-verified `ctx.jwtClaims`) |
|
||||
| `@supabase/server/middleware/required-claims` | **Alpha.** `withRequiredClaims` (user-mode auth gate, non-null `ctx.jwtClaims`) |
|
||||
| `@supabase/server/middleware/postgres` | **Alpha.** `withPostgresClient` (RLS-scoped `ctx.postgres` client) |
|
||||
| `@supabase/server/middleware/postgres-admin` | **Alpha.** `withPostgresAdminClient` (`ctx.postgresAdmin`, bypasses RLS) |
|
||||
| `@supabase/server/oauth-protected-resource` | **Alpha.** `withOAuthProtectedResource`, `fromSupabaseUrl`, `resourceMetadataResponse`, `unauthorizedResponse` |
|
||||
| `@supabase/server/peer/supabase-js` | Re-exported `supabase-js` types (`SupabaseClient`, `PostgrestError`, …) |
|
||||
| Export | What's in it |
|
||||
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `@supabase/server` | `withSupabase`, `createSupabaseContext` |
|
||||
| `@supabase/server/core` | `verifyAuth`, `verifyCredentials`, `extractCredentials`, `createContextClient`, `createAdminClient`, `resolveEnv` |
|
||||
| `@supabase/server/adapters/hono` | `withSupabase` (Hono middleware) |
|
||||
| `@supabase/server/adapters/h3` | `withSupabase` (H3 / Nuxt middleware) |
|
||||
| `@supabase/server/adapters/elysia` | `withSupabase` (Elysia plugin) |
|
||||
| `@supabase/server/adapters/nestjs` | `withSupabase` (NestJS guard), `SupabaseCtx` (param decorator) |
|
||||
| `@supabase/server/middleware/client` | **Alpha.** `withSupabaseClient` (RLS-scoped `ctx.supabase` client) |
|
||||
| `@supabase/server/middleware/admin-client` | **Alpha.** `withSupabaseAdminClient` (`ctx.supabaseAdmin`, bypasses RLS) |
|
||||
| `@supabase/server/middleware/claims` | **Alpha.** `withClaims` (JWKS-verified `ctx.jwtClaims`) |
|
||||
| `@supabase/server/middleware/required-claims` | **Alpha.** `withRequiredClaims` (user-mode auth gate, non-null `ctx.jwtClaims`) |
|
||||
| `@supabase/server/middleware/postgres` | **Alpha.** `withPostgresClient` (RLS-scoped `ctx.postgres` client) |
|
||||
| `@supabase/server/middleware/postgres-admin` | **Alpha.** `withPostgresAdminClient` (`ctx.postgresAdmin`, bypasses RLS) |
|
||||
| `@supabase/server/oauth-protected-resource` | **Alpha.** `withOAuthProtectedResource`, `fromSupabaseUrl`, `resourceMetadataResponse`, `unauthorizedResponse`; see [`docs/mcp.md`](docs/mcp.md) |
|
||||
| `@supabase/server/peer/supabase-js` | Re-exported `supabase-js` types (`SupabaseClient`, `PostgrestError`, …) |
|
||||
|
||||
## Documentation
|
||||
|
||||
| Question | Doc file |
|
||||
| ------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
||||
| How do I create a basic endpoint? | [`docs/getting-started.md`](docs/getting-started.md) |
|
||||
| What auth modes are available? Array syntax? Named keys? | [`docs/auth-modes.md`](docs/auth-modes.md) |
|
||||
| Which framework adapters exist? How do I contribute one? | [`src/adapters/README.md`](src/adapters/README.md) |
|
||||
| How do I use this with Hono? | [`docs/adapters/hono.md`](docs/adapters/hono.md) |
|
||||
| How do I use this with H3 / Nuxt? | [`docs/adapters/h3.md`](docs/adapters/h3.md) |
|
||||
| How do I use this with Elysia? | [`docs/adapters/elysia.md`](docs/adapters/elysia.md) |
|
||||
| How do I use this with NestJS? | [`docs/adapters/nestjs.md`](docs/adapters/nestjs.md) |
|
||||
| How do I use low-level primitives for custom flows? | [`docs/core-primitives.md`](docs/core-primitives.md) |
|
||||
| How do environment variables work across runtimes? | [`docs/environment-variables.md`](docs/environment-variables.md) |
|
||||
| How do I handle errors? What codes exist? | [`docs/error-handling.md`](docs/error-handling.md) |
|
||||
| How do I get typed database queries? | [`docs/typescript-generics.md`](docs/typescript-generics.md) |
|
||||
| How do I run raw SQL scoped to the caller by RLS? | [`docs/postgres.md`](docs/postgres.md) |
|
||||
| How do I use this with `@supabase/ssr` (Next.js, SvelteKit, Remix)? | [`docs/ssr-frameworks.md`](docs/ssr-frameworks.md) |
|
||||
| What's the complete API surface? | [`docs/api-reference.md`](docs/api-reference.md) |
|
||||
| Does this library support legacy API keys or HS256 JWTs? | [`docs/auth-modes.md`](docs/auth-modes.md#legacy-keys-and-jwts-are-not-supported) |
|
||||
| Question | Doc file |
|
||||
| ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
||||
| How do I create a basic endpoint? | [`docs/getting-started.md`](docs/getting-started.md) |
|
||||
| What auth modes are available? Array syntax? Named keys? | [`docs/auth-modes.md`](docs/auth-modes.md) |
|
||||
| Which framework adapters exist? How do I contribute one? | [`src/adapters/README.md`](src/adapters/README.md) |
|
||||
| How do I use this with Hono? | [`docs/adapters/hono.md`](docs/adapters/hono.md) |
|
||||
| How do I use this with H3 / Nuxt? | [`docs/adapters/h3.md`](docs/adapters/h3.md) |
|
||||
| How do I use this with Elysia? | [`docs/adapters/elysia.md`](docs/adapters/elysia.md) |
|
||||
| How do I use this with NestJS? | [`docs/adapters/nestjs.md`](docs/adapters/nestjs.md) |
|
||||
| How do I use low-level primitives for custom flows? | [`docs/core-primitives.md`](docs/core-primitives.md) |
|
||||
| How do environment variables work across runtimes? | [`docs/environment-variables.md`](docs/environment-variables.md) |
|
||||
| How do I handle errors? What codes exist? | [`docs/error-handling.md`](docs/error-handling.md) |
|
||||
| How do I get typed database queries? | [`docs/typescript-generics.md`](docs/typescript-generics.md) |
|
||||
| How do I run raw SQL scoped to the caller by RLS? | [`docs/postgres.md`](docs/postgres.md) |
|
||||
| How do I use this with `@supabase/ssr` (Next.js, SvelteKit, Remix)? | [`docs/ssr-frameworks.md`](docs/ssr-frameworks.md) |
|
||||
| How do I build an MCP server my users connect to (OAuth discovery, RLS-scoped tools)? | [`docs/mcp.md`](docs/mcp.md) |
|
||||
| What's the complete API surface? | [`docs/api-reference.md`](docs/api-reference.md) |
|
||||
| Does this library support legacy API keys or HS256 JWTs? | [`docs/auth-modes.md`](docs/auth-modes.md#legacy-keys-and-jwts-are-not-supported) |
|
||||
|
||||
## Development
|
||||
|
||||
|
||||
@@ -443,6 +443,62 @@ Defaults to the `SUPABASE_DB_URL` environment variable.
|
||||
|
||||
---
|
||||
|
||||
## @supabase/server/oauth-protected-resource
|
||||
|
||||
> **Alpha.** The config shape, the contributed context key, and the metadata
|
||||
> route may change in a minor release.
|
||||
|
||||
Also re-exported from `@supabase/server`. See [`docs/mcp.md`](mcp.md) for the MCP server walkthrough.
|
||||
|
||||
### withOAuthProtectedResource
|
||||
|
||||
```ts
|
||||
function withOAuthProtectedResource(
|
||||
config?: OAuthProtectedResourceConfig,
|
||||
): Entry<{ oauthProtectedResource: OAuthProtectedResourceContribution }>
|
||||
function withOAuthProtectedResource(handler: FetchHandler): FetchHandler
|
||||
function withOAuthProtectedResource(
|
||||
config: OAuthProtectedResourceConfig,
|
||||
handler: FetchHandler,
|
||||
): FetchHandler
|
||||
```
|
||||
|
||||
OAuth 2.1 Protected Resource behavior (RFC 9728) for the wrapped handler. Answers `GET` and `OPTIONS` on any path ending in `/oauth-protected-resource` with the metadata document and a permissive CORS preflight; adds `WWW-Authenticate: Bearer resource_metadata="…"` to a `401` from below unless the handler already set that header; passes everything else through. Runs before the `withSupabase` gate; placing it directly after `withSupabase` with a credentialed auth mode is refused when the stack is built.
|
||||
|
||||
Contributes `ctx.oauthProtectedResource.resourceMetadataUrl`, the resolved absolute URL of the metadata document.
|
||||
|
||||
### OAuthProtectedResourceConfig
|
||||
|
||||
| Option | Type | Default on Supabase Edge Functions | Default elsewhere |
|
||||
| --------------------- | ----------- | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `resourceServer` | `UrlOption` | Public origin from `X-Forwarded-*` (or `SUPABASE_PUBLIC_URL`) + `/functions/v1/{SUPABASE_FUNCTION_SLUG}` | None. Throws `MissingResourceServerError` (`MISSING_RESOURCE_SERVER`). |
|
||||
| `authorizationServer` | `UrlOption` | Public origin + `/auth/v1` | `SUPABASE_PUBLIC_URL`, then `SUPABASE_URL`, each + `/auth/v1`. Throws `MissingAuthorizationServerError` (`MISSING_AUTHORIZATION_SERVER`) if neither is set. |
|
||||
|
||||
`UrlOption` is `string | ((req: Request) => string)`. Without `SUPABASE_FUNCTION_SLUG` the resource path is reconstructed from the request path with `/functions/v1` restored; a request at the root path with no slug throws `MissingResourceServerError`.
|
||||
|
||||
### fromSupabaseUrl
|
||||
|
||||
```ts
|
||||
function fromSupabaseUrl(supabaseUrl: string): string
|
||||
```
|
||||
|
||||
Turns a project URL (`https://<ref>.supabase.co`) into its Auth issuer (`…/auth/v1`) for `authorizationServer`. Tolerates a value that already carries the `/auth/v1` path.
|
||||
|
||||
### resourceMetadataResponse / unauthorizedResponse
|
||||
|
||||
```ts
|
||||
function resourceMetadataResponse(
|
||||
req: Request,
|
||||
options?: { resource?: string; authorizationServers?: string[] },
|
||||
): Response
|
||||
function unauthorizedResponse(
|
||||
req: Request,
|
||||
options?: { resourceMetadataUrl?: string },
|
||||
): Response
|
||||
```
|
||||
|
||||
The building blocks behind the middleware, for custom routing. Defaults derive from the request as above.
|
||||
|
||||
## Types
|
||||
|
||||
### AuthMode
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
# MCP servers
|
||||
|
||||
> **Alpha.** `withOAuthProtectedResource` and composing `withSupabase` as a
|
||||
> `pipeline` entry track `@supabase/middleware` 0.x. The config shape, the
|
||||
> contributed context key, and the metadata route may change in a minor
|
||||
> release. The nested `withOAuthProtectedResource(withSupabase(config, handler))`
|
||||
> form is stable.
|
||||
|
||||
An MCP server your app exposes to its users is an HTTP endpoint that MCP clients (Claude, ChatGPT, Cursor, VS Code, Claude Code) call after an OAuth 2.1 flow. `@supabase/server` covers the two Supabase-specific parts: OAuth discovery for the client, and turning the user's token into an RLS-scoped Supabase client for your tools. The MCP transport and the tools come from any MCP library.
|
||||
|
||||
```ts
|
||||
import { pipeline } from '@supabase/middleware'
|
||||
import { withOAuthProtectedResource, withSupabase } from '@supabase/server'
|
||||
import { createMcpHandler, McpServer } from '@modelcontextprotocol/server'
|
||||
import { z } from 'zod/v4'
|
||||
import type { Database } from './database.types'
|
||||
|
||||
export default {
|
||||
fetch: pipeline(
|
||||
[withOAuthProtectedResource(), withSupabase<Database>({ auth: 'user' })],
|
||||
async (req, { supabase }) => {
|
||||
const handler = createMcpHandler(
|
||||
() => {
|
||||
const server = new McpServer({ name: 'todos', version: '0.1.0' })
|
||||
server.registerTool(
|
||||
'create_todo',
|
||||
{
|
||||
description: 'Create a todo',
|
||||
inputSchema: z.object({ title: z.string() }),
|
||||
},
|
||||
async ({ title }) => {
|
||||
const { data, error } = await supabase
|
||||
.from('todos')
|
||||
.insert({ title })
|
||||
.select()
|
||||
.single()
|
||||
if (error) throw new Error(error.message)
|
||||
return { content: [{ type: 'text', text: JSON.stringify(data) }] }
|
||||
},
|
||||
)
|
||||
return server
|
||||
},
|
||||
// Factory errors (duplicate tool name, failed schema fetch) surface as a
|
||||
// bare 500 otherwise; log them so they reach the function logs.
|
||||
{ onerror: (error) => console.error('MCP request failed', error) },
|
||||
)
|
||||
return handler.fetch(req)
|
||||
},
|
||||
),
|
||||
}
|
||||
```
|
||||
|
||||
Pass the `Database` generic (from `supabase gen types typescript`) when tools write. Without it the client is `SupabaseClient<unknown>` and `insert({ title })` fails type-checking with the argument resolved to `never[]`; reads compile either way.
|
||||
|
||||
## The two entries
|
||||
|
||||
Order matters.
|
||||
|
||||
`withOAuthProtectedResource()` runs **before** the auth gate, so it sees unauthenticated requests. It does two things:
|
||||
|
||||
| Request | Response |
|
||||
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| `GET {resource}/oauth-protected-resource` | RFC 9728 Protected Resource Metadata (`resource`, `authorization_servers`, `bearer_methods_supported`) |
|
||||
| `OPTIONS {resource}/oauth-protected-resource` | `204` with permissive CORS headers, so browser-based clients can read the document cross-origin |
|
||||
| Any response from below with status `401` | Adds `WWW-Authenticate: Bearer resource_metadata="…"` unless the handler already set one |
|
||||
|
||||
That header is how a client that hit a `401` finds the metadata, and through it the authorization server, without guessing URLs. It is generic OAuth middleware; the only MCP-specific detail is that the preflight allows the `mcp-protocol-version` request header.
|
||||
|
||||
`withSupabase({ auth: 'user' })` is the gate. Requests without a valid user JWT get a `401` (which the entry above enriches); requests with one reach the handler with `ctx.supabase` scoped to that user, so RLS applies to everything the tools do.
|
||||
|
||||
The handler is passed inline. Passing a separately declared function typed `(req: Request, ctx: SupabaseContext) => Promise<Response>` makes TypeScript collapse the inferred context to `object` (TS2345); wrap it as `(req, ctx) => handleMcp(req, ctx)` instead.
|
||||
|
||||
## URLs
|
||||
|
||||
On Supabase Edge Functions the metadata is derived with no configuration: the public origin from the gateway's `X-Forwarded-*` headers (`SUPABASE_PUBLIC_URL` wins when set, but the CLI does not set it), the path as `/functions/v1/{SUPABASE_FUNCTION_SLUG}`, and the issuer as `{origin}/auth/v1`. Supabase CLI 2.117.0 or later injects the slug locally. Without a slug the path is reconstructed from the request, which works for a function served at `/functions/v1/{name}`; a function served at the root path `/` with no slug throws `MISSING_RESOURCE_SERVER`, because there is no function segment to restore.
|
||||
|
||||
Anywhere else, a Next.js route handler, a Worker, a plain server, the app's origin is unrelated to the project's, so pass both URLs:
|
||||
|
||||
```ts
|
||||
import { withOAuthProtectedResource, fromSupabaseUrl } from '@supabase/server'
|
||||
|
||||
withOAuthProtectedResource({
|
||||
resourceServer: (req) => new URL(req.url).origin + '/api/mcp',
|
||||
authorizationServer: fromSupabaseUrl('https://<ref>.supabase.co'),
|
||||
})
|
||||
```
|
||||
|
||||
- `resourceServer`: the public URL of this endpoint. Required off Edge Functions; `MissingResourceServerError` (`MISSING_RESOURCE_SERVER`) otherwise.
|
||||
- `authorizationServer`: the OAuth issuer. Falls back to `SUPABASE_PUBLIC_URL`, then `SUPABASE_URL`, each with `/auth/v1`; `MissingAuthorizationServerError` (`MISSING_AUTHORIZATION_SERVER`) if neither is set. `fromSupabaseUrl(projectUrl)` builds it from a project URL. A non-Supabase OAuth 2.1 server (Clerk, WorkOS, Auth0) works too.
|
||||
|
||||
Both accept a string or `(req: Request) => string` (`UrlOption`). The full config:
|
||||
|
||||
| Option | Type | Default on Edge Functions | Default elsewhere |
|
||||
| --------------------- | ----------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| `resourceServer` | `UrlOption` | `{public origin}/functions/v1/{slug}` | none; throws `MissingResourceServerError` |
|
||||
| `authorizationServer` | `UrlOption` | `{public origin}/auth/v1` | `SUPABASE_PUBLIC_URL`, then `SUPABASE_URL`, each `+ /auth/v1`; else throws `MissingAuthorizationServerError` |
|
||||
|
||||
The middleware contributes `ctx.oauthProtectedResource.resourceMetadataUrl`, the resolved metadata URL, to the downstream context.
|
||||
|
||||
## Supabase Auth prerequisites
|
||||
|
||||
The project must have the OAuth 2.1 server enabled, dynamic client registration on (MCP clients register themselves), an asymmetric signing key (ES256 or RS256), and a consent screen hosted in the app's frontend. The signing key requirement comes from this library, not from OAuth: `withSupabase({ auth: 'user' })` verifies user JWTs against the project JWKS and rejects legacy HS256 tokens (see [`docs/auth-modes.md`](auth-modes.md#legacy-keys-and-jwts-are-not-supported)). On Edge Functions set `verify_jwt = false` for the function in `config.toml`; the gate does the verification, and the gateway must let the unauthenticated discovery request through.
|
||||
|
||||
## Escape hatches
|
||||
|
||||
For custom routing, the pieces behind the middleware are exported on `@supabase/server/oauth-protected-resource`: `resourceMetadataResponse(req, options?)` returns the metadata document, `unauthorizedResponse(req, options?)` returns a `401` with the `WWW-Authenticate` header.
|
||||
|
||||
## Limits
|
||||
|
||||
The one-request, one-response shape above is the handler's, not the library's: building a `McpServer` per request with `createMcpHandler` gives Streamable HTTP in its simplest form, with no server-initiated stream, so no MCP sampling and no elicitations that need an open channel. `@supabase/server` does not constrain the transport; a stateful transport composes the same way.
|
||||
|
||||
## See also
|
||||
|
||||
- [Deploy MCP servers](https://supabase.com/docs/guides/ai-tools/byo-mcp) on supabase.com, the end-to-end guide
|
||||
- [MCP Server block](https://supabase.com/library/docs/headless/mcp-server), an installable Edge Function built on this
|
||||
- [`docs/api-reference.md`](api-reference.md#withoauthprotectedresource) for `OAuthProtectedResourceConfig` and the error catalogue
|
||||
@@ -34,11 +34,12 @@ Server-side utilities for Supabase. Handles auth, client creation, and context i
|
||||
|
||||
## Entry points
|
||||
|
||||
| Import | Deno / Edge Functions | Provides |
|
||||
| -------------------------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
|
||||
| `@supabase/server` | `npm:@supabase/server` | `withSupabase`, `createSupabaseContext`, types, errors |
|
||||
| `@supabase/server/core` | `npm:@supabase/server/core` | `verifyAuth`, `verifyCredentials`, `extractCredentials`, `resolveEnv`, `createContextClient`, `createAdminClient` |
|
||||
| `@supabase/server/adapters/hono` | `npm:@supabase/server/adapters/hono` | `withSupabase` (Hono middleware variant) |
|
||||
| Import | Deno / Edge Functions | Provides |
|
||||
| ------------------------------------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `@supabase/server` | `npm:@supabase/server` | `withSupabase`, `createSupabaseContext`, types, errors |
|
||||
| `@supabase/server/core` | `npm:@supabase/server/core` | `verifyAuth`, `verifyCredentials`, `extractCredentials`, `resolveEnv`, `createContextClient`, `createAdminClient` |
|
||||
| `@supabase/server/adapters/hono` | `npm:@supabase/server/adapters/hono` | `withSupabase` (Hono middleware variant) |
|
||||
| `@supabase/server/oauth-protected-resource` | `npm:@supabase/server/oauth-protected-resource` | **Alpha.** `withOAuthProtectedResource`, `fromSupabaseUrl`, `resourceMetadataResponse`, `unauthorizedResponse` — OAuth 2.1 discovery for MCP servers; see `docs/mcp.md` |
|
||||
|
||||
## Quick starts
|
||||
|
||||
@@ -413,17 +414,18 @@ The full documentation lives in the `docs/` directory of the `@supabase/server`
|
||||
- **If working inside the SDK repo:** `docs/` is at the project root.
|
||||
- **If the package is installed as a dependency:** look in `node_modules/@supabase/server/docs/`.
|
||||
|
||||
| Question | Doc file |
|
||||
| ------------------------------------------------------------------- | ------------------------------- |
|
||||
| How do I create a basic endpoint? | `docs/getting-started.md` |
|
||||
| What auth modes are available? Array syntax? Named keys? | `docs/auth-modes.md` |
|
||||
| Which framework adapters exist? How do I contribute one? | `src/adapters/README.md` |
|
||||
| How do I use this with Hono? | `docs/adapters/hono.md` |
|
||||
| How do I use this with H3 / Nuxt? | `docs/adapters/h3.md` |
|
||||
| How do I use low-level primitives for custom flows? | `docs/core-primitives.md` |
|
||||
| How do environment variables work across runtimes? | `docs/environment-variables.md` |
|
||||
| How do I handle errors? What codes exist? | `docs/error-handling.md` |
|
||||
| How do I get typed database queries? | `docs/typescript-generics.md` |
|
||||
| How do I use this with `@supabase/ssr` (Next.js, SvelteKit, Remix)? | `docs/ssr-frameworks.md` |
|
||||
| What's the complete API surface? | `docs/api-reference.md` |
|
||||
| What security decisions does this package make? | `docs/security.md` |
|
||||
| Question | Doc file |
|
||||
| ------------------------------------------------------------------------------------- | ------------------------------- |
|
||||
| How do I create a basic endpoint? | `docs/getting-started.md` |
|
||||
| What auth modes are available? Array syntax? Named keys? | `docs/auth-modes.md` |
|
||||
| Which framework adapters exist? How do I contribute one? | `src/adapters/README.md` |
|
||||
| How do I use this with Hono? | `docs/adapters/hono.md` |
|
||||
| How do I use this with H3 / Nuxt? | `docs/adapters/h3.md` |
|
||||
| How do I use low-level primitives for custom flows? | `docs/core-primitives.md` |
|
||||
| How do environment variables work across runtimes? | `docs/environment-variables.md` |
|
||||
| How do I handle errors? What codes exist? | `docs/error-handling.md` |
|
||||
| How do I get typed database queries? | `docs/typescript-generics.md` |
|
||||
| How do I use this with `@supabase/ssr` (Next.js, SvelteKit, Remix)? | `docs/ssr-frameworks.md` |
|
||||
| How do I build an MCP server my users connect to (OAuth discovery, RLS-scoped tools)? | `docs/mcp.md` |
|
||||
| What's the complete API surface? | `docs/api-reference.md` |
|
||||
| What security decisions does this package make? | `docs/security.md` |
|
||||
|
||||
Reference in New Issue
Block a user