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
| Name | Required | Description | Default |
|---|---|---|---|
| check | No | WITH CHECK expression for policy (optional for create_policy/edit_policy) | |
| command | No | Command the policy applies to (for create_policy) | |
| connectionString | No | PostgreSQL connection string (optional) | |
| ifExists | No | Include IF EXISTS clause (for drop_policy) | |
| operation | Yes | Operation: enable/disable RLS, create_policy, edit_policy, drop_policy, get_policies | |
| policyName | No | Policy name (required for create_policy/edit_policy/drop_policy) | |
| replace | No | Whether to replace policy if exists (for create_policy) | |
| role | No | Role the policy applies to (for create_policy) | |
| roles | No | List of roles for policy (for edit_policy) | |
| schema | No | Schema name (defaults to public) | |
| tableName | No | Table name (required for enable/disable/create_policy/edit_policy/drop_policy, optional filter for get_policies) | |
| using | No | USING expression for policy (required for create_policy, optional for edit_policy) |
Implementation Reference
- src/tools/functions.ts:911-1066 (handler)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 }; } } };
- src/tools/functions.ts:914-935 (schema)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 ];
- src/tools/functions.ts:207-236 (helper)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(); } }