mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 18:05:11 +03:00
251 lines
7.2 KiB
Plaintext
251 lines
7.2 KiB
Plaintext
---
|
|
title: 'Enabling MCP Server Access'
|
|
description: 'Configure secure access to the MCP server in your self-hosted Supabase instance.'
|
|
subtitle: 'Configure secure access to the MCP server in your self-hosted Supabase instance.'
|
|
---
|
|
|
|
The MCP (Model Context Protocol) server in [self-hosted Supabase](/docs/guides/self-hosting/docker) runs behind the internal API. Currently, it does not offer OAuth 2.1 authentication, and is not intended to be exposed to the Internet. The corresponding API route has to be protected by restricting network connections from the outside. By default, all connections to the MCP server are denied.
|
|
|
|
This guide explains how to securely enable access to your self-hosted MCP server.
|
|
|
|
## Security considerations
|
|
|
|
<Admonition type="caution">
|
|
|
|
Do not allow connections to the self-hosted MCP server from the Internet. Only access it via:
|
|
|
|
- A VPN connection to the server running the Studio container
|
|
- An SSH tunnel from your local machine
|
|
|
|
</Admonition>
|
|
|
|
## Accessing via SSH tunnel
|
|
|
|
### Step 1: Determine the local IP address that will be used to access the MCP server
|
|
|
|
When connecting via an SSH tunnel to the Studio Docker container, the source IP will be that of the Docker bridge gateway. You need to allow connections from this IP address.
|
|
|
|
<Tabs
|
|
scrollable
|
|
size="small"
|
|
type="underlined"
|
|
defaultActiveId="envoy"
|
|
>
|
|
|
|
<TabPanel id="envoy" label="Envoy">
|
|
|
|
Determine the Docker bridge gateway IP on the host running your Supabase containers:
|
|
|
|
```sh
|
|
docker inspect supabase-envoy \
|
|
--format '{{range .NetworkSettings.Networks}}{{println .Gateway}}{{end}}'
|
|
```
|
|
|
|
</TabPanel>
|
|
|
|
<TabPanel id="kong" label="Kong">
|
|
|
|
Determine the Docker bridge gateway IP on the host running your Supabase containers:
|
|
|
|
```sh
|
|
docker inspect supabase-kong \
|
|
--format '{{range .NetworkSettings.Networks}}{{println .Gateway}}{{end}}'
|
|
```
|
|
|
|
</TabPanel>
|
|
|
|
</Tabs>
|
|
|
|
This command will output an IP address, e.g., `172.18.0.1`.
|
|
|
|
### Step 2: Allow connections from the gateway IP
|
|
|
|
<Tabs
|
|
scrollable
|
|
size="small"
|
|
type="underlined"
|
|
defaultActiveId="envoy"
|
|
>
|
|
|
|
<TabPanel id="envoy" label="Envoy">
|
|
|
|
Add the IP address you discovered to the Envoy configuration by editing the `/mcp` route in `./volumes/api/envoy/lds.template.yaml`:
|
|
|
|
1. Find the route with `prefix: /mcp`
|
|
2. Comment out the `rbac` block that denies all traffic and uncomment the allow-list policy below
|
|
3. Keep loopback entries (`127.0.0.1` and `::1`) and add your Docker bridge gateway IP
|
|
4. **Preserve the existing indentation** - YAML is whitespace-sensitive and the config will fail to load if it changes
|
|
5. Your edited configuration should look like the example below:
|
|
|
|
```yaml name=volumes/api/envoy/lds.template.yaml
|
|
- match:
|
|
prefix: /mcp
|
|
route:
|
|
cluster: studio
|
|
prefix_rewrite: /api/mcp
|
|
timeout: 30s
|
|
request_headers_to_add:
|
|
- header:
|
|
key: X-Forwarded-Prefix
|
|
value: /mcp
|
|
append_action: ADD_IF_ABSENT
|
|
typed_per_filter_config:
|
|
envoy.filters.http.basic_auth:
|
|
'@type': >-
|
|
type.googleapis.com/envoy.config.route.v3.FilterConfig
|
|
disabled: true
|
|
envoy.filters.http.rbac:
|
|
'@type': >-
|
|
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
|
|
# Block access to /mcp by default
|
|
#rbac:
|
|
# rules:
|
|
# action: DENY
|
|
# policies:
|
|
# deny_all:
|
|
# permissions:
|
|
# - any: true
|
|
# principals:
|
|
# - any: true
|
|
# Enable local access (danger zone!)
|
|
# 1. Comment out the 'rbac' block above.
|
|
# 2. Uncomment and adjust the 'rbac' block below.
|
|
# 3. Add or adjust your local IPs in 'principals'.
|
|
rbac:
|
|
rules:
|
|
action: ALLOW
|
|
policies:
|
|
allow_local:
|
|
permissions:
|
|
- any: true
|
|
principals:
|
|
- direct_remote_ip:
|
|
address_prefix: 127.0.0.1
|
|
prefix_len: 32
|
|
- direct_remote_ip:
|
|
address_prefix: ::1
|
|
prefix_len: 128
|
|
- direct_remote_ip:
|
|
# Add your Docker bridge gateway IP below
|
|
address_prefix: 172.18.0.1
|
|
prefix_len: 32
|
|
```
|
|
|
|
</TabPanel>
|
|
|
|
<TabPanel id="kong" label="Kong">
|
|
|
|
Add the IP address you discovered to the Kong configuration by editing the following section in `./volumes/api/kong.yml`:
|
|
|
|
1. Comment out the request-termination section
|
|
2. Remove the # symbols from the entire section starting with `- name: cors`, including `deny: []`
|
|
3. Add your local IP to the 'allow' list
|
|
4. **Preserve the existing indentation** - YAML is whitespace-sensitive and the config will fail to load if it changes
|
|
5. Your edited configuration should look like the example below:
|
|
|
|
```yaml name=volumes/api/kong.yml
|
|
## MCP endpoint - local access
|
|
- name: mcp
|
|
_comment: 'MCP: /mcp -> http://studio:3000/api/mcp (local access)'
|
|
url: http://studio:3000/api/mcp
|
|
routes:
|
|
- name: mcp
|
|
strip_path: true
|
|
paths:
|
|
- /mcp
|
|
plugins:
|
|
# Block access to /mcp by default
|
|
#- name: request-termination
|
|
# config:
|
|
# status_code: 403
|
|
# message: "Access is forbidden."
|
|
# Enable local access (danger zone!)
|
|
# 1. Comment out the 'request-termination' section above
|
|
# 2. Uncomment the entire section below, including 'deny'
|
|
# 3. Add your local IPs to the 'allow' list
|
|
- name: cors
|
|
- name: ip-restriction
|
|
config:
|
|
allow:
|
|
- 127.0.0.1
|
|
- ::1
|
|
# Add your Docker bridge gateway IP below
|
|
- 172.18.0.1
|
|
# Do not remove deny!
|
|
deny: []
|
|
```
|
|
|
|
</TabPanel>
|
|
|
|
</Tabs>
|
|
|
|
### Step 3: Restart API gateway
|
|
|
|
After you've added the local IP address as above, restart your gateway:
|
|
|
|
```sh
|
|
sh run.sh restart api-gw
|
|
```
|
|
|
|
### Step 4: Create the SSH tunnel
|
|
|
|
From your local machine, create an SSH tunnel to your Supabase host:
|
|
|
|
```sh
|
|
ssh -L localhost:8080:localhost:8000 you@your-supabase-host
|
|
```
|
|
|
|
This command forwards local port `8080` to port `8000` on your Supabase host.
|
|
|
|
### Step 5: Configure your MCP client
|
|
|
|
Edit the settings for your MCP client and add the following to `"mcpServers": {}` or `"servers": {}`:
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"supabase-self-hosted": {
|
|
"url": "http://localhost:8080/mcp"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Step 6: Start using the self-hosted MCP server
|
|
|
|
From your local machine, check that the MCP server is reachable:
|
|
|
|
```sh
|
|
curl http://localhost:8080/mcp \
|
|
-X POST \
|
|
-H "Content-Type: application/json" \
|
|
-H "Accept: application/json, text/event-stream" \
|
|
-H "MCP-Protocol-Version: 2025-06-18" \
|
|
-d '{
|
|
"jsonrpc": "2.0",
|
|
"id": 1,
|
|
"method": "initialize",
|
|
"params": {
|
|
"protocolVersion": "2025-06-18",
|
|
"capabilities": {
|
|
"elicitation": {}
|
|
},
|
|
"clientInfo": {
|
|
"name": "test-client",
|
|
"title": "Test Client",
|
|
"version": "1.0.0"
|
|
}
|
|
}
|
|
}'
|
|
```
|
|
|
|
Start your MCP client (Claude Code, Cursor, etc.) and verify access to the MCP tools. For example, you can ask: "What is Supabase anon key? Use the Supabase MCP server tools."
|
|
|
|
## Troubleshooting
|
|
|
|
If you are unable to connect to the MCP server:
|
|
|
|
1. Confirm the Docker bridge gateway IP is correctly added to the API gateway configuration
|
|
2. Check the API gateway's logs for errors: `docker compose logs api-gw`
|
|
3. Make sure your SSH tunnel is active
|