Skip to main content
Glama
HenkDz

PostgreSQL MCP Server

pg_manage_rls

Enable, disable, or manage PostgreSQL Row-Level Security (RLS) policies. Perform operations like creating, editing, dropping, or retrieving policies for specific tables and roles with detailed control over conditions and permissions.

Instructions

Manage PostgreSQL Row-Level Security - enable/disable RLS and manage policies. Examples: operation="enable" with tableName="users", operation="create_policy" with tableName, policyName, using, check

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
checkNoWITH CHECK expression for policy (optional for create_policy/edit_policy)
commandNoCommand the policy applies to (for create_policy)
connectionStringNoPostgreSQL connection string (optional)
ifExistsNoInclude IF EXISTS clause (for drop_policy)
operationYesOperation: enable/disable RLS, create_policy, edit_policy, drop_policy, get_policies
policyNameNoPolicy name (required for create_policy/edit_policy/drop_policy)
replaceNoWhether to replace policy if exists (for create_policy)
roleNoRole the policy applies to (for create_policy)
rolesNoList of roles for policy (for edit_policy)
schemaNoSchema name (defaults to public)
tableNameNoTable name (required for enable/disable/create_policy/edit_policy/drop_policy, optional filter for get_policies)
usingNoUSING expression for policy (required for create_policy, optional for edit_policy)

