Archive Connect MCP Server

The archive/archive-connect server exposes Archive data management capabilities to AI agents. This server enables AI-driven search, restoration, analysis, and compliance operations on archived records in the Archive app.

Use this server to:

  • Search archived data — Find archived records by object type, field values, and date ranges without unarchiving them to live storage
  • Unarchive records — Move archived records back into live Salesforce storage for active business processes
  • Analyze org storage — Run storage analysis to identify archivable data and get storage recommendations for your org
  • Anonymize personal data — Mask PII in archived records to comply with privacy regulations while maintaining record structure
  • Manage data erasure requests — Process Right To Be Forgotten (RTBF) requests by permanently deleting archived records

Prerequisites 

  • API version: v67.0 and later
  • Archive license enabled in your org
  • Permissions:
    • Archive Admin permission set for comprehensive access to all Archive operations
    • Or specific permissions based on operations (see Archive Admin Permissions for details)
    • Object-level and field-level security applies to all operations
  • External Client App configured with the mcp_api scope
  • MCP client installed and configured with OAuth authentication

For setup instructions, see Set Up Your Org.

Server URL 

Archive Connect tools are accessed through the Headless 360 MCP server.

  • Production: https://api.salesforce.com/platform/mcp/v1/platform/headless-360
  • Sandbox/Scratch: https://api.salesforce.com/platform/mcp/v1/sandbox/platform/headless-360

Use the Headless 360 server’s Discover tool to find Archive Connect operations at runtime.

Activate the Headless 360 Server 

  1. From Setup, in the Quick Find box, enter MCP Servers, and then select MCP Servers.
  2. Find headless-360 in the list of servers.
  3. Click Activate.

Once activated, use the server’s Discover tool to find Archive Connect operations.

Example Prompts 

  • “Search for archived Cases with Status ‘Closed’ created in January 2024.”
  • “Unarchive Account records for Acme Corporation that were archived in Q1 2024.”
  • “Run the storage analyzer to identify which objects are consuming the most storage.”
  • “Submit an RTBF erasure request for archived records matching customer@example.com.”
  • “Anonymize PII in archived Case records associated with Account ID 001xx000003DGbXXXX.”

Available Tools 

Archive Connect provides 13 tools for managing archived data through the Headless 360 MCP server. Tools are organized by capability: search, storage analysis, unarchive, compliance operations, and job monitoring.

1. run-archive-global-search — search archived records 

Searches archived records by object type, filters, date ranges, and sort criteria.

Internal name: run-archive-global-search

Annotations: readOnlyHint: true · openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {
4    "sobjectName": {
5      "type": "string",
6      "description": "API name of the sObject to search in the archive."
7    },
8    "filters": {
9      "type": "array",
10      "description": "At least 1 filter condition required; up to 6 allowed. Each filter is {field, value}. Filters are combined with AND logic.",
11      "minItems": 1,
12      "maxItems": 6
13    },
14    "dateRange": {
15      "type": "object",
16      "description": "Single date range {field, from, to}. Both from and to must be full ISO-8601 datetime strings (e.g., '2020-01-01T00:00:00Z').",
17      "properties": {
18        "field": { "type": "string" },
19        "from": { "type": "string", "format": "date-time" },
20        "to": { "type": "string", "format": "date-time" }
21      }
22    },
23    "dateRanges": {
24      "type": "array",
25      "description": "Array of date ranges, each {field, from, to}. Use the special field name 'archive_date' to filter by archive date.",
26      "items": {
27        "type": "object",
28        "properties": {
29          "field": { "type": "string" },
30          "from": { "type": "string", "format": "date-time" },
31          "to": { "type": "string", "format": "date-time" }
32        }
33      }
34    },
35    "fields": {
36      "type": "array",
37      "description": "Field API names to return in the result set.",
38      "items": { "type": "string" }
39    },
40    "pageSize": {
41      "type": "integer",
42      "description": "Number of records per page. Maximum 1000, default 25.",
43      "minimum": 1,
44      "maximum": 1000,
45      "default": 25
46    },
47    "sortDirection": {
48      "type": "string",
49      "description": "Sort order. Accepts 'asc' or 'desc' (case-insensitive), default 'asc'.",
50      "enum": ["asc", "desc", "ASC", "DESC"],
51      "default": "asc"
52    }
53  },
54  "required": ["sobjectName", "filters"],
55  "additionalProperties": false
56}

