Skip to main content

OpenWealth MCP

CI PyPI Python License

Three FastMCP servers that expose the OpenWealth APIs as MCP tools, so an AI assistant (Claude, Cursor, any MCP client) can read custody data, manage orders, and onboard customers through a typed, audited interface instead of raw HTTP.

Server API Console script Tools
Custody Custody Services v3.2.0 — customers, accounts, positions, transactions openwealth-custody-mcp 10 (read-only)
Trading Order Placement v3.0.1 — orders, executions, quotes, subscriptions openwealth-trading-mcp 18 (full lifecycle)
Customer Customer Management v2.0.6 — customers, persons, contacts, addresses, documents, KYC openwealth-customer-mcp 26 (full lifecycle)

All three ship in one Python package and speak MCP over stdio. OpenAPI specs are vendored from OpenWealth and served as sanitized MCP resources (server URLs and auth schemes are stripped before the spec is exposed to the LLM).

⚠️ Trading places real orders. create_order is a financially consequential tool. Read Safety model before pointing it at anything other than the sandbox.


Install

pip install openwealth-mcp

Requires Python ≥ 3.11 and a bearer token for an OpenWealth endpoint (sandbox or custodian).

To install from source for development:

git clone https://github.com/OpenWealth/OpenWealth-MCP.git
cd OpenWealth-MCP
pip install -e ".[dev]"    # or: uv sync --extra dev

Quickstart

Configure each server separately — each needs its own base URL and token.

Claude Desktop / Claude Code (claude_desktop_config.json):

{
  "mcpServers": {
    "openwealth-custody": {
      "command": "openwealth-custody-mcp",
      "env": {
        "OPENWEALTH_CUSTODY_BASE_URL": "<host>",
        "OPENWEALTH_BEARER_TOKEN": "<jwt>"
      }
    },
    "openwealth-trading": {
      "command": "openwealth-trading-mcp",
      "env": {
        "OPENWEALTH_TRADING_BASE_URL": "<host>",
        "OPENWEALTH_BEARER_TOKEN": "<jwt>"
      }
    },
    "openwealth-customer": {
      "command": "openwealth-customer-mcp",
      "env": {
        "OPENWEALTH_CUSTOMER_MANAGEMENT_BASE_URL": "<host>",
        "OPENWEALTH_BEARER_TOKEN": "<jwt>"
      }
    }
  }
}

Cursor (.cursor/mcp.json, or Settings → MCP for a global server):

{
  "mcpServers": {
    "openwealth-custody": {
      "command": "openwealth-custody-mcp",
      "env": {
        "OPENWEALTH_CUSTODY_BASE_URL": "<host>",
        "OPENWEALTH_BEARER_TOKEN": "<jwt>"
      }
    },
    "openwealth-trading": {
      "command": "openwealth-trading-mcp",
      "env": {
        "OPENWEALTH_TRADING_BASE_URL": "<host>",
        "OPENWEALTH_BEARER_TOKEN": "<jwt>"
      }
    },
    "openwealth-customer": {
      "command": "openwealth-customer-mcp",
      "env": {
        "OPENWEALTH_CUSTOMER_MANAGEMENT_BASE_URL": "<host>",
        "OPENWEALTH_BEARER_TOKEN": "<jwt>"
      }
    }
  }
}

Then run MCP: Restart Servers from the command palette and check that the server shows as connected. Configure only the domain you have access to.

Sandbox JWTs often expire in about 60 seconds — refresh from the portal and restart the server. Supply the token without the Bearer prefix; the client adds it.

Full client wiring, WSL specifics and troubleshooting live in docs/mcp-clients.md and docs/local-dev.md.


Configuration

All settings are environment variables prefixed OPENWEALTH_. A .env file in the working directory is loaded automatically (and is gitignored — never commit one). Host and credentials are never hard-coded.

Variable Default Description
OPENWEALTH_CUSTODY_BASE_URL — Custody API base URL including the path prefix, no trailing slash. Required when running the Custody server. https:// is added if the scheme is missing.
OPENWEALTH_TRADING_BASE_URL — Trading API base URL including the path prefix, no trailing slash. Required when running the Trading server.
OPENWEALTH_CUSTOMER_MANAGEMENT_BASE_URL — Customer Management API base URL including the path prefix, no trailing slash. Required when running the Customer Management server.
OPENWEALTH_BEARER_TOKEN — Access token without the Bearer prefix. Required unless OPENWEALTH_AUTH_HEADER is set.
OPENWEALTH_AUTH_HEADER — Full Authorization header value; overrides OPENWEALTH_BEARER_TOKEN.
OPENWEALTH_CORRELATION_ID generated Fixed correlation id; otherwise a UUID per request.
OPENWEALTH_TIMEOUT_SECONDS 120 Read/write timeout in seconds (max 300).
OPENWEALTH_CONNECT_TIMEOUT_SECONDS 10 Connect timeout in seconds (max 120).
OPENWEALTH_MAX_RETRIES 2 Retries for transient failures (0–5). See Safety model.
OPENWEALTH_VERIFY_TLS true Set to false only against a sandbox with a self-signed certificate.
OPENWEALTH_LOG_LEVEL INFO DEBUG, INFO, WARNING, or ERROR. JSON logs on stderr.
OPENWEALTH_LOG_FILE — Optional log file path (logs to both file and stderr).

