Skip to main content
Glama

Salesforce MCP Server

import { Tool } from "@modelcontextprotocol/sdk/types.js"; export const MANAGE_FIELD_PERMISSIONS: Tool = { name: "salesforce_manage_field_permissions", description: `Manage Field Level Security (Field Permissions) for custom and standard fields. - Grant or revoke read/edit access to fields for specific profiles or permission sets - View current field permissions - Bulk update permissions for multiple profiles Examples: 1. Grant System Administrator access to a field 2. Give read-only access to a field for specific profiles 3. Check which profiles have access to a field`, inputSchema: { type: "object", properties: { operation: { type: "string", enum: ["grant", "revoke", "view"], description: "Operation to perform on field permissions" }, objectName: { type: "string", description: "API name of the object (e.g., 'Account', 'Custom_Object__c')" }, fieldName: { type: "string", description: "API name of the field (e.g., 'Custom_Field__c')" }, profileNames: { type: "array", items: { type: "string" }, description: "Names of profiles to grant/revoke access (e.g., ['System Administrator', 'Sales User'])", optional: true }, readable: { type: "boolean", description: "Grant/revoke read access (default: true)", optional: true }, editable: { type: "boolean", description: "Grant/revoke edit access (default: true)", optional: true } }, required: ["operation", "objectName", "fieldName"] } }; export interface ManageFieldPermissionsArgs { operation: 'grant' | 'revoke' | 'view'; objectName: string; fieldName: string; profileNames?: string[]; readable?: boolean; editable?: boolean; } export async function handleManageFieldPermissions(conn: any, args: ManageFieldPermissionsArgs) { const { operation, objectName, fieldName, readable = true, editable = true } = args; let { profileNames } = args; try { // Ensure field name has __c suffix if it's a custom field and doesn't already have it const fieldApiName = fieldName.endsWith('__c') || fieldName.includes('.') ? fieldName : `${fieldName}__c`; const fullFieldName = `${objectName}.${fieldApiName}`; if (operation === 'view') { // Query existing field permissions const permissionsQuery = ` SELECT Id, Parent.ProfileId, Parent.Profile.Name, Parent.IsOwnedByProfile, Parent.PermissionSetId, Parent.PermissionSet.Name, Field, PermissionsRead, PermissionsEdit FROM FieldPermissions WHERE SobjectType = '${objectName}' AND Field = '${fullFieldName}' ORDER BY Parent.Profile.Name `; const result = await conn.query(permissionsQuery); if (result.records.length === 0) { return { content: [{ type: "text", text: `No field permissions found for ${fullFieldName}. This field might not have any specific permissions set, or it might be universally accessible.` }], isError: false, }; } let responseText = `Field permissions for ${fullFieldName}:\n\n`; result.records.forEach((perm: any) => { const name = perm.Parent.IsOwnedByProfile ? perm.Parent.Profile?.Name : perm.Parent.PermissionSet?.Name; const type = perm.Parent.IsOwnedByProfile ? 'Profile' : 'Permission Set'; responseText += `${type}: ${name}\n`; responseText += ` - Read Access: ${perm.PermissionsRead ? 'Yes' : 'No'}\n`; responseText += ` - Edit Access: ${perm.PermissionsEdit ? 'Yes' : 'No'}\n\n`; }); return { content: [{ type: "text", text: responseText }], isError: false, }; } // For grant/revoke operations if (!profileNames || profileNames.length === 0) { // If no profiles specified, default to System Administrator profileNames = ['System Administrator']; } // Get profile IDs const profileQuery = await conn.query(` SELECT Id, Name FROM Profile WHERE Name IN (${profileNames.map(name => `'${name}'`).join(', ')}) `); if (profileQuery.records.length === 0) { return { content: [{ type: "text", text: `No profiles found matching: ${profileNames.join(', ')}` }], isError: true, }; } const results: any[] = []; const errors: string[] = []; for (const profile of profileQuery.records) { try { if (operation === 'grant') { // First, check if permission already exists const existingPerm = await conn.query(` SELECT Id, PermissionsRead, PermissionsEdit FROM FieldPermissions WHERE ParentId IN ( SELECT Id FROM PermissionSet WHERE IsOwnedByProfile = true AND ProfileId = '${profile.Id}' ) AND Field = '${fullFieldName}' AND SobjectType = '${objectName}' LIMIT 1 `); if (existingPerm.records.length > 0) { // Update existing permission const updateResult = await conn.sobject('FieldPermissions').update({ Id: existingPerm.records[0].Id, PermissionsRead: readable, PermissionsEdit: editable && readable // Edit requires read }); results.push({ profile: profile.Name, action: 'updated', success: updateResult.success }); } else { // Get the PermissionSet ID for this profile const permSetQuery = await conn.query(` SELECT Id FROM PermissionSet WHERE IsOwnedByProfile = true AND ProfileId = '${profile.Id}' LIMIT 1 `); if (permSetQuery.records.length > 0) { // Create new permission const createResult = await conn.sobject('FieldPermissions').create({ ParentId: permSetQuery.records[0].Id, SobjectType: objectName, Field: fullFieldName, PermissionsRead: readable, PermissionsEdit: editable && readable // Edit requires read }); results.push({ profile: profile.Name, action: 'created', success: createResult.success }); } else { errors.push(`Could not find permission set for profile: ${profile.Name}`); } } } else if (operation === 'revoke') { // Find and delete the permission const existingPerm = await conn.query(` SELECT Id FROM FieldPermissions WHERE ParentId IN ( SELECT Id FROM PermissionSet WHERE IsOwnedByProfile = true AND ProfileId = '${profile.Id}' ) AND Field = '${fullFieldName}' AND SobjectType = '${objectName}' LIMIT 1 `); if (existingPerm.records.length > 0) { const deleteResult = await conn.sobject('FieldPermissions').delete(existingPerm.records[0].Id); results.push({ profile: profile.Name, action: 'revoked', success: true }); } else { results.push({ profile: profile.Name, action: 'no permission found', success: true }); } } } catch (error) { errors.push(`${profile.Name}: ${error instanceof Error ? error.message : String(error)}`); } } // Format response let responseText = `Field permission ${operation} operation completed for ${fullFieldName}:\n\n`; const successful = results.filter(r => r.success); const failed = results.filter(r => !r.success); if (successful.length > 0) { responseText += 'Successful:\n'; successful.forEach(r => { responseText += ` - ${r.profile}: ${r.action}\n`; }); } if (failed.length > 0 || errors.length > 0) { responseText += '\nFailed:\n'; failed.forEach(r => { responseText += ` - ${r.profile}: ${r.action}\n`; }); errors.forEach(e => { responseText += ` - ${e}\n`; }); } if (operation === 'grant') { responseText += `\nPermissions granted:\n - Read: ${readable ? 'Yes' : 'No'}\n - Edit: ${editable ? 'Yes' : 'No'}`; } return { content: [{ type: "text", text: responseText }], isError: false, }; } catch (error) { return { content: [{ type: "text", text: `Error managing field permissions: ${error instanceof Error ? error.message : String(error)}` }], isError: true, }; } }

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/tsmztech/mcp-server-salesforce'

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