1
1
import { Hono } from 'hono' ;
2
2
import { createSupabaseMcpServer } from '../server.js' ;
3
3
import { StatelessHttpServerTransport } from '@supabase/mcp-utils' ;
4
- import { ProxyOAuthServerProvider } from '@modelcontextprotocol/sdk/server/auth/providers/proxyProvider.js' ;
5
- import { mcpAuthMetadataRouter } from '@modelcontextprotocol/sdk/server/auth/router.js' ;
6
4
import { serve } from '@hono/node-server' ;
7
5
import { createSupabaseApiPlatform } from '../platform/api-platform.js' ;
8
6
import { cors } from 'hono/cors' ;
9
7
10
8
const managementApiUrl =
11
9
process . env . SUPABASE_API_URL ?? 'https://api.supabase.com' ;
12
10
13
- const port = process . env . PORT ? parseInt ( process . env . PORT , 10 ) : 3000
11
+ const port = process . env . PORT ? parseInt ( process . env . PORT , 10 ) : 3000 ;
14
12
15
13
const app = new Hono ( ) ;
16
14
17
15
//
18
- app . use ( cors (
19
- {
16
+ app . use (
17
+ cors ( {
20
18
origin : [ 'dev' , 'test' ] . includes ( ( process . env . ENV ?? '' ) . toLowerCase ( ) )
21
19
? '*'
22
20
: 'https://api.supabase.io/mcp' ,
23
- }
24
- ) )
21
+ } )
22
+ ) ;
25
23
26
24
/**
27
25
* Stateless HTTP transport for the Supabase MCP server.
@@ -40,9 +38,9 @@ app.post('/mcp', async (c) => {
40
38
}
41
39
42
40
const platform = createSupabaseApiPlatform ( {
43
- accessToken,
44
- apiUrl,
45
- } ) ;
41
+ accessToken,
42
+ apiUrl,
43
+ } ) ;
46
44
47
45
const server = createSupabaseMcpServer ( {
48
46
platform,
@@ -58,63 +56,82 @@ app.post('/mcp', async (c) => {
58
56
// SSE notifications not supported in stateless mode
59
57
app . get ( '/mcp' , async ( c ) => {
60
58
console . log ( 'Received GET MCP request' ) ;
61
- c . json ( {
62
- jsonrpc : "2.0" ,
63
- error : {
64
- code : - 32000 ,
65
- message : "Method not allowed."
59
+ c . json (
60
+ {
61
+ jsonrpc : '2.0' ,
62
+ error : {
63
+ code : - 32000 ,
64
+ message : 'Method not allowed.' ,
65
+ } ,
66
+ id : null ,
66
67
} ,
67
- id : null
68
- } , 405 ) ;
68
+ 405
69
+ ) ;
69
70
} ) ;
70
71
71
72
// Session termination not needed in stateless mode
72
73
app . delete ( '/mcp' , async ( c ) => {
73
74
console . log ( 'Received DELETE MCP request' ) ;
74
- c . json ( {
75
- jsonrpc : "2.0" ,
76
- error : {
77
- code : - 32000 ,
78
- message : "Method not allowed."
75
+ c . json (
76
+ {
77
+ jsonrpc : '2.0' ,
78
+ error : {
79
+ code : - 32000 ,
80
+ message : 'Method not allowed.' ,
81
+ } ,
82
+ id : null ,
79
83
} ,
80
- id : null
81
- } , 405 ) ;
84
+ 405
85
+ ) ;
82
86
} ) ;
83
87
84
-
85
88
const oauthMetadata = {
86
89
issuer : `${ managementApiUrl } ` ,
87
- authorization_endpoint : `${ managementApiUrl } /v1/oauth/authorize` ,
88
- token_endpoint : `${ managementApiUrl } /v1/oauth/token` ,
89
- registration_endpoint : `${ managementApiUrl } /platform/oauth/apps/register` ,
90
- token_endpoint_auth_methods_supported : [ 'client_secret_post' ] ,
91
- scopes_supported : [
92
- 'analytics:read' , 'analytics:write' ,
93
- 'auth:read' , 'auth:write' ,
94
- 'database:read' , 'database:write' ,
95
- 'domains:read' , 'domains:write' ,
96
- 'edge_functions:read' , 'edge_functions:write' ,
97
- 'environment:read' , 'environment:write' ,
98
- 'organizations:read' , 'organizations:write' ,
99
- 'projects:read' , 'projects:write' ,
100
- 'rest:read' , 'rest:write' ,
101
- 'secrets:read' , 'secrets:write' ,
102
- 'storage:read' , 'storage:write'
103
- ] ,
104
- response_types_supported : [ 'code' ] ,
105
- response_modes_supported : [ 'query' ] ,
106
- grant_types_supported : [ 'authorization_code' , 'refresh_token' ] ,
107
- code_challenge_methods_supported : [ 'S256' ] ,
108
- }
109
-
110
- const protectedResourceMetadata = {
111
- resource : `http://localhost:${ port } ` , // "https://api.supabase.io/mcp",
112
- authorization_servers : [ oauthMetadata . issuer ] ,
113
- scopes_supported : oauthMetadata . scopes_supported ,
114
- } ;
115
- app . get ( '/.well-known/oauth-protected-resource' , ( c ) => c . json ( protectedResourceMetadata ) ) ;
116
- app . get ( '/.well-known/oauth-authorization-server' , ( c ) => c . json ( oauthMetadata ) ) ;
117
-
90
+ authorization_endpoint : `${ managementApiUrl } /v1/oauth/authorize` ,
91
+ token_endpoint : `${ managementApiUrl } /v1/oauth/token` ,
92
+ registration_endpoint : `${ managementApiUrl } /platform/oauth/apps/register` ,
93
+ token_endpoint_auth_methods_supported : [ 'client_secret_post' ] ,
94
+ scopes_supported : [
95
+ 'analytics:read' ,
96
+ 'analytics:write' ,
97
+ 'auth:read' ,
98
+ 'auth:write' ,
99
+ 'database:read' ,
100
+ 'database:write' ,
101
+ 'domains:read' ,
102
+ 'domains:write' ,
103
+ 'edge_functions:read' ,
104
+ 'edge_functions:write' ,
105
+ 'environment:read' ,
106
+ 'environment:write' ,
107
+ 'organizations:read' ,
108
+ 'organizations:write' ,
109
+ 'projects:read' ,
110
+ 'projects:write' ,
111
+ 'rest:read' ,
112
+ 'rest:write' ,
113
+ 'secrets:read' ,
114
+ 'secrets:write' ,
115
+ 'storage:read' ,
116
+ 'storage:write' ,
117
+ ] ,
118
+ response_types_supported : [ 'code' ] ,
119
+ response_modes_supported : [ 'query' ] ,
120
+ grant_types_supported : [ 'authorization_code' , 'refresh_token' ] ,
121
+ code_challenge_methods_supported : [ 'S256' ] ,
122
+ } ;
123
+
124
+ const protectedResourceMetadata = {
125
+ resource : `http://localhost:${ port } ` , // "https://api.supabase.io/mcp",
126
+ authorization_servers : [ oauthMetadata . issuer ] ,
127
+ scopes_supported : oauthMetadata . scopes_supported ,
128
+ } ;
129
+ app . get ( '/.well-known/oauth-protected-resource' , ( c ) =>
130
+ c . json ( protectedResourceMetadata )
131
+ ) ;
132
+ app . get ( '/.well-known/oauth-authorization-server' , ( c ) =>
133
+ c . json ( oauthMetadata )
134
+ ) ;
118
135
119
136
serve (
120
137
{
0 commit comments