PackagePackagetypeA library you install and call yourself.See every one →What this type is →independently maintainedindependently maintainedoriginPublished by one person or a small company outside SAP. Says nothing about quality; the readings say that.See every one →

@marianfoo/sap-mcp-auth

A shared browser-login and session module for SAP MCP servers: it drives a Playwright browser through SAP Identity Authentication, caches the session cookies and returns a cookie header an HTTP client can send.

Three MCP servers in the same monorepo read official SAP sources from behind an SAP login: sap-api-hub-mcp, sap-roadmap-mcp and sap-note-search-mcp. This is the one place that login lives. It drives a Playwright browser through SAP Identity Authentication at accounts.sap.com by username and password, by an SAP Passport PFX certificate, or interactively when a multi-factor code is needed, and returns an AuthSession carrying a cookieHeader, the scoped cookies, the expiry and the method used. What differs per service, which page to open, how to scope the cookies and how to check that a session still works, arrives in a ServiceProfile; concurrent callers share one login attempt, cookies are cached until they near expiry, and a shared storage-state file lets one SAP login serve all three servers. It stops at the session: nothing in it calls an SAP API or reads a page, and the maintainer states that the token cache and the storage-state file hold live SAP session cookies and are to be treated as secrets.

Facts

Latestv0.1.3ReleasedLast pushLicenceApache-2.0

Where it sits

Lives in
Provides
AuthenticationBTPAuthenticationcapabilityEstablishing who is calling: validating credentials or tokens, resolving the user, and making that identity available to the application. [Authorization](capability:authorization) decides what that identity may do; [identity provisioning](capability:identity-provisioning) manages its lifecycle across systems.
Requires
PlaywrightPlaywrightoutside the atlasThe browser it drives through the SAP login page, installed by the caller rather than bundled, so the project decides which browsers are downloaded.

Who is behind it

Marian ZeisMarian ZeisPersonMaintains this
In the atlas: maintains 35, contributes to 86, wrote 25
@marianfoo
maintaineradam0thmanPersonContributes to this
In the atlas: maintains 1, contributes to 3
@adam0thman
David SlugaPersonContributes to this
In the atlas: contributes to 4
@army113
2 contributors

Before choosing this

Conditions

PracticalFunctional boundary

The maintainer states it is unofficial, not endorsed by SAP, and that it automates authenticated SAP web endpoints and browser session cookies in ways SAP's terms of service or an organisation's own policies may restrict. Password login is confined to accounts.sap.com and the standard SAP Cloud Identity Services tenant domains: a custom IAS domain, or a login that conditional authentication delegates to a corporate identity provider, fails closed before the password is filled and has to be completed through an interactive login instead.

What it declares

Every artifact

Type
Package
Origin
Independently maintained
Runtime
Node.js

As a package

Where it runs
In your own program
Distributed through
npm

Connections3

@marianfoo/sap-mcp-auth connections@marianfoo/sap-mcp-authPROVIDES→ provides1provides stated Signs a program in to an SAP service as the person running it: it completes the SAP Identity Authentication login in a browser, by password, by SAP Passport certificate or interactively where a multi-factor code is required, and keeps the resulting session until it expires so the caller can send it with each request. @marianfoo/sap-mcp-auth — README: https://raw.githubusercontent.com/marianfoo/sap-mcp-servers/main/packages/auth/README.md @marianfoo/sap-mcp-auth — README: https://raw.githubusercontent.com/marianfoo/sap-mcp-servers/main/packages/auth/README.md sap-mcp-servers — README, packages table: https://raw.githubusercontent.com/marianfoo/sap-mcp-servers/main/README.mdAuthenticationNEEDS→ connects to1connects to stated The login itself: the browser it drives opens SAP Identity Authentication, fills the credentials or presents the SAP Passport certificate there, and the cookies that login leaves are the session it hands back to the caller. @marianfoo/sap-mcp-auth — README, Customer IAS and corporate identity providers: https://raw.githubusercontent.com/marianfoo/sap-mcp-servers/main/packages/auth/README.md @marianfoo/sap-mcp-auth — README, Customer IAS and corporate identity providers: https://raw.githubusercontent.com/marianfoo/sap-mcp-servers/main/packages/auth/README.mdCloud Identity Services→ needs1needs stated The browser it drives through the SAP login page, installed by the caller rather than bundled, so the project decides which browsers are downloaded. @marianfoo/sap-mcp-auth — README, Install: https://raw.githubusercontent.com/marianfoo/sap-mcp-servers/main/packages/auth/README.md @marianfoo/sap-mcp-auth — README, Install: https://raw.githubusercontent.com/marianfoo/sap-mcp-servers/main/packages/auth/README.mdPlaywright

