Encompass ec360 Public Automation MCP Developer Guide
Contents
- What is ecpa-mcp?
- The ECPA policy model
- Getting started
- Connecting & authenticating
- MCP primitives reference
- Tools
- Resources
- Prompts
- End-to-end example
- Errors & troubleshooting
- Support & next steps
1 What is ecpa-mcp?
ecpa-mcp is Encompass Corporation's Model Context Protocol server for the Encompass Public Automation (ECPA) platform. It exposes ECPA capabilities — profile creation, policy execution, entity and document retrieval — as MCP tools and resources that any MCP-capable AI client can use.
This guide targets integrators who want their AI client to drive Encompass Public Automation workflows: running KYC screening policies, reading results, pulling evidence documents. It covers connection, authentication, every primitive currently exposed, and a working end-to-end example.
2 The ECPA policy model
This MCP server mirrors the Encompass Public Automation v3.1 REST API surface. Four concepts are enough to read the rest of this guide:
Profile. A persistent record of a subject target entity being screened — a person or organisation under KYC review. Profiles hold collected data, executed policies, and produced documents.
Policy. A Policy is a combination of pre-defined searches and rules, that your Company specifies, to complete the content gathering phase of the KYC process. A policy runs automatically through the searches with minimal user input required. Policies are defined by your Encompass tenant administrators; this server lets you execute them, not author them.
Policy step / sequence / resolution. A policy breaks into sequences of steps. Most steps execute automatically. Some steps resolve based on data returned by upstream sources; a subset require user input (resolve_policy_step) — for example, selecting a match from several candidate search results a data source returned. A policy completes when every step has a resolution.
Documents and the combined PDF. Executing a policy produces documents (data source proof documents, a purchase history, a chart PDF). The server exposes per-document downloads and a "combined PDF" that stitches all policy outputs and other documents from a profile into a single file — the canonical evidence artifact for a compliance record.
For exhaustive reference on data-source-specific fields, entity types, and policy configuration, see the Encompass Public Automation API documentation (same credentials as MCP auth — see §4). For field-level shapes use the get_schema tool; the REST reference remains the source for policy configuration and everything else.
3 Getting started
Prerequisites:
- An MCP-capable AI client — the primary route covered in this guide is Claude (claude.ai or the Claude family of apps) via the Encompass connector in Anthropic's Connector Directory.
- A signed commercial license with Encompass.
- An Encompass-provisioned user account (same credentials you use for the Encompass web UI, API and API documentation).
4 Connecting & authenticating
Connect through the Encompass ec360 Public Automation connector listed in Anthropic's Connector Directory (in claude.ai and the Claude apps). Add the connector and authentication takes the user-interactive route: on first use your client opens a browser to the Encompass Public Automation login; once you sign in, the token is cached and later tool calls reuse it until it expires. No manual configuration is needed — the listed connector carries all connection details.
For integration paths outside the Directory listing — other MCP-capable clients, headless / machine-to-machine agents, prospect-specific sandboxes, or production engagements — Encompass provides the connection details for your integration at the appropriate time; see §11 for how to get in touch.
4.1 Standards-based discovery
MCP clients that implement standards-based OAuth discovery (RFC 9728 + RFC 8414 / OIDC Discovery) instead of using a preconfigured connector can resolve everything they need from this server directly, with no manual audience configuration. A 401 response's WWW-Authenticate header (see §10.1) points at <base-url>/.well-known/oauth-protected-resource; that document's authorization_servers entry points back at this same server rather than at the Auth0 tenant directly. Following it to <base-url>/.well-known/oauth-authorization-server — also served under the /.well-known/openid-configuration spelling that OIDC-only clients probe — resolves authorization_endpoint to this server's own /oauth/authorize, which forwards the browser to the Auth0 login with the correct audience already attached. token_endpoint, revocation_endpoint, and userinfo_endpoint in that same document point at Auth0 directly, since those calls don't need the audience injected on their behalf. The document's issuer is this server's own base URL (or <base-url>/c/<connection>/oauth on a connection-specific route), exactly the identifier advertised in authorization_servers, as RFC 8414 §3.3 requires; tokens themselves are still issued and signed by the Auth0 tenant, whose jwks_uri the document points at.
4.2 Local development and testing
For local development, i.e. driving the server from a tool on your own machine rather than through a listed connector, you can complete the interactive OAuth flow yourself using your deployment's public client. This is the PKCE client the standards-based route above relies on; its client id is a public identifier (not a secret), and Encompass provides it at onboarding alongside your base URL. There is no dynamic client registration endpoint, so a pre-issued client id is always required.
The official MCP Inspector works out of the box. Start the Inspector (its UI opens at http://localhost:6274), set Transport to Streamable HTTP and the URL to <base-url>/mcp, then open the OAuth panel, enter your deployment's public client id, and connect. The Inspector's redirect URI (http://localhost:6274/oauth/callback) and browser origin are already registered on the public client, so the login completes in the browser and returns a bearer token with no further configuration. verify_auth (see below) then confirms the connection, and the Tools tab lists the full surface.
Your own loopback client. A local client or script that runs the authorization-code with PKCE flow can use any of the loopback redirect URIs reserved for a developer's own client, i.e. http://localhost:8080/callback through http://localhost:8084/callback (the Claude Code CLI and the MCP Inspector have their own dedicated callbacks). The public client validates redirect URIs exactly, so a client that listens on a port or path outside that set needs its callback registered first; contact Encompass support (see §11) to add one.
Non-interactive testing. For scripts and pipelines that run without a browser, use the M2M client-credentials grant described below rather than the interactive flow.
However you obtain the token, the MCP tool surface is identical, and the token is sent as Authorization: Bearer <access_token> on every request, exactly as the connector and M2M routes do.
4.3 Machine-to-machine (M2M) clients
Backend integrations, automated pipelines, and autonomous agents that run without a human at the keyboard authenticate with the OAuth 2.0 client-credentials grant rather than the interactive browser login described above. Once a token is obtained the MCP tool surface is identical; only the way you acquire the bearer token differs.
Each M2M integration is provisioned by Encompass as a dedicated application with its own client_id and client_secret, bound to a specific ECPA user identity (i.e. a service account). Everything the integration does is attributed to that user, so there is no per-request user selection. Because both the credentials and the user mapping are bespoke per integration, Encompass issues them, along with the token endpoint URL, as part of onboarding (see §11).
To obtain a token, make a form-encoded POST to the token endpoint Encompass provides:
POST <token endpoint>
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
client_id=<your client_id>
client_secret=<your client_secret>
audience=<this server's base URL, with a trailing slash>
The response is a standard OAuth token payload. Send its access_token on every MCP request as Authorization: Bearer <access_token>, exactly as the interactive route does. Tokens expire — cache and reuse the token within its expires_in lifetime, and request a fresh one when it lapses. As with the interactive route, verify_auth (see below) confirms the connection is wired correctly; for an M2M client the reported userSub is the client identity rather than a human user.
4.4 Sanity-checking the connection
Call the verify_auth tool. It is a simple diagnostic tool that confirms both authentication with the MCP server and the server's access to your credentials for accessing the Encompass Public Automation REST API.
Successful response:
{
"status": "succeeded",
"userSub": "auth0|<your-auth0-user-id>",
"coreTokenExpiresIn": 3600,
"deployment": "<deployment label, e.g. ecpa-mcp-staging>",
"mcpBaseUrl": "https://<this server's public URL>",
"ecpaApiHost": "<host of the connected ECPA instance>"
}
Failure response:
{
"status": "failed",
"userSub": "auth0|<your-auth0-user-id>",
"deployment": "<deployment label, e.g. ecpa-mcp-staging>",
"mcpBaseUrl": "https://<this server's public URL>",
"ecpaApiHost": "<host of the connected ECPA instance>",
"error": "<message from the CTE failure>"
}
userSub is the Auth0 sub claim. This is not an ECPA user identifier — it is the Auth0 subject, useful for support tickets and not much else. When contacting support about an auth problem, include the full verify_auth payload (including the error field on failures).
deployment, mcpBaseUrl, and ecpaApiHost identify which deployment this connector is talking to. If you have multiple ECPA connectors configured (e.g. staging and production), call verify_auth on each to tell them apart — the same identity also appears in the first line of the server's instructions, and the deployment label as serverInfo.title, so capable clients can distinguish deployments without any tool call.
5 MCP primitives reference
Each entry below begins with a narrative "when to use" paragraph followed by the reference block. Input and output schemas are summaries; for exhaustive field-level shapes (especially for tools whose outputs carry polymorphic or source-specific payloads: get_profile_entities, get_profile_data_sources, get_profile_data_sources_all, get_profile_news, get_profile_purchases, get_profile_audit_trail) call the get_schema tool with the type value you see in the response (see the "Schema discovery" entry in §6).
Where a tool returns polymorphism via a type discriminator with per-type fields or similar open-map payloads, this guide documents the discriminator pattern and the common values; it does not duplicate every type's field list, so call get_schema with the type value for that.
5.1 Standard ECPA error envelope
Every ECPA-backed tool (with the exception of verify_auth) surfaces upstream EcpaApiError and EcpaTimeoutError instances the same way:
- The MCP result has
isError: true. - A text-content block in
content[0].textcarries the human-readable message. For most errors this is the upstream message prefixed with"ECPA API error <status>: <detail>"or"ECPA request timed out after Nms: <method> <path>". For upstream 429 errors the text is an imperative wait instruction the LLM honours (see §10.4). - A structured
_metapayload distinguishes the error category for programmatic consumers._meta.erroris one of:'rate_limited'— a rate-limit budget was exhausted (either by the ECPA upstream API or by this server's own rate limiter). Also carriesrule: <string>,retryAfterSeconds: <int>,tool: '<name>'. See §10.4 for handling andrulesemantics.'upstream_error'— other 4xx/5xx from ECPA. Also carriesstatus: <int>,tool: '<name>'.'upstream_timeout'— the request exceeded the client-side timeout. Also carriestool: '<name>'.
- If the upstream response does not match the expected schema, the tool returns
isError: truewith a"upstream response did not match expected schema: …"diagnostic incontent[0].text(no_meta).
Individual entries below reference this as the standard ECPA error envelope rather than repeating it. Tool-specific validation errors (e.g. create_policy_order complaining about missing firstName) are called out inline where they exist; they return plain-text isError: true without _meta.
5.2 Pagination
List-returning tools share the shape documented in the server's instructions block:
Pagination: list-returning tools return
data(array of results) andpagination({ totalItems, nextCursor }). To page forward, call the tool again passing the returned cursor as thecursorargument untilnextCursoris null. Per-item objects are full resources; this server does not yet trim list fields.
All paginated tools accept cursor (opaque string from a previous response's pagination.nextCursor), offset (int, min 0, default 0), and limit (int, 1-100, default 10). When cursor is supplied it supersedes offset/limit and other filters. To page forward, pass the returned cursor until pagination.nextCursor is null. Where an entry says "paginated," assume this shape.
An invalid or tampered cursor returns isError: true with _meta.error: 'invalid_cursor'; restart the listing without a cursor.
5.3 Value handling
The rule is stated once in the server's instructions block:
Value handling: when you put a value into a tool argument, send exactly the characters the value contains — never HTML-escape it and never percent-encode it. Most free-text fields are matched upstream by a fuzzy, token-based search, so a transformed value does not fail loudly: it silently matches the wrong things, and on an order that wrong match becomes a permanent, billable compliance record. Encoding applies in exactly one place — when a value is being packed into a URI or query-string carrier, such as a resource URI's query string — and the field's own description says so where it applies.
- In JSON tool arguments — literal.
companyName,firstName,surname,customerReference, and everylist_*search filter take the characters as they are. This server forwards them unchanged: it does not trim, case-fold, unescape or normalise anything. - In a URI or query-string carrier — encode as that carrier requires. One place does this, and it says so on the field: the filtered-zip resource URI. There
&must be%26, and a+in a UTC offset must be%2Bor it decodes to a space. - Never HTML-escape, anywhere. No surface on this server takes
&,'oréas the correct spelling of a value.
Neither spelling errors, which is what makes this worth watching: DEERE & COMPANY returns a page of candidates matching on the token amp, topped by a dormant branch record with no LEI, where DEERE & COMPANY returns a short, clean list. If a search returns nothing, or candidates sharing only a fragment of the name, check the spelling of the value you sent before widening the search.
5.4 Document classification and source metadata
get_profile_document and list_profile_documents can return eight classification and source fields on each document, plus documentLanguage:
| Field | Meaning |
|---|---|
taxonomyCategory, taxonomySubCategory |
KYC taxonomy: the broad purpose of the document and the finer kind within it (e.g. IDENTITY / ENTITY_PROFILE_REPORT). |
documentNature |
How the document was produced (e.g. REGISTRY_PROOF_PDF, SCREENSHOT_PDF, SOURCE_DOCUMENT, ENCOMPASS_GENERATED). |
documentJurisdiction |
Jurisdiction of the document's source, usually ISO 3166-1 alpha-2 (e.g. GB) or ISO 3166-2 (e.g. CA-ON). |
documentLanguage |
Language of the document, usually an ISO 639-1 code (e.g. en). Returned whether or not document metadata is enabled. |
sourceDocumentId |
The source authority's own reference for the document (e.g. a corporation file number). Not an ECPA document id: never pass it as documentId. |
documentEffectiveDate, documentPeriodEnd, documentValidTo |
When the document takes effect, the end of the period it covers, and until when it is valid. |
Call list_document_classification_values for the meaning of every taxonomyCategory, taxonomySubCategory and documentNature value. The set grows, so read it rather than hard-coding values.
Why a field can be missing. A missing field is omitted from the response (ECPA does not send null for these fields), and it means unknown, never "none": a missing documentValidTo does not mean the document never expires. There are three reasons:
- Document metadata is not enabled on the connected ECPA deployment. All eight fields are then missing from every document (
documentLanguageis not affected), andlist_document_classification_valuesreports that metadata is not enabled. This is the only reason a client can detect. - The document's source does not record the value. Sources are being enabled region by region; user uploads and file attachments never carry these fields.
- The document was captured before that deployment began recording metadata for it. Values are recorded when a document is captured and are never backfilled.
Reasons 2 and 3 cannot be told apart from the document alone.
Which fields arrive together. When document metadata is enabled, the classification fields (taxonomyCategory, taxonomySubCategory, documentNature, documentJurisdiction, documentLanguage) usually arrive as a set, because a source declares them together. sourceDocumentId and the three dates are set per document and are rare (e.g. a period end only on an annual filing).
Reading the dates. All three are ISO 8601 UTC date-times (yyyy-MM-ddTHH:mm:ssZ). Some sources send a calendar date as midnight UTC, and others may send a true instant. A value at exactly T00:00:00Z most likely stands for a calendar date: treat it as that date, without time-zone conversion, including when comparing (otherwise "valid to 31 December" lapses a day early for a user west of UTC). Read any other value as the UTC instant it states. A documentPeriodEnd may be built from a year alone (e.g. 31 December), so do not quote it as an exact filing date.
documentValidTo and documentExpiryDate are filled separately. documentExpiryDate is the data provider's own expiry string, as the provider sent it; documentValidTo is the metadata date above. Both mean "valid until", but they are filled independently, so a document may carry either, both or neither: check both.
5.5 Document dates
documentFiledDate, dateProcessed and dateCreated do not depend on document metadata being enabled, and each answers a different question:
| Field | Answers | Caveat |
|---|---|---|
documentFiledDate |
When was the document first filed with the source registry or authority? | Where the source sent no filing date, ECPA may have recorded the capture time instead, and such documents keep it: a value within a minute of dateCreated is the capture time, not a filing date, so treat it as unknown. A value at exactly T00:00:00Z is most likely a calendar date (see Reading the dates above). |
dateProcessed |
When did the data provider process the document? | In the provider's own format, and the capture time where the provider supplies none. Neither the filing date nor the age of ECPA's copy. dateProcessedIso is the same value in ISO format. |
dateCreated |
How old is ECPA's copy? | When ECPA stored this copy of the document. |
6 Tools
6.1 Auth
6.2 verify_auth
Verify authentication
When to use. Confirm your connection and auth are wired correctly. Useful as a first call after setting up an MCP client connection, and as a diagnostic when you suspect a token-exchange problem. The failure payload is the recommended attachment when raising a support ticket about auth or token-exchange problems (see §10). Also the canonical way to identify which deployment (environment / ECPA instance) a connector is talking to when several are configured.
Input. None.
Output shape.
{
"status": "succeeded",
"userSub": "<auth0 sub>",
"coreTokenExpiresIn": 3600,
"deployment": "<label>",
"mcpBaseUrl": "<url>",
"ecpaApiHost": "<host>"
}
or on failure:
{
"status": "failed",
"userSub": "<auth0 sub>",
"deployment": "<label>",
"mcpBaseUrl": "<url>",
"ecpaApiHost": "<host>",
"error": "<message>"
}
userSub is the Auth0 sub claim (auth0|<id> for a human; <clientId>@clients for M2M). It is not an ECPA user identifier.
Notable errors. Token-exchange failures surface as status: 'failed' with the exception message in error. The MCP call itself still returns HTTP 200 — the failure is inside the result.
6.3 Profile management
6.4 list_profiles
List profiles
When to use. Discover existing profiles — by name, customer reference, target entity, risk level, owner, date window, or archived state. The standard entry point when you need to locate a profile you don't already have an ID for, or produce a roster for review.
Input schema (summary).
offset,limit— pagination.name,customerReference,targetEntity— case-insensitive substring match (or exact match ifuseExactNameMatch: true).companyIdentifier— include profiles with a matching company identifier.reviewDateStart/reviewDateEnd,createdDateStart/createdDateEnd— ISO-8601 date-time windows.riskStatus/riskStatuses— one ofNOT_APPLICABLE | UNSET | LOW | MEDIUM | HIGH.screeningAlerts— array ofHIGH | MIDDLE | LOW | NONE.status—ACTIVE | INACTIVE.archived— boolean.owner— profile owner email.onlyIncludeProfilesUserHasWorkedOn,includeAllAccountProfiles,quickFilter.sort— comma-separated fields,-prefix for descending (e.g.-dateModified,dateCreated).
Output shape. Paginated (see §5 preamble). data[] items are ProfileSummary — id, customerReference, name, targetEntity, profileLevel, riskLevel, userId, callerReferenceId, dateCreated, dateModified, dateArchived, nextReviewDate, archived, status, activePerspective, plus any additional fields the upstream returns.
Notable errors. Standard ECPA error envelope (see top of section). Watch for large tenants — apply filters and stop paging once you have enough data; do not mass-iterate.
Example.
{ "name": "Acme", "archived": false, "limit": 25 }
6.5 get_profile
Get profile summary
When to use. You already have a
profileId(e.g. fromlist_profiles,create_policy_order, orget_policy_order) and need the full summary — name, customer reference, target entity, risk level, status, dates, active perspective.
Input schema (summary).
profileId(string, required).
Output shape. Single ProfileSummary (see list_profiles). The relationship/ownership chart is available as a separate resource (profile_chart_pdf, see §7).
Notable errors. Standard ECPA error envelope.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da" }
6.6 get_profile_sharing_link
Get profile sharing link
When to use. You want to hand a profile to another Encompass user who already has their own access to this ECPA instance (they may be in a different account). You must already be able to access the profile yourself (same precondition as
get_profile).
Input schema (summary).
profileId(string, required).accessLevel(enum, required) —readOnly(recipient gets a view-only copy) orreadAndWrite(collaborative edit access).
Output shape. { data: { profileId, accessLevel, url } } — url is a link that opens the profile in the ECPA web UI. The recipient must be logged in; the link is not anonymous/public and is long-lived (it does not carry its own expiry).
Notable errors. Standard ECPA error envelope — 401 if you cannot access the profile, 404 if it does not exist.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da", "accessLevel": "readOnly" }
6.7 create_profile
Create profile
When to use. Create a new profile explicitly (e.g. you want to set it up before running any policy). Note:
create_policy_ordercan also create a profile on the fly viacustomerReference.
Input schema (summary).
customerReference(string, required) — unique customer reference describing what this profile is about.name(string, ≤256 chars, optional) — human-readable name; auto-generated fromcustomerReference+ timestamp if omitted.
Output shape. Single ProfileSummary for the newly created profile.
Notable errors. Standard ECPA error envelope.
Example.
{ "customerReference": "CUST-12345", "name": "Acme Holdings Ltd" }
6.8 refresh_profile
Refresh profile
When to use. Re-run a profile's KYC/AML policy over fresh data. Creates a new profile (the source profile is untouched) by re-running the full policy — this may incur new data purchases. The response carries a
callerReferenceIdfor the new policy run: pass it towait_for_policy_completionto monitor progress.
Input schema (summary).
refreshSourceProfileId(string, required) — ID of the existing profile to refresh. The simple case needs nothing else: ECPA re-runs the profile's existing policy (its earliest policy, if it has run several) with inputs derived from the profile.name(string, ≤256 chars, optional) — name for the new profile; copied from the source if omitted.customerReference(string, optional) — copied from the source if omitted. Only honoured for accounts with the customer-reference field enabled.policyIdentifier(string, optional) — run a different policy instead of the profile's own.policyParametersType+ parameter fields (optional) — override the subject inputs. Refresh supports three shapes:CompanyTemplateParameters(companyName,companyIdentifiers,countryCode,subdivision) for any company-shaped policy,PersonTemplateParameters(firstName,surname,middleName,birthDate) for any person-shaped policy, andCompanyWithIdAndRelatedPersonTemplateParametersfor policies declared with exactly that type. Other parameter shapes are rejected with guidance (the refresh API only honours base fields — usecreate_policy_orderwhen full parameter fidelity matters). Policies takingPersonWithIdentifierTemplateParameterscannot be refreshed.
Output shape. Single ProfileSummary for the newly created profile, including callerReferenceId for the policy run it started.
Notable errors. Standard ECPA error envelope; 422 when the profile has never run a policy and no policyIdentifier is supplied.
Example.
{ "refreshSourceProfileId": "64f0a1b2c3d4e5f6a7b8c9d0" }
6.9 archive_profile
Archive/restore profile
When to use. Move a profile into the archived state (
archived: true) or restore a previously archived profile (archived: false). Idempotent.
Input schema (summary).
profileId(string, required).archived(boolean, required) —trueto archive,falseto restore.
Output shape. Single ProfileSummary reflecting the new state.
Notable errors. Standard ECPA error envelope.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da", "archived": true }
6.10 Profile data
6.11 get_profile_data_sources
Get profile data sources
When to use. Inspect the entities collected in a profile together with which upstream data source supplied each attribute (the "selected" values after match-and-merge). Paired with
get_profile_entitieswhen you want to understand provenance.
Input schema (summary).
profileId(required).offset,limit— pagination.perspectiveType— one ofAllOwnership | AllOwnershipAndControl | BeneficialOwnership | BeneficialOwnershipAndControl | BeneficialOwnershipAndControlOfTargetEntity | ControlOnly | Everything. Defaults toEverythingwhen omitted.minSharePercent,maxSharePercent,beneficialOwnershipPercent— numeric 0-100. ECPA acceptsminSharePercentandmaxSharePercentonly withBeneficialOwnershiporBeneficialOwnershipAndControl, and rejects either one with any other perspective, including theEverythingdefault whenperspectiveTypeis omitted.minSharePercentmust not exceedmaxSharePercent.includeExtraData(string).
Output shape. Paginated EntityResource[]. Each entity has an id, a type discriminator (string), and the type's own fields sitting flat on the entity itself via OpenAPI allOf composition (open-map on the wire, catchall(unknown)); call get_schema with the type value for the field-level shape. A dataSourceAttributes[] array is provenance only, not the field values: each element identifies which upstream source supplied which attribute names (orderId, dataSource, serviceIdentifier, dateCreated, documentIds, attributesSourceMapping, sourceUrl).
Notable errors. Standard ECPA error envelope.
Example.
{
"profileId": "69e589e22ed8ec3a7b2432da",
"perspectiveType": "BeneficialOwnership",
"beneficialOwnershipPercent": 25,
"limit": 50
}
6.12 get_profile_data_sources_all
Get all profile data sources
When to use. Same as
get_profile_data_sources, but also includes the non-selected values from match-and-merge (i.e. values the data-primacy rules rejected). Use when you need to audit why a particular value was chosen over another.
Input schema (summary). Identical to get_profile_data_sources.
Output shape. Same paginated EntityResource[] shape; dataSourceAttributes[].attributesSourceMappingNotSelected is populated with the non-selected values (open-map Record<string, unknown>). See get_profile_data_sources for where the type's own fields live on the entity and how to get their shape via get_schema.
Notable errors. Standard ECPA error envelope.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da", "perspectiveType": "Everything" }
6.13 get_profile_entities
Get profile entities
When to use. Retrieve the merged, post-selection entity graph for a profile (Individuals, organisations, and their relationships). Use this when you want the authoritative view of who-and-what is in the profile without needing per-source provenance.
Input schema (summary). Identical to get_profile_data_sources (profileId, offset, limit, perspectiveType, minSharePercent, maxSharePercent, beneficialOwnershipPercent, includeExtraData).
Output shape. Paginated EntityResource[]. Each entity exposes:
id— entity identifier.type— string discriminator. In practice common values are driven by the upstream data source and include entity-kind discriminators such as individuals/persons, organisations/companies, and other KYC entity types. Treat this field as an open set: common values include but are not limited to the discriminator values the ECPA data source returns.dataSourceAttributes[]— provenance only, not the attribute values themselves: each element identifies which upstream source supplied which attribute names (orderId,dataSource,serviceIdentifier,dateCreated,documentIds,attributesSourceMapping,sourceUrl). The type's own fields sit flat on the entity, open-map on the wire; callget_schemawith thetypevalue for the field-level shape.dateCreated,dateModified.
Notable errors. Standard ECPA error envelope.
Example.
{
"profileId": "69e589e22ed8ec3a7b2432da",
"perspectiveType": "AllOwnershipAndControl"
}
6.14 get_profile_news
Get profile news
When to use. Retrieve adverse-media / news items collected for a profile by running a policy that includes a search with a screening data product such as LSEG World-Check One. Filter by review status to show only active items, only discarded items, or everything.
Input schema (summary).
profileId(required).offset,limit— pagination.status—NON_DISCARDED(default),DISCARDED, orALL.
Output shape. Paginated News[] — each item has id, type, entityId, date, title, source, linkToOriginal, linkToSource, snippet, risk, discarded, plus any additional fields the upstream returns.
Notable errors. Standard ECPA error envelope.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da", "status": "NON_DISCARDED" }
6.15 get_profile_purchases
Get profile purchases
When to use. Audit the data-product purchases made against a profile, including associated documents and billed cost. Useful for cost reporting and for locating the
dataProductOrderIdtied to a specific document.
Input schema (summary).
profileId(required).offset,limit— pagination.
Output shape. Paginated PurchaseHistoryResource[] — each entry: id, createdDate, searchCriteria, cost, purchasedBy, serviceName, costLabel, billedBy, dataProductOrderId.
Notable errors. Standard ECPA error envelope.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da" }
6.16 get_profile_audit_trail
Get profile audit trail
When to use. Retrieve the history of actions performed on a profile — creation, edits, policy runs, resolutions, archive/restore. The full, compliance-friendly paper trail. Audit trails can be very large; paginate deliberately.
Input schema (summary).
profileId(required).offset,limit— pagination.
Output shape. Paginated AuditTrailResource[] — each entry: id, type, createdDate, description, profileId, userId, plus any upstream-specific fields (open-map); call get_schema with AuditTrailResource for the field-level shape.
Notable errors. Standard ECPA error envelope.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da", "limit": 100 }
6.17 Profile documents
6.18 list_profile_documents
List profile documents
When to use. Search and list the documents attached to a profile (data source PDFs, purchase history, no-match reports, user attachments), filtered by document type, status, data provider, related entity, and created/modified date ranges.
kindandprovidertake profile-specific values — calllist_profile_document_types/list_profile_document_providersfirst and pass a value from their results; do not guess.
Input schema (summary).
profileId(required).offset,limit— pagination.kind— filter to this effective document type. Uselist_profile_document_typesfor the values available on this profile.status—PENDING | READY | ERROR.provider— filter to this data provider (source). Uselist_profile_document_providersfor the values available on this profile.entityId— filter to documents related to this entity id, following the entity merge lineage.dateCreatedStart,dateCreatedEnd— ISO-8601 windows on document creation.dateModifiedStart,dateModifiedEnd— ISO-8601 windows ondateModified(the UI "Date received").includeUserAttachments— boolean; whether to include user-uploaded attachments.includePurchaseHistory— boolean; include the workspace purchase-history document (defaulttrue; setfalseto exclude).includeNoMatchReports— boolean; include no-match reports (defaulttrue; setfalseto exclude).includeScreeningNoMatchReports— boolean; only takes effect whenincludeNoMatchReportsisfalse: defaulttruekeeps no-match reports from screening providers while excluding the rest, setfalseto exclude them all too.
Attachment-exclusion caveat. Setting
kind,status,provider,entityId, or adateModifiedbound excludes file attachments from the result — these are the selecting filters.dateCreatedbounds and theinclude*booleans do not exclude attachments.
Output shape. Paginated DocumentResource[]. Each document carries metadata including id, type, productCode, category, description, documentType, kind, filename, descriptiveFileName, dateCreated, dateProcessed, dateProcessedIso, documentFiledDate (see Document dates), dateModified, documentName, documentAuthority, uploadedByUser, entityId, status (PENDING | READY | ERROR), documentLanguage, the classification and source metadata fields (taxonomyCategory, taxonomySubCategory, documentNature, documentJurisdiction, sourceDocumentId, documentEffectiveDate, documentPeriodEnd, documentValidTo; see Document classification and source metadata for why they can be missing), plus upstream extras. Each document may also carry a trimmed related entity (entity: { id, searchableName }) — full entity details come from get_profile_entities.
Notable errors. Standard ECPA error envelope.
Example.
{
"profileId": "69e589e22ed8ec3a7b2432da",
"kind": "PASSPORT",
"status": "READY"
}
Related resources: profile_document_raw (single document bytes), profile_documents_zip / profile_documents_filtered_zip (all / filtered documents bundled). See §7.
6.19 list_profile_document_types
List profile document types
When to use. Discover the distinct document types ('kind' values) present on a profile before filtering documents. Pass a returned kind value as the 'kind' argument to
list_profile_documentsordownload_profile_documents_zipto filter by type.
Input schema (summary).
profileId(required).
Output shape. Unpaginated collection of document types. Each item is { id, type, attributes: { kind, profileId } } — the kind value lives in attributes, not at the top level.
Notable errors. Standard ECPA error envelope.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da" }
6.20 list_profile_document_providers
List profile document providers
When to use. Discover the distinct data providers (document sources) present on a profile before filtering documents. Pass a returned provider value as the 'provider' argument to
list_profile_documentsordownload_profile_documents_zipto filter by source.
Input schema (summary).
profileId(required).
Output shape. Unpaginated collection of document providers. Each item is { id, type, attributes: { provider, profileId } } — the provider value lives in attributes, not at the top level.
Notable errors. Standard ECPA error envelope.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da" }
6.21 get_profile_document
Get profile document
When to use. Read a single document's metadata (filename, type, status, dates) by
documentId. This tool does not return the binary content — fetch that throughdownload_profile_document(§6) for a signed URL, or theprofile_document_rawresource (see §7) if your client fetches MCP resources, using theidandprofileIdfrom this response.
Input schema (summary).
profileId(required).documentId(required).
Output shape. Single DocumentResource (metadata only). The raw bytes are addressable via download_profile_document or the MCP resource URI ecpa://profiles/<profileId>/documents/<documentId>/raw (see §7 for the canonical URI form). sizeInBytes reports the size of the file those routes return, so you can decide before fetching — but only for the format listed first in formats: a multi-format document (in practice only the Australian PPSR summary report) may have sizeInBytes describe a different file than the one download_profile_document / profile_document_raw actually delivers. Omitted when no size was recorded (e.g. PENDING documents), and absent altogether on a deployment whose ECPA predates the upstream change that adds it. The classification and source metadata fields can be missing; see Document classification and source metadata. documentFiledDate, dateProcessed and dateCreated answer different questions; see Document dates.
Notable errors. Standard ECPA error envelope. On a deployment whose ECPA instance does not yet support metadata-only document fetches, a very large document is refused with a 413: the upstream response still embeds the whole file, so it exceeds the server's limit on a metadata read. The error says so, and the rejection lifts once that deployment's ECPA is upgraded.
Example.
{
"profileId": "69e589e22ed8ec3a7b2432da",
"documentId": "69e589e22ed8ec3a7b36b2c1"
}
6.22 delete_profile_document
Delete profile document
When to use. Permanently delete a user-uploaded document from a profile. Use
list_profile_documentsto find thedocumentIdfirst. Only user-uploaded documents can be deleted — ECPA-generated (system) documents will return an error. This operation is irreversible.
Input schema (summary).
profileId(required).documentId(required) — must be a user-uploaded document.
Output shape. { success: true, documentId } on success.
Notable errors. Standard ECPA error envelope. Attempting to delete a system-generated document returns an error from ECPA.
Example.
{
"profileId": "69e589e22ed8ec3a7b2432da",
"documentId": "69e589e22ed8ec3a7b36b2c1"
}
6.23 update_profile_document
Update profile document
When to use. Update a user-uploaded document's metadata or replace its content. Two modes: (1) metadata update — supply at least one of
filename(to rename) orentityId+entityType(to associate with a charted entity); changes apply immediately and the updatedDocumentResourceis returned. (2) Content replacement — setreplaceContent: trueto replace the document bytes; the tool returns a short-lived upload URL envelope (same shape asupload_profile_document) and thedocumentIdis preserved. Only user-uploaded documents can be updated. To perform a metadata-only update, omitreplaceContent.
Input schema (summary).
profileId(required).documentId(required) — must be a user-uploaded document.filename(optional) — new filename; must keep a permitted extension.entityId(optional) — ID of a charted entity to associate with the document.entityType(optional) — type of the associated entity.replaceContent(optional, boolean) — settrueto replace the document bytes (returns an upload URL envelope). Omit to perform a metadata-only update.
entityId and entityType must be supplied together (both or neither). For a metadata-only update, at least one of filename or entityId+entityType is required.
Output shape. Metadata-only path: single DocumentResource (the updated document metadata). Content-replacement path: { upload_url, expires_at, instructions } — see upload_profile_document for the two-step flow.
Notable errors. Standard ECPA error envelope. Returns isError: true if neither filename nor entityId+entityType are supplied for a metadata-only update, or if only one of entityId/entityType is provided.
Example (metadata update).
{
"profileId": "69e589e22ed8ec3a7b2432da",
"documentId": "69e589e22ed8ec3a7b36b2c1",
"filename": "updated-report.pdf"
}
Example (content replacement).
{
"profileId": "69e589e22ed8ec3a7b2432da",
"documentId": "69e589e22ed8ec3a7b36b2c1",
"replaceContent": true
}
6.24 upload_profile_document
Upload profile document
When to use. Upload a new document to a profile. The tool returns a short-lived, single-use upload URL — the file bytes are never passed through the MCP tool call itself. Use
get_upload_statusafter uploading to confirm completion and obtain the newdocumentId.
Input schema (summary).
profileId(required).filename(optional) — desired filename, including extension. If omitted, the filename is taken from the uploaded file.entityId(optional) — ID of a charted entity to associate with the document (requiresentityType).entityType(optional) — type of the associated entity (requiresentityId).
entityId and entityType must be supplied together (both or neither).
Output shape. { upload_url, expires_at, instructions }.
upload_url— single-use HTTPS URL; the file isPOSTed here asmultipart/form-datawith the field namefile.expires_at— ISO-8601 timestamp after which the URL is no longer valid.instructions— guidance text for the calling client on how to complete the upload and poll for status.
Two-step flow. (1) Call upload_profile_document to obtain the upload_url. (2) Send the file bytes to upload_url. Agentic clients with a network sandbox: POST the file as multipart/form-data (field name file) with Accept: application/json to receive the documentId synchronously. Chat clients: open upload_url in a browser to use the upload form. Each file is limited by the upload cap (DOCUMENT_UPLOAD_MAX_BYTES, default 10 MiB); a larger file is refused with 413. After uploading, call get_upload_status with the upload token (the last path segment of upload_url) to confirm completion. On a 503 response, the server is busy — honour the Retry-After header and retry the same URL. A 4xx is terminal; call this tool again for a fresh URL.
Notable errors. Returns isError: true when only one of entityId/entityType is supplied.
Example.
{
"profileId": "69e589e22ed8ec3a7b2432da",
"filename": "kyc-document.pdf"
}
6.25 get_upload_status
Get document upload status
When to use. Check the status of a document upload started with
upload_profile_documentor a content replacement viaupdate_profile_document. Pass the upload token from the upload URL (the last path segment ofupload_url). Only the user who started the upload can query it.
Input schema (summary).
token(required) — the upload token from the upload URL.
Output shape. { state, documentId?, error? }.
state— one ofpending(URL issued, not yet uploaded),in-progress,complete,failed, orunknown(token not found or expired).documentId— present whenstateiscomplete.error— present whenstateisfailedorunknown; a human-readable reason.
Notable errors. Returns isError: true when the token is not found or has expired (state unknown).
Example.
{ "token": "abc123..." }
6.26 Policy execution
6.27 list_policies
List policy definitions
When to use. Search and list the policy definitions available to the caller's tenant — each has a
policyIdentifier(used bycreate_policy_order), apolicyName, apolicyDescription, and apolicyParametersType(the input shape the policy expects, e.g.CompanyTemplateParameters,CompanyWithJurisdictionTemplateParameters, orPersonTemplateParameters— seecreate_policy_orderfor the full list). Filter by identifier, name, description, or parameter type to narrow the catalogue server-side instead of paging the full set.
Input schema (summary).
offset,limit— pagination.identifier,name,description— case-insensitive substring matches onpolicyIdentifier,policyName, andpolicyDescriptionrespectively.parameterType— case-insensitive substring match on the canonical input-type class name (e.g.CompanyTemplate). Note the filter is namedparameterType; the matched value is returned in the response underpolicyParametersType.search— case-insensitive substring match OR'd across identifier, name, and description. Does not coverparameterType— pass that explicitly. Prefer a specific parameter when you know which dimension you're filtering on.
Output shape. Paginated PolicyDefinition[] — policyIdentifier, policyName, policyDescription, policyParametersType, plus upstream extras.
Notable errors. Standard ECPA error envelope.
Example.
{ "name": "sanctions", "limit": 25 }
6.28 list_data_products
List standalone data products
When to use. Search and list the data products this account is entitled to run standalone (paginated) — single KYC/AML searches or reports run without authoring a policy. Each entry has a
serviceIdentifier(the valuecreate_data_product_orderaccepts; the same value is reported asserviceIdentifieron each sequence of a policy order, so a failed sequence can be matched back to the data product to re-run it), a displayname, adataProvider,productCodes, and theparameterTypesit accepts — field descriptors for each type come fromlist_policy_parameter_types. The listing is already entitlement-filtered: absence from it means this account cannot run that product standalone. A listed parameter type that is not amongcreate_data_product_order'spolicyParametersTypeoptions cannot be ordered through this MCP build.
Input schema (summary).
offset,limit— pagination.identifier,name,dataProvider— case-insensitive substring matches onserviceIdentifier,name, anddataProviderrespectively.parameterType— case-insensitive substring match against the entry'sparameterTypes(e.g.CompanyTemplate).search— case-insensitive substring match acrossserviceIdentifier,name, anddataProvidercombined. Does not coverparameterType— pass that explicitly.- Filters are ANDed together and applied server-side before pagination; results are sorted by
serviceIdentifier.
Output shape. Paginated DataProductDefinition[] — serviceIdentifier, name, dataProvider, productCodes, parameterTypes, plus upstream extras.
Notable errors. On a deployment where standalone data products are not yet enabled, the tool returns isError: true with a message explaining the feature has not been rolled out there — this is not an authentication or permission problem, and the call should not be retried. Other failures follow the standard ECPA error envelope.
Example.
{ "dataProvider": "Creditsafe", "limit": 25 }
6.29 list_company_identifier_types
List company identifier types
When to use. Search and list the company identifier types known to the connected ECPA instance — the valid keys for the
companyIdentifiersmap oncreate_policy_orderandrefresh_profile. Small, unpaginated set; call it before constructing acompanyIdentifiersmap rather than guessing keys. The vocabulary is instance-specific and can change at runtime; it is informative only — unknown keys are silently ignored upstream, never rejected.
Input. None.
Output shape. Collection of { identifierType, displayName, description } — identifierType is the raw key to use in the companyIdentifiers map. Two optional top-level fields: on an ECPA instance that predates the vocabulary endpoint the tool returns a non-error result with data: [], vocabularyUnavailable: true, and an explanatory note (order submission is never blocked on vocabulary availability); an instance with no registered types returns data: [] with a note alone.
Notable errors. A pre-DEV-5954 ECPA instance yields the non-error vocabularyUnavailable result described above, not an error. Other failures follow the standard ECPA error envelope.
Example.
{}
6.30 list_policy_parameter_types
List policy parameter types
When to use. Search and list the policy input parameter types registered on the connected ECPA instance — the
policyParametersTypediscriminator values accepted bycreate_policy_orderandcreate_data_product_order— each listed once with its field descriptors (name,type,required). Small, static set per deployment; takes no parameters and is safe to fetch once per session. This reports what the connected ECPA server accepts; the order tools' ownpolicyParametersTypeoptions are the set this MCP build can construct — a type listed here but absent from those options cannot be ordered through MCP.
Input. None.
Output shape. Collection of { name, fields: [{ name, type, required }] } — one entry per registered parameter type.
Notable errors. On a deployment where standalone data products are not yet enabled, the tool returns isError: true with a message explaining the feature has not been rolled out there — this is not an authentication or permission problem, and the call should not be retried. Other failures follow the standard ECPA error envelope.
Example.
{}
6.31 list_document_classification_values
List document classification values
When to use. List the possible values of the document classification fields
documentNature,taxonomyCategoryandtaxonomySubCategory, as returned byget_profile_documentandlist_profile_documents. Each has a description. Categories also have alabel. Sub-categories also have their parentcategory. Small, unpaginated set that may change over time.
Input. None.
Output shape. A single resource: { data: { id: "current", type: "document-classification-values", attributes: { documentNature: [{ value, description }], taxonomyCategory: [{ value, label, description }], taxonomySubCategory: [{ value, category, description }] } } }. A top-level note appears only if a list came back without values.
Notable errors. Document metadata is not enabled on every ECPA deployment. Where it is not, the tool returns isError: true with _meta.error: 'forbidden' and _meta.forbiddenReason: 'feature_disabled', and a message saying so. This is not an authentication or permission problem, and the call should not be retried; documents on that deployment carry no classification fields either. Other failures follow the standard ECPA error envelope.
Example.
{}
6.32 create_policy_order
Create policy order
When to use. Start a KYC/AML screening: pick a
policyIdentifierfromlist_policiesor use a known value, supply the subject (company or person) parameters, and either reuse an existing profile (profileId) or create a new one implicitly (customerReference). Returns acallerReferenceIdused by all follow-up tools.
Input schema (summary).
policyIdentifier(string, required).policyParametersType(required) — must match the policy definition'spolicyParametersType(seelist_policies). One of:CompanyTemplateParameters—companyName(required);companyNumber,countryCode(2-letter ISO),subdivision,companyIdentifiers(optional).CompanyWithJurisdictionTemplateParameters—companyName(required);countryCode,companyNumber,companyIdentifiers(optional).CompanyWithJurisdictionAndAddressTemplateParameters—companyName(required);countryCode,companyNumber,zipCode,townCity,stateTerritory,streetLineAddress,companyIdentifiers(optional).CompanyWithBvDIDAndJurisdictionTemplateParameters—companyName(required);countryCode,companyNumber,bvdId,companyIdentifiers(optional).CompanyWithIdAndRelatedPersonTemplateParameters—companyName(required);companyIdentifier,companyIdentifierType, plus related-personfirstName,surname,middleName,birthDate(optional).VedaasCompanySearchParameters—companyName(required);countryCode,companyNumber,companyNumberType(optional). The scalarcompanyNumberTypeis a closed set, validated on this server — one ofAVID,CIK,INCORPORATED_REGISTERED_NUMBER,LEI,OPERATIONAL_REGISTERED_NUMBER,REGULATORY_ID,SWIFT_BIC,TAX_ID,TICKER_CODE(defaults toAVIDupstream); an unlisted value is rejected before the request is sent.companyIdentifiersis also accepted, and its map keys are a different thing — they are not limited to that closed set; they follow the same runtime-defined rules as for the other company types (seecompanyIdentifiersbelow).companyNumber/companyNumberTypeoverwrite a colliding map entry upstream — supply a given identifier via the map or the scalar pair, not both.PersonTemplateParameters—firstName+surname(required);middleName,birthDate(YYYY-MM-DD,YYYY-MM, orYYYY) optional.PersonAddressTemplateParameters—firstName+surname(required);middleName,birthDate,streetNumber,streetName,locality,country,postcode,addressLine1,addressLine2(optional).PersonWithIdentifierTemplateParameters—personIdentifier(required).
companyIdentifiers (all company types above except CompanyWithIdAndRelatedPersonTemplateParameters) — a map of raw identifier type → value, e.g. {"LEI": "5299000RWD2J46DMCW33"}, pinning the company by one or more registry identifiers. Discover the valid keys for this instance with list_company_identifier_types (common examples: LEI, DNB_DUNS, UK_COMPANY_NUMBER); the set is instance-specific, and unknown or misspelled types are silently ignored upstream (the order then falls back to name-based matching). Distinct from the scalar companyIdentifier/companyIdentifierType pair — supply multiple identifiers via a map not multiple scalar pairs.
- Exactly one of
customerReferenceorprofileIdmust be supplied.
Output shape. Single PolicyOrderResult — callerReferenceId, status (IN_PROGRESS | ACTION_REQUIRED | PAUSED | COMPLETED | MATCHES | NO_MATCHES | NO_RESULTS | RISK_IDENTIFIED | FAILED | ABORTED | UNKNOWN, plus legacy SUCCESS / REFER / USER_SKIPPED, only returned for orders that pre-date the v3.1 policy statuses), policyIdentifier, profileId, policyParameters, dateCreated, dateStarted, dateCompleted, executionSummary (per-sequence status counts — present on any status with a persisted execution tree, grows during the run), and, when recorded, partialFailure (FAILED orders only: whether some data products completed), failureReason and failureCode.
Notable errors. Standard ECPA error envelope, plus tool-level validation errors as plain-text isError: true responses: missing customerReference/profileId, missing companyName for company policies, missing firstName/surname for person policies, missing personIdentifier for PersonWithIdentifierTemplateParameters, companyIdentifiers supplied with an ineligible policyParametersType (the error names the eligible types; for CompanyWithIdAndRelatedPersonTemplateParameters it points at the scalar companyIdentifier/companyIdentifierType pair instead).
Example.
{
"policyIdentifier": "pol_default_kyc",
"policyParametersType": "PersonTemplateParameters",
"firstName": "Jane",
"surname": "Doe",
"birthDate": "1980-05-20",
"customerReference": "CUST-12345"
}
6.33 create_data_product_order
Create standalone data product order
When to use. Run a single data product standalone — one KYC/AML search or report from one provider, without authoring a policy — by supplying a
serviceIdentifierfromlist_data_productsand the subject parameters, against either a new profile (customerReference) or an existing one (profileId). The created order is an ordinary policy order: after calling this, follow the same flow ascreate_policy_order—wait_for_policy_completion, thenget_policy_order/get_policy_sequences/get_policy_step/resolve_policy_stepas needed, including user-input-required resolution.
Input schema (summary).
serviceIdentifier(string, required) — fromlist_data_products; the same value is reported asserviceIdentifieron policy-order sequences.policyParametersType(required) — must be one of the type names the data product'sparameterTypeslists (fromlist_data_products); same options and per-type field rules ascreate_policy_order(see that entry for the full type-by-type field list,companyIdentifiers, andcompanyNumberType).- Exactly one of
customerReferenceorprofileIdmust be supplied.
Output shape. Single DataProductOrderResult — the 201 echo of the create request, with callerReferenceId and profileId assigned by ECPA (callers cannot supply their own callerReferenceId — there is no such input on this tool), plus serviceIdentifier, customerReference, and policyParameters.
Notable errors. Standard ECPA error envelope, plus tool-level validation errors as plain-text isError: true responses (missing customerReference/profileId, missing required parameter fields for the chosen policyParametersType — same messages as create_policy_order). An entitlement failure (HTTP 403) names the missing product(s) the account is not licensed for; a validation failure (HTTP 422) covers an unknown serviceIdentifier or a policyParametersType the product doesn't accept; an unknown profileId returns a not-found error (upstream wording calls profiles "workspaces"). On a deployment where standalone data products are not yet enabled, the tool returns isError: true explaining the feature has not been rolled out there — this is not an authentication or permission problem, and the call should not be retried.
Example.
{
"serviceIdentifier": "ASIC_ABR",
"policyParametersType": "CompanyTemplateParameters",
"companyName": "Telstra",
"customerReference": "CUST-12345"
}
6.34 get_policy_order
Get policy order
When to use. Retrieve the full order detail — status, dates,
profileId, originalpolicyParameters— after a policy has progressed. Typically called afterwait_for_policy_completionreports a terminal state, or whenever you need theprofileIdderived from the order.
Input schema (summary).
callerReferenceId(required) — fromcreate_policy_order.
Output shape. Single PolicyOrderResult (see create_policy_order).
Notable errors. Standard ECPA error envelope.
Example.
{ "callerReferenceId": "69e58759ca1d985769e7e29a" }
6.35 list_policy_orders
List policy orders
When to use. Discover policy orders that have already been created — by
profileId, lifecyclestatus, and/or creation-date window. Useful for resume / recovery flows where you have aprofileIdbut nocallerReferenceId, or for auditing which policies have run against a profile. Covers policy orders on profiles the calling identity can access (as the profile owner, through a read-write share, or as a user of the same account where account profile view-and-access is enabled), whoever placed the order. A read-only share does not grant access.
Input schema (summary).
offset,limit— pagination.profileId— restrict results to orders run against this profile.status— filter by lifecycle status. A single value (e.g.IN_PROGRESS) or a comma-separated list (e.g.IN_PROGRESS,ACTION_REQUIRED). Recognised values:ABORTED,ACTION_REQUIRED,COMPLETED,FAILED,IN_PROGRESS,MATCHES,NO_MATCHES,NO_RESULTS,PAUSED,RISK_IDENTIFIED(plus legacySUCCESS/REFER, not expected from the ECPA API v3.1 and this MCP server).UNKNOWNandUSER_SKIPPEDappear in results but are not accepted as filter values.dateCreatedStart,dateCreatedEnd— ISO-8601 date-time windows.
Output shape. Paginated PolicyOrderResult[] (per-item fields documented under create_policy_order / get_policy_order: callerReferenceId, status, policyIdentifier, profileId, policyParameters, dateCreated, dateStarted, dateCompleted, executionSummary, and, when recorded, partialFailure, failureReason and failureCode).
Notable errors. Standard ECPA error envelope. Naming a profileId the calling identity cannot access returns a permission error (_meta.error: 'forbidden'), not an empty list. A 403 (_meta.error: 'forbidden') on an order whose profile the calling identity cannot access says so and names who can grant access (the profile owner, a read-write share holder, or a same-account user with profile view-and-access). Do not retry; escalate.
Note on filters. When scoped by profileId the returned set is expected to be small (a single profile is rarely run against many policies), so post-filtering the returned array on a result field such as policyIdentifier is acceptable — but only when profileId is set; it does not license fetching unfiltered orders. Results are newest first by creation date.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da", "limit": 25 }
6.36 get_policy_step
Get policy step
When to use. Drill into a single step — in particular, retrieve
userInputRequired.optionsfor a step whose status isACTION_REQUIRED. The response also carriesautoResolutionPermitted, which governs whether you may select an option yourself or must present the candidates to the user and wait for their choice before callingresolve_policy_step— see that tool's entry for the full permission contract. Covers policy orders on profiles the calling identity can access (as the profile owner, through a read-write share, or as a user of the same account where account profile view-and-access is enabled), whoever placed the order. A read-only share does not grant access.
Input schema (summary).
callerReferenceId,sequenceId,stepId— all required, sourced fromget_policy_sequences.
Output shape. Single PolicySequenceStep — id, name, sequenceId, status, statusMessage, userInputRequired (with type discriminator SINGLE_ITEM_SELECTION | MULTIPLE_ITEM_SELECTION | ADDITIONAL_PARAMETER | SHAREHOLDER_CONVERSION | USER_CONFIRMATION | NONE and options[]), callerReferenceId, profileId, and autoResolutionPermitted (whether the calling identity may resolve autonomously — see resolve_policy_step). Once the step has been resolved it also carries userInput and the resolution readback: autoResolved, rationale, authorisationBasis (HUMAN_CONFIRMED_SELECTION | HUMAN_MANDATE | OPERATING_MANDATE | AGENT_DISCRETION | SYSTEM), mandateReference, and resolutionChannel (API | MCP | UI) — the route the current resolution was submitted through, where MCP is the MCP route (how this server submits) and UI the Encompass user interface route. Of the five readback fields, only resolutionChannel is always derived by Encompass; the other four are what the resolving caller supplied (or, for a step Encompass resolved itself, authorisationBasis: SYSTEM). The readback describes the current resolution only (re-resolving a step overwrites it), and each field is present only when the resolution recorded it — in particular, a step resolved before Encompass began recording the route carries no resolutionChannel. The route is recorded on the step itself and read back here; a caller never sends it.
Notable errors. Standard ECPA error envelope. A 403 (_meta.error: 'forbidden') on an order whose profile the calling identity cannot access says so and names who can grant access (the profile owner, a read-write share holder, or a same-account user with profile view-and-access). Do not retry; escalate.
Example.
{
"callerReferenceId": "69e58759ca1d985769e7e29a",
"sequenceId": "69e5853eca1d985769e7ceab",
"stepId": "69e581f52ed8ec3a7b1eacb7"
}
6.37 get_policy_sequences
Get policy sequences
When to use. Enumerate every sequence and step for a policy order. The primary way to locate steps needing resolution: look for
steps[].attributes.status === 'ACTION_REQUIRED'and then callget_policy_stepfor each. Each sequence and each step summary also carriesautoResolutionPermitted— seeresolve_policy_stepfor what it governs. Covers policy orders on profiles the calling identity can access (as the profile owner, through a read-write share, or as a user of the same account where account profile view-and-access is enabled), whoever placed the order. A read-only share does not grant access.
Input schema (summary).
callerReferenceId(required).
Output shape. Collection (not paginated) of PolicySequence. Each sequence has id, callerReferenceId, profileId, name, serviceIdentifier, inputParameters, status, statusMessage, and steps[]. Each step is wrapped in a JSON:API resource envelope (id, type, attributes — the attributes is a PolicySequenceStepSummary). serviceIdentifier (e.g. CreditsafeUkCompanyReportSequence) is an opaque, case-sensitive token identifying what the sequence executed; for a data product it is the same identifier the API uses wherever it refers to that data product, including standalone re-ordering where available. Presence does not mean the sequence is standalone-orderable or that the caller is entitled to it. It is absent on servers that pre-date the field and on placeholder sequences that recorded no result.
Notable errors. Standard ECPA error envelope. A 403 (_meta.error: 'forbidden') on an order whose profile the calling identity cannot access says so and names who can grant access (the profile owner, a read-write share holder, or a same-account user with profile view-and-access). Do not retry; escalate.
Example.
{ "callerReferenceId": "69e58759ca1d985769e7e29a" }
6.38 resolve_policy_step
Resolve policy step
When to use. Submit a user's answer to a step that is in
ACTION_REQUIRED. Three resolution modes: pick a single option, pick multiple options, or declare that none of the options match. Required to unblock an order that is waiting inACTION_REQUIREDso it can resume processing and progress toward a terminal outcome. Whether you may choose an option yourself is governed byautoResolutionPermitted, published on the sequence, on the step, and on each step summary — read it from the current response rather than remembering it, since it is a property of the calling identity and can change between calls. When it is false, retrieve the candidates withget_policy_step, present them to the user, and wait for explicit confirmation — an instruction from the user to resolve autonomously does not override a false value, and neither does an option that looks unambiguous. When it is true, you may select without a per-step confirmation; afterwards, tell the user which step you resolved, which option you selected (or that you submittedNO_MATCH), and the basis for the decision. Every call must stateautoResolved; an autonomous resolution must also carryrationaleandauthorisationBasis.autoResolvedandrationalereach the profile audit trail today;authorisationBasisandmandateReferencedo not yet (deferred, DEV-6151). Resolves steps of policy orders on profiles the calling identity can access (as the profile owner, through a read-write share, or as a user of the same account where account profile view-and-access is enabled), whoever placed the order. A read-only share does not grant access. Access to the profile is a separate check fromautoResolutionPermitted: permission to resolve autonomously does not grant access, and access does not grant autonomy.
Input schema (summary).
callerReferenceId,sequenceId,stepId— required.resolutionType—SINGLE_ITEM_SELECTION | MULTIPLE_ITEM_SELECTION | NO_MATCH.optionIds(array of int) — required forSINGLE_ITEM_SELECTION(exactly one) andMULTIPLE_ITEM_SELECTION(at least one); not used forNO_MATCH.autoResolved(boolean, required) — your attestation:trueunless you have positive grounds forfalse. A host prompt confirming the call is not such grounds.rationale(string, ≤2000 chars) — required whenautoResolvedis true (a blank/whitespace-only value counts as missing); optional, and recorded if supplied, when it is false. The evidence you matched on (name, registration number, jurisdiction). Never shorten it to retry a refused call — a permission refusal is not a length problem.authorisationBasis—HUMAN_CONFIRMED_SELECTION | HUMAN_MANDATE | OPERATING_MANDATE | AGENT_DISCRETION. Required whenautoResolvedis true; must not be sent whenautoResolvedis false. (SYSTEMis a readback-only value that can appear on a step you retrieve — a caller must never send it.)mandateReference(string, ≤500 chars, optional) — only valid alongsideauthorisationBasisHUMAN_MANDATEorOPERATING_MANDATE; sending it with any other basis is rejected. It is never required on its own — never send a fabricated reference to satisfy it.
Output shape. On success: { "resolved": true, "callerReferenceId": ..., "sequenceId": ..., "stepId": ... } (no structuredContent — this tool does not have an output schema).
Notable errors. Standard ECPA error envelope, plus tool-level validation: SINGLE_ITEM_SELECTION without exactly one optionId or MULTIPLE_ITEM_SELECTION without at least one optionId returns isError: true with an explanation. The resolutionType must also match the step's userInputRequired.type. A 403 (_meta.error: 'forbidden') is a permission failure, distinct from a 422 payload failure: do not retry the refused call unchanged. _meta.forbiddenReason says which of three refusals it is:
auto_resolution_not_permitted: an autonomous resolution was attempted whileautoResolutionPermittedis false. Do not retry, even with a shortened or alteredrationale. Present the candidates to the user, then submit their selection withautoResolved: falseand noauthorisationBasis(the API accepts that call regardless ofautoResolutionPermitted, and it is not a retry of the refused call).profile_access: the calling identity cannot access the order's profile, so it cannot resolve the step in any form. Do not resubmit with any attestation; escalate to someone with access (the profile owner, a read-write share holder, or a same-account user with profile view-and-access).unclassified: any other403. The message quotes ECPA's reason; act as forauto_resolution_not_permittedif it says automated resolution is not permitted, otherwise treat it asprofile_access.
These are the only forbiddenReason values resolve_policy_step returns. feature_disabled belongs to list_document_classification_values.
An auto_resolution_not_permitted refusal says nothing about access; if the human-picked resubmission is refused again, stop.
Example. The payload below assumes autoResolutionPermitted is true for the calling identity — a permission set at the user and/or account level. Otherwise send the user's own choice with autoResolved: false and no authorisationBasis.
{
"callerReferenceId": "69e58759ca1d985769e7e29a",
"sequenceId": "69e5853eca1d985769e7ceab",
"stepId": "69e581f52ed8ec3a7b1eacb7",
"resolutionType": "SINGLE_ITEM_SELECTION",
"optionIds": [3],
"autoResolved": true,
"rationale": "Company name, registration number, and jurisdiction all match the profile's target entity.",
"authorisationBasis": "AGENT_DISCRETION"
}
6.39 wait_for_policy_completion
Wait for policy completion
When to use. After
create_policy_order(or afterresolve_policy_step), poll until the order reaches a terminal state or requires user input. This is the standard progress-monitoring primitive; prefer it over hand-rollingget_policy_orderpolling.
Input schema (summary).
callerReferenceId(required).maxWaitSeconds(int, 1-180, default 30) — polling window upper bound. Size it to the expected run: a full policy typically takes several minutes, so one call at 120-180 s replaces a chain of short polls. The tool returns no later thanmaxWaitSecondsafter it starts polling.pollIntervalMs(int, 2000-10000, default 3000) — between-check delay.
Output shape. Structured content { status, elapsedSeconds, isTerminal, lastError?, partialFailure?, failureReason?, failureCode? }. status is a policy-order status (IN_PROGRESS | ACTION_REQUIRED | PAUSED | COMPLETED | MATCHES | NO_MATCHES | NO_RESULTS | RISK_IDENTIFIED | FAILED | ABORTED | UNKNOWN, plus legacy SUCCESS / REFER / USER_SKIPPED, only returned for orders that pre-date the v3.1 policy statuses). isTerminal is true for truly terminal statuses; ACTION_REQUIRED returns with isTerminal: false so you know more input is needed, and UNKNOWN returns immediately with isTerminal: false — diagnose via get_policy_order/get_policy_sequences instead of re-polling. On orders carrying recorded failure detail the three failure fields are included; on FAILED orders check partialFailure — when true, completed data products' results remain available. If the window expires without a terminal state, the tool returns the last observed status with isTerminal: false — call again to keep waiting.
Notable errors. Transient EcpaApiError / EcpaTimeoutError during a poll are logged and the loop retries. If the window expires with no successful status read, the last error is surfaced via the standard ECPA error envelope. Per-poll status request timeout is 5 s. An unknown or vanished callerReferenceId (HTTP 404), or a malformed one (400/405/409/422), ends the wait at once with an error rather than after the window, including when an earlier poll in the same call succeeded; that error is not a transport failure — for an unknown or vanished id, confirm it with list_policy_orders and do not create a replacement order without asking the user (a new order purchases its data products again), and for a malformed id, correct it.
Example.
{ "callerReferenceId": "69e58759ca1d985769e7e29a", "maxWaitSeconds": 30 }
6.40 Schema discovery
6.41 get_schema
Get schema
When to use. When a tool result or input carries a polymorphic type you need the field-level shape of — an entity
typesuch ascompany, apolicyParametersType, a resolutiontype— and the ECPA API reference is out of reach from your client. Call it with no arguments first to see the four hierarchies, their members and each member's size; then request the schemas you need.
Input schema (summary).
schemas(optional, 1–24) — schema names or wire values. Omit for the index.includeReferenced(optional) — include directly referenced schemas in full (one level).includeDescriptions(optional, defaulttrue).properties(optional, 1–256; with exactly one schema) — a subset of that schema's properties. Cannot be combined withincludeReferenced. Thecompanyschema (~74 KB with descriptions) exceeds the default 40 KiB budget, so read it in two calls:includeDescriptions: falsefor the shape, thenpropertiesfor the descriptions you need.
Output shape. { document, hierarchies[], components: { schemas }, bytes, budgetBytes }. The schema objects are the document's own OpenAPI 3.0 Schema Objects, verbatim; every $ref resolves inside the response, either to a full schema (the ones you asked for and their allOf parents) or to a stub marked x-ec360-stub: true with x-ec360-propertyCount and x-ec360-bytes. Each hierarchy entry's sendableFromMcp names the members this server's tools can actually emit — check it before building a payload.
Notable errors. Over budget: the error names a split that fits, or a cheaper way to ask (includeDescriptions: false, properties). Unknown name: five closest matches. Ambiguous name (e.g. RELATION matches both Relation and relation): the candidates. document_not_exposed: this deployment does not serve the document; do not retry.
Example.
{ "schemas": ["company"], "includeDescriptions": false }
6.42 Combined PDF
6.43 order_combined_pdf
Order combined PDF
When to use. Generate a single PDF combining some-or-all documents in a profile — the canonical evidence artefact for a compliance record. Returns immediately with a PDF resource whose
statusstarts atPENDING.
Input schema (summary).
profileId(required).documentIds(string array, optional) — omit to include all documents.includeToc,includeProfileRecord,includePurchaseHistory,includeAuditTrail,includeChartPdf— booleans.includeProfileRecordrequires a special subscription.
Output shape. Single CombinedPdfDocumentResource — id, profileId, documentIds, the include* flags, and status (PENDING | READY | ERROR).
Notable errors. Standard ECPA error envelope.
Example.
{
"profileId": "69e589e22ed8ec3a7b2432da",
"includeToc": true,
"includeAuditTrail": true
}
6.44 get_combined_pdf
Get combined PDF status
When to use. Check the status of a previously ordered combined PDF, or retrieve its metadata. This tool returns metadata + status only — the bytes are fetched through the
combined_pdf_rawresource (see §7). For polling, preferwait_for_combined_pdf.
Input schema (summary).
profileId(required).id(required) — combined PDF ID fromorder_combined_pdf.
Output shape. Single CombinedPdfDocumentResource (see order_combined_pdf). When status === 'READY', fetch the bytes via the combined_pdf_raw resource URI.
Notable errors. Standard ECPA error envelope.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da", "id": "69e58759ca1d985769e7e29a" }
6.45 wait_for_combined_pdf
Wait for combined PDF
When to use. Poll a combined PDF order to
READY(orERROR). Mirrorswait_for_policy_completionin shape — call repeatedly ifisTerminalis false. Oncestatus === 'READY', fetch the bytes via thecombined_pdf_rawresource (see §7).
Input schema (summary).
profileId(required).id(required) — combined PDF ID fromorder_combined_pdf.maxWaitSeconds(int, 1-180, default 30).pollIntervalMs(int, 2000-10000, default 3000).
Output shape. Structured content { status, elapsedSeconds, isTerminal, lastError? }. status is PENDING | READY | ERROR. isTerminal is true for READY and ERROR; PENDING returns isTerminal: false when the window expires.
Notable errors. Transient EcpaApiError / EcpaTimeoutError are retried; a window that ends with no status read surfaces the last error via the standard ECPA error envelope. Per-poll status request timeout is 5 s. Timing defaults mirror wait_for_policy_completion; if typical PDF generation exceeds 30 s in practice, raise the defaults. An unknown or vanished profileId or id (HTTP 404), or a malformed one (400/405/409/422), ends the wait at once with an error rather than after the window, including when an earlier poll in the same call succeeded; that error is not a transport failure, so correct the id rather than retrying.
Example.
{
"profileId": "69e589e22ed8ec3a7b2432da",
"id": "69e58759ca1d985769e7e29a",
"maxWaitSeconds": 30
}
6.46 Downloads
Each
download_*tool is a tool-call equivalent for the matching binary resource (see §7). The tool returns a short-lived signed download URL; the bytes are then retrieved by following the URL with a standard HTTPS GET. Use these tools when your MCP client surfaces tool calls but does not fetch resources directly — Claude Desktop and the claude.ai connectors are the canonical examples. Use the matching resource in §7 when your client does fetch resources (e.g. Claude Code).
All five download tools share the same response shape — a small URL envelope:
{
"download_url": "https://<server>/downloads/<token>",
"expires_at": "<ISO-8601 timestamp>",
"mime_type": "<MIME type>",
"suggested_filename": "<filename>",
"resource_uri": "ecpa://..."
}
The download_url is valid for ~5 minutes (DOWNLOAD_TOKEN_TTL_SECONDS, default 300) and may be reused within that window. The resource_uri echoes the sibling resource (§7) for clients that later want to switch paths. The /downloads/:token endpoint is mounted outside the bearer-auth chain — the 256-bit opaque token in the URL is the only authentication for retrieval, so the GET does not need an Authorization header. Each download is bounded by the streamed download cap (DOWNLOAD_STREAM_MAX_BYTES, default 500 MiB) — substantially larger than the inline read cap on a resource read (§7, default 8 MiB), so the download path is the right choice for large profile archives.
6.47 download_profile_document
Download profile document
When to use. Tool-call equivalent of the
profile_document_rawresource (§7). Returns a signed URL to download a single document's bytes. Use afterlist_profile_documents/get_profile_documenthas told you which document you want.
Input schema (summary).
profileId(required).documentId(required) — fromlist_profile_documentsorget_profile_document.
Output shape. Download envelope (see preamble). mime_type is inferred from the document filename extension (commonly application/pdf, an image MIME type, or application/octet-stream as fallback).
Notable errors. Standard ECPA error envelope. Document IDs that do not exist surface as the upstream 404. This tool reads the document's metadata to derive its filename, so it is subject to the same 413 as get_profile_document on a deployment whose ECPA does not yet support metadata-only fetches — for such a document, neither tool can reach it until that deployment is upgraded.
Example.
{
"profileId": "69e589e22ed8ec3a7b2432da",
"documentId": "69e589e22ed8ec3a7b36b2c1"
}
6.48 download_combined_pdf
Download combined PDF
When to use. Tool-call equivalent of the
combined_pdf_rawresource (§7). Returns a signed URL to download a previously generated combined PDF. The combined PDF must already be instatus: 'READY'— runorder_combined_pdf→wait_for_combined_pdffirst.
Input schema (summary).
profileId(required).id(required) — combined PDF ID returned byorder_combined_pdf.
Output shape. Download envelope (see preamble). mime_type is application/pdf.
Notable errors. Standard ECPA error envelope. Calling before the combined PDF is READY surfaces as the upstream error.
Example.
{
"profileId": "69e589e22ed8ec3a7b2432da",
"id": "69e58759ca1d985769e7e29a"
}
6.49 download_profile_chart_pdf
Download profile chart PDF
When to use. Tool-call equivalent of the
profile_chart_pdfresource (§7). Returns a signed URL to download the profile's relationship / ownership chart as a PDF. The chart is rendered on demand by ECPA — no separate ordering or polling step is required.
Input schema (summary).
profileId(required).
Output shape. Download envelope (see preamble). mime_type is application/pdf.
Notable errors. Standard ECPA error envelope. Profiles without chartable entities surface as an upstream error.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da" }
6.50 download_profile_documents_zip
Download profile documents (zip)
When to use. Tool-call equivalent of the
profile_documents_zip/profile_documents_filtered_zipresources (§7). Returns a signed URL to download documents in a profile bundled into a single zip — every document with no filters, or a narrower bundle when filters are supplied. Useful for bulk evidence archival when the client cannot fetch resources directly. Bounded by the streamed download cap (DOWNLOAD_STREAM_MAX_BYTES, default 500 MiB); very large profiles may still need per-document downloads.
Input schema (summary).
profileId(required).kind,status,provider,entityId,dateCreatedStart/dateCreatedEnd,dateModifiedStart/dateModifiedEnd,includeUserAttachments,includePurchaseHistory,includeNoMatchReports,includeScreeningNoMatchReports— same filters aslist_profile_documents(see that entry for the discovery-tools rule, the attachment-exclusion caveat, and the screening carve-out).useDescriptiveFilenames— boolean; name the files inside the zip by their descriptive filename instead of the stored one. Does not by itself count as a filter (seeresource_uribehaviour below).
resource_uri behaviour. The result's resource_uri field names the sibling resource this mint corresponds to: ecpa://profiles/{profileId}/documents/all.zip only when the call sets none of the zip params at all (no filters and no useDescriptiveFilenames); as soon as any zip param is present — including useDescriptiveFilenames on its own, with no other filter — it becomes ecpa://profiles/{profileId}/documents/filtered.zip?<params>, the query string built from the params you passed (e.g. useDescriptiveFilenames alone yields .../filtered.zip?useDescriptiveFilenames=true). The filename marker is unaffected by this: it still only gains " (filtered)" when a genuine filter (something other than useDescriptiveFilenames) is present — a useDescriptiveFilenames-only call routes to the filtered.zip URI but keeps the plain, unmarked filename. Date filters accept ISO-8601; when embedding a value with a numeric UTC offset in a URI, percent-encode the plus (%2B) or use a Z/date-only form instead — an unencoded + decodes to a space and fails the resource's own validation.
Filename marker. The suggested filename ends in " (filtered)" whenever at least one genuine filter is present (any parameter other than useDescriptiveFilenames); with no filters it is the plain "<Profile> - documents.zip".
Output shape. Download envelope (see preamble). mime_type is application/zip.
Notable errors. Standard ECPA error envelope. Profiles whose total document size exceeds DOWNLOAD_STREAM_MAX_BYTES now fail as a clean 413 before the GET starts streaming, when ECPA declares the zip's size upfront via Content-Length; when that header is absent (a size the server assembles on the fly), the same limit is instead enforced mid-transfer. Either way the error is on the GET, not in the tool response itself. A filter set matching no documents is not an error: the download succeeds (HTTP 200) with a valid empty zip (a ~22-byte archive containing zero entries) — do not treat a tiny download as corruption.
Example.
{ "profileId": "69e589e22ed8ec3a7b2432da", "kind": "PASSPORT", "status": "READY" }
6.51 download_openapi_document
Download ECPA OpenAPI document
When to use. Tool-call equivalent of the
openapi_documentresource (§7). Returns a signed URL to download the connected ECPA deployment's complete live v3.1 OpenAPI document. Validates the document is reachable before minting, so a blocked cluster surfaces as a tool error here rather than a browser 403 later. Preferget_schemafor in-context slices of individual schemas; use this tool (or the sibling resource) when you need the whole document offline.
Input. None.
Output shape. Download envelope (see preamble). mime_type is application/json.
Notable errors. Standard ECPA error envelope. A deployment that does not serve the document at /encompass/api-docs/v3.1 (a 403/404/406 from ECPA) surfaces as document_not_exposed; do not retry.
Example.
{}
7 Resources
ecpa-mcp currently exposes seven binary resources: six profile-scoped templates (one of which is the guidance stub) and one static document resource (openapi_document). They share consistent behaviour:
- Transport. Each resource returns the bytes as a single
blobcontent entry with the declared MIME type. MCP has no partial or ranged resource read:resources/readanswers with one JSON-RPC result carrying the whole content as a base64 string, so both ends materialise it in full. That is why large files belong on thedownload_*tools, whose signed URLs are ordinary HTTPS GETs that stream. Claude Code and other clients that store resources on disk write the blob to a file rather than holding it in context, which is useful for the largest of these, the OpenAPI document. - Size limit. Reads are bounded by the inline read cap, a server-configurable maximum (
BINARY_READ_MAX_BYTES, default 8 MiB). Requests that exceed the limit fail fast with an error rather than streaming a truncated body — the error states the size and the cap, and points at the matchingdownload_*tool (named per resource below), which streams and is not subject to this limit. The server also bounds how much it will buffer at once, so a read can be refused for server capacity rather than for document size; that rejection is retryable, says so, and does not mean the document is too large. - Error handling. Upstream
EcpaApiError/EcpaTimeoutErrorare converted toProtocolError(InternalError) with the upstream message preserved — the same 404 / 413 / 5xx surfaces you would get calling ECPA directly, re-raised as MCP errors. Two exceptions carry application-defined codes rather thanInternalError, because neither is an upstream failure: a size refusal this server applies itself (a document over the inline read cap) is-31001, and its message names the download route to use instead; and a rejection of the request you sent (a malformed filter query, or a path variable of the wrong type) is-31003, and its message says what to send instead. Both are deliberately outside the JSON-RPC reserved range, so a client renders the message rather than treating it as a protocol-level fault. Unknown errors propagate unchanged. - URI scheme. All resource URIs use the
ecpa://scheme; six profile-scoped templates (one of which is the guidance stub) are registered viaResourceTemplate(nolist, so they appear underresources/templates/list), andopenapi_documentis a single static URI with no template variables, registered inresources/list.
Prefer a resource over the equivalent metadata tool (get_profile_document, get_combined_pdf) whenever you want the raw bytes — the metadata tools return JSON descriptions while resources return the document content itself. For MCP clients that surface tool calls but do not fetch resources (e.g. Claude Desktop / the claude.ai connectors), §6 includes download_* tools that return short-lived signed URLs pointing at the same underlying bytes — pick the resource path when your client supports it, the download tool path when it does not.
7.1 profile_document_raw
Raw profile document — by profile & document ID
When to use. Download a single document's raw bytes in its default format. Use this after
list_profile_documents/get_profile_documenthas told you which document you want. The tool returns the metadata; the resource returns the file.
URI template. ecpa://profiles/{profileId}/documents/{documentId}/raw
MIME type. application/octet-stream (the underlying format depends on the document — commonly PDF, HTML, or image).
What you get. The document body in ECPA's default format for that document type, as a single binary blob.
Standard errors. Follows the shared binary-resource pattern described in the §7 preamble — 404 when the profile or document does not exist, 413 when the document exceeds BINARY_READ_MAX_BYTES, upstream 5xx re-raised as InternalError.
7.2 combined_pdf_raw
Raw combined PDF — by profile & combined-PDF ID
When to use. Fetch the combined PDF bytes after
order_combined_pdf→wait_for_combined_pdfhas reachedstatus === 'READY'. This is the only way to retrieve the combined PDF body; the ordering/polling tools return metadata only.
URI template. ecpa://profiles/{profileId}/documents/combined-pdf/{id}/raw
MIME type. application/pdf
What you get. The combined PDF as a single binary blob. {id} is the combined-PDF identifier returned by order_combined_pdf.
Standard errors. Follows the shared binary-resource pattern described in the §7 preamble. 404 if the combined PDF has not been ordered / is not yet ready; 413 if the generated PDF exceeds the download limit.
7.3 profile_chart_pdf
Profile relationship/ownership chart PDF — by profile ID
When to use. Retrieve the relationship / ownership chart for a profile as a PDF. Generated on demand — no separate ordering step required. Use when you want a visual corporate-structure summary alongside the structured
get_profile_entitiesdata.
URI template. ecpa://profiles/{profileId}/documents/chart-pdf
MIME type. application/pdf
What you get. A freshly rendered PDF of the profile's relationship chart. No polling is required — ECPA generates the chart synchronously.
Standard errors. Follows the shared binary-resource pattern described in the §7 preamble. Profiles without chartable entities may return an upstream error; that is surfaced through the standard envelope.
7.4 profile_documents_zip
All profile documents as a zip — by profile ID
When to use. Bulk-download every document in a profile in a single request. Handy for evidence archival. Prefer
profile_document_rawper-document if you only need a subset — large profiles can easily exceed the inline read cap (BINARY_READ_MAX_BYTES, default 8 MiB); for bulk archival at scale,download_profile_documents_zip(§6) streams instead and is bounded by the much larger streamed download cap (DOWNLOAD_STREAM_MAX_BYTES, default 500 MiB).
URI template. ecpa://profiles/{profileId}/documents/all.zip
MIME type. application/zip
What you get. A zip archive of all documents in the profile, using ECPA's server-side defaults for includeUserAttachments and useDescriptiveFilenames.
Standard errors. Follows the shared binary-resource pattern described in the §7 preamble. Profiles whose total document size exceeds BINARY_READ_MAX_BYTES will return an error — either lift the server-side limit, fetch documents individually, or use download_profile_documents_zip (§6), which streams under the much larger DOWNLOAD_STREAM_MAX_BYTES instead.
7.5 profile_documents_filtered_zip
Filtered profile documents as a zip — by profile ID + filters
When to use. Bulk-download only the documents in a profile matching given filters (kind, status, provider, entityId, date ranges, and the include* flags), bundled into a single zip. Prefer this over
profile_documents_zipwhen you only need a subset — narrower zips are smaller and faster.
URI template. ecpa://profiles/{profileId}/documents/filtered.zip{+query}
MIME type. application/zip
Query parameters (at least one required). kind, status, provider, entityId, dateCreatedStart/dateCreatedEnd, dateModifiedStart/dateModifiedEnd, includeUserAttachments, includePurchaseHistory, includeNoMatchReports, includeScreeningNoMatchReports, useDescriptiveFilenames. Unknown parameter names and duplicate keys are rejected, never ignored. Date values are ISO-8601; percent-encode + in UTC offsets (%2B) or use a Z/date-only form instead — an unencoded + is decoded to a space by query-string parsing and fails validation.
What you get. A zip archive of only the documents in the profile that match the supplied filters. A filter set matching no documents yields a valid empty zip (zero entries), not an error.
Strict validation. A read with no query string at all (bare filtered.zip) is served by a companion registration that always fails with guidance pointing at ecpa://profiles/{profileId}/documents/all.zip for the full unfiltered bundle. A query string present but empty (a bare trailing ?) fails with the same "at least one filter required" message.
Standard errors. Follows the shared binary-resource pattern described in the §7 preamble, plus the strict query validation above, which is rejected before any upstream call is made, carries the application-defined code -31003, and states what to send instead.
7.6 openapi_document
ECPA v3.1 OpenAPI document (whole, as served)
When to use. Fetch the connected ECPA deployment's complete live v3.1 OpenAPI document, byte for byte as served (about 450 KB), when you want to parse it client-side rather than take in-context slices. Unlike the other resources in this section this one is static (a single URI with no template variables). For clients that write resources to disk (e.g. Claude Code), read it once and reuse the file rather than re-fetching. For in-context slices of individual schemas use
get_schemainstead; for clients without resource support usedownload_openapi_document.
URI. ecpa://openapi/v3.1 (static, not a template; registered in resources/list, not resources/templates/list).
MIME type. application/json
What you get. The document as a single binary blob. The document's own servers[0].url is the serving cluster's generated URL, not this MCP server's.
Standard errors. Follows the shared binary-resource pattern described in the §7 preamble. A deployment that does not serve the document surfaces as an upstream 403/404/406, re-raised as InternalError.
8 Prompts
This server exposes no prompts and declares no prompts capability.
9 End-to-end example
A realistic demo-path walkthrough, from a fresh client connection to a fully retrieved combined PDF. Each step lists the call in generic MCP tool-call JSON ({ "tool": "...", "arguments": { ... } }), as an equivalent example prompt and one sentence on what to look for in the response. Long identifiers and payload fields are elided as "..." for readability.
9.1 Connect the client and verify auth
Once your MCP client has authenticated against the ecpa-mcp server, confirm the plumbing with verify_auth before doing anything else. The response payload shape is documented in §4; if status is "failed", stop here and copy the full payload into a support ticket.
{ "tool": "verify_auth", "arguments": {} }
Look for "status": "succeeded" and a non-empty userSub. Any failure path at this step blocks every subsequent step.
9.2 list_profiles — find an existing subject (or confirm none match)
Narrow to a small, human-scannable subset. You can filter by name, by a recent creation window, or simply take the first page. The goal is to decide whether to reuse a profile or create a fresh one.
{
"tool": "list_profiles",
"arguments": {
"name": "Acme",
"limit": 10
}
}
Look at data[].id, data[].name, data[].dateCreated. If an existing profile is suitable, skip step 3 and pass its id as profileId in step 5.
9.3 create_profile — create a new subject
Only run this step if no existing profile matches. Use a stable customerReference — it's your side's idempotency key and shows up in support conversations.
{
"tool": "create_profile",
"arguments": {
"customerReference": "demo-acme-2026-04",
"name": "Acme Holdings Ltd"
}
}
Look for id in the response — that's the profileId you will use everywhere downstream. Subject-specific details like companyName/countryCode are not part of the profile itself; they are supplied later to create_policy_order (step 5).
9.4 list_policies — pick a policy definition
Fetch the policies available to your tenant and pick one whose policyParametersType matches your subject (a company-shaped type such as CompanyTemplateParameters or CompanyWithJurisdictionTemplateParameters, or a person-shaped type such as PersonTemplateParameters — see create_policy_order for the full list of supported types and their fields). When you already know roughly which policy you want, filter (name, identifier, description, parameterType, or a broad search) to narrow the list rather than paging all of it.
{ "tool": "list_policies", "arguments": { "name": "onboarding", "limit": 50 } }
Look for a policy's policyIdentifier (that's what step 5 passes to create_policy_order), its policyDescription to confirm it does what you expect, and its policyParametersType so the next step sends the correct subject fields.
9.5 create_policy_order — kick off execution
Bind the chosen policy to the profile from step 2 or step 3. Provide either customerReference (to create a new profile implicitly) or profileId (to run against an existing one) — never both.
{
"tool": "create_policy_order",
"arguments": {
"policyIdentifier": "company_onboarding_policy_xyz",
"policyParametersType": "CompanyWithJurisdictionTemplateParameters",
"profileId": "69e589e22ed8ec3a7b2432da",
"companyName": "Acme Holdings Ltd",
"countryCode": "GB"
}
}
Note: you could alternatively omit the profile ID but specify a custom reference to let the server create a new profile for you on-the-fly.
Look for callerReferenceId (threaded through every polling / resolution call) and profileId (confirm it matches the one you passed in).
9.6 wait_for_policy_completion
Poll the order. The tool blocks for up to maxWaitSeconds and returns the latest status. If isTerminal is false and status is not ACTION_REQUIRED, simply call it again — the polling tool is safe to re-invoke and does not lose state. If status === 'ACTION_REQUIRED', jump to step 8.
{
"tool": "wait_for_policy_completion",
"arguments": {
"callerReferenceId": "69e58759ca1d985769e7e29a",
"maxWaitSeconds": 30
}
}
Look at status and isTerminal. Terminal values (COMPLETED, MATCHES, NO_MATCHES, NO_RESULTS, RISK_IDENTIFIED, FAILED, ABORTED, legacy USER_SKIPPED) unlock step 7; ACTION_REQUIRED unlocks step 8; PAUSED means hold until a human decides what to do; UNKNOWN means stop polling and inspect the order directly.
9.7 Inspect with get_policy_order / get_policy_step / get_policy_sequences
Once terminal, pull the structured result. get_policy_order gives you the order-level status and decision. get_policy_sequences enumerates the sequences the policy ran. get_policy_step dives into a single step (useful both for diagnosis and for entity-resolution candidate inspection).
{
"tool": "get_policy_order",
"arguments": { "callerReferenceId": "69e58759ca1d985769e7e29a" }
}
Look for the final status and, for FAILED / ABORTED, any diagnostic fields on the order or on individual steps.
9.8 resolve_policy_step — only if a step needs user input
Skip this step entirely if no step returned ACTION_REQUIRED. Otherwise, for each unresolved step: call get_policy_sequences to find the unresolved steps, get_policy_step to retrieve the candidate entities and check autoResolutionPermitted, and then resolve each one. A human picks the match (or confirms none match) unless autoResolutionPermitted is true, in which case you may select the best-supported option yourself and report the resolution afterwards (step, option, basis).
The example below assumes autoResolutionPermitted is true for the calling identity — a permission set at the user and/or account level. Otherwise send the user's own choice with autoResolved: false and no authorisationBasis.
{
"tool": "resolve_policy_step",
"arguments": {
"callerReferenceId": "69e58759ca1d985769e7e29a",
"sequenceId": "69e5853eca1d985769e7ceab",
"stepId": "69e581f52ed8ec3a7b1eacb7",
"resolutionType": "SINGLE_ITEM_SELECTION",
"optionIds": [1],
"autoResolved": true,
"rationale": "Company name, registration number, and jurisdiction all match the profile's target entity.",
"authorisationBasis": "AGENT_DISCRETION"
}
}
resolutionType is one of SINGLE_ITEM_SELECTION, MULTIPLE_ITEM_SELECTION, or NO_MATCH. optionIds is an array of integers taken from get_policy_step's userInputRequired.options; omit it when resolutionType is NO_MATCH. autoResolved is mandatory on every call — true unless you have positive grounds for false. rationale (≤2000 chars) is required when autoResolved is true. authorisationBasis is one of HUMAN_CONFIRMED_SELECTION, HUMAN_MANDATE, OPERATING_MANDATE, or AGENT_DISCRETION, required when autoResolved is true and forbidden when it is false. mandateReference (≤500 chars) is optional and valid only alongside HUMAN_MANDATE or OPERATING_MANDATE — never send a fabricated reference to satisfy it.
Look for an acknowledgement and then go back to step 6; after resolution the policy resumes IN_PROGRESS and may yield further ACTION_REQUIRED pauses or a terminal outcome.
9.9 Combined PDF: order, wait, fetch
Unlike the earlier steps, this final step is a three-stage path made of three separate MCP calls — two tool calls (shown as JSON fences below) and a resource read (shown as a URI fence). When the policy has reached a terminal status and you want the full packaged evidence, run all three in order: order_combined_pdf kicks off generation and returns an id; wait_for_combined_pdf polls it to READY; the combined_pdf_raw resource returns the bytes.
{
"tool": "order_combined_pdf",
"arguments": { "profileId": "69e589e22ed8ec3a7b2432da" }
}
Then poll:
{
"tool": "wait_for_combined_pdf",
"arguments": {
"profileId": "69e589e22ed8ec3a7b2432da",
"id": "69e58759ca1d985769e7e29a",
"maxWaitSeconds": 30
}
}
Once status === 'READY', fetch the resource by URI — MCP-resource-capable MCP clients such as Claude Code expose this as a resource read, not a tool call. Note: MCP clients that cannot work with resources can fall back on the download_combined_pdf tool that exposes the document as a short-lived direct download link:
ecpa://profiles/69e589e22ed8ec3a7b2432da/documents/combined-pdf/cpdf_01H.../raw
Look for a blob content entry with mimeType: "application/pdf". You now have the full evidence PDF locally and the demo path is complete.
10 Errors & troubleshooting
10.1 Auth failures (HTTP 401 from the MCP server)
If the MCP server rejects your request outright it returns HTTP 401 with a WWW-Authenticate: Bearer resource_metadata="<base-url>/.well-known/oauth-protected-resource" header (per RFC 9728). That means the bearer token is missing, invalid, or scoped to the wrong audience. Common causes:
- Expired access token. Re-run your OAuth / M2M flow to mint a fresh one.
- Wrong
audienceparameter on the client-credentials grant (machine-to-machine integrations). The audience must exactly match the value Encompass supplied when your integration was provisioned. - Wrong Auth0 tenant. Double-check your client is configured against the Auth0 tenant Encompass supplied for your integration.
401s are returned before the request reaches any ECPA-backed tool. If you see one, do not retry with the same token — fix the credentials.
Tight loops trip a 429. If authentication keeps failing from the same source, repeated failures may respond with HTTP 429 (carrying Retry-After and X-Rate-Limit-* headers) instead of 401. The fix is the same — replace the broken token — but in-flight requests with the bad token will continue to receive 429 until the Retry-After window elapses. Honour Retry-After before retrying.
10.2 ECPA errors (isError: true inside a 200 response)
ECPA-backed tools use the standard ECPA error envelope (see §5). The MCP call itself returns HTTP 200 — the failure is encoded inside the MCP result:
isError: trueon the result.- A human-readable message in
content[0].text. For non-rate-limit failures this is"ECPA API error <status>: <detail>"for HTTP errors or"ECPA request timed out after Nms: …"for timeouts. For upstream 429s the text is an imperative wait instruction (see §10.4). - Structured
_metacarryingerror: 'rate_limited' | 'upstream_error' | 'upstream_timeout'plus per-category fields (status,tool,rule,retryAfterSeconds) — full schema in §5. - Schema-validation failures from ECPA return a distinct
"upstream response did not match expected schema: …"diagnostic listing up to 5 Zod issues (no_meta).
When an ECPA error appears, read content[0].text first — for non-rate-limit failures it contains the upstream HTTP status and message, which is what your ECPA support contact will ask for. For upstream 429s specifically, see §10.4 for the rate-limit shape and retry semantics.
10.3 verify_auth failure payload
On failure, verify_auth returns the structured diagnostic payload documented in §4 (includes status: "failed", userSub, the deployment identity fields, and error). Copy the payload verbatim into any support ticket — the error field in particular disambiguates Auth0-side failures (tenant config, audience, CTE) from downstream issues.
10.4 Rate limits and timeouts
Three classes of failures land here, with distinct shapes.
Upstream Encompass Public Automation REST API code 429 errors (rate-limited). The MCP call returns HTTP 200 with isError: true. The content[0].text is an imperative instruction the LLM is expected to honour:
"Upstream rate limit exceeded for tool 'X' (ECPA API). You MUST wait at least N seconds before retrying. Retrying sooner will be rejected with the same response. Continue with other work or report the rate limit to the user; do not retry sooner."
_meta carries the structured payload: { error: 'rate_limited', rule: 'ecpa-upstream', retryAfterSeconds: <int>, tool: '<name>' }. Programmatic clients should read retryAfterSeconds from _meta and wait at least that long before retrying; LLM-driven clients will follow the imperative wait instruction in the text content. rule: 'ecpa-upstream' identifies the throttle source as the ECPA upstream API.
MCP server's own rate limit. Separately from the upstream, this server applies its own rate limiting to incoming MCP calls. When a budget is exhausted, the call returns HTTP 200 with the same Annex A shape as the upstream-429 case — isError: true, the imperative wait message in content[0].text, and _meta: { error: 'rate_limited', rule: <string>, retryAfterSeconds: <int>, tool: '<name>' }. The only fields integrators need to act on are retryAfterSeconds (wait at least that long before retrying) and _meta.error: 'rate_limited' (to recognise the category). The rule value is 'ecpa-upstream' when the throttle comes from Encompass's upstream API (above); any other value indicates this server's own throttle — treat it as an opaque identifier whose specific value may change between releases.
Requests to the discovery endpoints under /.well-known/* may instead respond with a real HTTP 429 plus standard Retry-After and X-Rate-Limit-* headers — not the in-body shape described above. Authenticated /mcp traffic is unaffected by this. Repeated authentication failures from a single source can likewise respond with HTTP 429 instead of 401 (see §10.1).
Malformed or unsupported requests (HTTP 4xx from the MCP server, or a JSON-RPC error). These are answered by the MCP server itself, before any ECPA call, so they never carry the ECPA error envelope:
- A
tools/callnaming a tool that does not exist (e.g. a misspelt name) is answered with a JSON-RPC error object, code-32602(Invalid params), inside an HTTP 200, rather than aCallToolResultwithisError: true. Treat both shapes as "the call failed"; check the tool name againsttools/list. - Request bodies over 64 KiB are refused with HTTP 413 and a JSON-RPC envelope (
error.code -32600); no legitimate MCP request approaches this, i.e. binary uploads use the separate upload URL. - A body that is not valid JSON is HTTP 400 with
error.code -32700; an empty body, or one that is not a JSON-RPC message, is HTTP 400 witherror.code -32600. Content-Type: application/jsonwith a charset other than UTF-8, or a compressed (Content-Encoding) body, is HTTP 415 witherror.code -32600. Send plain UTF-8 JSON.
Other ECPA errors (non-2xx, timeouts). Surface through the standard ECPA error envelope (see §5):
EcpaApiError— ECPA returned a non-2xx;content[0].textincludes the status and upstream message;_meta.error: 'upstream_error'withstatusandtool.EcpaTimeoutError— the request exceeded the client-side timeout;_meta.error: 'upstream_timeout'withtool. Retry policy is caller-driven.
For the polling tools (wait_for_policy_completion, wait_for_combined_pdf) a non-terminal result means the underlying ECPA operation did not complete within maxWaitSeconds — it does not indicate a failed operation. Call the polling tool again with the same arguments; state is server-side and nothing is lost between polls.
The polling tools never fail on their own timeout: window expiry always returns a status with isTerminal: false. If a wait call instead ends in a timeout or connection error, the client or something on the network path cut the request before the window finished (every MCP client applies its own tool-call timeout, and some hops do too). Retry with a smaller maxWaitSeconds, e.g. halve it, and keep it there for the rest of the session. The 30 s default is safe on every client we know of. The server stops polling as soon as it notices the client has gone.
10.5 Capacity refusals
Separately from the per-user rate limits above, this server bounds how much work it will hold in flight at once, across every caller sharing a pod. A capacity refusal means the pod is momentarily full, not that your account has used up a quota — the fix is the same either way (wait, then send less at once), but the two are worth telling apart when you're deciding what to change.
- On
tools/call. Same wire shape as the rate-limit case above:isError: true, an imperative retry instruction incontent[0].text, and_meta: { error: 'rate_limited', rule: <string>, retryAfterSeconds: <int>, tool: '<name>' }. Handle it identically — readretryAfterSecondsand wait at least that long. Therulevalue distinguishes a capacity refusal from an upstream or per-user one; treat it as an opaque identifier whose specific value may change between releases. - On every other MCP method (
initialize,tools/list,resources/list, and any other method that has noCallToolResultto carry the shape above), a capacity refusal is a JSON-RPC error object over HTTP 200, withcode: -31002and adatapayload carrying the sameruleandretryAfterSecondsfields. There is no successful result for that call; wait forretryAfterSecondsbefore sending it again. - A legacy JSON-RPC batch refused for capacity gets one JSON-RPC error object — the plain "every other MCP method" shape above,
code: -31002, never thetools/callisErrorshape even for atools/callinside the batch — for every request in the batch (a message with bothmethodandid). A notification or an already-posted response in the same array gets nothing, since neither expects a reply. - A legacy JSON-RPC batch refused as malformed (too many messages in one array, a
wait_for_*call included in a batch, or more requests in one array than the server would ever run at once for one caller) is a different case: JSON-RPC errorcode: -32600(Invalid Request), one per request in the batch, over HTTP 200. Notifications and posted responses in the array get nothing, and an array with no requests in it gets HTTP 202 with no body. This is not a capacity refusal and is not retryable as sent — resend the messages individually rather than batched. Batching left the MCP protocol in the 2025-06-18 revision; a client built against a current SDK should not be sending one.
Handling rule, for all of the above: honour retryAfterSeconds before retrying, reduce how many calls you run in parallel rather than retrying the same one immediately, and don't assume a bare retry will succeed — if you keep hitting this, the fix is less concurrency from your side, not a tighter retry loop.
10.6 Download links that return 404
The download_* tools return a short-lived download_url (the expires_at timestamp is included in the response envelope; links may be reused within that window — see download_profile_document in §6 for the full envelope shape). A plain HTTP 404 with { "error": "not_found" } from /downloads/<token> means the link has expired or is unknown to the server.
Expired links are not recoverable — re-run the download tool to mint a fresh URL, then fetch it promptly.
10.7 Order stuck in ACTION_REQUIRED
A policy order in ACTION_REQUIRED is waiting for user input — it will not progress regardless of how long you poll. Whether the assistant may resolve the blocked steps itself is governed by autoResolutionPermitted (see resolve_policy_step) rather than anything said in the conversation; when it is false, resolve them by presenting the candidates to the user instead.
Call get_policy_sequences to list the order's steps, then for each step with status: "ACTION_REQUIRED" call get_policy_step to retrieve the candidate options and check autoResolutionPermitted, then resolve_policy_step to submit the selection (or NO_MATCH if none match) along with the mandatory autoResolved attestation. A 403 from resolve_policy_step is either a refusal of an autonomous resolution (_meta.forbiddenReason: auto_resolution_not_permitted) or a lack of access to the order's profile (profile_access); stop and escalate to a human rather than retrying. For the first, present the candidates and, once the user has chosen, submit their selection with autoResolved: false and no authorisationBasis (not a retry of the refused call); for the second, escalate to someone with access to the profile. Once every blocked step is resolved, call wait_for_policy_completion again to resume monitoring.
11 Support & next steps
11.1 Reporting issues
Email support@encompasscorporation.com — the standard support entry point for Encompass production systems — with questions, bug reports, and feature requests. Include the details below to speed up triage.
11.2 What to include in a support ticket
The more of the following you include up front, the faster the turnaround:
- The full
verify_authresponse payload (especially on auth problems — theerrorfield is load-bearing). - The MCP response body from the failing tool call, including the
isErrorflag andcontent[0].text. - A request-id from the response headers, or from your self-hosted server logs if running locally (filter by
userSub+ timestamp if you don't have the id directly). - A UTC timestamp for when the failure occurred.
- A one-line description of what you were trying to do, including the tool name and relevant IDs (
profileId,callerReferenceId).
Important: Do not paste bearer tokens or client secrets — they are never needed to triage an issue.
11.3 Further reading
- ECPA API documentation — the upstream REST reference. Reachable with the same Encompass credentials used for MCP authentication; your Encompass contact can point you at the current URL for your specific environment if you do not already have it bookmarked. For field-level shapes use the
get_schematool; the REST reference remains the source for policy configuration and everything else. - Other Encompass developer resources — contact Encompass for access to additional developer resources, SDK samples, and onboarding material appropriate to your use case.