mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 01:15:03 +03:00
docs: drop alpha labels and pin server and middleware imports to a major (#51031)
## Problem `@supabase/middleware` ships as 1.0.0. The docs still label the `pipeline` entry form of `withSupabase` alpha, and several snippets import `npm:@supabase/server` and `npm:@supabase/middleware` with no version or with a `^0.5.0` pin. A snippet without a version leaves readers and tools to guess one, and a guessed version fails on deploy. ## Solution - Removes the alpha wording from the middleware reference intro and usage examples, the server frameworks partial, and the Bring your own MCP guide. The `@supabase/server` 1.6.0 floor stays. - Pins every `npm:@supabase/server` and `npm:@supabase/middleware` import in the guides to a major range, `@1`, following the `npm:@supabase/supabase-js@2` convention in Managing dependencies. - Bumps the authenticated-mcp-server example to middleware `^1.0.0` and server `^1.9.0`. ~~Blocked by supabase/middleware#49. The `@1` range resolves once 1.0.0 is on npm.~~ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated authentication, API key, and MCP examples to use versioned Supabase server and middleware packages. * Clarified that pipeline and nested composition behave the same, and that both require `@supabase/server` 1.6.0 or later. * Removed alpha-status labels from `withSupabase` guidance while retaining the 1.6.0 minimum-version requirement. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
b59447d310
commit
2013ebf417
14 files changed
+41
-52
No files matched your search
@@ -196,8 +196,8 @@ Replace the contents of `supabase/functions/mcp/index.ts`. Compared with the pub
|
||||
import 'jsr:@supabase/functions-js/edge-runtime.d.ts'
|
||||
|
||||
import { createMcpHandler, McpServer } from 'npm:@modelcontextprotocol/server@^2.0.0'
|
||||
import { pipeline } from 'npm:@supabase/middleware@^0.5.0'
|
||||
import { withOAuthProtectedResource, withSupabase } from 'npm:@supabase/server@^1.6.0'
|
||||
import { pipeline } from 'npm:@supabase/middleware@1'
|
||||
import { withOAuthProtectedResource, withSupabase } from 'npm:@supabase/server@1'
|
||||
import { z } from 'npm:zod@^4.3.6'
|
||||
|
||||
import type { Database } from './database.types.ts'
|
||||
@@ -254,7 +254,7 @@ Deno.serve(
|
||||
|
||||
<Admonition type="note">
|
||||
|
||||
Composing `withSupabase` as a `pipeline` entry is alpha and tracks `@supabase/middleware` 0.x. The nested form, `withOAuthProtectedResource(withSupabase({ auth: 'user' }, handler))`, is stable and behaves the same. Both need `@supabase/server` 1.6.0 or later.
|
||||
The nested form, `withOAuthProtectedResource(withSupabase({ auth: 'user' }, handler))`, behaves the same. Both need `@supabase/server` 1.6.0 or later.
|
||||
|
||||
</Admonition>
|
||||
|
||||
|
||||
@@ -84,8 +84,8 @@ When building your own MCP server, integrate with Supabase Auth to authenticate
|
||||
On Supabase Edge Functions, or any runtime with a `fetch`-style handler, [`@supabase/server`](/docs/reference/server/introduction) does the OAuth plumbing for you. `withOAuthProtectedResource()` publishes the protected resource metadata and the `WWW-Authenticate` challenge that MCP clients use to find your Auth server; `withSupabase({ auth: 'user' })` verifies the token and gives your tools a client scoped to that user:
|
||||
|
||||
```ts
|
||||
import { pipeline } from 'npm:@supabase/middleware@^0.5.0'
|
||||
import { withOAuthProtectedResource, withSupabase } from 'npm:@supabase/server@^1.6.0'
|
||||
import { pipeline } from 'npm:@supabase/middleware@1'
|
||||
import { withOAuthProtectedResource, withSupabase } from 'npm:@supabase/server@1'
|
||||
|
||||
Deno.serve(
|
||||
pipeline(
|
||||
|
||||
@@ -21,7 +21,7 @@ For how authorization headers and the `verify_jwt` platform check work under the
|
||||
Functions called by signed-in users — typically through `supabase.functions.invoke` from the client — send the user's session JWT on the `Authorization` header. Keep `verify_jwt = true` (the default) so the platform validates the JWT before your handler runs, then use `auth: 'user'` to get `ctx.supabase` already scoped to the caller's RLS policies.
|
||||
|
||||
```ts
|
||||
import { withSupabase } from 'npm:@supabase/server'
|
||||
import { withSupabase } from 'npm:@supabase/server@1'
|
||||
|
||||
export default {
|
||||
fetch: withSupabase({ auth: 'user' }, async (_req, ctx) => {
|
||||
@@ -43,7 +43,7 @@ export default {
|
||||
Cron jobs, workers, `pg_net`, or another Edge Function make calls with a secret key on the `apikey` header rather than a user JWT. Disable `verify_jwt` and use `auth: 'secret'` to validate the key against any secret key from your [dashboard](/dashboard/project/_/settings/api-keys). You get `ctx.supabaseAdmin` for privileged work.
|
||||
|
||||
```ts
|
||||
import { withSupabase } from 'npm:@supabase/server'
|
||||
import { withSupabase } from 'npm:@supabase/server@1'
|
||||
|
||||
export default {
|
||||
fetch: withSupabase({ auth: 'secret' }, async (_req, ctx) => {
|
||||
@@ -71,7 +71,7 @@ verify_jwt = false
|
||||
```
|
||||
|
||||
```ts
|
||||
import { withSupabase } from 'npm:@supabase/server'
|
||||
import { withSupabase } from 'npm:@supabase/server@1'
|
||||
|
||||
export default {
|
||||
fetch: withSupabase({ auth: 'none' }, async () => {
|
||||
@@ -88,7 +88,7 @@ export default {
|
||||
External providers like Stripe or GitHub don't send Supabase credentials. They sign the request body with their own shared secret. Use `auth: 'none'` to skip the SDK's credential check, then verify the provider's signature inside the handler. Keep `verify_jwt = false`.
|
||||
|
||||
```ts
|
||||
import { withSupabase } from 'npm:@supabase/server'
|
||||
import { withSupabase } from 'npm:@supabase/server@1'
|
||||
import Stripe from 'npm:stripe'
|
||||
|
||||
const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!)
|
||||
@@ -134,7 +134,7 @@ export default {
|
||||
Functions that answer both users and internal callers take an array on `auth`. Modes are tried in order. The first match wins, and `ctx.authMode` tells you which matched.
|
||||
|
||||
```ts
|
||||
import { withSupabase } from 'npm:@supabase/server'
|
||||
import { withSupabase } from 'npm:@supabase/server@1'
|
||||
|
||||
export default {
|
||||
fetch: withSupabase({ auth: ['user', 'secret'] }, async (req, ctx) => {
|
||||
@@ -154,7 +154,7 @@ export default {
|
||||
To shape the 401 response yourself, use `createSupabaseContext` instead of `withSupabase`. It returns a `{ data, error }` tuple so you stay in control.
|
||||
|
||||
```ts
|
||||
import { createSupabaseContext } from 'npm:@supabase/server'
|
||||
import { createSupabaseContext } from 'npm:@supabase/server@1'
|
||||
|
||||
export default {
|
||||
fetch: async (req: Request) => {
|
||||
|
||||
@@ -246,7 +246,7 @@ export const supabaseAdmin = createClient(
|
||||
Don't read the key from the environment inside an Edge Function. Use the [`@supabase/server`](/docs/guides/functions/auth) SDK instead. It verifies the caller's secret key for you and hands back a privileged client on `ctx`, so the key never appears in your code.
|
||||
|
||||
```ts supabase/functions/roster/index.ts
|
||||
import { withSupabase } from 'npm:@supabase/server'
|
||||
import { withSupabase } from 'npm:@supabase/server@1'
|
||||
|
||||
export default {
|
||||
fetch: withSupabase({ auth: 'secret' }, async (_req, ctx) => {
|
||||
|
||||
@@ -149,7 +149,7 @@ Wrap your existing `Deno.serve` handler with `withSupabase` and declare an `auth
|
||||
For a function your users call from the client, use `auth: 'user'`. The SDK validates the user's session JWT and gives you a client scoped to their Row Level Security policies.
|
||||
|
||||
```ts
|
||||
import { withSupabase } from 'npm:@supabase/server'
|
||||
import { withSupabase } from 'npm:@supabase/server@1'
|
||||
|
||||
Deno.serve(
|
||||
withSupabase({ auth: 'user' }, async (_req, ctx) => {
|
||||
@@ -162,7 +162,7 @@ Deno.serve(
|
||||
For a function called by your own backend, a worker, or `pg_net`, use `auth: 'secret'`. The SDK validates the secret key and gives you a client that bypasses Row Level Security.
|
||||
|
||||
```ts
|
||||
import { withSupabase } from 'npm:@supabase/server'
|
||||
import { withSupabase } from 'npm:@supabase/server@1'
|
||||
|
||||
Deno.serve(
|
||||
withSupabase({ auth: 'secret' }, async (_req, ctx) => {
|
||||
@@ -177,7 +177,7 @@ To accept a specific named key instead of `default`, add its name after the mode
|
||||
`withSupabase` returns a standard request handler, so you can also export it as a `fetch` handler instead of passing it to `Deno.serve`:
|
||||
|
||||
```ts
|
||||
import { withSupabase } from 'npm:@supabase/server'
|
||||
import { withSupabase } from 'npm:@supabase/server@1'
|
||||
|
||||
export default {
|
||||
fetch: withSupabase({ auth: 'user' }, async (_req, ctx) => {
|
||||
|
||||
@@ -7,12 +7,6 @@ title: Introduction
|
||||
|
||||
Each middleware can guard the request, edit the response, or contribute typed values to a shared context that later middleware and your handler read. TypeScript checks the composition: a middleware that needs a value from an earlier middleware will not compile unless that middleware runs first.
|
||||
|
||||
<Admonition type="caution" title="Alpha">
|
||||
|
||||
`@supabase/middleware` is in alpha. APIs may change between 0.x releases.
|
||||
|
||||
</Admonition>
|
||||
|
||||
This package contains the engine and the framework-neutral middleware: `withCors` and `withFeatureFlag`. Supabase-specific middleware such as `withClaims`, `withSupabaseClient`, `withSupabaseAdminClient`, `withPostgresClient`, and `withPostgresAdminClient` ships in [`@supabase/server`](/docs/reference/server/introduction).
|
||||
|
||||
### Trust model
|
||||
|
||||
@@ -53,7 +53,7 @@ Each example builds one Fetch handler with `pipeline`. Entries run in array orde
|
||||
|
||||
Without `withCors`, `withSupabase` answers every `OPTIONS` request itself with `204` and wildcard CORS headers (`Access-Control-Allow-Origin: *`). That is enough when you do not need an origin allowlist. A layer that owns CORS must sit before `withSupabase` in the array. Placed after it, the preflight reaches the auth gate and gets a `401`.
|
||||
|
||||
The entry form of `withSupabase` is alpha. It needs `@supabase/server` 1.6.0 or later.
|
||||
The entry form of `withSupabase` needs `@supabase/server` 1.6.0 or later.
|
||||
|
||||
</RefSubLayout.Details>
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ Neither entry answers a CORS preflight, and the short-circuits carry no CORS hea
|
||||
|
||||
`withSupabase(config, handler)` still does the verify-then-reject work for you, and it is not deprecated. It wraps a fetch handler rather than composing into a framework chain, so it does not slot into a bridge. If an endpoint is already a plain fetch handler, staying on `withSupabase()` is a legitimate end state. It is also the only way to get the full `SupabaseContext`, `userClaims` and `authMode` included, behind an auth gate.
|
||||
|
||||
To compose other entries around it, `withSupabase({ auth: 'user' })` with no handler is a `pipeline` entry placed by position. Entries before it run ahead of the auth gate. Entries after it receive the full `SupabaseContext`. Nesting, as in `withSupabase(config, entry(handler))`, still works. The entry form is alpha and needs 1.6.0 or later.
|
||||
To compose other entries around it, `withSupabase({ auth: 'user' })` with no handler is a `pipeline` entry placed by position. Entries before it run ahead of the auth gate. Entries after it receive the full `SupabaseContext`. Nesting, as in `withSupabase(config, entry(handler))`, still works. The entry form needs 1.6.0 or later.
|
||||
|
||||
```ts
|
||||
import { pipeline } from '@supabase/middleware'
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
},
|
||||
{
|
||||
"path": "registry/default/blocks/mcp/supabase/functions/mcp/index.ts",
|
||||
"content": "import 'jsr:@supabase/functions-js@2.108.2/edge-runtime.d.ts'\n\nimport { createMcpHandler, McpServer } from 'npm:@modelcontextprotocol/server@2.0.0'\nimport { pipeline } from 'npm:@supabase/middleware@0.5.0'\nimport {\n withOAuthProtectedResource,\n withSupabase,\n type SupabaseContext,\n} from 'npm:@supabase/server@1.6.0'\n\nimport { registerTools, type ToolContext } from './tools/index.ts'\n\n// An MCP server as a single Supabase Edge Function, composed as a pipeline:\n//\n// withOAuthProtectedResource OAuth discovery for external MCP clients. Runs\n// before the auth gate so unauthenticated clients\n// can fetch the RFC 9728 metadata, and adds the\n// WWW-Authenticate challenge to the gate's 401.\n// withSupabase Verifies the user access token and builds an\n// RLS-scoped client, so both embedded product\n// agents and external OAuth clients act as the\n// signed-in user.\n// handleMcp MCP transport and tools (./tools/index.ts).\n//\n// On Supabase Edge Functions the public URLs in the OAuth metadata are derived\n// automatically, locally and hosted. Off Edge Functions, pass `resourceServer`\n// and `authorizationServer` to withOAuthProtectedResource.\n\nfunction readTextEnv(name: string, fallback: string): string {\n return Deno.env.get(name)?.trim() || fallback\n}\n\nconst SERVER_NAME = readTextEnv('MCP_SERVER_NAME', 'supabase-mcp')\nconst SERVER_DESCRIPTION = readTextEnv(\n 'MCP_SERVER_DESCRIPTION',\n 'MCP access to this Supabase project for the signed-in user.'\n)\n\nconst SERVER_INSTRUCTIONS =\n `${SERVER_DESCRIPTION} ` +\n 'Every tool runs as the signed-in Supabase user, so role grants and Row Level Security apply. ' +\n \"Call tools/list to discover what this project exposes, and read a tool's description and \" +\n 'annotations before calling it — some tools have side effects.'\n\nconst CORS_HEADERS: Record<string, string> = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers':\n 'Authorization, Content-Type, Accept, Mcp-Protocol-Version, Mcp-Session-Id, Mcp-Method, Mcp-Name',\n 'Access-Control-Expose-Headers': 'WWW-Authenticate, Mcp-Session-Id',\n}\n\nfunction createServer(context: ToolContext): McpServer {\n const server = new McpServer(\n { name: SERVER_NAME, version: '1.0.0' },\n { instructions: SERVER_INSTRUCTIONS }\n )\n\n registerTools(server, context)\n return server\n}\n\nasync function handleMcp(request: Request, ctx: SupabaseContext): Promise<Response> {\n // The server and its tools are bound to this caller for exactly one request.\n const handler = createMcpHandler(\n () =>\n createServer({\n supabase: ctx.supabase,\n // auth: 'user' guarantees both claim shapes before this handler runs.\n userClaims: ctx.userClaims!,\n jwtClaims: ctx.jwtClaims!,\n }),\n { onerror: (error) => console.error('MCP request failed', error) }\n )\n\n return handler.fetch(request)\n}\n\n// The handler is passed inline so TypeScript infers its context from the entries.\n// Passing `handleMcp` directly collapses the inferred context to `object`.\nDeno.serve(\n pipeline(\n [withOAuthProtectedResource(), withSupabase({ auth: 'user', cors: { headers: CORS_HEADERS } })],\n (request, ctx) => handleMcp(request, ctx)\n )\n)\n",
|
||||
"content": "import 'jsr:@supabase/functions-js@2.108.2/edge-runtime.d.ts'\n\nimport { createMcpHandler, McpServer } from 'npm:@modelcontextprotocol/server@2.0.0'\nimport { pipeline } from 'npm:@supabase/middleware@1'\nimport {\n withOAuthProtectedResource,\n withSupabase,\n type SupabaseContext,\n} from 'npm:@supabase/server@1'\n\nimport { registerTools, type ToolContext } from './tools/index.ts'\n\n// An MCP server as a single Supabase Edge Function, composed as a pipeline:\n//\n// withOAuthProtectedResource OAuth discovery for external MCP clients. Runs\n// before the auth gate so unauthenticated clients\n// can fetch the RFC 9728 metadata, and adds the\n// WWW-Authenticate challenge to the gate's 401.\n// withSupabase Verifies the user access token and builds an\n// RLS-scoped client, so both embedded product\n// agents and external OAuth clients act as the\n// signed-in user.\n// handleMcp MCP transport and tools (./tools/index.ts).\n//\n// On Supabase Edge Functions the public URLs in the OAuth metadata are derived\n// automatically, locally and hosted. Off Edge Functions, pass `resourceServer`\n// and `authorizationServer` to withOAuthProtectedResource.\n\nfunction readTextEnv(name: string, fallback: string): string {\n return Deno.env.get(name)?.trim() || fallback\n}\n\nconst SERVER_NAME = readTextEnv('MCP_SERVER_NAME', 'supabase-mcp')\nconst SERVER_DESCRIPTION = readTextEnv(\n 'MCP_SERVER_DESCRIPTION',\n 'MCP access to this Supabase project for the signed-in user.'\n)\n\nconst SERVER_INSTRUCTIONS =\n `${SERVER_DESCRIPTION} ` +\n 'Every tool runs as the signed-in Supabase user, so role grants and Row Level Security apply. ' +\n \"Call tools/list to discover what this project exposes, and read a tool's description and \" +\n 'annotations before calling it — some tools have side effects.'\n\nconst CORS_HEADERS: Record<string, string> = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers':\n 'Authorization, Content-Type, Accept, Mcp-Protocol-Version, Mcp-Session-Id, Mcp-Method, Mcp-Name',\n 'Access-Control-Expose-Headers': 'WWW-Authenticate, Mcp-Session-Id',\n}\n\nfunction createServer(context: ToolContext): McpServer {\n const server = new McpServer(\n { name: SERVER_NAME, version: '1.0.0' },\n { instructions: SERVER_INSTRUCTIONS }\n )\n\n registerTools(server, context)\n return server\n}\n\nasync function handleMcp(request: Request, ctx: SupabaseContext): Promise<Response> {\n // The server and its tools are bound to this caller for exactly one request.\n const handler = createMcpHandler(\n () =>\n createServer({\n supabase: ctx.supabase,\n // auth: 'user' guarantees both claim shapes before this handler runs.\n userClaims: ctx.userClaims!,\n jwtClaims: ctx.jwtClaims!,\n }),\n { onerror: (error) => console.error('MCP request failed', error) }\n )\n\n return handler.fetch(request)\n}\n\n// The handler is passed inline so TypeScript infers its context from the entries.\n// Passing `handleMcp` directly collapses the inferred context to `object`.\nDeno.serve(\n pipeline(\n [withOAuthProtectedResource(), withSupabase({ auth: 'user', cors: { headers: CORS_HEADERS } })],\n (request, ctx) => handleMcp(request, ctx)\n )\n)\n",
|
||||
"type": "registry:file",
|
||||
"target": "~/supabase/functions/mcp/index.ts"
|
||||
},
|
||||
@@ -67,7 +67,7 @@
|
||||
},
|
||||
{
|
||||
"path": "registry/default/blocks/mcp/supabase/functions/mcp/deno.lock",
|
||||
"content": "{\n \"version\": \"5\",\n \"specifiers\": {\n \"jsr:@supabase/functions-js@2.108.2\": \"2.108.2\",\n \"npm:@modelcontextprotocol/server@2.0.0\": \"2.0.0\",\n \"npm:@supabase/middleware@0.5.0\": \"0.5.0\",\n \"npm:@supabase/server@1.6.0\": \"1.6.0_@supabase+supabase-js@2.108.2\",\n \"npm:@supabase/supabase-js@2.108.2\": \"2.108.2\",\n \"npm:openai@^4.52.5\": \"4.104.0_zod@4.4.3\",\n \"npm:zod@4.4.3\": \"4.4.3\"\n },\n \"jsr\": {\n \"@supabase/functions-js@2.108.2\": {\n \"integrity\": \"39665d68e1cb721b0714ed1f55c075fba16f8d992672b51458660b3c1ec77c8f\",\n \"dependencies\": [\n \"npm:openai\"\n ]\n }\n },\n \"npm\": {\n \"@modelcontextprotocol/core@2.0.0\": {\n \"integrity\": \"sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==\",\n \"dependencies\": [\n \"zod\"\n ]\n },\n \"@modelcontextprotocol/server@2.0.0\": {\n \"integrity\": \"sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==\",\n \"dependencies\": [\n \"@modelcontextprotocol/core\",\n \"zod\"\n ]\n },\n \"@supabase/auth-js@2.108.2\": {\n \"integrity\": \"sha512-tNaQmBgodDZwgB40mRwVbxFy8IDYwjdpcZ0BYrWiwlULCSQoJj4QoG4zgJT7QRPXcqipefNOzvO/qAu4dF98ag==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/functions-js@2.108.2\": {\n \"integrity\": \"sha512-RNUX8EiBy3iLwAX19jtRzLyePnl11/fHcgwDHLnpKcDSXt/5qBnh3LUwAtIjT21Q66QsmNUR2esrHziLCpNubw==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/middleware@0.5.0\": {\n \"integrity\": \"sha512-OjukUo+5p14zxTuylf2zVg1hZCHWKLO6VrZhtVeQQw09yrVo3GAduvFJPiFDhTAz/Du1ZfEzAR+s6aRAWD5wzQ==\",\n \"dependencies\": [\n \"std-env\"\n ]\n },\n \"@supabase/phoenix@0.4.5\": {\n \"integrity\": \"sha512-aAn9H9ovVyeApKy11OWOrrOGq8DV68yWeH4ud2lN9fzn4aO8Zb5GLL9m1pUg9nLqIcT+ZDfAcsZe0E/nqdv2lw==\"\n },\n \"@supabase/postgrest-js@2.108.2\": {\n \"integrity\": \"sha512-GQ28/Y8hk3CFmkb3kXH1h/AQx6JIYSQfO0CJMRVBcEKZoNy6C45cXAZ4fcJvRC5Id0cs6xnkUV0+c0rIocigsw==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/realtime-js@2.108.2\": {\n \"integrity\": \"sha512-aAGxCSUemZvQIibnCdvNvgaKib28I4rfrNjKbQ9cG1uBLwUsI7hVpGXgEbypCCDhLjQlDTAiJlu7rgljYUT73g==\",\n \"dependencies\": [\n \"@supabase/phoenix\",\n \"tslib\"\n ]\n },\n \"@supabase/server@1.6.0_@supabase+supabase-js@2.108.2\": {\n \"integrity\": \"sha512-LtUkzUqUGip6I2+kvSmA04u3s+npwLseer2yomBnUdQ1zyJPtlgjAqbwsNuGC1DT/FHi1BvvJluI7dZVV2XdTw==\",\n \"dependencies\": [\n \"@supabase/middleware\",\n \"@supabase/supabase-js\",\n \"jose\"\n ]\n },\n \"@supabase/storage-js@2.108.2\": {\n \"integrity\": \"sha512-TVZPQxXGxY2+A6yTtm77zUHsh70lBhYUEaJL8RQC+BghcX/ygiMG/rmXrNVBce30/WAeNPa8FiG8HbqlGeV05g==\",\n \"dependencies\": [\n \"iceberg-js\",\n \"tslib\"\n ]\n },\n \"@supabase/supabase-js@2.108.2\": {\n \"integrity\": \"sha512-hFhnPveb5JQg4a0QYicM0swT253YHMdfeRAl2BKHOlI5VAzuHxUGSr8RbwNLYNPauWOgQMS1H8sz8bvYlgwUfQ==\",\n \"dependencies\": [\n \"@supabase/auth-js\",\n \"@supabase/functions-js\",\n \"@supabase/postgrest-js\",\n \"@supabase/realtime-js\",\n \"@supabase/storage-js\"\n ]\n },\n \"@types/node-fetch@2.6.13\": {\n \"integrity\": \"sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==\",\n \"dependencies\": [\n \"@types/node\",\n \"form-data\"\n ]\n },\n \"@types/node@18.19.130\": {\n \"integrity\": \"sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==\",\n \"dependencies\": [\n \"undici-types\"\n ]\n },\n \"abort-controller@3.0.0\": {\n \"integrity\": \"sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==\",\n \"dependencies\": [\n \"event-target-shim\"\n ]\n },\n \"agentkeepalive@4.6.0\": {\n \"integrity\": \"sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==\",\n \"dependencies\": [\n \"humanize-ms\"\n ]\n },\n \"asynckit@0.4.0\": {\n \"integrity\": \"sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==\"\n },\n \"call-bind-apply-helpers@1.0.2\": {\n \"integrity\": \"sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==\",\n \"dependencies\": [\n \"es-errors\",\n \"function-bind\"\n ]\n },\n \"combined-stream@1.0.8\": {\n \"integrity\": \"sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==Line truncated
|
||||
"content": "{\n \"version\": \"5\",\n \"specifiers\": {\n \"jsr:@supabase/functions-js@2.108.2\": \"2.108.2\",\n \"npm:@modelcontextprotocol/server@2.0.0\": \"2.0.0\",\n \"npm:@supabase/middleware@1\": \"1.0.0\",\n \"npm:@supabase/server@1\": \"1.9.0_@supabase+supabase-js@2.108.2\",\n \"npm:@supabase/supabase-js@2.108.2\": \"2.108.2\",\n \"npm:openai@^4.52.5\": \"4.104.0\"\n },\n \"jsr\": {\n \"@supabase/functions-js@2.108.2\": {\n \"integrity\": \"39665d68e1cb721b0714ed1f55c075fba16f8d992672b51458660b3c1ec77c8f\",\n \"dependencies\": [\n \"npm:openai\"\n ]\n }\n },\n \"npm\": {\n \"@modelcontextprotocol/core@2.0.0\": {\n \"integrity\": \"sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==\",\n \"dependencies\": [\n \"zod\"\n ]\n },\n \"@modelcontextprotocol/server@2.0.0\": {\n \"integrity\": \"sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==\",\n \"dependencies\": [\n \"@modelcontextprotocol/core\",\n \"zod\"\n ]\n },\n \"@supabase/auth-js@2.108.2\": {\n \"integrity\": \"sha512-tNaQmBgodDZwgB40mRwVbxFy8IDYwjdpcZ0BYrWiwlULCSQoJj4QoG4zgJT7QRPXcqipefNOzvO/qAu4dF98ag==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/functions-js@2.108.2\": {\n \"integrity\": \"sha512-RNUX8EiBy3iLwAX19jtRzLyePnl11/fHcgwDHLnpKcDSXt/5qBnh3LUwAtIjT21Q66QsmNUR2esrHziLCpNubw==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/middleware@1.0.0\": {\n \"integrity\": \"sha512-ecA+z/o5E9sB+quuupGt8d7QjrnD4BBwZr+Qthm0uj6CtL/+yvAUTDlknhGuTbUidvx5CxBHJ1R3H96UjDpgyg==\",\n \"dependencies\": [\n \"std-env\"\n ]\n },\n \"@supabase/phoenix@0.4.5\": {\n \"integrity\": \"sha512-aAn9H9ovVyeApKy11OWOrrOGq8DV68yWeH4ud2lN9fzn4aO8Zb5GLL9m1pUg9nLqIcT+ZDfAcsZe0E/nqdv2lw==\"\n },\n \"@supabase/postgrest-js@2.108.2\": {\n \"integrity\": \"sha512-GQ28/Y8hk3CFmkb3kXH1h/AQx6JIYSQfO0CJMRVBcEKZoNy6C45cXAZ4fcJvRC5Id0cs6xnkUV0+c0rIocigsw==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/realtime-js@2.108.2\": {\n \"integrity\": \"sha512-aAGxCSUemZvQIibnCdvNvgaKib28I4rfrNjKbQ9cG1uBLwUsI7hVpGXgEbypCCDhLjQlDTAiJlu7rgljYUT73g==\",\n \"dependencies\": [\n \"@supabase/phoenix\",\n \"tslib\"\n ]\n },\n \"@supabase/server@1.9.0_@supabase+supabase-js@2.108.2\": {\n \"integrity\": \"sha512-EhgfKFWjB6bCWy2UR2JdExnK+B8WBdwiG90+bLTt0GkdAuHZZSooNxOsn/fP3UlcXUNJ6xfAkYlvGzN8NUpz1w==\",\n \"dependencies\": [\n \"@supabase/middleware\",\n \"@supabase/supabase-js\",\n \"jose\"\n ]\n },\n \"@supabase/storage-js@2.108.2\": {\n \"integrity\": \"sha512-TVZPQxXGxY2+A6yTtm77zUHsh70lBhYUEaJL8RQC+BghcX/ygiMG/rmXrNVBce30/WAeNPa8FiG8HbqlGeV05g==\",\n \"dependencies\": [\n \"iceberg-js\",\n \"tslib\"\n ]\n },\n \"@supabase/supabase-js@2.108.2\": {\n \"integrity\": \"sha512-hFhnPveb5JQg4a0QYicM0swT253YHMdfeRAl2BKHOlI5VAzuHxUGSr8RbwNLYNPauWOgQMS1H8sz8bvYlgwUfQ==\",\n \"dependencies\": [\n \"@supabase/auth-js\",\n \"@supabase/functions-js\",\n \"@supabase/postgrest-js\",\n \"@supabase/realtime-js\",\n \"@supabase/storage-js\"\n ]\n },\n \"@types/node-fetch@2.6.13\": {\n \"integrity\": \"sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==\",\n \"dependencies\": [\n \"@types/node\",\n \"form-data\"\n ]\n },\n \"@types/node@18.19.130\": {\n \"integrity\": \"sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==\",\n \"dependencies\": [\n \"undici-types\"\n ]\n },\n \"abort-controller@3.0.0\": {\n \"integrity\": \"sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==\",\n \"dependencies\": [\n \"event-target-shim\"\n ]\n },\n \"agentkeepalive@4.6.0\": {\n \"integrity\": \"sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==\",\n \"dependencies\": [\n \"humanize-ms\"\n ]\n },\n \"asynckit@0.4.0\": {\n \"integrity\": \"sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==\"\n },\n \"call-bind-apply-helpers@1.0.2\": {\n \"integrity\": \"sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==\",\n \"dependencies\": [\n \"es-errors\",\n \"function-bind\"\n ]\n },\n \"combined-stream@1.0.8\": {\n \"integrity\": \"sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==\",\n \"dependencies\": [\n \"delayed-strLine truncated
|
||||
"type": "registry:file",
|
||||
"target": "~/supabase/functions/mcp/deno.lock"
|
||||
},
|
||||
@@ -79,7 +79,7 @@
|
||||
},
|
||||
{
|
||||
"path": "registry/default/blocks/mcp/supabase/functions/mcp/tools/types.ts",
|
||||
"content": "import type { SupabaseContext } from 'npm:@supabase/server@1.6.0'\nimport type { SupabaseClient } from 'npm:@supabase/supabase-js@2.108.2'\n\n// Only expose the user-scoped client and verified identity to tools. Keeping\n// supabaseAdmin out of this type makes bypassing RLS an explicit design choice.\nexport type ToolContext = {\n supabase: SupabaseClient\n userClaims: NonNullable<SupabaseContext['userClaims']>\n jwtClaims: NonNullable<SupabaseContext['jwtClaims']>\n}\n",
|
||||
"content": "import type { SupabaseContext } from 'npm:@supabase/server@1'\nimport type { SupabaseClient } from 'npm:@supabase/supabase-js@2.108.2'\n\n// Only expose the user-scoped client and verified identity to tools. Keeping\n// supabaseAdmin out of this type makes bypassing RLS an explicit design choice.\nexport type ToolContext = {\n supabase: SupabaseClient\n userClaims: NonNullable<SupabaseContext['userClaims']>\n jwtClaims: NonNullable<SupabaseContext['jwtClaims']>\n}\n",
|
||||
"type": "registry:file",
|
||||
"target": "~/supabase/functions/mcp/tools/types.ts"
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/default/blocks/mcp/supabase/functions/mcp/index.ts",
|
||||
"content": "import 'jsr:@supabase/functions-js@2.108.2/edge-runtime.d.ts'\n\nimport { createMcpHandler, McpServer } from 'npm:@modelcontextprotocol/server@2.0.0'\nimport { pipeline } from 'npm:@supabase/middleware@0.5.0'\nimport {\n withOAuthProtectedResource,\n withSupabase,\n type SupabaseContext,\n} from 'npm:@supabase/server@1.6.0'\n\nimport { registerTools, type ToolContext } from './tools/index.ts'\n\n// An MCP server as a single Supabase Edge Function, composed as a pipeline:\n//\n// withOAuthProtectedResource OAuth discovery for external MCP clients. Runs\n// before the auth gate so unauthenticated clients\n// can fetch the RFC 9728 metadata, and adds the\n// WWW-Authenticate challenge to the gate's 401.\n// withSupabase Verifies the user access token and builds an\n// RLS-scoped client, so both embedded product\n// agents and external OAuth clients act as the\n// signed-in user.\n// handleMcp MCP transport and tools (./tools/index.ts).\n//\n// On Supabase Edge Functions the public URLs in the OAuth metadata are derived\n// automatically, locally and hosted. Off Edge Functions, pass `resourceServer`\n// and `authorizationServer` to withOAuthProtectedResource.\n\nfunction readTextEnv(name: string, fallback: string): string {\n return Deno.env.get(name)?.trim() || fallback\n}\n\nconst SERVER_NAME = readTextEnv('MCP_SERVER_NAME', 'supabase-mcp')\nconst SERVER_DESCRIPTION = readTextEnv(\n 'MCP_SERVER_DESCRIPTION',\n 'MCP access to this Supabase project for the signed-in user.'\n)\n\nconst SERVER_INSTRUCTIONS =\n `${SERVER_DESCRIPTION} ` +\n 'Every tool runs as the signed-in Supabase user, so role grants and Row Level Security apply. ' +\n \"Call tools/list to discover what this project exposes, and read a tool's description and \" +\n 'annotations before calling it — some tools have side effects.'\n\nconst CORS_HEADERS: Record<string, string> = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers':\n 'Authorization, Content-Type, Accept, Mcp-Protocol-Version, Mcp-Session-Id, Mcp-Method, Mcp-Name',\n 'Access-Control-Expose-Headers': 'WWW-Authenticate, Mcp-Session-Id',\n}\n\nfunction createServer(context: ToolContext): McpServer {\n const server = new McpServer(\n { name: SERVER_NAME, version: '1.0.0' },\n { instructions: SERVER_INSTRUCTIONS }\n )\n\n registerTools(server, context)\n return server\n}\n\nasync function handleMcp(request: Request, ctx: SupabaseContext): Promise<Response> {\n // The server and its tools are bound to this caller for exactly one request.\n const handler = createMcpHandler(\n () =>\n createServer({\n supabase: ctx.supabase,\n // auth: 'user' guarantees both claim shapes before this handler runs.\n userClaims: ctx.userClaims!,\n jwtClaims: ctx.jwtClaims!,\n }),\n { onerror: (error) => console.error('MCP request failed', error) }\n )\n\n return handler.fetch(request)\n}\n\n// The handler is passed inline so TypeScript infers its context from the entries.\n// Passing `handleMcp` directly collapses the inferred context to `object`.\nDeno.serve(\n pipeline(\n [withOAuthProtectedResource(), withSupabase({ auth: 'user', cors: { headers: CORS_HEADERS } })],\n (request, ctx) => handleMcp(request, ctx)\n )\n)\n",
|
||||
"content": "import 'jsr:@supabase/functions-js@2.108.2/edge-runtime.d.ts'\n\nimport { createMcpHandler, McpServer } from 'npm:@modelcontextprotocol/server@2.0.0'\nimport { pipeline } from 'npm:@supabase/middleware@1'\nimport {\n withOAuthProtectedResource,\n withSupabase,\n type SupabaseContext,\n} from 'npm:@supabase/server@1'\n\nimport { registerTools, type ToolContext } from './tools/index.ts'\n\n// An MCP server as a single Supabase Edge Function, composed as a pipeline:\n//\n// withOAuthProtectedResource OAuth discovery for external MCP clients. Runs\n// before the auth gate so unauthenticated clients\n// can fetch the RFC 9728 metadata, and adds the\n// WWW-Authenticate challenge to the gate's 401.\n// withSupabase Verifies the user access token and builds an\n// RLS-scoped client, so both embedded product\n// agents and external OAuth clients act as the\n// signed-in user.\n// handleMcp MCP transport and tools (./tools/index.ts).\n//\n// On Supabase Edge Functions the public URLs in the OAuth metadata are derived\n// automatically, locally and hosted. Off Edge Functions, pass `resourceServer`\n// and `authorizationServer` to withOAuthProtectedResource.\n\nfunction readTextEnv(name: string, fallback: string): string {\n return Deno.env.get(name)?.trim() || fallback\n}\n\nconst SERVER_NAME = readTextEnv('MCP_SERVER_NAME', 'supabase-mcp')\nconst SERVER_DESCRIPTION = readTextEnv(\n 'MCP_SERVER_DESCRIPTION',\n 'MCP access to this Supabase project for the signed-in user.'\n)\n\nconst SERVER_INSTRUCTIONS =\n `${SERVER_DESCRIPTION} ` +\n 'Every tool runs as the signed-in Supabase user, so role grants and Row Level Security apply. ' +\n \"Call tools/list to discover what this project exposes, and read a tool's description and \" +\n 'annotations before calling it — some tools have side effects.'\n\nconst CORS_HEADERS: Record<string, string> = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers':\n 'Authorization, Content-Type, Accept, Mcp-Protocol-Version, Mcp-Session-Id, Mcp-Method, Mcp-Name',\n 'Access-Control-Expose-Headers': 'WWW-Authenticate, Mcp-Session-Id',\n}\n\nfunction createServer(context: ToolContext): McpServer {\n const server = new McpServer(\n { name: SERVER_NAME, version: '1.0.0' },\n { instructions: SERVER_INSTRUCTIONS }\n )\n\n registerTools(server, context)\n return server\n}\n\nasync function handleMcp(request: Request, ctx: SupabaseContext): Promise<Response> {\n // The server and its tools are bound to this caller for exactly one request.\n const handler = createMcpHandler(\n () =>\n createServer({\n supabase: ctx.supabase,\n // auth: 'user' guarantees both claim shapes before this handler runs.\n userClaims: ctx.userClaims!,\n jwtClaims: ctx.jwtClaims!,\n }),\n { onerror: (error) => console.error('MCP request failed', error) }\n )\n\n return handler.fetch(request)\n}\n\n// The handler is passed inline so TypeScript infers its context from the entries.\n// Passing `handleMcp` directly collapses the inferred context to `object`.\nDeno.serve(\n pipeline(\n [withOAuthProtectedResource(), withSupabase({ auth: 'user', cors: { headers: CORS_HEADERS } })],\n (request, ctx) => handleMcp(request, ctx)\n )\n)\n",
|
||||
"type": "registry:file",
|
||||
"target": "~/supabase/functions/mcp/index.ts"
|
||||
},
|
||||
@@ -18,7 +18,7 @@
|
||||
},
|
||||
{
|
||||
"path": "registry/default/blocks/mcp/supabase/functions/mcp/deno.lock",
|
||||
"content": "{\n \"version\": \"5\",\n \"specifiers\": {\n \"jsr:@supabase/functions-js@2.108.2\": \"2.108.2\",\n \"npm:@modelcontextprotocol/server@2.0.0\": \"2.0.0\",\n \"npm:@supabase/middleware@0.5.0\": \"0.5.0\",\n \"npm:@supabase/server@1.6.0\": \"1.6.0_@supabase+supabase-js@2.108.2\",\n \"npm:@supabase/supabase-js@2.108.2\": \"2.108.2\",\n \"npm:openai@^4.52.5\": \"4.104.0_zod@4.4.3\",\n \"npm:zod@4.4.3\": \"4.4.3\"\n },\n \"jsr\": {\n \"@supabase/functions-js@2.108.2\": {\n \"integrity\": \"39665d68e1cb721b0714ed1f55c075fba16f8d992672b51458660b3c1ec77c8f\",\n \"dependencies\": [\n \"npm:openai\"\n ]\n }\n },\n \"npm\": {\n \"@modelcontextprotocol/core@2.0.0\": {\n \"integrity\": \"sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==\",\n \"dependencies\": [\n \"zod\"\n ]\n },\n \"@modelcontextprotocol/server@2.0.0\": {\n \"integrity\": \"sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==\",\n \"dependencies\": [\n \"@modelcontextprotocol/core\",\n \"zod\"\n ]\n },\n \"@supabase/auth-js@2.108.2\": {\n \"integrity\": \"sha512-tNaQmBgodDZwgB40mRwVbxFy8IDYwjdpcZ0BYrWiwlULCSQoJj4QoG4zgJT7QRPXcqipefNOzvO/qAu4dF98ag==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/functions-js@2.108.2\": {\n \"integrity\": \"sha512-RNUX8EiBy3iLwAX19jtRzLyePnl11/fHcgwDHLnpKcDSXt/5qBnh3LUwAtIjT21Q66QsmNUR2esrHziLCpNubw==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/middleware@0.5.0\": {\n \"integrity\": \"sha512-OjukUo+5p14zxTuylf2zVg1hZCHWKLO6VrZhtVeQQw09yrVo3GAduvFJPiFDhTAz/Du1ZfEzAR+s6aRAWD5wzQ==\",\n \"dependencies\": [\n \"std-env\"\n ]\n },\n \"@supabase/phoenix@0.4.5\": {\n \"integrity\": \"sha512-aAn9H9ovVyeApKy11OWOrrOGq8DV68yWeH4ud2lN9fzn4aO8Zb5GLL9m1pUg9nLqIcT+ZDfAcsZe0E/nqdv2lw==\"\n },\n \"@supabase/postgrest-js@2.108.2\": {\n \"integrity\": \"sha512-GQ28/Y8hk3CFmkb3kXH1h/AQx6JIYSQfO0CJMRVBcEKZoNy6C45cXAZ4fcJvRC5Id0cs6xnkUV0+c0rIocigsw==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/realtime-js@2.108.2\": {\n \"integrity\": \"sha512-aAGxCSUemZvQIibnCdvNvgaKib28I4rfrNjKbQ9cG1uBLwUsI7hVpGXgEbypCCDhLjQlDTAiJlu7rgljYUT73g==\",\n \"dependencies\": [\n \"@supabase/phoenix\",\n \"tslib\"\n ]\n },\n \"@supabase/server@1.6.0_@supabase+supabase-js@2.108.2\": {\n \"integrity\": \"sha512-LtUkzUqUGip6I2+kvSmA04u3s+npwLseer2yomBnUdQ1zyJPtlgjAqbwsNuGC1DT/FHi1BvvJluI7dZVV2XdTw==\",\n \"dependencies\": [\n \"@supabase/middleware\",\n \"@supabase/supabase-js\",\n \"jose\"\n ]\n },\n \"@supabase/storage-js@2.108.2\": {\n \"integrity\": \"sha512-TVZPQxXGxY2+A6yTtm77zUHsh70lBhYUEaJL8RQC+BghcX/ygiMG/rmXrNVBce30/WAeNPa8FiG8HbqlGeV05g==\",\n \"dependencies\": [\n \"iceberg-js\",\n \"tslib\"\n ]\n },\n \"@supabase/supabase-js@2.108.2\": {\n \"integrity\": \"sha512-hFhnPveb5JQg4a0QYicM0swT253YHMdfeRAl2BKHOlI5VAzuHxUGSr8RbwNLYNPauWOgQMS1H8sz8bvYlgwUfQ==\",\n \"dependencies\": [\n \"@supabase/auth-js\",\n \"@supabase/functions-js\",\n \"@supabase/postgrest-js\",\n \"@supabase/realtime-js\",\n \"@supabase/storage-js\"\n ]\n },\n \"@types/node-fetch@2.6.13\": {\n \"integrity\": \"sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==\",\n \"dependencies\": [\n \"@types/node\",\n \"form-data\"\n ]\n },\n \"@types/node@18.19.130\": {\n \"integrity\": \"sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==\",\n \"dependencies\": [\n \"undici-types\"\n ]\n },\n \"abort-controller@3.0.0\": {\n \"integrity\": \"sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==\",\n \"dependencies\": [\n \"event-target-shim\"\n ]\n },\n \"agentkeepalive@4.6.0\": {\n \"integrity\": \"sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==\",\n \"dependencies\": [\n \"humanize-ms\"\n ]\n },\n \"asynckit@0.4.0\": {\n \"integrity\": \"sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==\"\n },\n \"call-bind-apply-helpers@1.0.2\": {\n \"integrity\": \"sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==\",\n \"dependencies\": [\n \"es-errors\",\n \"function-bind\"\n ]\n },\n \"combined-stream@1.0.8\": {\n \"integrity\": \"sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==Line truncated
|
||||
"content": "{\n \"version\": \"5\",\n \"specifiers\": {\n \"jsr:@supabase/functions-js@2.108.2\": \"2.108.2\",\n \"npm:@modelcontextprotocol/server@2.0.0\": \"2.0.0\",\n \"npm:@supabase/middleware@1\": \"1.0.0\",\n \"npm:@supabase/server@1\": \"1.9.0_@supabase+supabase-js@2.108.2\",\n \"npm:@supabase/supabase-js@2.108.2\": \"2.108.2\",\n \"npm:openai@^4.52.5\": \"4.104.0\"\n },\n \"jsr\": {\n \"@supabase/functions-js@2.108.2\": {\n \"integrity\": \"39665d68e1cb721b0714ed1f55c075fba16f8d992672b51458660b3c1ec77c8f\",\n \"dependencies\": [\n \"npm:openai\"\n ]\n }\n },\n \"npm\": {\n \"@modelcontextprotocol/core@2.0.0\": {\n \"integrity\": \"sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==\",\n \"dependencies\": [\n \"zod\"\n ]\n },\n \"@modelcontextprotocol/server@2.0.0\": {\n \"integrity\": \"sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==\",\n \"dependencies\": [\n \"@modelcontextprotocol/core\",\n \"zod\"\n ]\n },\n \"@supabase/auth-js@2.108.2\": {\n \"integrity\": \"sha512-tNaQmBgodDZwgB40mRwVbxFy8IDYwjdpcZ0BYrWiwlULCSQoJj4QoG4zgJT7QRPXcqipefNOzvO/qAu4dF98ag==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/functions-js@2.108.2\": {\n \"integrity\": \"sha512-RNUX8EiBy3iLwAX19jtRzLyePnl11/fHcgwDHLnpKcDSXt/5qBnh3LUwAtIjT21Q66QsmNUR2esrHziLCpNubw==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/middleware@1.0.0\": {\n \"integrity\": \"sha512-ecA+z/o5E9sB+quuupGt8d7QjrnD4BBwZr+Qthm0uj6CtL/+yvAUTDlknhGuTbUidvx5CxBHJ1R3H96UjDpgyg==\",\n \"dependencies\": [\n \"std-env\"\n ]\n },\n \"@supabase/phoenix@0.4.5\": {\n \"integrity\": \"sha512-aAn9H9ovVyeApKy11OWOrrOGq8DV68yWeH4ud2lN9fzn4aO8Zb5GLL9m1pUg9nLqIcT+ZDfAcsZe0E/nqdv2lw==\"\n },\n \"@supabase/postgrest-js@2.108.2\": {\n \"integrity\": \"sha512-GQ28/Y8hk3CFmkb3kXH1h/AQx6JIYSQfO0CJMRVBcEKZoNy6C45cXAZ4fcJvRC5Id0cs6xnkUV0+c0rIocigsw==\",\n \"dependencies\": [\n \"tslib\"\n ]\n },\n \"@supabase/realtime-js@2.108.2\": {\n \"integrity\": \"sha512-aAGxCSUemZvQIibnCdvNvgaKib28I4rfrNjKbQ9cG1uBLwUsI7hVpGXgEbypCCDhLjQlDTAiJlu7rgljYUT73g==\",\n \"dependencies\": [\n \"@supabase/phoenix\",\n \"tslib\"\n ]\n },\n \"@supabase/server@1.9.0_@supabase+supabase-js@2.108.2\": {\n \"integrity\": \"sha512-EhgfKFWjB6bCWy2UR2JdExnK+B8WBdwiG90+bLTt0GkdAuHZZSooNxOsn/fP3UlcXUNJ6xfAkYlvGzN8NUpz1w==\",\n \"dependencies\": [\n \"@supabase/middleware\",\n \"@supabase/supabase-js\",\n \"jose\"\n ]\n },\n \"@supabase/storage-js@2.108.2\": {\n \"integrity\": \"sha512-TVZPQxXGxY2+A6yTtm77zUHsh70lBhYUEaJL8RQC+BghcX/ygiMG/rmXrNVBce30/WAeNPa8FiG8HbqlGeV05g==\",\n \"dependencies\": [\n \"iceberg-js\",\n \"tslib\"\n ]\n },\n \"@supabase/supabase-js@2.108.2\": {\n \"integrity\": \"sha512-hFhnPveb5JQg4a0QYicM0swT253YHMdfeRAl2BKHOlI5VAzuHxUGSr8RbwNLYNPauWOgQMS1H8sz8bvYlgwUfQ==\",\n \"dependencies\": [\n \"@supabase/auth-js\",\n \"@supabase/functions-js\",\n \"@supabase/postgrest-js\",\n \"@supabase/realtime-js\",\n \"@supabase/storage-js\"\n ]\n },\n \"@types/node-fetch@2.6.13\": {\n \"integrity\": \"sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==\",\n \"dependencies\": [\n \"@types/node\",\n \"form-data\"\n ]\n },\n \"@types/node@18.19.130\": {\n \"integrity\": \"sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==\",\n \"dependencies\": [\n \"undici-types\"\n ]\n },\n \"abort-controller@3.0.0\": {\n \"integrity\": \"sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==\",\n \"dependencies\": [\n \"event-target-shim\"\n ]\n },\n \"agentkeepalive@4.6.0\": {\n \"integrity\": \"sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==\",\n \"dependencies\": [\n \"humanize-ms\"\n ]\n },\n \"asynckit@0.4.0\": {\n \"integrity\": \"sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==\"\n },\n \"call-bind-apply-helpers@1.0.2\": {\n \"integrity\": \"sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==\",\n \"dependencies\": [\n \"es-errors\",\n \"function-bind\"\n ]\n },\n \"combined-stream@1.0.8\": {\n \"integrity\": \"sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==\",\n \"dependencies\": [\n \"delayed-strLine truncated
|
||||
"type": "registry:file",
|
||||
"target": "~/supabase/functions/mcp/deno.lock"
|
||||
},
|
||||
@@ -30,7 +30,7 @@
|
||||
},
|
||||
{
|
||||
"path": "registry/default/blocks/mcp/supabase/functions/mcp/tools/types.ts",
|
||||
"content": "import type { SupabaseContext } from 'npm:@supabase/server@1.6.0'\nimport type { SupabaseClient } from 'npm:@supabase/supabase-js@2.108.2'\n\n// Only expose the user-scoped client and verified identity to tools. Keeping\n// supabaseAdmin out of this type makes bypassing RLS an explicit design choice.\nexport type ToolContext = {\n supabase: SupabaseClient\n userClaims: NonNullable<SupabaseContext['userClaims']>\n jwtClaims: NonNullable<SupabaseContext['jwtClaims']>\n}\n",
|
||||
"content": "import type { SupabaseContext } from 'npm:@supabase/server@1'\nimport type { SupabaseClient } from 'npm:@supabase/supabase-js@2.108.2'\n\n// Only expose the user-scoped client and verified identity to tools. Keeping\n// supabaseAdmin out of this type makes bypassing RLS an explicit design choice.\nexport type ToolContext = {\n supabase: SupabaseClient\n userClaims: NonNullable<SupabaseContext['userClaims']>\n jwtClaims: NonNullable<SupabaseContext['jwtClaims']>\n}\n",
|
||||
"type": "registry:file",
|
||||
"target": "~/supabase/functions/mcp/tools/types.ts"
|
||||
},
|
||||
|
||||
+13
-18
@@ -3,11 +3,10 @@
|
||||
"specifiers": {
|
||||
"jsr:@supabase/functions-js@2.108.2": "2.108.2",
|
||||
"npm:@modelcontextprotocol/server@2.0.0": "2.0.0",
|
||||
"npm:@supabase/middleware@0.5.0": "0.5.0",
|
||||
"npm:@supabase/server@1.6.0": "1.6.0_@supabase+supabase-js@2.108.2",
|
||||
"npm:@supabase/middleware@1": "1.0.0",
|
||||
"npm:@supabase/server@1": "1.9.0_@supabase+supabase-js@2.108.2",
|
||||
"npm:@supabase/supabase-js@2.108.2": "2.108.2",
|
||||
"npm:openai@^4.52.5": "4.104.0_zod@4.4.3",
|
||||
"npm:zod@4.4.3": "4.4.3"
|
||||
"npm:openai@^4.52.5": "4.104.0"
|
||||
},
|
||||
"jsr": {
|
||||
"@supabase/functions-js@2.108.2": {
|
||||
@@ -43,8 +42,8 @@
|
||||
"tslib"
|
||||
]
|
||||
},
|
||||
"@supabase/middleware@0.5.0": {
|
||||
"integrity": "sha512-OjukUo+5p14zxTuylf2zVg1hZCHWKLO6VrZhtVeQQw09yrVo3GAduvFJPiFDhTAz/Du1ZfEzAR+s6aRAWD5wzQ==",
|
||||
"@supabase/middleware@1.0.0": {
|
||||
"integrity": "sha512-ecA+z/o5E9sB+quuupGt8d7QjrnD4BBwZr+Qthm0uj6CtL/+yvAUTDlknhGuTbUidvx5CxBHJ1R3H96UjDpgyg==",
|
||||
"dependencies": [
|
||||
"std-env"
|
||||
]
|
||||
@@ -65,8 +64,8 @@
|
||||
"tslib"
|
||||
]
|
||||
},
|
||||
"@supabase/server@1.6.0_@supabase+supabase-js@2.108.2": {
|
||||
"integrity": "sha512-LtUkzUqUGip6I2+kvSmA04u3s+npwLseer2yomBnUdQ1zyJPtlgjAqbwsNuGC1DT/FHi1BvvJluI7dZVV2XdTw==",
|
||||
"@supabase/server@1.9.0_@supabase+supabase-js@2.108.2": {
|
||||
"integrity": "sha512-EhgfKFWjB6bCWy2UR2JdExnK+B8WBdwiG90+bLTt0GkdAuHZZSooNxOsn/fP3UlcXUNJ6xfAkYlvGzN8NUpz1w==",
|
||||
"dependencies": [
|
||||
"@supabase/middleware",
|
||||
"@supabase/supabase-js",
|
||||
@@ -238,8 +237,8 @@
|
||||
"iceberg-js@0.8.1": {
|
||||
"integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA=="
|
||||
},
|
||||
"jose@6.2.10": {
|
||||
"integrity": "sha512-iiW7J9qRFlGxvCOIBDBDxFePQSn7ZMAnrYGhrrOo6siO/MIqwfyilLR27pkfDgUk+raLuzADS8A3S/KLBisc0g=="
|
||||
"jose@6.2.12": {
|
||||
"integrity": "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw=="
|
||||
},
|
||||
"math-intrinsics@1.1.0": {
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="
|
||||
@@ -266,7 +265,7 @@
|
||||
"whatwg-url"
|
||||
]
|
||||
},
|
||||
"openai@4.104.0_zod@4.4.3": {
|
||||
"openai@4.104.0": {
|
||||
"integrity": "sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==",
|
||||
"dependencies": [
|
||||
"@types/node",
|
||||
@@ -275,11 +274,7 @@
|
||||
"agentkeepalive",
|
||||
"form-data-encoder",
|
||||
"formdata-node",
|
||||
"node-fetch",
|
||||
"zod"
|
||||
],
|
||||
"optionalPeers": [
|
||||
"zod"
|
||||
"node-fetch"
|
||||
],
|
||||
"bin": true
|
||||
},
|
||||
@@ -308,8 +303,8 @@
|
||||
"webidl-conversions"
|
||||
]
|
||||
},
|
||||
"zod@4.4.3": {
|
||||
"integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="
|
||||
"zod@4.6.2": {
|
||||
"integrity": "sha512-lh5RCAGFa1Cm2hjtNwLQhSs/AsqdWnTQaBER9fEwN/88pSh7KOtJavtBx/0VlkN/uFd61SwYmljLMDAsHlvzBQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
import 'jsr:@supabase/functions-js@2.108.2/edge-runtime.d.ts'
|
||||
|
||||
import { createMcpHandler, McpServer } from 'npm:@modelcontextprotocol/server@2.0.0'
|
||||
import { pipeline } from 'npm:@supabase/middleware@0.5.0'
|
||||
import { pipeline } from 'npm:@supabase/middleware@1'
|
||||
import {
|
||||
withOAuthProtectedResource,
|
||||
withSupabase,
|
||||
type SupabaseContext,
|
||||
} from 'npm:@supabase/server@1.6.0'
|
||||
} from 'npm:@supabase/server@1'
|
||||
|
||||
import { registerTools, type ToolContext } from './tools/index.ts'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { SupabaseContext } from 'npm:@supabase/server@1.6.0'
|
||||
import type { SupabaseContext } from 'npm:@supabase/server@1'
|
||||
import type { SupabaseClient } from 'npm:@supabase/supabase-js@2.108.2'
|
||||
|
||||
// Only expose the user-scoped client and verified identity to tools. Keeping
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"imports": {
|
||||
"@modelcontextprotocol/server": "npm:@modelcontextprotocol/server@^2.0.0",
|
||||
"@supabase/middleware": "npm:@supabase/middleware@^0.6.0",
|
||||
"@supabase/server": "npm:@supabase/server@^1.6.0",
|
||||
"@supabase/middleware": "npm:@supabase/middleware@^1.0.0",
|
||||
"@supabase/server": "npm:@supabase/server@^1.9.0",
|
||||
"zod": "npm:zod@^4.3.6"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user