MCP Developer Guide

Encompass ec360 Public Automation MCP Developer Guide

Contents

  1. What is ecpa-mcp?
  2. The ECPA policy model
  3. Getting started
  4. Connecting & authenticating
  5. MCP primitives reference
  6. Tools
  7. Resources
  8. Prompts
  9. End-to-end example
  10. Errors & troubleshooting
  11. 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, resources, and prompts 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).


3 Getting started

Prerequisites:


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 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.3 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) — refer to the ECPA v3.1 API documentation. The ECPA API documentation is reachable with the same Encompass credentials used for MCP authentication.

Where a tool returns polymorphism via a type discriminator with per-type dataSourceAttributes or similar open-map payloads, this guide documents the discriminator pattern and the common values; it does not duplicate every type's field list.

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:

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) and pagination ({ totalItems, nextCursor }). To page forward, call the tool again passing the returned cursor as the cursor argument until nextCursor is 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.

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 the run_policy prompt's parameters argument or a resource URI's query string — and the field's own description says so where it applies.

Neither spelling errors, which is what makes this worth watching: DEERE &amp; 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.


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).

Output shape. Paginated (see §5 preamble). data[] items are ProfileSummaryid, 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. from list_profiles, create_policy_order, or get_policy_order) and need the full summary — name, customer reference, target entity, risk level, status, dates, active perspective.

Input schema (summary).

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" }

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).

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_order can also create a profile on the fly via customerReference.

Input schema (summary).

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 callerReferenceId for the new policy run: pass it to wait_for_policy_completion to monitor progress.

Input schema (summary).

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).

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_entities when you want to understand provenance.

Input schema (summary).

Output shape. Paginated EntityResource[]. Each entity has an id, a type discriminator (string), and a dataSourceAttributes[] array — each element identifies the orderId, dataSource, serviceIdentifier, dateCreated, documentIds, attributesSourceMapping, and a sourceUrl. Per-type attribute fields are open-map (catchall(unknown)) — refer to the ECPA API documentation for field-level schemas per entity type.

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>).

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:

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).

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 dataProductOrderId tied to a specific document.

Input schema (summary).

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).

Output shape. Paginated AuditTrailResource[] — each entry: id, type, createdDate, description, profileId, userId, plus any upstream-specific fields (open-map).

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. kind and provider take profile-specific values — call list_profile_document_types / list_profile_document_providers first and pass a value from their results; do not guess.

Input schema (summary).

Attachment-exclusion caveat. Setting kind, status, provider, entityId, or a dateModified bound excludes file attachments from the result — these are the selecting filters. dateCreated bounds and the include* booleans do not exclude attachments.

Output shape. Paginated DocumentResource[]. Each document carries metadata including id, type, productCode, category, description, documentType, kind, filename, descriptiveFileName, dateProcessedIso, dateModified, documentName, documentAuthority, uploadedByUser, entityId, status (PENDING | READY | ERROR), 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_documents or download_profile_documents_zip to filter by type.

Input schema (summary).

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_documents or download_profile_documents_zip to filter by source.

Input schema (summary).

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 through the profile_document_raw resource (see §7), using the id and profileId from this response.

Input schema (summary).

Output shape. Single DocumentResource (metadata only). The raw bytes are addressable via the MCP resource URI ecpa://profiles/<profileId>/documents/<documentId>/raw (see §7 for the canonical URI form).

Notable errors. Standard ECPA error envelope.

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_documents to find the documentId first. Only user-uploaded documents can be deleted — ECPA-generated (system) documents will return an error. This operation is irreversible.

Input schema (summary).

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) or entityId+entityType (to associate with a charted entity); changes apply immediately and the updated DocumentResource is returned. (2) Content replacement — set replaceContent: true to replace the document bytes; the tool returns a short-lived upload URL envelope (same shape as upload_profile_document) and the documentId is preserved. Only user-uploaded documents can be updated. To perform a metadata-only update, omit replaceContent.

Input schema (summary).

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_status after uploading to confirm completion and obtain the new documentId.

Input schema (summary).

entityId and entityType must be supplied together (both or neither).

Output shape. { upload_url, expires_at, instructions }.

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. 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_document or a content replacement via update_profile_document. Pass the upload token from the upload URL (the last path segment of upload_url). Only the user who started the upload can query it.

Input schema (summary).

Output shape. { state, documentId?, error? }.

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 by create_policy_order), a policyName, a policyDescription, and a policyParametersType (the input shape the policy expects, e.g. CompanyTemplateParameters, CompanyWithJurisdictionTemplateParameters, or PersonTemplateParameters — see create_policy_order for 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).

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 value create_data_product_order accepts; the same value is reported as serviceIdentifier on each sequence of a policy order, so a failed sequence can be matched back to the data product to re-run it), a display name, a dataProvider, productCodes, and the parameterTypes it accepts — field descriptors for each type come from list_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 among create_data_product_order's policyParametersType options cannot be ordered through this MCP build.