Returns HTTP 201 with {records[], total_result_count, scroll_id, errorMessage, statusCode}. The errorMessage is null on success. When scroll_id is "-1", there are no more pages.

2. get-archive-global-search-next-page — paginate search results 

Retrieves the next page of archived record search results using a scroll cursor from the previous search.

Internal name: get-archive-global-search-next-page

Annotations: readOnlyHint: true · openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {
4    "scrollId": {
5      "type": "string",
6      "description": "The scroll cursor returned from the previous search response."
7    }
8  },
9  "required": ["scrollId"],
10  "additionalProperties": false
11}

Returns next page of search results with structure {records[], total_result_count, scroll_id, errorMessage, statusCode}.

3. run-archive-global-search-with-sharing-rules — search with sharing rules enforced 

Archive search optimized for Agentforce agents. Enforces sharing rules and returns results in a rich-text summary format.

Internal name: run-archive-global-search-with-sharing-rules

Annotations: readOnlyHint: true · openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {
4    "objectName": {
5      "type": "string",
6      "description": "API name of the sObject to search."
7    },
8    "filtersJson": {
9      "type": "string",
10      "description": "JSON-encoded object map of fieldName→value, e.g., '{\"Subject\":\"Foo\",\"Status\":\"New\"}'. Must be an object, not an array."
11    },
12    "dateField": {
13      "type": "string",
14      "description": "API name of the date field for temporal filtering."
15    },
16    "startDate": {
17      "type": "string",
18      "description": "Start date for the search window (ISO 8601 format)."
19    },
20    "endDate": {
21      "type": "string",
22      "description": "End date for the search window (ISO 8601 format)."
23    },
24    "maxResults": {
25      "type": "integer",
26      "description": "Maximum number of records to return. Default 100.",
27      "default": 100
28    }
29  },
30  "required": ["objectName", "filtersJson"],
31  "additionalProperties": false
32}

Returns {isSuccess, totalResultCount, records, recordsJson, errorMessage, message, warnings}. The records field contains a rich-text summary of ~5 key fields per record. The recordsJson field contains HTML-entity-encoded JSON. The warnings field contains schema-validation and auto-fix advisories.

Note: Check the isSuccess field, not the HTTP status code. Validation failures return HTTP 201 with isSuccess: false.

4. get-organization-archive-storage-used — get storage consumption 

Returns the current archive storage consumption across storage tiers.

Internal name: get-organization-archive-storage-used

Annotations: readOnlyHint: true · openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {},
4  "additionalProperties": false
5}

Returns {usedStorage[4], availableStorage[4]}. Two parallel arrays where indices 0/1 represent general storage and 2/3 represent archive-tier storage. Values are in bytes.

Note: Interpret per-index rather than as a flat metric. Each index represents a different storage tier and shouldn’t be summed together.

5. run-analyzer — trigger storage analysis 

Triggers the archive analyzer to run immediately and generate a storage readiness report.

Internal name: run-analyzer

Annotations: openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {},
4  "additionalProperties": false
5}

Returns {isRunning, message}. The isRunning field is always null; read the message field for human-readable status.

Note: This is a write operation that is idempotent and non-destructive.

6. get-analyzer-report — retrieve analyzer report 

Retrieves the latest analyzer report showing archive readiness and storage recommendations.

Internal name: get-analyzer-report

Annotations: readOnlyHint: true · openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {},
4  "additionalProperties": false
5}

Returns {topRecords[], topFiles[], fileGeneralStorage, dataGeneralStorage, createdDateReport}. Each item in topRecords and topFiles contains {objectName, objectLabel, objectIcon, size, count, usagePercent}. Storage objects contain {storageUsed, storageRemaining, usagePercent}. The createdDateReport is in "DD/MM/YYYY HH:MM:SS" format.

