{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "mcp",
  "title": "MCP Server",
  "description": "Add a user-scoped MCP server to your product.",
  "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@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"
    },
    {
      "path": "registry/default/blocks/mcp/supabase/functions/mcp/deno.json",
      "content": "{\n  \"nodeModulesDir\": \"none\",\n  \"compilerOptions\": {\n    \"strict\": true\n  },\n  \"tasks\": {\n    \"check\": \"deno check index.ts\"\n  }\n}\n",
      "type": "registry:file",
      "target": "~/supabase/functions/mcp/deno.json"
    },
    {
      "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@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-stream\"\n      ]\n    },\n    \"delayed-stream@1.0.0\": {\n      \"integrity\": \"sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==\"\n    },\n    \"dunder-proto@1.0.1\": {\n      \"integrity\": \"sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==\",\n      \"dependencies\": [\n        \"call-bind-apply-helpers\",\n        \"es-errors\",\n        \"gopd\"\n      ]\n    },\n    \"es-define-property@1.0.1\": {\n      \"integrity\": \"sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==\"\n    },\n    \"es-errors@1.3.0\": {\n      \"integrity\": \"sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==\"\n    },\n    \"es-object-atoms@1.1.2\": {\n      \"integrity\": \"sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==\",\n      \"dependencies\": [\n        \"es-errors\"\n      ]\n    },\n    \"es-set-tostringtag@2.1.0\": {\n      \"integrity\": \"sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==\",\n      \"dependencies\": [\n        \"es-errors\",\n        \"get-intrinsic\",\n        \"has-tostringtag\",\n        \"hasown\"\n      ]\n    },\n    \"event-target-shim@5.0.1\": {\n      \"integrity\": \"sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==\"\n    },\n    \"form-data-encoder@1.7.2\": {\n      \"integrity\": \"sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==\"\n    },\n    \"form-data@4.0.6\": {\n      \"integrity\": \"sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==\",\n      \"dependencies\": [\n        \"asynckit\",\n        \"combined-stream\",\n        \"es-set-tostringtag\",\n        \"hasown\",\n        \"mime-types\"\n      ]\n    },\n    \"formdata-node@4.4.1\": {\n      \"integrity\": \"sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==\",\n      \"dependencies\": [\n        \"node-domexception\",\n        \"web-streams-polyfill\"\n      ]\n    },\n    \"function-bind@1.1.2\": {\n      \"integrity\": \"sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==\"\n    },\n    \"get-intrinsic@1.3.0\": {\n      \"integrity\": \"sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==\",\n      \"dependencies\": [\n        \"call-bind-apply-helpers\",\n        \"es-define-property\",\n        \"es-errors\",\n        \"es-object-atoms\",\n        \"function-bind\",\n        \"get-proto\",\n        \"gopd\",\n        \"has-symbols\",\n        \"hasown\",\n        \"math-intrinsics\"\n      ]\n    },\n    \"get-proto@1.0.1\": {\n      \"integrity\": \"sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==\",\n      \"dependencies\": [\n        \"dunder-proto\",\n        \"es-object-atoms\"\n      ]\n    },\n    \"gopd@1.2.0\": {\n      \"integrity\": \"sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==\"\n    },\n    \"has-symbols@1.1.0\": {\n      \"integrity\": \"sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==\"\n    },\n    \"has-tostringtag@1.0.2\": {\n      \"integrity\": \"sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==\",\n      \"dependencies\": [\n        \"has-symbols\"\n      ]\n    },\n    \"hasown@2.0.4\": {\n      \"integrity\": \"sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==\",\n      \"dependencies\": [\n        \"function-bind\"\n      ]\n    },\n    \"humanize-ms@1.2.1\": {\n      \"integrity\": \"sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==\",\n      \"dependencies\": [\n        \"ms\"\n      ]\n    },\n    \"iceberg-js@0.8.1\": {\n      \"integrity\": \"sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==\"\n    },\n    \"jose@6.2.12\": {\n      \"integrity\": \"sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==\"\n    },\n    \"math-intrinsics@1.1.0\": {\n      \"integrity\": \"sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==\"\n    },\n    \"mime-db@1.52.0\": {\n      \"integrity\": \"sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==\"\n    },\n    \"mime-types@2.1.35\": {\n      \"integrity\": \"sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==\",\n      \"dependencies\": [\n        \"mime-db\"\n      ]\n    },\n    \"ms@2.1.3\": {\n      \"integrity\": \"sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==\"\n    },\n    \"node-domexception@1.0.0\": {\n      \"integrity\": \"sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==\",\n      \"deprecated\": true\n    },\n    \"node-fetch@2.7.0\": {\n      \"integrity\": \"sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==\",\n      \"dependencies\": [\n        \"whatwg-url\"\n      ]\n    },\n    \"openai@4.104.0\": {\n      \"integrity\": \"sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==\",\n      \"dependencies\": [\n        \"@types/node\",\n        \"@types/node-fetch\",\n        \"abort-controller\",\n        \"agentkeepalive\",\n        \"form-data-encoder\",\n        \"formdata-node\",\n        \"node-fetch\"\n      ],\n      \"bin\": true\n    },\n    \"std-env@4.2.0\": {\n      \"integrity\": \"sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==\"\n    },\n    \"tr46@0.0.3\": {\n      \"integrity\": \"sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==\"\n    },\n    \"tslib@2.8.1\": {\n      \"integrity\": \"sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==\"\n    },\n    \"undici-types@5.26.5\": {\n      \"integrity\": \"sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==\"\n    },\n    \"web-streams-polyfill@4.0.0-beta.3\": {\n      \"integrity\": \"sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==\"\n    },\n    \"webidl-conversions@3.0.1\": {\n      \"integrity\": \"sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==\"\n    },\n    \"whatwg-url@5.0.0\": {\n      \"integrity\": \"sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==\",\n      \"dependencies\": [\n        \"tr46\",\n        \"webidl-conversions\"\n      ]\n    },\n    \"zod@4.6.2\": {\n      \"integrity\": \"sha512-lh5RCAGFa1Cm2hjtNwLQhSs/AsqdWnTQaBER9fEwN/88pSh7KOtJavtBx/0VlkN/uFd61SwYmljLMDAsHlvzBQ==\"\n    }\n  }\n}\n",
      "type": "registry:file",
      "target": "~/supabase/functions/mcp/deno.lock"
    },
    {
      "path": "registry/default/blocks/mcp/supabase/functions/mcp/.env.example",
      "content": "# Copy this file to supabase/functions/.env before serving locally:\n#   cp supabase/functions/mcp/.env.example supabase/functions/.env\n#   supabase functions serve mcp --env-file supabase/functions/.env\n\n# Deploy these values after linking your project:\n#   supabase secrets set --env-file supabase/functions/.env\n# Supabase provides the project URL and API keys automatically.\n\n# Keep the protocol-level server name short and project-specific.\nMCP_SERVER_NAME=supabase-mcp\nMCP_SERVER_DESCRIPTION=\"MCP access to this Supabase project for the signed-in user.\"\n",
      "type": "registry:file",
      "target": "~/supabase/functions/mcp/.env.example"
    },
    {
      "path": "registry/default/blocks/mcp/supabase/functions/mcp/tools/types.ts",
      "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"
    },
    {
      "path": "registry/default/blocks/mcp/supabase/functions/mcp/tools/result.ts",
      "content": "import type { CallToolResult } from 'npm:@modelcontextprotocol/server@2.0.0'\n\n// Shared helpers for building MCP tool results, so every tool returns the same\n// shape and signals failure the same way.\n\n/**\n * A successful structured result with a JSON text fallback for older clients.\n */\nexport function jsonResult(value: unknown): CallToolResult {\n  return {\n    content: [{ type: 'text', text: JSON.stringify(value) ?? 'null' }],\n    structuredContent: value ?? null,\n  }\n}\n\n/**\n * A failed result. The message goes back to the model so it can correct itself,\n * so keep it actionable — and free of credentials, claims, and stack traces.\n */\nexport function errorResult(message: string): CallToolResult {\n  return {\n    isError: true,\n    content: [{ type: 'text', text: message }],\n  }\n}\n\nfunction readString(value: unknown, key: string): string | null {\n  if (!value || typeof value !== 'object' || !(key in value)) return null\n  const property = (value as Record<string, unknown>)[key]\n  return typeof property === 'string' && property ? property : null\n}\n\n/**\n * Turn an unknown thrown value into a safe MCP error. Supabase API errors often\n * carry a `code` and `hint`, both of which help a model fix its next call.\n */\nexport function runtimeErrorResult(error: unknown): CallToolResult {\n  const message = error instanceof Error ? error.message : String(error)\n  const code = readString(error, 'code')\n  const hint = readString(error, 'hint')\n\n  return errorResult(\n    [code ? `[${code}]` : null, message, hint ? `Hint: ${hint}` : null].filter(Boolean).join(' ')\n  )\n}\n",
      "type": "registry:file",
      "target": "~/supabase/functions/mcp/tools/result.ts"
    },
    {
      "path": "registry/default/blocks/mcp/supabase/functions/mcp/tools/whoami.ts",
      "content": "import type { McpServer } from 'npm:@modelcontextprotocol/server@2.0.0'\n\nimport { jsonResult } from './result.ts'\nimport type { ToolContext } from './types.ts'\n\n// Answers from verified claims, demonstrating that every tool runs as the\n// signed-in user. client_id is present for OAuth tokens and null for ordinary\n// product sessions.\nexport function registerWhoamiTool(\n  server: McpServer,\n  { userClaims, jwtClaims }: ToolContext\n): void {\n  const clientId =\n    typeof jwtClaims?.client_id === 'string' && jwtClaims.client_id ? jwtClaims.client_id : null\n\n  server.registerTool(\n    'whoami',\n    {\n      description: \"Return the signed-in user's identity and OAuth client id, when present.\",\n      annotations: {\n        readOnlyHint: true,\n        destructiveHint: false,\n        openWorldHint: false,\n      },\n    },\n    () =>\n      jsonResult({\n        id: userClaims.id,\n        email: userClaims.email ?? null,\n        role: userClaims.role ?? null,\n        client_id: clientId,\n      })\n  )\n}\n",
      "type": "registry:file",
      "target": "~/supabase/functions/mcp/tools/whoami.ts"
    },
    {
      "path": "registry/default/blocks/mcp/supabase/functions/mcp/tools/index.ts",
      "content": "import type { McpServer } from 'npm:@modelcontextprotocol/server@2.0.0'\n\nimport type { ToolContext } from './types.ts'\nimport { registerWhoamiTool } from './whoami.ts'\n\nexport type { ToolContext } from './types.ts'\n\n// The one composition point for this server. Add one registration call for\n// each tool module; the MCP SDK rejects duplicate protocol tool names.\nexport function registerTools(server: McpServer, context: ToolContext): void {\n  registerWhoamiTool(server, context)\n}\n",
      "type": "registry:file",
      "target": "~/supabase/functions/mcp/tools/index.ts"
    }
  ],
  "docs": "Disable gateway JWT verification, then deploy the Edge Function. A trusted product backend can call it with the signed-in user's access token. For external clients, install the [OAuth Consent block](https://supabase.com/library/docs/nextjs/oauth-consent), enable OAuth and dynamic registration, and set the Auth Site URL to the consent app. Every call runs through the user's RLS-scoped client. OAuth tokens include `client_id`; product sessions do not, so define policies for both paths. See [MCP authentication](https://supabase.com/docs/guides/auth/oauth-server/mcp-authentication) and [token security](https://supabase.com/docs/guides/auth/oauth-server/token-security).",
  "type": "registry:item"
}