ASAPIO Spend Lens
Setup Guide
Deploy Spend Lens on SAP BTP, connect it to your S/4HANA system, and configure roles and access. No ETL pipeline, no additional SAP licence.
Deployment
Prerequisites
- SAP BTP subaccount with the Cloud Foundry environment enabled and a space for Spend Lens. Install Spend Lens once per subaccount: the XSUAA name
asapio-spendlensand the role collections SpendLens User / SpendLens Admin are unique per subaccount, so a second installation (for example a test system) belongs in its own subaccount. - CF CLI with the MultiApps plugin:
cf install-plugin multiapps - Cloud Foundry runtime memory for two small applications and one deployment task (about 1.2 GB in total).
- For S/4HANA on-premise: a Cloud Connector connected to the subaccount.
- The following entitlements in the subaccount. The deploy creates the service instances itself:
| Service (instance created) | Plan | Purpose |
|---|---|---|
Authorization and Trust Management, xsuaa (asapio-spendlens-auth) |
application |
Authentication and role management |
PostgreSQL on SAP BTP, hyperscaler option, postgresql-db (asapio-spendlens-postgres) |
standard (default, MTA parameter postgresPlan) |
Settings, alerts, audit log, and the data cache, in the schema asapio_spendlens (see Database) |
SAP Credential Store, credstore (asapio-spendlens-credstore) |
standard (default) or proxy |
Required since Spend Lens 2.0.0. Holds the encryption keys and the gateway secret (see below) |
Destination, destination (asapio-spendlens-destination) |
lite |
S/4HANA connectivity |
Connectivity, connectivity (asapio-spendlens-connectivity) |
lite |
On-premise Cloud Connector tunnel (not needed for S/4HANA Cloud Public Edition) |
The entitlements, including the one for the Credential Store plan you use, must exist in the subaccount before you deploy. The deployment fails without them.
Database
Since Spend Lens 1.5.0 the database is PostgreSQL on SAP BTP, hyperscaler option (service postgresql-db). SAP HANA Cloud (hdi-shared) is no longer used. Spend Lens keeps its tables in its own schema asapio_spendlens, so a PostgreSQL instance can be shared with other applications.
- Own instance (default). The deploy creates the instance
asapio-spendlens-postgres. Its plan is set with the MTA parameterpostgresPlan(defaultstandard;cf marketplace -e postgresql-dblists the plans your subaccount is entitled to). Thefreeplan is for non-productive use only and can expire (check the plan terms in your subaccount). - Existing instance. Instead of creating its own instance, Spend Lens can use an existing PostgreSQL on SAP BTP, hyperscaler option instance that is available in the target space. Name it with the MTA parameter
existingDbServicein an extension descriptor (see Optional: change defaults) and switch the resources:parameters: existingDbService: <existing-instance-name> resources: - name: asapio-spendlens-postgres active: false - name: asapio-spendlens-db active: true
cf undeploy asapio-spendlens --delete-servicesdeletes the PostgreSQL instance the deploy created, with all data in it. Undeploy without--delete-servicesto keep the services.
SAP Credential Store
Since Spend Lens 2.0.0, every deployment on SAP BTP Cloud Foundry requires an SAP Credential Store service instance (service credstore), named asapio-spendlens-credstore. It holds the encryption keys (the credential key for stored per-user S/4HANA passwords and the MCP token key) and the gateway secret between the approuter and the backend. Spend Lens creates these secrets itself on first start, in the namespace asapio-spendlens. Production refuses to start without a Credential Store.
The plan is set with the MTA parameter credstorePlan:
standard(default) — a Credential Store instance of its own.proxy— a proxy to a central Credential Store instance that is shared with the target subaccount.
Do not assume the
freeplan. It is limited to one instance per subaccount (and per space), so it only works if nothing else in the subaccount uses it.
Using a central instance (proxy plan)
- Share the central instance with the target subaccount (SAP Credential Store guide, section Share, Unshare, and Authorize a Service Instance). In the BTP cockpit use the Service Sharing tab of the instance, or run
cf update-service <instance> -c '{"share":{"subaccountGuid":"<target>"}}'. Limit the share to the Spend Lens namespace with this authorization:{"namespace_permissions":{"asapio-spendlens":["create","delete","list","read","update"]}} - In the extension descriptor of the deployment (
<customer>.mtaext, copied fromcustomer.mtaext.template), setcredstorePlan: proxyand add the origin of the central instance to the resourceasapio-spendlens-credstore:parameters: credstorePlan: proxy resources: - name: asapio-spendlens-credstore parameters: config: origin: serviceGuid: <central-instance-guid> landscape: cf-eu10serviceGuidis the GUID of the central instance.landscapeis the landscape of that instance, for examplecf-eu10for AWS Frankfurt. - Deploy with the extension:
cf deploy <path-to-your-package>/asapio-spendlens_<version>.mtar -e <customer>.mtaext.
Advanced: key overrides
The MTA parameters slCredKey, mcpKey and gatewaySecret (64 hexadecimal characters each) override the values kept in the Credential Store. Normally leave them unset.
Upgrading an existing installation to 2.0.0
The deployment now also needs the Credential Store: provide the entitlement and, if applicable, the credstorePlan before you deploy the new package. Stored per-user S/4HANA passwords are encrypted with the credential key. If that key changes (for example because a new Credential Store is used), users have to enter their S/4HANA passwords again.
Download package
ASAPIO provides Spend Lens as the download asapio-spendlens_latest.zip (register for the download). It contains:
| File | Purpose |
|---|---|
asapio-spendlens_<version>.mtar | The application archive for SAP BTP, Cloud Foundry environment |
INSTALL.md | Installation guide |
customer.mtaext.template | Optional extension descriptor, only needed to change defaults |
LICENSE.txt | License notice (ASAPIO Free License Terms) |
THIRD-PARTY-LICENSES.md | Notices of the open-source and SAP components |
Deploy app package
Log in to Cloud Foundry, target the space for Spend Lens, and deploy the archive from the download package. No parameters need to be edited: every MTA parameter has a working default. Deploying the archive from the BTP cockpit works the same way.
Terminal
cf login -a https://api.cf.<region>.hana.ondemand.com --sso
cf target -o "<org>" -s "<space>"
cf deploy asapio-spendlens_<version>.mtar
The deploy creates the service instances listed above and creates or updates three CF applications (asapio-spendlens-approuter, asapio-spendlens-srv, asapio-spendlens-db-deployer). The database deployer runs first, then srv (which creates the Credential Store secrets on its first start), then the approuter. The first deployment also creates the PostgreSQL instance, so it takes longer than later updates.
App URL and routes
There is no fixed host by default. The approuter gets the route that Cloud Foundry generates for it, https://<org>-<space>-asapio-spendlens-approuter.<domain>, which is unique per org and space, so installations on a shared domain do not collide. The app is served at <route>/app/spendlens/, which is also where / leads. To find the URL after the deployment, run:
cf app asapio-spendlens-approuter
The XSUAA login redirect is derived from this route at deploy time and follows it automatically; there is nothing to configure.
A fixed host is optional: set the module parameter host of asapio-spendlens-approuter in an extension descriptor. The host must be free on the domain (on a shared domain it is global across all subaccounts); the login redirect follows it automatically.
modules:
- name: asapio-spendlens-approuter
parameters:
host: spendlens-companyx
The approuter has exactly one route. Do not map further routes (for example an alias next to
host): login fails on any route that is not listed in the XSUAA redirect URIs. A custom domain needs thedomainparameter as well, and its URL must then be added to theredirect-urisof the resourceasapio-spendlens-auth.
Optional: change defaults
An extension descriptor is only needed to change defaults. Copy customer.mtaext.template from the download package to <name>.mtaext, keep only the sections you need, and deploy with it:
cf deploy asapio-spendlens_<version>.mtar -e <name>.mtaext
Typical reasons, each explained in the comments of the template:
- a fixed host instead of the generated route (module parameter
host, see App URL and routes) - an existing PostgreSQL instance (
existingDbService, see Database) or another database plan (postgresPlan) - a Credential Store proxy to a central store (
credstorePlan: proxy, see SAP Credential Store) - cache tuning (
cacheLookbackMonths,dbCacheTtlHours, see Data caching)
Keep a filled-in extension descriptor in a secure place: it may contain secret overrides.
Updates
Deploy the new archive the same way, with the same extension descriptor if you used one. Data and settings are kept. An installation that was set up with an existing PostgreSQL instance must be updated with the extension descriptor that names it; otherwise the deployment creates a new, empty database.
Upgrading to 2.0.0:
- Provide the SAP Credential Store entitlement first (see SAP Credential Store).
- Installations on SAP HANA Cloud (1.4.x and older) cannot be upgraded in place. Deploy 2.0.0 as a new installation and enter the settings, spend limits, and per-user S/4HANA credentials again; the purchase order and invoice caches refill from S/4HANA.
- Unless the extension descriptor sets
host, the app moves to the generated route. Users and MCP clients must use the new URL (cf app asapio-spendlens-approuter). - Old bookmarks of the form
/app/spendlens/index.html#/<page>open the Total Spend page. The page addresses are now/app/spendlens/<page>; users should bookmark them again. - Role collections keep their names (SpendLens User, SpendLens Admin); no role re-assignment is needed.
First-run checklist
After deployment:
After assigning or changing a role collection in BTP Cockpit, users must log out and log back in for the new token (with updated scopes) to take effect. Use Log out in the profile menu of the app header.
Roles and access
Spend Lens uses SAP BTP XSUAA for all authentication. There are no local user accounts.
Role collections
| Role Collection | Scope | What it covers |
|---|---|---|
| SpendLens User | asapio.spendlens.user |
Total Spend, Purchase Orders, Invoices, Suppliers, Alerts (spend limits), Audit Log, CSV export, user-level settings (own S/4HANA sign-in, org-unit labels, deep links) |
| SpendLens Admin | asapio.spendlens.user + asapio.spendlens.admin |
All User permissions, plus: configure the S/4HANA destination and auth mode, test connectivity, currency settings, MCP access |
Connection settings (which S/4HANA system to connect to, which destination to use) are global and admin-only. A change by one admin takes effect for all users immediately.
Assigning a role in BTP Cockpit
- Open BTP Cockpit and navigate to your subaccount.
- Go to Security → Role Collections.
- Open SpendLens Admin (or SpendLens User).
- Click Edit, then Users → Add User.
- Enter the user's email address and select the identity provider the user actually logs in with (see below).
- Save. The role takes effect on the user's next login (the user must log out and back in).
Assign SpendLens Admin only to users responsible for system configuration. All other users should receive SpendLens User.
Which identity provider?
Role-collection assignments are scoped per identity provider. A role takes effect only when it is assigned under the same identity provider the user signs in with — assigning it under a different one is the most common cause of a "403 — lacking required roles" error even though the role looks assigned.
Which identity provider to choose depends on your subaccount's trust configuration:
- If your subaccount has no custom identity provider, users authenticate via the Default identity provider (SAP Cloud Identity / SAP ID service) — assign roles there.
- If your organisation uses its own SAP Cloud Identity Services (IAS) tenant (optionally federated to a corporate IdP such as Microsoft Entra ID or Okta), users authenticate through that tenant's business-user trust — assign roles there, not under "Default".
To see your subaccount's identity providers, open BTP Cockpit → Security → Trust Configuration (each entry shows its Purpose — pick the one for Business users, not Platform users). The same list is available from the SAP BTP CLI with btp list security/trust.
Troubleshooting "403 — lacking required roles". If a user gets this after the role is assigned: (1) confirm the assignment is under the business-user identity provider the user actually logs in with — not "Platform users" and not a different IdP; (2) have the user log out and log back in (a fresh, e.g. incognito, session) so a new token with the role is issued.
Connecting to S/4HANA
Spend Lens reads from three standard SAP OData APIs — API_PURCHASEORDER_2 (OData v4, purchase orders), API_SUPPLIERINVOICE_PROCESS_SRV (OData V2, supplier invoices), and API_BUSINESS_PARTNER (OData V2, supplier master data). No S/4HANA add-on or custom development is required. The APIs are available on SAP S/4HANA 2022+ (on-premise / private cloud) and S/4HANA Cloud Public Edition, and all three share the same BTP destination.
The connection is configured by an admin in Settings → Connection Settings: select the BTP destination, choose an auth mode, and click Test Connection. Follow the section below that matches your S/4HANA deployment.
S/4HANA On-Premise / Private Cloud
BTP destination
| Setting | Value |
|---|---|
| ProxyType | OnPremise |
| Cloud Connector | Required |
| Connectivity Service binding | Required |
| Supported authentication types | BasicAuthentication, PrincipalPropagation |
BasicAuthentication: a shared SAP technical user. All Spend Lens users access S/4HANA under the same SAP identity. Simple to set up; set Auth Mode to Technical user in Spend Lens.
PrincipalPropagation: the logged-in BTP user's identity is forwarded to S/4HANA via the Cloud Connector trust configuration. Requires a system trust between BTP and S/4HANA. When the selected destination uses Principal Propagation, Spend Lens shows the Auth Mode as Principal Propagation (read-only) and stores no credentials.
Per-user Basic Auth (auth mode in Spend Lens): only relevant for on-premise BasicAuthentication destinations where Principal Propagation is not configured. Each user signs in with their own SAP credentials. The password is stored encrypted on the server (with the credential key from the SAP Credential Store) and is never kept in the browser. Users can replace or remove their stored sign-in on the Settings → User Settings tab.
Required authorizations
The SAP identity used (technical or propagated user) needs read access to the three APIs. Field-value restrictions (e.g. limiting EKORG to specific purchasing organisations) are respected — Spend Lens shows only data the SAP user is authorized to read.
API_PURCHASEORDER_2
| Authorization Object | Required for |
|---|---|
M_BEST_BSA (document type) | Reading PO headers |
M_BEST_EKG (purchasing group) | Reading PO headers |
M_BEST_EKO (purchasing org) | Reading PO headers |
M_BEST_WRK (plant) | Reading PO items |
S_SERVICE with SRV_NAME = API_PURCHASEORDER_2_0001 | OData API access |
API_SUPPLIERINVOICE_PROCESS_SRV
| Authorization Object | Required for |
|---|---|
M_RECH_BUK (company code) | Reading supplier invoice headers |
M_RECH_WRK (plant) | Reading invoice line items |
S_SERVICE with SRV_NAME = API_SUPPLIERINVOICE_PROCESS_SRV | OData V2 API access |
API_BUSINESS_PARTNER (Supplier Profiles — optional)
Powers the supplier fact sheet (master data, addresses, contacts) on the Suppliers page. Optional: if unavailable, the rest of the Suppliers page still works — only the fact-sheet panel stays empty.
| Authorization Object | Required for |
|---|---|
S_SERVICE with SRV_NAME = API_BUSINESS_PARTNER_0001 | OData V2 API access |
B_BUPA_RLT (BP relationship) | Reading contact person relationships |
B_BUPA_GRP (BP grouping) | Reading business partner groupings |
S/4HANA Cloud Public Edition
BTP destination
| Setting | Value |
|---|---|
| ProxyType | Internet |
| Cloud Connector | Not required |
| Connectivity Service binding | Not required |
| Supported authentication types | OAuth2ClientCredentials, OAuth2SAMLBearerAssertion |
OAuth2ClientCredentials: a shared service account. All Spend Lens users access S/4HANA under the same service identity. Set Auth Mode to Technical user in Spend Lens.
OAuth2SAMLBearerAssertion: the BTP user's identity is asserted to S/4HANA via a SAML bearer token exchange. Requires a communication arrangement in S/4HANA that trusts your BTP subaccount as an identity provider. Set Auth Mode to Technical user in Spend Lens (the Cloud SDK performs the SAML assertion exchange automatically).
Basic Auth is not used with S/4HANA Cloud Public Edition.
Communication scenarios
Create a Communication Arrangement for each scenario below (Communication Management → Communication Arrangements). All three can be assigned to the same inbound communication user and the same communication system.
| API | Communication Scenario |
|---|---|
API_PURCHASEORDER_2 | SAP_COM_0102 — Procurement API Integration |
API_SUPPLIERINVOICE_PROCESS_SRV | SAP_COM_0057 — Supplier Invoice Integration |
API_BUSINESS_PARTNER (optional) | SAP_COM_0009 — Business Partner, Customer and Supplier Integration |
No separate BTP destination is needed per API — the existing purchase-order destination is reused for all three.
API_BUSINESS_PARTNER/SAP_COM_0009is optional (only the supplier fact sheet uses it).
Features
| Capability | Description |
|---|---|
| Total Spend Dashboard | Combined view of procurement spend: PO commitment from API_PURCHASEORDER_2 plus non-PO invoice spend from API_SUPPLIERINVOICE_PROCESS_SRV. Global scope toggle (Both / PO Spend / Non-PO Spend). Primary tiles: PO Spend, Open PO Value, Non-PO Spend (+ a combined Total Spend tile when scope = Both). 15+ secondary KPIs. All metrics are alertable; click the bell icon on any tile to set an upper or lower threshold. |
| Invoices | Total invoice spend, PO-backed vs non-PO ratio, payment-blocked invoices, credit memos, top vendors. Clicking an invoice opens a detail overlay with its header summary plus PO-reference and G/L line items fetched from S/4HANA. Data is cached locally and refreshed on demand. |
| Purchase Orders | Full PO list: All, Overdue, Pending Release, Unacknowledged, Blocked, Not Invoiced. CSV export of any filtered view. Spend-by-Dimension chart and detail table embedded at the top; clicking a bar or row drills the PO list below in place, no navigation. Clicking a PO opens a detail overlay with line items, account assignments, header and item long texts, and an Open in S/4HANA button (when deep links are configured). |
| Supplier Profiles | Ranked supplier list with spend trend, KPI summary, and recent purchase orders per supplier. A supplier fact sheet (from API_BUSINESS_PARTNER) shows master data, full contact details — all address phone numbers and email addresses plus each contact person's phone/email — and the responsible purchasing organisation(s) and group(s) used with that supplier. Clicking a PO opens the same line-item detail overlay as the Purchase Orders page. |
| Global Display Currency | Report all amounts in a single display currency, so every KPI, chart, and table shows one currency with no "Mixed" warning. See Currency conversion for setup and details. |
| Alerts (spend limits) | Threshold alerts on any KPI. Breach history with configurable retention and one-click clear. |
| CSV Export | Export the filtered purchase order list and the audit log as CSV. |
| User interface | Built with React and UI5 Web Components (new in 2.0.0). Available in English and German, with light, dark, and high-contrast themes, and usable on phones. |
| Deep Links | Clickable PO numbers to S/4HANA via WebGUI or Fiori Launchpad. Configure base URL and SAP client in User Settings. |
| Audit Log | Immutable record of every configuration change and connection test, with field-level diffs. Every SpendLens user can read it. |
All analytics are read-only. Spend Lens does not write any procurement data back to S/4HANA.
Currency conversion
Procurement documents often span several currencies. By default Spend Lens keeps each amount in its document currency and flags any mixed total; optionally you can enable Global Display Currency to report everything in one currency. Both behaviours are described below. Configure currency on the Settings → Currency tab (admin only).
Default: native currency with a mixed-currency safeguard
When Global Display Currency is off, each KPI tile shows the dominant currency and its share of the result set (e.g. "EUR 62%"). If the dominant currency covers less than 80% of the total, the tile shows "Mixed (top: EUR 62%)" to flag that the number bundles more than one currency and should not be read as a single-currency total. Table amounts are shown as plain numbers (e.g. 1.2M) with a separate CCY column for the document currency code — no currency symbol is embedded in the amount cell, so a USD figure can never be mislabelled with a € sign.
Global Display Currency
Enable Global Display Currency to report all amounts in a single currency, so the Dashboard, charts, Top Suppliers, Purchase Orders, and Invoices all show one currency with no "Mixed" warning.
Exchange rates from the ECB. Rates for the 29 ECB reference currencies (USD, GBP, CHF, JPY, SEK, DKK, NOK, PLN, CZK, HUF, RON, ISK, TRY, AUD, CAD, CNY, HKD, INR, MXN, ZAR, and more) are fetched from the ECB Data Portal, with EUR as the base.
ECB API & network egress. "Pull from ECB" makes an outbound HTTPS call from the Spend Lens backend to the European Central Bank's public Data API (SDMX-JSON) — no key or registration required:
https://data-api.ecb.europa.eu/service/data/EXR/D.<currencies>.EUR.SP00.A?lastNObservations=1&format=jsondata
The BTP environment (and any egress proxy/firewall) must allow outbound access to data-api.ecb.europa.eu. Currency conversion is optional — if you never enable Global Display Currency, no ECB call is ever made.
Setup is two steps:
- Click "Pull from ECB" to fetch live rates for the 29 ECB reference currencies.
- Turn on the toggle and choose the display currency. The display-currency dropdown only lists currencies that have a stored rate, so you can never select a currency the app cannot convert to.
Rates must exist for every document currency in your data; rows in a currency with no rate are excluded from converted totals and a "missing rates" banner appears on the Dashboard.
Custom currencies & manual rates. The Exchange Rates table's Add / Update row has a currency-code field — type any code (up to 5 characters) and its rate (1 EUR = X). Codes the ECB does not publish show a warning that "Pull from ECB" will not refresh them, so you maintain their rate manually. Edit any existing rate inline and click Save, or remove one with the ✕ button. "Pull from ECB" refreshes every ECB-covered currency already in the table and leaves manual ones untouched.
Applying a change
After enabling Global Currency or switching the display currency, a banner offers a Sync Now button — no need to leave Settings. Totals are correct immediately, including for data synced before the feature was switched on.
Reading the tables. With Global Currency on, tables add a Converted column in the display currency alongside the document-currency amount and its CCY code, so you always see both the original and the converted figure.
Data caching
Spend Lens does not query S/4HANA on every interaction. It reads the relevant procurement documents from the standard OData APIs, caches them, and serves the dashboard from that cache. This limits how often Spend Lens calls your S/4HANA system. All metrics are derived from the cached source documents, so they match what you would compute directly in S/4HANA. Spend Lens is read-only and never writes back.
Refresh and time-to-live
Cached data is refreshed automatically after a time-to-live (TTL) expires, and on demand whenever you press Refresh. Purchase Orders and Supplier Invoices share a single lookback window so combined views and the spend trend never mix mismatched time spans. Both the TTL and the lookback window are configurable per deployment:
| Setting | Default | Configuration |
|---|---|---|
| Cache time-to-live | 24 hours | Settings → Connection Settings → Data & Sync, or MTA parameter dbCacheTtlHours |
| Lookback window (Purchase Orders + Invoices) | 25 months | Settings → Connection Settings → Data & Sync, or MTA parameter cacheLookbackMonths |
The lookback window vs. your date filter. The cache holds documents inside the lookback window (e.g. the last 25 months). The date filter on the dashboard narrows what you see within the cached data — it is applied to the cache and makes no S/4HANA call. If you set the filter to reach earlier than the cache covers, the older documents are not loaded yet and the dashboard shows an information banner inviting you to Refresh, which re-pulls from S/4HANA back to your filter's start date. Setting a date within the window never shrinks the cache.
When Global Display Currency is enabled, amounts are converted to your chosen currency for every KPI, chart, and table — see Currency conversion.
Claude AI / MCP Access
Overview
Spend Lens implements the Model Context Protocol (MCP), allowing users to connect Claude AI (claude.ai) to their Spend Lens instance and query procurement data through natural language. Users authenticate with their own credentials and see data according to their existing Spend Lens permissions — no new role is required. All interactions are read-only; Claude cannot write or modify any data.
Default state: disabled. When you first deploy Spend Lens, MCP access is off and must be explicitly enabled by an admin in the Settings page.
Setup
- Admin enables MCP. In Spend Lens, go to Settings → Connection → AI / MCP Access and turn on "Enable MCP Access". This is a global feature flag; disabling it immediately disconnects all active Claude sessions.
- Find the MCP URL. It is the app URL with
/mcpappended — e.g.https://<org>-<space>-asapio-spendlens-approuter.<domain>/mcpfor the generated route. To find your own host runcf app asapio-spendlens-approuterand use its route. - User connects the MCP client. In Claude (Desktop or Web, on a plan that allows custom connectors), open Settings → Connectors → Add custom connector, enter the MCP URL, and confirm. Claude starts an OAuth 2.1 login flow with PKCE. Other MCP clients (e.g. Microsoft Copilot / Copilot Studio, VS Code) connect the same way — see Supported clients below.
- One-time login. Claude opens a login window; the user signs in with their SAP/IAS credentials (the same identity provider as the Spend Lens UI). Spend Lens runs its own OAuth authorization-code flow directly against IAS — it does not use the App Router login, so the flow works inside Claude's pop-up window.
- Authorization. After login, Spend Lens issues Claude an opaque access token and refresh token. These are proxies for the underlying XSUAA tokens — Claude never sees the SAP identity tokens directly. The connection stays valid for 30 days and renews S/4HANA access automatically in the background; after that the user re-authorizes once.
- Claude queries Spend Lens. Each request includes the access token; the MCP server decrypts the stored XSUAA token and calls the internal CAP OData services. The user's existing
asapio.spendlens.user/asapio.spendlens.adminscope is enforced — no special MCP role is needed.
What Claude can do
After connecting, Claude has these read-only tools. Each analytic answer also includes a deep link back into the relevant Spend Lens view.
| Tool | Answers |
|---|---|
get_spend_overview | Total spend and all headline KPIs (open PO value, overdue / blocked / pending-release, cash discount, active suppliers, …) |
get_top_suppliers | Top suppliers by net spend, with share and lead time |
get_spend_by_dimension | Spend grouped by plant, material group, company code, purchasing org/group, or supplier |
list_purchase_orders | Purchase orders for a period, optionally filtered by status (overdue / blocked / pending release / unacknowledged / not invoiced) |
get_spend_trend | Monthly spend trend (PO + invoice combined) |
get_invoice_overview | Supplier-invoice KPIs (total, PO-linked vs non-PO, payment-blocked, credit memos, vendors) |
list_invoices | Supplier invoices for a period (all / blocked / credit memos / non-PO) |
get_supplier_details | Master-data fact sheet for one supplier (address, contacts, purchasing orgs/groups) |
get_alerts | Status of the user's spend-limit alerts (threshold, current value, triggered or not) |
refresh_erp_data | Force a fresh sync of PO and/or invoice data from S/4HANA |
whoami | The connected user and their permissions |
Time range. Every analytic tool covers the last 90 days by default and returns a period block stating exactly which range the numbers cover, so an answer is never ambiguous. Other ranges are available via a predefined range parameter (mtd, lastMonth, qtd, lastQuarter, ytd, lastYear, allTime) or an explicit dateFrom/dateTo window — matching the SpendLens dashboard's date presets.
Supported clients & connection
You configure only the one MCP URL (/mcp); all OAuth endpoints are discovered automatically from the well-known metadata (/.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server). The server identifies clients in two ways and picks whichever the client uses:
- Client ID Metadata Document (CIMD) — used by Claude, whose
client_idis a URL (claude.ai). The origin is allowlisted. - Dynamic Client Registration (RFC 7591) — used by clients such as Microsoft Copilot / Copilot Studio and VS Code that register at the
registration_endpoint(/oauth/register) and receive a generatedclient_id. Public clients only (PKCE, no secret).
Registration is bounded: a redirect URI is accepted only if its host is allowlisted (claude.ai, copilot.microsoft.com, copilotstudio.microsoft.com, teams.microsoft.com, vscode.dev, insiders.vscode.dev, global.consent.azure-apim.net for Copilot Studio custom connectors) or it is an http(s)://127.0.0.1/localhost loopback (desktop / VS Code). Any other host is rejected. If a new MCP client uses a different callback host, contact ASAPIO.
Security
- OAuth 2.1 with PKCE S256. Every login flow uses a PKCE code challenge to protect against authorization code interception.
- Token encryption. The XSUAA access and refresh tokens are stored in the database encrypted with AES-256-GCM. The encryption key is derived via HKDF from the MCP token key kept in the SAP Credential Store.
- Refresh token rotation. When Claude refreshes its access token, the old refresh token is invalidated and a new one is issued.
- Kill-switch. An admin can disable MCP access at any time in Settings → Connection → AI / MCP Access. Disabling the feature immediately returns HTTP 401 to all active Claude sessions and clears all stored sessions from the database.
- Audit log. Every MCP enable/disable action is recorded in the immutable Audit Log with the admin's user ID and timestamp.
- No writes. The MCP tools only call read-only CAP OData functions. Claude cannot create, update, or delete any Spend Lens data.
- Redirect-URI allowlist. The authorize and registration endpoints only accept the CIMD
claude.aicallback or redirect URIs whose host is on the allowlist / a loopback address, and a dynamically-registered client may only use a redirect URI it registered — preventing open-redirect / SSRF attacks.
Architecture note: Spend Lens acts as an OAuth Authorization Server to claude.ai (proxy mode) while being an OAuth Client to XSUAA/IAS (its own authorization-code flow). The user's real identity is always preserved; Claude sees the same data the user would see in the Spend Lens UI.
License
ASAPIO Spend Lens is provided under the ASAPIO Free License Terms, published at https://asapio.com/terms. They apply to every installation and use of Spend Lens. Spend Lens contains open-source and SAP components under their own licenses; the notices are listed in THIRD-PARTY-LICENSES.md in the download package and in the in-app Help.
Trademarks
SAP, S/4HANA, SAP Fiori, SAP BTP, and other SAP products referenced here are trademarks or registered trademarks of SAP SE (or an SAP affiliate company) in Germany and other countries. Claude and Anthropic are trademarks of Anthropic, PBC. The Model Context Protocol (MCP) is an open protocol introduced by Anthropic. Microsoft and Microsoft Copilot Studio are trademarks of the Microsoft group of companies. All other product and company names are the trademarks of their respective owners.
ASAPIO Spend Lens is an independent product of ASAPIO GmbH and is not affiliated with, endorsed by, or sponsored by SAP SE, Anthropic, PBC, or Microsoft. Trademarks are used only for identification and descriptive purposes.