/**
* [Beta] Authorize user through oauth.
*
* @param {Object} args - Arguments for OAuth authorization.
* @param {string} args.client_id - The client ID.
* @param {string} args.response_type - The response type.
* @param {string} args.redirect_uri - The redirect URI.
* @param {string} args.scope - The scope.
* @param {string} args.state - The state.
* @param {string} args.response_mode - The response mode.
* @param {string} args.code_challenge - The code challenge.
* @param {string} args.code_challenge_method - The code challenge method.
* @param {string} args.organization_slug - Organization slug.
* @param {string} args.resource - Resource indicator for MCP clients.
* @returns {Promise<Object>} - The response from the Supabase Management API.
*/
const authorizeUserOauth = async ({
client_id,
response_type,
redirect_uri,
scope,
state,
response_mode,
code_challenge,
code_challenge_method,
organization_slug,
resource
}) => {
const baseUrl = 'https://api.supabase.com';
try {
const url = new URL(`${baseUrl}/v1/oauth/authorize`);
if (client_id) url.searchParams.append('client_id', client_id);
if (response_type) url.searchParams.append('response_type', response_type);
if (redirect_uri) url.searchParams.append('redirect_uri', redirect_uri);
if (scope) url.searchParams.append('scope', scope);
if (state) url.searchParams.append('state', state);
if (response_mode) url.searchParams.append('response_mode', response_mode);
if (code_challenge) url.searchParams.append('code_challenge', code_challenge);
if (code_challenge_method) url.searchParams.append('code_challenge_method', code_challenge_method);
if (organization_slug) url.searchParams.append('organization_slug', organization_slug);
if (resource) url.searchParams.append('resource', resource);
const response = await fetch(url.toString(), {
method: 'GET'
});
// The endpoint may redirect or return no content.
if (response.status === 204) {
return { success: true, message: 'No Content' };
}
// Try to parse JSON, fallback to text
let data;
try {
data = await response.json();
} catch {
data = await response.text();
}
if (!response.ok) {
throw new Error(typeof data === 'string' ? data : JSON.stringify(data));
}
return data;
} catch (error) {
return {
error: error instanceof Error ? error.message : JSON.stringify(error)
};
}
};
/**
* Tool definition for authorizing user through oauth.
*/
const apiTool = {
function: authorizeUserOauth,
definition: {
type: 'function',
function: {
name: 'authorize_user_oauth',
description: '[Beta] Authorize user through oauth.',
parameters: {
type: 'object',
properties: {
client_id: {
type: 'string',
description: 'The client ID.'
},
response_type: {
type: 'string',
description: 'The response type.'
},
redirect_uri: {
type: 'string',
description: 'The redirect URI.'
},
scope: {
type: 'string',
description: 'The scope.'
},
state: {
type: 'string',
description: 'The state.'
},
response_mode: {
type: 'string',
description: 'The response mode.'
},
code_challenge: {
type: 'string',
description: 'The code challenge.'
},
code_challenge_method: {
type: 'string',
description: 'The code challenge method.'
},
organization_slug: {
type: 'string',
description: 'Organization slug.'
},
resource: {
type: 'string',
description: 'Resource indicator for MCP clients.'
}
},
required: [
'client_id',
'response_type',
'redirect_uri',
'scope',
'state',
'response_mode',
'code_challenge',
'code_challenge_method',
'organization_slug',
'resource'
]
}
}
}
};
export { apiTool };