Install

npm add @marianfoo/sap-mcp-auth

Derived from the package name. No recipe recorded; the README has the configuration.

Where it sits in your app

Download
Your program (Node.js)Your SAP BTP subaccount@marianfoo/sap-mcp-auth — README, Customer IAS and corporate identity providers, checked 2026-10-19: “Direct password login supports the standard SAP Cloud Identity Services tenant domains”HTTP, outbounddocumentedrequiresPlaywright, SoftwarePlaywrightSoftware@marianfoo/sap-mcp-auth, module@marianfoo/sap-mcp-a…Cloud Identity Services, service instanceCloud IdentityServices
SAPnot SAP's, or the project's ownauthenticationstated in the documentdocumented only

README

quoted from marianfoo/sap-mcp-servers under Apache-2.0, read
marianfoo/sap-mcp-servers/packages/auth/README.mdOn GitHub

@marianfoo/sap-mcp-auth

Part of the sap-mcp-servers monorepo (npm workspaces) — published to npm independently as @marianfoo/sap-mcp-auth with build provenance.

Shared SAP IAS (accounts.sap.com) browser-login and session module for SAP MCP servers.

It drives a Playwright browser to complete SAP login — username/password, SAP Passport (PFX) certificate, or interactive/manual — captures and caches the resulting session cookies, and returns a structured AuthSession. Service-specific differences (which app URL to open, how to scope cookies, how to validate a session) are supplied through a small ServiceProfile, so the login mechanics live in one place.

Used by its sibling servers in the monorepo: sap-api-hub-mcp, sap-roadmap-mcp, and sap-note-search-mcp. Each supplies a service-specific ServiceProfile to this module's SapWebAuthenticator.

Unofficial. This package is not endorsed by SAP. It automates authenticated SAP web endpoints and browser session cookies in ways that may be restricted by SAP terms of service or your organization's policies. Use at your own risk and only where you are permitted to.

Install

playwright is a peer dependency — install it in your project (the SAP MCP servers already do):

npm install @marianfoo/sap-mcp-auth playwright
npx playwright install chromium

Requires Node.js >= 18 and is published as ESM only.

Quick start

import { SapWebAuthenticator, type AuthConfig, type ServiceProfile } from '@marianfoo/sap-mcp-auth';

const config: AuthConfig = {
  authMethod: 'auto',                 // 'auto' | 'password' | 'certificate' | 'interactive'
  sapUsername: process.env.SAP_USERNAME,
  sapPassword: process.env.SAP_PASSWORD,
  sapLoginUrl: 'https://me.sap.com/home',
  mfaTimeout: 180_000,
  maxSessionAgeH: 12,
  headful: false,                     // set true when MFA / manual login is required
  tokenCacheFile: '/abs/path/token-cache.json',
  ssoStorageStateFile: '/abs/path/.sap-mcp/sso-storage-state.json'
};

const profile: ServiceProfile = {
  serviceName: 'SAP Road Map',
  appUrl: 'https://roadmaps.sap.com/board',                 // optional page that mints app cookies
  cookieScope: { type: 'url', url: 'https://roadmaps.sap.com' },
  expectedHost: 'roadmaps.sap.com',
  // optional: confirm the cookies actually work before trusting them (cache reuse AND fresh login)
  validateSession: async cookieHeader => {
    const res = await fetch('https://roadmaps.sap.com/services/deliverable-search/periods?range=CURRENT-LAST', {
      headers: { cookie: cookieHeader, accept: 'application/json' }
    });
    return res.ok && (res.headers.get('content-type') || '').includes('json');
  }
};