Startup fails fast if neither OPENWEALTH_BEARER_TOKEN nor OPENWEALTH_AUTH_HEADER is set. The URL for each server is validated at startup — a missing URL prints a clear error and exits.

Transport is stdio only. HTTP transport and JWKS ingress are out of scope in favour of a smaller surface.


Tools

Every response is JSON with status_code, correlation_id and data (plus next_cursor on paginated GETs). Errors return {"error": true, "error_code": "...", "message": "...", "retryable": bool} — never a stack trace.

Custody — openwealth-custody-mcp

Tool operationId Endpoint
get_customers getCustomers GET /customers
get_customers_by_customer_id getCustomersByCustomerId GET /customers/{customerId}
get_customer_accounts_by_customer_id getCustomerAccountsByCustomerId GET /customers/{customerId}/accounts
get_customer_account_by_id getCustomerAccountById GET /customers/{customerId}/accounts/{accountId}
get_customer_position_by_customer_id getCustomerPositionByCustomerId GET /customers/{customerId}/positions
get_customer_position_by_id getCustomerPositionById GET /customers/{customerId}/positions/{positionId}
get_account_position_by_account_id getAccountPositionByAccountId GET /accounts/{accountId}/positions
get_account_position_by_id getAccountPositionById GET /accounts/{accountId}/positions/{positionId}
get_transaction_by_customer_id getTransactionByCustomerId GET /customers/{customerId}/transactions
get_transaction_by_transaction_id getTransactionByTransactionId GET /customers/{customerId}/transactions/{transactionId}

Listing positions and transactions requires a date (YYYY-MM-DD) — the OpenAPI spec makes it mandatory.

Trading — openwealth-trading-mcp

Tool operationId Endpoint
list_customers listCustomers GET /customers
get_customer getCustomer GET /customers/{customerId}
list_accounts listAccounts GET /accounts
get_account getAccount GET /accounts/{accountId}
list_orders listOrders GET /orders
get_order getOrder GET /orders/{orderId}
create_order ⚠️ createOrder POST /orders
cancel_order actionCancelOrder POST /orders/{orderId}/actions/cancel
list_order_executions listOrderExecutions GET /orders/{orderId}/executions
get_order_execution getOrderExecution GET /orders/{orderId}/executions/{executionId}
list_order_states listOrderStates GET /orders/{orderId}/states
create_quote createQuote POST /quotes
list_event_subscriptions listEventSubscriptions GET /event-subscriptions
get_event_subscription getEventSubscription GET /event-subscriptions/{eventSubscriptionId}
create_event_subscription createEventSubscription POST /event-subscriptions
update_event_subscription updateEventSubscription PUT /event-subscriptions/{eventSubscriptionId}
delete_event_subscription deleteEventSubscription DELETE /event-subscriptions/{eventSubscriptionId}
list_event_subscription_notifications listEventSubscriptionEventNotifications GET /event-subscriptions/{eventSubscriptionId}/event-notifications

Customer Management — openwealth-customer-mcp

Tool operationId Endpoint
get_customers getCustomers GET /customers
create_customer ⚠️ postCustomer POST /customer-details
get_customer getCustomerByCustomerId GET /customers/{customerId}
get_customer_details getCustomerDetailsByCustomerId GET /customers/{customerId}/customer-details
get_persons getPersons GET /customers/{customerId}/persons
create_person ⚠️ postPerson POST /customers/{customerId}/person-details
get_person getPersonByPersonId GET /customers/{customerId}/persons/{personId}
get_person_details getPersonDetailsByPersonId GET /customers/{customerId}/person-details/{personId}
get_contacts getContactDetailsByCustomerId GET /customers/{customerId}/persons/{personId}/contacts
create_contact postContactDetailsByCustomerId POST /customers/{customerId}/persons/{personId}/contacts
get_contact getContactDetailsByContactDetailID GET /customers/{customerId}/persons/{personId}/contacts/{contactId}
update_contact putContactDetailByContactDetailId PUT /customers/{customerId}/persons/{personId}/contacts/{contactId}
delete_contact deleteContactDetailsByContactDetailID DELETE /customers/{customerId}/persons/{personId}/contacts/{contactId}
get_addresses getAddressByCustomerId GET /customers/{customerId}/persons/{personId}/addresses
create_address postAddressByCustomerId POST /customers/{customerId}/persons/{personId}/addresses
get_address getAddressByAddressId GET /customers/{customerId}/persons/{personId}/addresses/{addressId}
update_address putAddressByCustomerId PUT /customers/{customerId}/persons/{personId}/addresses/{addressId}
get_documents getDocumentsByCustomerId GET /customers/{customerId}/documents
create_document ⚠️ postDocumentByCustomerId POST /customers/{customerId}/document-details
get_document getDocumentByDocumentId GET /customers/{customerId}/documents/{documentId}
get_document_details getDocumentDetailsByDocumentId GET /customers/{customerId}/documents/{documentId}/document-details
get_kyc getKycByCustomerId GET /customers/{customerId}/persons/{personId}/kyc
create_kyc ⚠️ postKyc POST /customers/{customerId}/persons/{personId}/kyc
create_prospect_precheck postProspect POST /prospect-precheck
get_prospect_precheck getPreCheck GET /prospect-precheck/{temporaryId}
get_status getStatusByTemporaryId GET /status/{temporaryId}

