docs: remote MCP UI paper cut improvements (#39211)
* fix: only show "Authentication" note for hosted platform * fix: platform/project selector wrapping for small screens * fix: disable contentEditable on codeblock to hide system spellcheck * feat: standalone codeblock for mcpUrl * fix: use <Portal> for client select popover to improve scrollIntoView behavior * feat: remove "Other" client option * feat: tooltip specifying MCP transport / auth requirements * feat: update auth tooltip copy, only show for hosted platform * docs: remove old local Supabase MCP instructions * feat: improve description on docs feature group --------- Co-authored-by: Greg Richardson <greg.nmr@gmail.com>
This commit is contained in:
1
.cursorignore
Normal file
1
.cursorignore
Normal file
@@ -0,0 +1 @@
|
||||
!.env.example
|
||||
@@ -20,14 +20,6 @@ Choose your Supabase platform, project, and MCP client and follow the installati
|
||||
|
||||
<McpConfigPanel />
|
||||
|
||||
<Admonition type="note" title="Authentication" className="mt-3">
|
||||
|
||||
Your MCP client will automatically prompt you to login to Supabase during setup. This will open a browser window where you can login to your Supabase account and grant access to the MCP client. Be sure to choose the organization that contains the project you wish to work with. In the future, we'll offer more fine grain control over these permissions.
|
||||
|
||||
Previously Supabase MCP required you to generate a personal access token (PAT), but this is no longer required.
|
||||
|
||||
</Admonition>
|
||||
|
||||
### Next steps
|
||||
|
||||
Your AI tool is now connected to your Supabase project or account using remote MCP. Try asking the AI tool to query your database using natural language commands.
|
||||
@@ -63,33 +55,3 @@ We recommend the following best practices to mitigate security risks when using
|
||||
- **Project scoping**: Scope your MCP server to a [specific project](https://github.com/supabase-community/supabase-mcp#project-scoped-mode), limiting access to only that project's resources. This prevents LLMs from accessing data from other projects in your Supabase account.
|
||||
- **Branching**: Use Supabase's [branching feature](/docs/guides/deployment/branching) to create a development branch for your database. This allows you to test changes in a safe environment before merging them to production.
|
||||
- **Feature groups**: The server allows you to enable or disable specific [tool groups](https://github.com/supabase-community/supabase-mcp#feature-groups), so you can control which tools are available to the LLM. This helps reduce the attack surface and limits the actions that LLMs can perform to only those that you need.
|
||||
|
||||
## MCP for local Supabase instances
|
||||
|
||||
The Supabase MCP server connects directly to the cloud platform to access your database. If you are running a local instance of Supabase, you can instead use the [Postgres MCP server](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/postgres) to connect to your local database. This MCP server runs all queries as read-only transactions.
|
||||
|
||||
### Step 1: Find your database connection string
|
||||
|
||||
To connect to your local Supabase instance, you need to get the connection string for your local database. You can find your connection string by running:
|
||||
|
||||
```shell
|
||||
supabase status
|
||||
```
|
||||
|
||||
or if you are using `npx`:
|
||||
|
||||
```shell
|
||||
npx supabase status
|
||||
```
|
||||
|
||||
This will output a list of details about your local Supabase instance. Copy the `DB URL` field in the output.
|
||||
|
||||
### Step 2: Configure the MCP server
|
||||
|
||||
Configure your client with the following:
|
||||
|
||||
<$Partial path="mcp_postgres_config.mdx" variables={{ "app": "your MCP client" }} />
|
||||
|
||||
### Next steps
|
||||
|
||||
Your AI tool is now connected to your local Supabase instance using MCP. Try asking the AI tool to query your database using natural language commands.
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
PopoverContent_Shadcn_,
|
||||
PopoverTrigger_Shadcn_,
|
||||
} from 'ui'
|
||||
import { Admonition } from 'ui-patterns'
|
||||
import { McpConfigPanel as McpConfigPanelBase } from 'ui-patterns/McpUrlBuilder'
|
||||
import { useProjectsQuery } from '~/lib/fetch/projects'
|
||||
|
||||
@@ -193,28 +194,44 @@ export function McpConfigPanel() {
|
||||
const project = isPlatform ? selectedProject : null
|
||||
|
||||
return (
|
||||
<div className="not-prose">
|
||||
<div className="flex gap-3 mb-3">
|
||||
<PlatformSelector
|
||||
selectedPlatform={selectedPlatform}
|
||||
onPlatformSelect={setSelectedPlatform}
|
||||
<>
|
||||
<div className="not-prose">
|
||||
<div className="flex flex-wrap gap-3 mb-3">
|
||||
<PlatformSelector
|
||||
selectedPlatform={selectedPlatform}
|
||||
onPlatformSelect={setSelectedPlatform}
|
||||
/>
|
||||
{isPlatform && (
|
||||
<ProjectSelector selectedProject={project} onProjectSelect={setSelectedProject} />
|
||||
)}
|
||||
</div>
|
||||
<p className="text-xs text-foreground-lighter">
|
||||
{isPlatform
|
||||
? 'Scope the MCP server to a project. If no project is selected, all projects will be accessible.'
|
||||
: 'Project selection is only available for the hosted platform.'}
|
||||
</p>
|
||||
<McpConfigPanelBase
|
||||
basePath="/docs"
|
||||
className="mt-6"
|
||||
projectRef={project?.ref}
|
||||
theme={theme as 'light' | 'dark'}
|
||||
isPlatform={isPlatform}
|
||||
/>
|
||||
{isPlatform && (
|
||||
<ProjectSelector selectedProject={project} onProjectSelect={setSelectedProject} />
|
||||
)}
|
||||
</div>
|
||||
<p className="text-xs text-foreground-lighter">
|
||||
{isPlatform
|
||||
? 'Scope the MCP server to a project. If no project is selected, all projects will be accessible.'
|
||||
: 'Project selection is only available for the hosted platform.'}
|
||||
</p>
|
||||
<McpConfigPanelBase
|
||||
basePath="/docs"
|
||||
className="mt-6"
|
||||
projectRef={project?.ref}
|
||||
theme={theme as 'light' | 'dark'}
|
||||
isPlatform={isPlatform}
|
||||
/>
|
||||
</div>
|
||||
{isPlatform && (
|
||||
<Admonition type="note" title="Authentication" className="mt-3">
|
||||
<p>
|
||||
{
|
||||
"Your MCP client will automatically prompt you to login to Supabase during setup. This will open a browser window where you can login to your Supabase account and grant access to the MCP client. Be sure to choose the organization that contains the project you wish to work with. In the future, we'll offer more fine grain control over these permissions."
|
||||
}
|
||||
</p>
|
||||
<p>
|
||||
{
|
||||
'Previously Supabase MCP required you to generate a personal access token (PAT), but this is no longer required.'
|
||||
}
|
||||
</p>
|
||||
</Admonition>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
'use client'
|
||||
|
||||
import React, { useMemo, useState } from 'react'
|
||||
import { cn, Separator } from 'ui'
|
||||
import { cn, Separator, CodeBlock } from 'ui'
|
||||
|
||||
import { ClientSelectDropdown } from './components/ClientSelectDropdown'
|
||||
import { McpConfigurationDisplay } from './components/McpConfigurationDisplay'
|
||||
import { McpConfigurationOptions } from './components/McpConfigurationOptions'
|
||||
import { FEATURE_GROUPS_PLATFORM, FEATURE_GROUPS_NON_PLATFORM, MCP_CLIENTS } from './constants'
|
||||
import { FEATURE_GROUPS_NON_PLATFORM, FEATURE_GROUPS_PLATFORM, MCP_CLIENTS } from './constants'
|
||||
import type { McpClient } from './types'
|
||||
import { getMcpUrl } from './utils/getMcpUrl'
|
||||
import { InfoTooltip } from '../info-tooltip'
|
||||
|
||||
export interface McpConfigPanelProps {
|
||||
basePath: string
|
||||
@@ -43,7 +44,7 @@ export function McpConfigPanel({
|
||||
)
|
||||
}, [selectedFeatures, supportedFeatures])
|
||||
|
||||
const { clientConfig } = getMcpUrl({
|
||||
const { mcpUrl, clientConfig } = getMcpUrl({
|
||||
projectRef,
|
||||
isPlatform,
|
||||
apiUrl,
|
||||
@@ -78,6 +79,24 @@ export function McpConfigPanel({
|
||||
onFeaturesChange={setSelectedFeatures}
|
||||
featureGroups={isPlatform ? FEATURE_GROUPS_PLATFORM : FEATURE_GROUPS_NON_PLATFORM}
|
||||
/>
|
||||
<div className={innerPanelSpacing}>
|
||||
<CodeBlock
|
||||
focusable={false}
|
||||
title={
|
||||
<div className="flex items-center gap-2">
|
||||
Server URL
|
||||
<InfoTooltip>
|
||||
{`MCP clients should support the Streamable HTTP transport${isPlatform ? ' and OAuth 2.1 with dynamic client registration' : ''}`}
|
||||
</InfoTooltip>
|
||||
</div>
|
||||
}
|
||||
hideLineNumbers
|
||||
language="http"
|
||||
className="max-h-64 overflow-y-auto"
|
||||
>
|
||||
{mcpUrl}
|
||||
</CodeBlock>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-3">
|
||||
<ClientSelectDropdown
|
||||
|
||||
@@ -77,7 +77,7 @@ export const ClientSelectDropdown = ({
|
||||
</Button>
|
||||
</PopoverTrigger_Shadcn_>
|
||||
</div>
|
||||
<PopoverContent_Shadcn_ className="mt-0 p-0 max-w-48" side="bottom" align="start">
|
||||
<PopoverContent_Shadcn_ className="mt-0 p-0 max-w-48" side="bottom" align="start" portal>
|
||||
<Command_Shadcn_>
|
||||
<CommandInput_Shadcn_ placeholder="Search..." />
|
||||
<CommandList_Shadcn_>
|
||||
|
||||
@@ -65,6 +65,7 @@ export function McpConfigurationDisplay({
|
||||
value={JSON.stringify(clientConfig, null, 2)}
|
||||
language="json"
|
||||
className="max-h-64 overflow-y-auto"
|
||||
focusable={false}
|
||||
/>
|
||||
|
||||
{selectedClient.alternateInstructions && selectedClient.alternateInstructions(clientConfig)}
|
||||
|
||||
@@ -3,7 +3,6 @@ import type {
|
||||
ClaudeCodeMcpConfig,
|
||||
McpClient,
|
||||
McpFeatureGroup,
|
||||
OtherMcpConfig,
|
||||
VSCodeMcpConfig,
|
||||
WindsurfMcpConfig,
|
||||
} from './types'
|
||||
@@ -12,7 +11,7 @@ export const FEATURE_GROUPS_PLATFORM: McpFeatureGroup[] = [
|
||||
{
|
||||
id: 'docs',
|
||||
name: 'Documentation',
|
||||
description: 'Access project documentation and guides',
|
||||
description: 'Access Supabase documentation and guides',
|
||||
},
|
||||
{
|
||||
id: 'account',
|
||||
@@ -151,29 +150,6 @@ export const MCP_CLIENTS: McpClient[] = [
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'other',
|
||||
label: 'Other',
|
||||
transformConfig: (config): OtherMcpConfig => {
|
||||
return {
|
||||
mcpServers: {
|
||||
supabase: {
|
||||
type: 'http',
|
||||
url: config.mcpServers.supabase.url,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
alternateInstructions: (_config) => {
|
||||
return (
|
||||
<p className="text-xs text-foreground-light">
|
||||
These generic MCP settings may work with other MCP clients, but there are no guarantees,
|
||||
due to differences between clients. Refer to your specific client docs for where to input
|
||||
the configuration.
|
||||
</p>
|
||||
)
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export const DEFAULT_MCP_URL_PLATFORM = 'http://localhost:8080/mcp'
|
||||
|
||||
Reference in New Issue
Block a user