const auth = new SapWebAuthenticator(config, profile);

const session = await auth.ensureSession();
const res = await fetch('https://roadmaps.sap.com/services/deliverable-search/search?q=workflow', {
  headers: { cookie: session.cookieHeader }
});
Retry-on-expiry pattern

Wrap calls so an expired session re-authenticates once. Have your API layer throw an error whose message contains SESSION_EXPIRED / 401 / Unauthorized when the server returns a login page instead of data:

async function withAuthRetry<T>(fn: (cookieHeader: string) => Promise<T>): Promise<T> {
  const { cookieHeader } = await auth.ensureSession();
  try {
    return await fn(cookieHeader);
  } catch (err) {
    if (/SESSION_EXPIRED|401|Unauthorized/.test(String((err as Error)?.message))) {
      auth.invalidateAuth();
      const { cookieHeader: fresh } = await auth.ensureSession();
      return fn(fresh);
    }
    throw err;
  }
}

How it works

  • Single-flight — concurrent ensureSession() callers share one login attempt.
  • Cookie cache — the session is cached to tokenCacheFile (JSON) and reused until it nears expiry (maxSessionAgeH, 5-minute buffer).
  • Shared SSO — after login the Playwright storage state is written to ssoStorageStateFile; other SAP MCP servers seed their browser context from it, so a single SAP login is reused across services. With sharedSsoTokenFastPath: true a valid storage-state file is reused without launching a browser.
  • validateSession gate — when provided, it runs on both cached reuse and fresh login; a rejected session is evicted and re-minted once.
  • Cookie scoping — cookieScope decides which cookies form the header: { type: 'url', url } (origin-scoped), { type: 'domain', includes, fallbackToAll? }, or { type: 'all' }.
  • Credential-origin guard — password login fills credentials only on SAP's public identity origin or the configured standard customer-IAS tenant, and refuses to forward the password when federation changes the origin.

API

new SapWebAuthenticator(config: AuthConfig, profile: ServiceProfile)
MethodDescription
ensureSession(): Promise<AuthSession>Return a valid session, logging in if needed.
invalidateAuth(): voidDrop the in-memory + on-disk cache; next call re-authenticates.
loginOnly(): Promise<AuthSession>Force a fresh login (useful for a HEADFUL=true "mint SSO state" script).
destroy(): Promise<void>Reset state and close any browser.
AuthSession
interface AuthSession {
  cookieHeader: string;       // "name=value; name2=value2" for your API requests
  cookies: Cookie[];          // Playwright cookies, scoped per profile
  expiresAt: number;          // epoch ms
  storageStateFile?: string;  // path to the shared SSO storage state, if configured
  authMethod: 'password' | 'certificate' | 'interactive';
}
ServiceProfile
FieldRequiredDescription
serviceNameyesUsed in log messages.
appUrlnoApp page opened after SAP login to mint service-scoped cookies. Omit for me.sap.com-only flows.
cookieScopeyes{type:'url',url} | {type:'domain',includes,fallbackToAll?} | {type:'all'}.
expectedHostnoSubstring the post-login URL must contain before the MFA/redirect wait resolves.
validateSessionno(cookieHeader) => Promise<boolean>; gates cached reuse and fresh login.
authCompletePredicatenoOverride of the "left the auth pages" check during certificate auth.
userAgentnoCustom browser user agent.
AuthConfig

authMethod, sapUsername, sapPassword, pfxPath, pfxPassphrase, sapLoginUrl, mfaTimeout (ms), maxSessionAgeH, headful, tokenCacheFile, ssoStorageStateFile, browserType ('chromium'|'firefox'|'webkit'), launchRetries (default 3), sharedSsoTokenFastPath (default false), logger.

loadAuthConfigFromEnv(options)

Builds an AuthConfig from environment variables (reads both MAX_JWT_AGE_H and MAX_COOKIE_AGE_H for compatibility):

import { loadAuthConfigFromEnv } from '@marianfoo/sap-mcp-auth';