Implementation Reference

  • Main handler implementation for the 'pg_manage_rls' tool. Defines the tool object with name, description, input schema, and execute function that handles multiple RLS operations by dispatching to internal helper functions based on the 'operation' parameter.
    export const manageRLSTool: PostgresTool = { name: 'pg_manage_rls', description: 'Manage PostgreSQL Row-Level Security - enable/disable RLS and manage policies. Examples: operation="enable" with tableName="users", operation="create_policy" with tableName, policyName, using, check', inputSchema: z.object({ connectionString: z.string().optional().describe('PostgreSQL connection string (optional)'), operation: z.enum(['enable', 'disable', 'create_policy', 'edit_policy', 'drop_policy', 'get_policies']).describe('Operation: enable/disable RLS, create_policy, edit_policy, drop_policy, get_policies'), // Common parameters tableName: z.string().optional().describe('Table name (required for enable/disable/create_policy/edit_policy/drop_policy, optional filter for get_policies)'), schema: z.string().optional().describe('Schema name (defaults to public)'), // Policy-specific parameters policyName: z.string().optional().describe('Policy name (required for create_policy/edit_policy/drop_policy)'), using: z.string().optional().describe('USING expression for policy (required for create_policy, optional for edit_policy)'), check: z.string().optional().describe('WITH CHECK expression for policy (optional for create_policy/edit_policy)'), command: z.enum(['ALL', 'SELECT', 'INSERT', 'UPDATE', 'DELETE']).optional().describe('Command the policy applies to (for create_policy)'), role: z.string().optional().describe('Role the policy applies to (for create_policy)'), replace: z.boolean().optional().describe('Whether to replace policy if exists (for create_policy)'), // Edit policy parameters roles: z.array(z.string()).optional().describe('List of roles for policy (for edit_policy)'), // Drop policy parameters ifExists: z.boolean().optional().describe('Include IF EXISTS clause (for drop_policy)') }), // biome-ignore lint/suspicious/noExplicitAny: <explanation> execute: async (args: any, getConnectionStringVal: GetConnectionStringFn): Promise<ToolOutput> => { const { connectionString: connStringArg, operation, tableName, schema, policyName, using, check, command, role, replace, roles, ifExists } = args as { connectionString?: string; operation: 'enable' | 'disable' | 'create_policy' | 'edit_policy' | 'drop_policy' | 'get_policies'; tableName?: string; schema?: string; policyName?: string; using?: string; check?: string; command?: 'ALL' | 'SELECT' | 'INSERT' | 'UPDATE' | 'DELETE'; role?: string; replace?: boolean; roles?: string[]; ifExists?: boolean; }; const resolvedConnString = getConnectionStringVal(connStringArg); let result: FunctionResult; try { switch (operation) { case 'enable': { if (!tableName) { return { content: [{ type: 'text', text: 'Error: tableName is required for enable operation' }], isError: true }; } result = await _enableRLS(resolvedConnString, tableName, schema); break; } case 'disable': { if (!tableName) { return { content: [{ type: 'text', text: 'Error: tableName is required for disable operation' }], isError: true }; } result = await _disableRLS(resolvedConnString, tableName, schema); break; } case 'create_policy': { if (!tableName || !policyName || !using) { return { content: [{ type: 'text', text: 'Error: tableName, policyName, and using are required for create_policy operation' }], isError: true }; } result = await _createRLSPolicy(resolvedConnString, tableName, policyName, using, check, { schema, command, role, replace }); break; } case 'edit_policy': { if (!tableName || !policyName) { return { content: [{ type: 'text', text: 'Error: tableName and policyName are required for edit_policy operation' }], isError: true }; } result = await _editRLSPolicy(resolvedConnString, tableName, policyName, { schema, roles, using, check }); break; } case 'drop_policy': { if (!tableName || !policyName) { return { content: [{ type: 'text', text: 'Error: tableName and policyName are required for drop_policy operation' }], isError: true }; } result = await _dropRLSPolicy(resolvedConnString, tableName, policyName, { schema, ifExists }); break; } case 'get_policies': { result = await _getRLSPolicies(resolvedConnString, tableName, schema); if (result.success) { return { content: [{ type: 'text', text: JSON.stringify(result.details, null, 2) || result.message }] }; } break; } default: return { content: [{ type: 'text', text: `Error: Unknown operation "${operation}". Supported operations: enable, disable, create_policy, edit_policy, drop_policy, get_policies` }], isError: true }; } if (result.success) { return { content: [{ type: 'text', text: result.message + (result.details ? ` Details: ${JSON.stringify(result.details)}` : '') }] }; } return { content: [{ type: 'text', text: result.message }], isError: true }; } catch (error) { return { content: [{ type: 'text', text: `Error executing ${operation} operation: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } };
  • Zod input schema defining parameters for pg_manage_rls tool, including operation type and specific fields for RLS management.
    inputSchema: z.object({ connectionString: z.string().optional().describe('PostgreSQL connection string (optional)'), operation: z.enum(['enable', 'disable', 'create_policy', 'edit_policy', 'drop_policy', 'get_policies']).describe('Operation: enable/disable RLS, create_policy, edit_policy, drop_policy, get_policies'), // Common parameters tableName: z.string().optional().describe('Table name (required for enable/disable/create_policy/edit_policy/drop_policy, optional filter for get_policies)'), schema: z.string().optional().describe('Schema name (defaults to public)'), // Policy-specific parameters policyName: z.string().optional().describe('Policy name (required for create_policy/edit_policy/drop_policy)'), using: z.string().optional().describe('USING expression for policy (required for create_policy, optional for edit_policy)'), check: z.string().optional().describe('WITH CHECK expression for policy (optional for create_policy/edit_policy)'), command: z.enum(['ALL', 'SELECT', 'INSERT', 'UPDATE', 'DELETE']).optional().describe('Command the policy applies to (for create_policy)'), role: z.string().optional().describe('Role the policy applies to (for create_policy)'), replace: z.boolean().optional().describe('Whether to replace policy if exists (for create_policy)'), // Edit policy parameters roles: z.array(z.string()).optional().describe('List of roles for policy (for edit_policy)'), // Drop policy parameters ifExists: z.boolean().optional().describe('Include IF EXISTS clause (for drop_policy)') }),
  • src/index.ts:225-257 (registration)
    The pg_manage_rls tool (imported as manageRLSTool) is registered by inclusion in the allTools array, which is passed to the PostgreSQLServer constructor to set up MCP tool capabilities.
    const allTools: PostgresTool[] = [ // Core Analysis & Debugging analyzeDatabaseTool, debugDatabaseTool, // Schema & Structure Management (Meta-Tools) manageSchemaTools, manageFunctionsTool, manageTriggersTools, manageIndexesTool, manageConstraintsTool, manageRLSTool, // User & Security Management manageUsersTool, // Query & Performance Management manageQueryTool, // Data Operations (Enhancement Tools) executeQueryTool, executeMutationTool, executeSqlTool, // Documentation & Metadata manageCommentsTool, // Data Migration & Monitoring exportTableDataTool, importTableDataTool, copyBetweenDatabasesTool, monitorDatabaseTool ];
  • Helper function _enableRLS used by pg_manage_rls handler for enabling RLS on a table.
    async function _enableRLS( connectionString: string, tableName: string, schema = 'public' ): Promise<FunctionResult> { const db = DatabaseConnection.getInstance(); try { await db.connect(connectionString); await db.query(`ALTER TABLE ${schema}.${tableName} ENABLE ROW LEVEL SECURITY`); return { success: true, message: `Row-Level Security enabled on ${schema}.${tableName}`, details: { table: tableName, schema } }; } catch (error) { return { success: false, message: `Failed to enable RLS: ${error instanceof Error ? error.message : String(error)}`, details: null }; } finally { await db.disconnect(); } }

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/HenkDz/postgresql-mcp-server'

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