salesforce-metadata-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| PORT | No | HTTP server port (default: 3000) | |
| SF_ALIAS | No | Salesforce CLI org alias | |
| TRANSPORT | No | stdio or http (default: stdio) | |
| SF_CLIENT_ID | No | Connected App client ID | |
| SF_ACCESS_TOKEN | No | Static access token (expires ~1hr) | |
| SF_INSTANCE_URL | Yes | Your org URL (e.g. https://org.salesforce.com) | |
| SF_CLIENT_SECRET | No | Connected App client secret | |
| SF_REFRESH_TOKEN | No | OAuth refresh token |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| sf_create_custom_objectA | Creates a new Salesforce Custom Object using the Metadata API. The object name must end with '__c'. Use this when a user asks to create a new object, entity, or table in Salesforce. |
| sf_create_custom_fieldB | Creates a new custom field on an existing Salesforce object. The field API name must end with '__c'. Supports all field types: Text, Number, Picklist, Lookup, etc. |
| sf_add_picklist_valuesA | Adds new picklist values to an existing Picklist or MultiselectPicklist field without removing existing values. Use when a user wants to add new options to a dropdown. |
| sf_create_approval_processA | Creates or updates a Salesforce Approval Process via the Metadata API. Define who can submit, approval steps with approvers, entry criteria, and what happens on approval or rejection. |
| sf_create_validation_ruleA | Creates or updates a Salesforce Validation Rule on any object via the Metadata API. The errorConditionFormula returns TRUE when data is INVALID. Use for data quality enforcement. |
| sf_create_workflow_field_updateA | Creates a Workflow Field Update action that can be referenced by Approval Processes, Workflow Rules, or Flows. Sets a field to a literal value, formula result, or null. |
| sf_create_formula_fieldA | Creates a formula field on any Salesforce object. Supports all return types (Text, Number, Currency, Date, DateTime, Checkbox, Percent) and the full Salesforce formula language: IF/AND/OR/NOT, BLANKVALUE, TEXT, VALUE, DATE, DATEVALUE, TODAY, NOW, date functions (MONTH/YEAR/DAY), math (FLOOR/CEILING/MOD), string functions (LEN/LEFT/RIGHT/MID/TRIM/UPPER/LOWER/CONTAINS/BEGINS), record type and picklist functions (ISPICKVAL, ISNULL, ISBLANK), cross-object field references (e.g. Account.Owner.Name), and VLOOKUP. Complex multi-line formulas are fully supported. |
| sf_deploy_metadataA | Deploys a set of metadata components directly to the org using the Metadata API SOAP deploy operation. Builds a package.xml and deployment zip in memory. Supports validate-only (checkOnly:true) for pre-deployment validation without making changes. Specify runTests to execute test classes during deployment (required for production). Polls until complete or timeout. |
| sf_check_deploy_statusA | Checks the status of an in-progress or recently completed metadata deployment by async job ID. Returns the status (Pending, InProgress, Succeeded, Failed, Canceled), component successes, failures, and test results. Use with the deploy ID returned from sf_deploy_metadata. |
| sf_retrieve_metadataA | Retrieves metadata components from the org and returns their actual file contents. Use this to read existing configuration before making changes, to back up metadata, or to check what is really deployed rather than what you think is deployed. Waits for the async retrieve to finish and unpacks the resulting zip, returning each file's path and source. Large files are truncated. Accepts 'components' (array), or 'metadataType'+'componentName' as a single-item shortcut, or a raw 'packageXml' document — provide exactly one form. |
| sf_delete_metadataA | Permanently deletes one or more metadata components of a given type via the Metadata API's deleteMetadata call — works for CustomObject, CustomField, Flow, GenAiFunction, GenAiPlugin, GenAiPlannerBundle, Bot, ApexClass, and most other metadata types. There was previously no way to remove anything created by this MCP server (sf_deploy_metadata only supports adding/updating components, not destructiveChanges) — diagnostic or abandoned metadata had nowhere to go. Deletes each fullName independently: check the response's deleted/errors lists rather than assuming all all-or-nothing. Some types have dependency order requirements (e.g. delete a Bot's GenAiFunction/GenAiPlugin/GenAiPlannerBundle before the Bot itself, delete CustomField before its parent CustomObject) — Salesforce will reject a delete that still has dependents, naming them in the error. |
| sf_query_recordsA | Executes a SOQL query against the org and returns matching records. Provide the full SOQL string in the query param. Use for reading data, checking existing records before creating, or verifying changes. Supports aggregate queries — GROUP BY with COUNT(), SUM(), AVG(), MAX(), MIN(), e.g.: 'SELECT StageName, COUNT(Id), SUM(Amount) FROM Opportunity GROUP BY StageName' Aggregate results come back as regular records with the aggregate expressions as field keys (e.g. "expr0"). Row cap: 'limit' defaults to 200 and is a ceiling, not a hint. If the SOQL carries its own LIMIT the smaller of the two applies, so a LIMIT in the query can tighten the cap but never raise it. When rows are cut off the response sets truncated: true and reports appliedLimit and limitSource, so a capped result is never mistaken for a complete one. |
| sf_describe_objectA | Retrieves schema metadata for a Salesforce object via the REST Describe API: fields (name, label, type, required, picklist values, length, references), child relationships, and record type info. Call this before querying or creating records on an unfamiliar object, or when a user asks what fields exist on an object. objectApiName: SObject API name, e.g. 'Account', 'My_Object__c' fieldsOnly: set true for a smaller/faster response with just the field list, omitting child relationships and record types waitForFields: field API names to poll for after a sf_create_custom_field call — Salesforce's own REST describe/SOQL schema cache can lag several minutes behind the Metadata API on some orgs even though the field is fully deployed; this retries so you don't have to. Not caused by this MCP server and not fixable here — it's Salesforce-side. timeoutSeconds: max time to poll when waitForFields is set (default 60, max 300) |
| sf_list_objectsA | Finds Salesforce objects by PARTIAL name or label — the discovery step before sf_describe_object, which needs an exact API name you may not know yet. Use this whenever the user refers to objects loosely ("what objects handle cases?", "is there a custom object for invoices?", "show me the custom objects") rather than by exact API name. searchTerm: partial API name or label, case-insensitive. Omit to list every object in the org. objectType: 'all' (default), 'custom' (only __c), or 'standard' queryableOnly: true to hide objects that cannot be queried with SOQL limit: max results (default 50) Results rank exact matches first, then prefix matches, then substring matches, so a search for "Account" returns Account before AccountBrandShare. Returns name, label, keyPrefix and CRUD-ability per object; call sf_describe_object with an exact name for full field detail. |
| sf_get_metadata_dependenciesA | Answers "what breaks if I change this?" for any metadata component. Read-only — it changes nothing. Returns every component that REFERENCES the target (Apex classes, triggers, flows, validation rules, layouts, report types, formulas), grouped by type. For custom fields it also reports how many records currently hold a value, which is usually the deciding factor in whether a change is safe. componentType + componentName: e.g. CustomField + 'Account.Revenue__c', or ApexClass + 'AccountService' componentId: alternatively pass the Salesforce Id directly (needed for types outside the supported list) includeUses: also return what the component itself depends on Run this BEFORE deleting or reshaping anything that holds data. Note the blindSpots list returned with every response: this API cannot see dynamic SOQL, string-built field names, managed-package internals, or external integrations, so an empty result means "nothing found", never "safe to change". |
| sf_list_toolsetsA | Lists every available Salesforce toolset, how many tools each contains, and which are currently loaded. This server keeps most of its 228 tools unloaded to save context; unloaded tools do not appear in the tool list until you load their toolset with sf_load_toolset. Call this when you need a capability you cannot see. |
| sf_load_toolsetA | Loads one or more Salesforce toolsets, making their tools callable and visible in the tool list. Available toolsets: core, metadata, objects, data, flows, automation, security, apex, lwc, ui, pages, actions, agentforce, omnistudio, omnichannel, devops, deployment, integrations, identity, reports, experience, admin, monitoring, audit, einstein, knowledge, cpq, sandbox, streaming, visualforce, aura, comms, mcp, i18n. Call sf_list_toolsets for descriptions and tool counts. |
| sf_find_toolA | Searches all 228 Salesforce tools by name — including tools in toolsets that are not loaded — and by default loads whichever toolsets contain the matches, so you can call them immediately. Use this whenever a tool you expect does not appear in the tool list, or when you do not know which toolset a capability lives in. Example queries: "flow", "permission set", "agent", "omniscript", "debug log". |
| sf_tool_schemaA | Returns the input schema, title and description of any of this server's 228 tools, whether or not its toolset is loaded. Use this to find out what arguments a tool takes when it is not in your tool list, then invoke it with sf_call_tool. |
| sf_call_toolA | Invokes any of this server's 228 tools by name, including tools whose toolset is not loaded and tools that do not appear in your tool list. Use this whenever a Salesforce tool you need is not directly callable — it works even on clients that do not refresh their tool list after sf_load_toolset. Get the argument shape first with sf_tool_schema or sf_find_tool. Arguments are validated and permission-checked exactly as they are on a direct call. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 20 tools
Each tool targets a distinct metadata operation with clear descriptions, making most boundaries easy to identify. Some ambiguity exists between sf_create_custom_field and sf_create_formula_field, since a formula field is a type of custom field, and several tools say "creates or updates" rather than separating those actions.
All tools share the sf_ prefix and mostly follow a verb_noun pattern such as sf_create_custom_object, sf_retrieve_metadata, and sf_delete_metadata. The main deviation is sf_tool_schema, which lacks a verb, and minor semantic variation among verbs like add, get, and query, but the overall convention is consistent.
Twenty tools is on the heavy side for a single server, though the broad Salesforce metadata domain justifies much of it. The five tool-management tools add overhead, but they serve a clear purpose given the server's 228-tool backend.
The set covers the core metadata lifecycle well: create, retrieve, deploy, check status, and delete, plus object discovery, schema description, SOQL querying, and dependency analysis. Minor gaps exist, such as no explicit update tool for custom objects/fields and no metadata listing beyond object discovery, but the generic deploy and delete tools cover most needs.