const config = loadAuthConfigFromEnv({
  defaultTokenCacheFile: '/abs/path/token-cache.json',
  tokenCacheEnvVars: ['MY_TOKEN_CACHE_FILE', 'TOKEN_CACHE_FILE'],
  sharedSsoTokenFastPath: false,
  logger: myLogger
});
Env varMeaning
AUTH_METHODauto (default) | password | certificate | interactive
SAP_USERNAME, SAP_PASSWORDUsername/password auth
PFX_PATH, PFX_PASSPHRASESAP Passport / client-certificate auth
SAP_LOGIN_URLLogin start page (default https://me.sap.com/home)
HEADFULtrue shows the browser (needed for MFA / interactive)
MFA_TIMEOUTms to wait for MFA / redirect (default 180000)
MAX_JWT_AGE_H / MAX_COOKIE_AGE_HCache lifetime in hours (default 12)
SAP_SSO_STORAGE_STATEPath to the shared SSO storage-state file
PLAYWRIGHT_BROWSER_TYPEchromium (default) | firefox | webkit

When loading configuration from a .env file, quote any value containing #; dotenv otherwise treats # and everything after it as a comment. For example, use SAP_PASSWORD="My#Pass". The same applies to PFX_PASSPHRASE.

Customer IAS and corporate identity providers

Direct password login supports the standard SAP Cloud Identity Services tenant domains *.accounts.ondemand.com, *.accounts.cloud.sap, and *.accounts.sapcloud.cn. Set SAP_LOGIN_URL to the intended tenant's HTTPS URL; only that exact tenant origin and https://accounts.sap.com are allowed to receive credentials. Custom IAS domains require interactive login. The authenticator waits for the JavaScript redirect used by an unauthenticated tenant /admin entry page before detecting the credential form.

If conditional authentication delegates the login to a corporate identity provider, the password flow fails closed before filling SAP_PASSWORD on the new origin. Corporate federation can require different credentials, MFA, passkeys, or organization-specific policies and must be completed through a separate interactive login flow. The authenticator never assumes that SAP_PASSWORD is valid for the delegated identity provider.

Also exported

isOnAuthPage, isAuthUrl, selectCookies, serializeCookies, defaultLogger, and the error classes AuthenticationError, CertificateLoadError, AuthenticationTimeoutError, BrowserNotFoundError. The Logger interface lets you inject your own logger ({ warn, error, info, debug }); a stderr defaultLogger is used otherwise.

Security

The tokenCacheFile and the SSO storageStateFile contain live SAP session cookies. Treat them as secrets: store them outside your repo (e.g. ~/.sap-mcp/), never commit them, and add them to .gitignore. Credentials and passphrases are never written to these files, but the cookies they hold can be used to act as you on SAP services until they expire.

Finding and recovering cached sessions

For MCP clients, set the shared-state path and each service's token-cache path to explicit absolute paths outside node_modules. The resolved paths are logged at startup, without cookie contents.

StateOverrideDefault when unset
Shared SSOSAP_SSO_STORAGE_STATE~/.sap-mcp/sso-storage-state.json in the user's home
API HubAPI_HUB_TOKEN_CACHE_FILE (then TOKEN_CACHE_FILE)api-hub-token-cache.json in the process working directory
Road MapROADMAP_TOKEN_CACHE_FILE (then TOKEN_CACHE_FILE)roadmap-token-cache.json in the process working directory
NotesSAP_NOTES_TOKEN_CACHE_FILE (then TOKEN_CACHE_FILE)token-cache.json in the installed Notes package directory

Create the parent directory, not an empty state file. Malformed state is ignored during login; it is replaced only after a successful, service-validated login. Rejected service caches trigger fresh authentication. A temporary validation outage is reported and preserves the cached session.

If login needs MFA, run once with HEADFUL=true and complete the browser login. Notes honors this on Windows and when launched over stdio. Explicit DOCKER_ENV=true or CI=true still forces its browser to run headless. Use the same absolute SSO path when returning to the MCP client.

Tests

Run npm test -w @marianfoo/sap-mcp-auth from the repository root for unit tests. For browser regressions, install Chromium with npx playwright install chromium, then run npm run test:browser -w @marianfoo/sap-mcp-auth. These tests use synthetic credentials and locally served forms to verify allowed origins, delegated login rejection, and the tenant admin redirect.

License

Apache-2.0

Apache-2.0, read

History

Latest

v0.1.3

Features 1, Fixes 4

Notes
Features
  • notes: add fetch_attachment tool to download SAP Note attachments (#48) (b7f5655)
Bug Fixes
  • auth: recover malformed SSO state and validate Notes sessions (#87) (565145c)
  • deps: refresh SDK and vulnerable dependency resolutions (#83) (e20284b)
  • enforce IAS login origin boundaries (#49) (cee93e2)
  • shared SSO state path on Windows, real notes version, keep SSO state on session expiry (#81) (b9ffee1)
  1. v0.1.2

    Fixes 1

    Notes
    Bug Fixes
    • stabilize API Hub authentication (#13) (b584fba)
  2. v0.1.1

    Docs 1

    Notes
    Documentation
    • auth: note npm build provenance (fc55f39)
392downloads per week, npm
Weekly downloads for @marianfoo/sap-mcp-auth26 complete calendar weeks from 2026-04-20 to 2026-10-18; the latest total is 392.20 Apr – 26 Apr: 027 Apr – 3 May: 04 May – 10 May: 011 May – 17 May: 018 May – 24 May: 025 May – 31 May: 3431 Jun – 7 Jun: 2698 Jun – 14 Jun: 5015 Jun – 21 Jun: 8022 Jun – 28 Jun: 6529 Jun – 5 Jul: 846 Jul – 12 Jul: 4713 Jul – 19 Jul: 4520 Jul – 26 Jul: 6027 Jul – 2 Aug: 1233 Aug – 9 Aug: 8710 Aug – 16 Aug: 6017 Aug – 23 Aug: 4324 Aug – 30 Aug: 8731 Aug – 6 Sept: 487 Sept – 13 Sept: 11314 Sept – 20 Sept: 11621 Sept – 27 Sept: 20128 Sept – 4 Oct: 2645 Oct – 11 Oct: 22212 Oct – 18 Oct: 392
Authentication
  1. @arc-mcp/xsuaa-authXSUAA authentication stack for an MCP server on SAP BTP
  2. SAP Authorization and Trust Management serviceOAuth server issuing JWTs and holding scopes for BTP apps
  3. Cloud Identity ServicesIdentity Authentication and Identity Provisioning as one tenant
  4. SAP Customer Identity and Access Management for B2CRegistration, login and consent for customer-facing sites
  5. OAuth 2.0 on SAP BTPOAuth 2.0 grant flows for applications and APIs in Neo regions
  6. abap_cloud_platformTypeScript library reaching ABAP service instances on Cloud Foundry
  7. @sap/approuterSAP's Node.js application router in front of business applications
  8. Cloud ConnectorSAP's on-premises agent linking SAP BTP to customer-network systems
  9. @saptools/cf-xsuaaOAuth2 token fetcher for a Cloud Foundry app's XSUAA binding

Details

Sources4
GitHub organisations and accountsdiscovered here, marianfoochecked
npm registry, @marianfoo/sap-mcp-authversion, releases, installschecked
github.com/git+https://github.com/marianfoo/sap-mcp-servers.gittree, pushes, contributors, CIchecked
packages/auth/README.mdquoted, and what the entry declareschecked

Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.

Compatibility and provenance
runtimesnode
latestv0.1.3
first release
releases and cadence4, ~4d median
discovered viaGitHub organisations and accounts · marianfoo
first seen in the atlas
ecosystem and domainbtp, security-and-compliance
Contributors2

From the repository’s contributor list, .

History in the atlas3
  1. the module as its README states it, where it runs and how it is installed, and the login edge to the identity service the README names
  2. Entered with the three servers of the same monorepo that name it. It publishes on its own and answers a question of its own — how a tool outside SAP gets an authenticated session against an SAP portal — so it is an entry rather than an implementation detail of the three.
  3. First seen.
For your agent
Ref
artifact:marianfoo-sap-mcp-auth
JSON
/artifacts/marianfoo-sap-mcp-auth.json
MCP
Connecting an agent