Input schema (summary).

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 companyIdentifiers map on create_policy_order and refresh_profile. Small, unpaginated set; call it before constructing a companyIdentifiers map 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 policyParametersType discriminator values accepted by create_policy_order and create_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' own policyParametersType options 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 create_policy_order

Create policy order

When to use. Start a KYC/AML screening: pick a policyIdentifier from list_policies or 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 a callerReferenceId used by all follow-up tools.

Input schema (summary).

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.

Output shape. Single PolicyOrderResultcallerReferenceId, 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.32 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 serviceIdentifier from list_data_products and 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 as create_policy_orderwait_for_policy_completion, then get_policy_order / get_policy_sequences / get_policy_step / resolve_policy_step as needed, including user-input-required resolution.

Input schema (summary).

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.33 get_policy_order

Get policy order

When to use. Retrieve the full order detail — status, dates, profileId, original policyParameters — after a policy has progressed. Typically called after wait_for_policy_completion reports a terminal state, or whenever you need the profileId derived from the order.

Input schema (summary).

Output shape. Single PolicyOrderResult (see create_policy_order).

Notable errors. Standard ECPA error envelope.

Example.

{ "callerReferenceId": "69e58759ca1d985769e7e29a" }

6.34 list_policy_orders

List policy orders

When to use. Discover policy orders that have already been created — by profileId, lifecycle status, and/or creation-date window. Useful for resume / recovery flows where you have a profileId but no callerReferenceId, or for auditing which policies have run against a profile.

Input schema (summary).

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.

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. Result ordering from the upstream endpoint is unspecified — there is no sort parameter and no documented default order.

Example.

{ "profileId": "69e589e22ed8ec3a7b2432da", "limit": 25 }

6.35 get_policy_step

Get policy step

When to use. Drill into a single step — in particular, retrieve userInputRequired.options for a step whose status is ACTION_REQUIRED. The response also carries autoResolutionPermitted, which governs whether you may select an option yourself or must present the candidates to the user and wait for their choice before calling resolve_policy_step — see that tool's entry for the full permission contract.

Input schema (summary).

Output shape. Single PolicySequenceStepid, 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, userInput (once resolved).

Notable errors. Standard ECPA error envelope.

Example.

{
    "callerReferenceId": "69e58759ca1d985769e7e29a",
    "sequenceId": "69e5853eca1d985769e7ceab",
    "stepId": "69e581f52ed8ec3a7b1eacb7"
}

6.36 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 call get_policy_step for each. Each sequence and each step summary also carries autoResolutionPermitted — see resolve_policy_step for what it governs.

Input schema (summary).

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.

Example.

{ "callerReferenceId": "69e58759ca1d985769e7e29a" }

6.37 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 in ACTION_REQUIRED so it can resume processing and progress toward a terminal outcome. Whether you may choose an option yourself is governed by autoResolutionPermitted, 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 with get_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 submitted NO_MATCH), and the basis for the decision. Every call must state autoResolved; an autonomous resolution must also carry rationale and authorisationBasis. autoResolved and rationale reach the profile audit trail today; authorisationBasis and mandateReference do not yet (deferred, DEV-6151).

Input schema (summary).

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') means the calling identity was not permitted to perform this resolution — most commonly, an autonomous resolution attempted while autoResolutionPermitted is false. This is a permission failure, distinct from a 422 payload failure: do not retry, even with a shortened or altered rationale — stop and escalate to a human instead. Once the user has chosen, submit their selection with autoResolved: false and no authorisationBasis: the API accepts that call regardless of autoResolutionPermitted, and it is not a retry of the refused call.

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.38 wait_for_policy_completion

Wait for policy completion