7. run-unarchive — unarchive records 

Unarchives archived records back into live Salesforce storage based on search criteria.

Internal name: run-unarchive

Annotations: openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {
4    "sobjectName": {
5      "type": "string",
6      "description": "API name of the sObject to unarchive."
7    },
8    "filters": {
9      "type": "array",
10      "description": "Filter criteria identifying which archived records to unarchive."
11    },
12    "dateRange": {
13      "type": "object",
14      "description": "Single date range {field, from, to} with full ISO-8601 datetime strings. Omitting this parameter unarchives records based on filters alone with no date constraints.",
15      "properties": {
16        "field": { "type": "string" },
17        "from": { "type": "string", "format": "date-time" },
18        "to": { "type": "string", "format": "date-time" }
19      }
20    }
21  },
22  "required": ["sobjectName", "filters"],
23  "additionalProperties": false
24}

Returns {body, errorMessage, statusCode}. The body contains unarchive job details including job ID.

Note: This is a write operation that is potentially long-running. Maximum 1000 matched records per request. Maximum 50 unarchive requests per hour per org. Restores the entire archived hierarchy of each matched record.

8. run-rtbf — submit RTBF erasure request 

Submits a Right To Be Forgotten (RTBF) data erasure request for archived records matching the specified criteria.

Internal name: run-rtbf

Annotations: openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {
4    "criteria": {
5      "type": "array",
6      "description": "Array of {sobject, field, value} criteria. Maximum 10 criteria per request, one per object type. Field and object names are case-insensitive.",
7      "maxItems": 10,
8      "items": {
9        "type": "object",
10        "properties": {
11          "sobject": { "type": "string" },
12          "field": { "type": "string" },
13          "value": { "type": "string" }
14        }
15      }
16    }
17  },
18  "required": ["criteria"],
19  "additionalProperties": false
20}

Returns {body.request_id, errorMessage, statusCode}. The request_id is a UUID used to track the request via get-rtbf-status.

Warning: Not reversible. RTBF erasure permanently deletes the matched archived hierarchy. Maximum 10,000 root records erased per org per day. Deletes the entire archived hierarchy of each matched record. Values must be exact matches, not partial. The criterion’s record type must have been archived as a root record.

9. get-rtbf-status — poll RTBF request status 

Polls the status of an RTBF data erasure request to confirm whether personal data has been purged from the archive.

Internal name: get-rtbf-status

Annotations: readOnlyHint: true · openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {
4    "requestId": {
5      "type": "string",
6      "description": "The request UUID returned by run-rtbf."
7    }
8  },
9  "required": ["requestId"],
10  "additionalProperties": false
11}

Returns {body, errorMessage, statusCode}. The body contains RTBF request status details.

10. run-masking — submit PII masking request 

Submits a masking request to irreversibly anonymize PII in archived records matching the criteria.

Internal name: run-masking

Annotations: openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {
4    "criteria": {
5      "type": "array",
6      "description": "Array of {sobject, field, value} criteria identifying archived records to anonymize. Same structure as RTBF criteria.",
7      "items": {
8        "type": "object",
9        "properties": {
10          "sobject": { "type": "string" },
11          "field": { "type": "string" },
12          "value": { "type": "string" }
13        }
14      }
15    }
16  },
17  "required": ["criteria"],
18  "additionalProperties": false
19}

Returns {body.request_id, errorMessage, statusCode}. The request_id is a UUID used to track the masking job via get-masking-status.

Warning: Not reversible. Anonymization is permanent; original PII values cannot be recovered. Replaces detected PII field values with placeholders (e.g., "redacted@example.com"). Permanent and one-time per record. Duplicate requests on an already-masked record are ignored. PII fields are auto-detected; you cannot choose specific fields. Records under legal hold or retention lock are excluded. Cascades to child records in the same hierarchy. Shares the 10,000/day rate limit with RTBF operations. Requires org entitlement; without it, returns VALIDATION_ERROR “Masking not allowed for this org”.

11. get-masking-status — poll masking request status 

Polls the status of a masking request to confirm when PII anonymization has completed.

Internal name: get-masking-status