⚠️ marks tools that create regulatory or compliance-significant entities (customer, person, document, kyc) — records that are hard to reverse and carry KYC/AML implications. Write tools on softer, mutable data (contact, address, prospect_precheck) are not marked because they can be freely updated or deleted without compliance impact. All Customer Management write tools are still never retried regardless of the ⚠️ marker — see Safety model.

MCP resources

URI Content
openwealth://specs/custody Custody tool/endpoint table (Markdown)
openwealth://specs/custody.yaml Custody OpenAPI schema reference (server URLs and auth stripped)
openwealth://specs/trading Trading tool/endpoint table with financial-impact notes
openwealth://specs/trading.yaml Trading OpenAPI schema reference (server URLs and auth stripped)
openwealth://specs/customer Customer Management tool/endpoint table with write-impact notes
openwealth://specs/customer.yaml Customer Management OpenAPI schema reference (server URLs and auth stripped)

Safety model

  • create_order is never retried. A duplicate order is a financial error, so a failed POST fails loudly rather than silently placing a second one.
  • Customer Management write tools are never retried. create_customer, create_person, create_contact, create_address, create_document, create_kyc and create_prospect_precheck are not retried to avoid duplicate records at the custody bank.
  • Idempotent writes are retried on 5xx: cancel_order, create_quote, update_contact, update_address, PUT and DELETE. GETs retry on 408, 429 and 5xx with exponential backoff and ±20% jitter. The Retry-After header is honoured.
  • Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are set per tool, so MCP clients can require confirmation for writes.
  • Tokens are never tool arguments. They come from the environment only, and are never echoed in tool results or logs.
  • Custody is read-only by design. Only the Trading and Customer servers can mutate state.

Always confirm order details with a human before calling create_order.


Development

With uv (recommended):

uv sync --extra dev

uv run ruff check src tests
uv run ruff format --check src tests
uv run mypy
uv run pytest -q

With pip:

pip install -e ".[dev]"

ruff check src tests
ruff format --check src tests
mypy
pytest -q

The same four gates run in CI on every push and pull request across Python 3.11, 3.12 and 3.13. pre-commit install wires ruff and mypy into your commits.

See CONTRIBUTING.md for full contribution guidelines.


Documentation

Where What
CHANGELOG.md Release history
CONTRIBUTING.md Dev setup and contribution guidelines
docs/mcp-clients.md MCP client configuration (Claude, Cursor, WSL)
docs/local-dev.md Local development setup
docs/release.md Release and publishing process
specs/ Vendored OpenAPI definitions
SECURITY.md Vulnerability reporting and secret handling

Scope

Custody is read-only (GET). Trading covers the full order lifecycle (GET, POST, PUT, DELETE). Customer Management covers the full customer onboarding and lifecycle (GET, POST, PUT, DELETE). HTTP transport, JWKS ingress and a central MCP gateway are out of scope.


License

Apache-2.0

Metadata

Release files for openwealth-mcp 0.3.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openwealth-mcp 0.3.8
File Size Uploaded Provenance Actions
openwealth_mcp-0.3.8.tar.gz 210.8 kB With provenance Details for openwealth_mcp-0.3.8.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for openwealth-mcp 0.3.8
File Interpreter ABI Platform Actions
openwealth_mcp-0.3.8-py3-none-any.whl Python 3 none any Details for openwealth_mcp-0.3.8-py3-none-any.whl

Total release size: 300.2 kB

Release files / openwealth_mcp-0.3.8.tar.gz

Download URL openwealth_mcp-0.3.8.tar.gz
Size 210.8 kB
Tags Source
SHA-256 checksum
How to use checksums
6cbba2a57aa0342628fb9aa6e9b98c32cd6f3f9b7f841fb015cfa0c100415420
BLAKE2b-256 checksum
How to use checksums
2c544a537ad743b254685a0a05d0da8efe349e96ef9d7b56b338103533abbd91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / openwealth_mcp-0.3.8-py3-none-any.whl

Download URL openwealth_mcp-0.3.8-py3-none-any.whl
Size 89.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f7d8c60ec4fe6badd445b5b3086febdc0356bd1f3843ea192b3b7d781eda857e
BLAKE2b-256 checksum
How to use checksums
f56b00f5159374a8b56bc7aa09f04d24e2e50396ccfe6d56f1e904d28aae90cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Security for openwealth-mcp 0.3.8

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for openwealth_mcp-0.3.8.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.3.8 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page