When to use. After create_policy_order (or after resolve_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-rolling get_policy_order polling.

Input schema (summary).

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.

Example.

{ "callerReferenceId": "69e58759ca1d985769e7e29a", "maxWaitSeconds": 30 }

6.39 Combined PDF

6.40 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 status starts at PENDING.

Input schema (summary).

Output shape. Single CombinedPdfDocumentResourceid, profileId, documentIds, the include* flags, and status (PENDING | READY | ERROR).

Notable errors. Standard ECPA error envelope.

Example.

{
    "profileId": "69e589e22ed8ec3a7b2432da",
    "includeToc": true,
    "includeAuditTrail": true
}

6.41 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_raw resource (see §7). For polling, prefer wait_for_combined_pdf.

Input schema (summary).

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.42 wait_for_combined_pdf

Wait for combined PDF

When to use. Poll a combined PDF order to READY (or ERROR). Mirrors wait_for_policy_completion in shape — call repeatedly if isTerminal is false. Once status === 'READY', fetch the bytes via the combined_pdf_raw resource (see §7).

Input schema (summary).

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.

Example.

{
    "profileId": "69e589e22ed8ec3a7b2432da",
    "id": "69e58759ca1d985769e7e29a",
    "maxWaitSeconds": 30
}

6.43 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 four 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. Per-download streaming is capped by DOWNLOAD_STREAM_MAX_BYTES (default 500 MB) — substantially larger than the 50 MiB inline-resource cap (§7), so the download path is the right choice for large profile archives.

6.44 download_profile_document

Download profile document

When to use. Tool-call equivalent of the profile_document_raw resource (§7). Returns a signed URL to download a single document's bytes. Use after list_profile_documents / get_profile_document has told you which document you want.

Input schema (summary).

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.

Example.

{
    "profileId": "69e589e22ed8ec3a7b2432da",
    "documentId": "69e589e22ed8ec3a7b36b2c1"
}

6.45 download_combined_pdf

Download combined PDF

When to use. Tool-call equivalent of the combined_pdf_raw resource (§7). Returns a signed URL to download a previously generated combined PDF. The combined PDF must already be in status: 'READY' — run order_combined_pdfwait_for_combined_pdf first.

Input schema (summary).

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.46 download_profile_chart_pdf

Download profile chart PDF

When to use. Tool-call equivalent of the profile_chart_pdf resource (§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).

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.47 download_profile_documents_zip

Download profile documents (zip)

When to use. Tool-call equivalent of the profile_documents_zip / profile_documents_filtered_zip resources (§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. Capped by DOWNLOAD_STREAM_MAX_BYTES (default 500 MB); very large profiles may still need per-document downloads.

Input schema (summary).

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 surface as a streaming error during 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" }

7 Resources

ecpa-mcp currently exposes five binary resources. They share consistent behaviour:

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_document has 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 ECPA_MAX_BINARY_DOWNLOAD_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_pdfwait_for_combined_pdf has reached status === '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_entities data.

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_raw per-document if you only need a subset — large profiles can easily exceed the 50 MiB download cap.

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 ECPA_MAX_BINARY_DOWNLOAD_BYTES will return an error — either lift the server-side limit or fetch documents individually.

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_zip when 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 (InvalidParams) before any upstream call is made.


8 Prompts

The MCP server currently exposes a single prompt. Prompts return orchestration instructions for the AI client to execute — invoking a prompt does not run the workflow; it supplies a structured plan that the client then drives via tool calls.

8.1 run_policy

Run a compliance policy

When to use. Kick off an end-to-end compliance check where you want the assistant to handle policy discovery, order creation, polling, entity-resolution pauses, and result retrieval as a single coherent flow. Prefer the prompt over stitching the individual tools together yourself when you want the assistant to own the branching logic (ACTION_REQUIRED, PAUSED, non-terminal timeouts) and the closing summary. Use the raw tools directly when you need deterministic control or are embedding the calls in your own code.

Arguments. All optional; the prompt degrades gracefully as arguments are omitted. Provide as many as you know up front.

What it returns. Two PromptMessages (one user, one assistant) that encode a six-step workflow: discover policies (if none specified) → create the policy order → poll to completion → resolve entity matches if ACTION_REQUIRED → fetch results in parallel (get_policy_order, get_profile, get_profile_entities, list_profile_documents, get_profile_data_sources) → present findings. The plan also references optional follow-ups: get_profile_news, get_profile_audit_trail, get_profile_purchases, and the combined-PDF path (order_combined_pdfwait_for_combined_pdfcombined_pdf_raw resource).

Example call.

{
    "prompt": "run_policy",
    "arguments": {
        "customerReference": "demo-acme-2026-04",
        "companyName": "Acme Holdings Ltd",
        "countryCode": "GB",
        "policyIdentifier": "default_company_kyc"
    }
}

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:

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:

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:

Other ECPA errors (non-2xx, timeouts). Surface through the standard ECPA error envelope (see §5):

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.

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.6 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 means the calling identity was not permitted to resolve autonomously — stop and escalate to a human rather than retrying. Once the user has chosen, submit their selection with autoResolved: false and no authorisationBasis: the API accepts that call regardless of autoResolutionPermitted, and it is not a retry of the refused call. 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:

Important: Do not paste bearer tokens or client secrets — they are never needed to triage an issue.

11.3 Further reading