Annotations: readOnlyHint: true · openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {
4    "requestId": {
5      "type": "string",
6      "description": "The masking request UUID returned by run-masking."
7    }
8  },
9  "required": ["requestId"],
10  "additionalProperties": false
11}

Returns {body, errorMessage, statusCode}. The body contains masking request status details. Status reaches "HANDLED" when anonymization completes.

12. get-archive-execution-details-streaming-url — get job execution log URL 

Generates a presigned download URL for an archive job’s execution details log file.

Internal name: get-archive-execution-details-streaming-url

Annotations: readOnlyHint: true · openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {
4    "reportType": {
5      "type": "string",
6      "description": "The ArchiveActivity Type of the job.",
7      "enum": ["Archive", "Unarchive", "Analyzer", "Purge", "Export-to-external-bucket", "Export-and-download"]
8    },
9    "requestId": {
10      "type": "string",
11      "description": "The ArchiveActivity Id of a completed, log-producing job (the '8qv...' key)."
12    },
13    "sobjectName": {
14      "type": "string",
15      "description": "API name of the sObject associated with the archive job. The backend can self-resolve this."
16    }
17  },
18  "required": ["reportType", "requestId"],
19  "additionalProperties": false
20}

Returns {url}. If url is not null, it contains a time-limited presigned download URL. If url is null, no log was resolved.

13. get-archive-failed-records-streaming-url — get failed records log URL 

Generates a presigned download URL for an archive job’s failed records log file.

Internal name: get-archive-failed-records-streaming-url

Annotations: readOnlyHint: true · openWorldHint: false

Request Schema:

1{
2  "type": "object",
3  "properties": {
4    "reportType": {
5      "type": "string",
6      "description": "The ArchiveActivity Type of the job.",
7      "enum": ["Archive", "Unarchive", "Analyzer", "Purge", "Export-to-external-bucket", "Export-and-download"]
8    },
9    "requestId": {
10      "type": "string",
11      "description": "The ArchiveActivity Id of a completed job (the '8qv...' key)."
12    },
13    "sobjectName": {
14      "type": "string",
15      "description": "API name of the sObject associated with the archive job."
16    }
17  },
18  "required": ["reportType", "requestId"],
19  "additionalProperties": false
20}

Returns {url}. If url is not null, it contains a time-limited presigned download URL. If url is null, no failed-records log was resolved.

Understand How Security Works 

Every Archive Connect operation runs as the authenticated user through an External Client App with the mcp_api scope. Object permissions (CRUD), field-level security (FLS), sharing rules, and user permissions all apply. If you can’t perform an action in Salesforce, your agent can’t perform it through the MCP server. The audit trail attributes every action to you.

For full guidance, see Security Best Practices and General Best Practices.

Important for compliance operations: The RTBF and masking tools are destructive and irreversible. Configure your MCP client to require explicit approval before executing these operations.

Usage Limits 

The Archive Connect API has the following operational constraints:

Rate Limits 

  • Unarchive requests: Maximum 50 requests per hour per org. Each request can match up to 1,000 records.
  • RTBF and masking operations: Combined maximum of 10,000 root records erased or masked per org per day.
  • Search filters: Maximum 6 filter conditions per search request.
  • RTBF and masking criteria: Maximum 10 criteria per request, one per object type.

Operational Constraints 

  • Unarchive scope: Restores the entire archived hierarchy of each matched record, not just the root record.
  • RTBF and masking scope: Deletes or anonymizes the entire archived hierarchy of each matched record.
  • Masking permanence: Anonymization is permanent and one-time per record. Duplicate masking requests on already-masked records are ignored.
  • RTBF permanence: Data erasure is not reversible. RTBF permanently deletes matched archived records.
  • Legal holds: Records under legal hold or retention lock are excluded from masking operations.
  • Masking entitlement: Masking operations require org entitlement. Without it, requests return VALIDATION_ERROR “Masking not allowed for this org”.
  • Exact value matching: RTBF and masking criteria require exact field value matches, not partial matches.
  • Root record requirement: For RTBF, the criterion’s record type must have been archived as a root record.

Related Resources