Skip to main content
Glama
abushadab

Self-Hosted Supabase MCP Server

by abushadab

get_auth_user

Retrieve user details, such as authentication data, from a self-hosted Supabase instance by specifying a user’s UUID. Simplify user management directly from MCP-compatible environments for efficient Supabase integration.

Instructions

Retrieves details for a specific user from auth.users by their ID.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
user_idYesThe UUID of the user to retrieve.

Implementation Reference

  • The execute handler function for the get_auth_user tool. It performs a parameterized SQL query on auth.users to fetch user details by ID using a direct PG transaction, validates the single row result with AuthUserZodSchema, handles errors, logs progress, and returns the AuthUser object.
    execute: async (input: GetAuthUserInput, context: ToolContext): Promise<GetAuthUserOutput> => { // Use GetAuthUserOutput
        const client = context.selfhostedClient;
        const { user_id } = input;
    
        if (!client.isPgAvailable()) {
            context.log('Direct database connection (DATABASE_URL) is required to get auth user details.', 'error');
            throw new Error('Direct database connection (DATABASE_URL) is required to get auth user details.');
        }
    
        const sql = `
            SELECT
                id,
                email,
                role,
                raw_app_meta_data,
                raw_user_meta_data,
                created_at::text,
                last_sign_in_at::text
            FROM auth.users
            WHERE id = $1
        `;
        const params = [user_id];
    
        console.error(`Attempting to get auth user ${user_id} using direct DB connection...`);
    
        // Use transaction for parameterized query
        const user = await client.executeTransactionWithPg(async (pgClient: PoolClient) => {
            const result = await pgClient.query(sql, params);
    
            if (result.rows.length === 0) {
                throw new Error(`User with ID ${user_id} not found.`);
            }
    
            // handleSqlResponse expects SqlExecutionResult (SuccessResponse | ErrorResponse)
            // We pass the single row which structurally matches SqlSuccessResponse[0]
            // but handleSqlResponse expects the array wrapper or error.
            // So, we validate the single object directly.
            try {
                const singleUser = AuthUserZodSchema.parse(result.rows[0]);
                return singleUser;
            } catch (validationError) {
                 if (validationError instanceof z.ZodError) {
                    console.error("Zod validation failed:", validationError.errors);
                    throw new Error(`Output validation failed: ${validationError.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ')}`);
                } 
                throw validationError; // Rethrow other errors
            }
        });
    
        console.error(`Found user ${user_id}.`);
        context.log(`Found user ${user_id}.`);
        // The return type is already AuthUser (via GetAuthUserOutput)
        return user;
    },
  • Zod input schema requiring user_id (UUID), output schema matching AuthUser fields, TypeScript type aliases, and static MCP JSON input schema.
    const GetAuthUserInputSchema = z.object({
        user_id: z.string().uuid().describe('The UUID of the user to retrieve.'),
    });
    type GetAuthUserInput = z.infer<typeof GetAuthUserInputSchema>;
    
    // Output schema - Zod for validation (single user)
    const AuthUserZodSchema = z.object({
        id: z.string().uuid(),
        email: z.string().email().nullable(),
        role: z.string().nullable(),
        created_at: z.string().nullable(),
        last_sign_in_at: z.string().nullable(),
        raw_app_meta_data: z.record(z.unknown()).nullable(),
        raw_user_meta_data: z.record(z.unknown()).nullable(),
        // Add more fields as needed
    });
    // Use AuthUser for the output type hint
    type GetAuthUserOutput = AuthUser;
    
    // Static JSON Schema for MCP
    const mcpInputSchema = {
        type: 'object',
        properties: {
            user_id: {
                type: 'string',
                description: 'The UUID of the user to retrieve.',
                format: 'uuid', // Hint format if possible
            },
        },
        required: ['user_id'],
    };
  • src/index.ts:114-114 (registration)
    Registers the imported getAuthUserTool in the availableTools object, which is used to populate the MCP server's tools capabilities.
    [getAuthUserTool.name]: getAuthUserTool as AppTool,
  • TypeScript interface defining the AuthUser type, used for output typing and Zod schema basis in get_auth_user tool.
     * Represents a user object from the auth.users table.
     * Based on fields selected in listAuthUsersTool, getAuthUserTool etc.
     */
    export interface AuthUser {
        id: string; // uuid
        email: string | null;
        role: string | null;
        created_at: string | null; // Timestamps returned as text from DB
        last_sign_in_at: string | null;
        raw_app_meta_data: Record<string, unknown> | null;
        raw_user_meta_data: Record<string, unknown> | null;
        // Add other relevant fields if needed, e.g., email_confirmed_at
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states it 'retrieves details' but doesn't specify what details are included, whether it's a read-only operation, error handling for invalid IDs, or any rate limits. This leaves significant gaps in understanding the tool's behavior beyond basic functionality.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that directly states the tool's purpose without unnecessary words. It is front-loaded with the core action and resource, making it easy to understand quickly. Every part of the sentence contributes essential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of user retrieval (which may involve authentication, data sensitivity, or error cases), the description is insufficient. With no annotations and no output schema, it fails to explain what details are returned, potential errors, or security considerations. This makes it incomplete for effective agent use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description mentions retrieving by 'ID', which aligns with the 'user_id' parameter in the schema. Since schema description coverage is 100%, the schema already fully documents the parameter, so the description adds minimal value beyond confirming the parameter's role. This meets the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Retrieves details') and resource ('specific user from auth.users'), making the purpose unambiguous. However, it doesn't differentiate from sibling tools like 'list_auth_users' or 'get_database_connections', which would require explicit comparison to achieve a score of 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like 'list_auth_users' for multiple users or other user-related tools. It lacks context about prerequisites, such as needing a specific user ID, and doesn't mention any exclusions or typical use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/abushadab/selfhosted-supabase-mcp-basic-auth'

If you have feedback or need assistance with the MCP directory API, please join our Discord server