Skip to main content
mcpjam xaa run drives a complete Cross-App Access flow — the Identity Assertion Authorization Grant (ID-JAG, an active IETF Internet-Draft) — against your authorization server and MCP server. MCPJam plays the enterprise identity provider (it mints and signs the ID-JAG) and the client/agent (it redeems the ID-JAG and calls your MCP server with the resulting access token). Your authorization server and MCP server are the system under test.

The three parties

Cross-App Access separates trust into three relationships that are easy to conflate. The CLI covers two of them and simulates the third:
RelationshipWho configures itIn this test
Client ↔ IdPEnterprise SSO registrationSimulated — the CLI is the IdP, so this leg always succeeds
RAS ↔ IdPYour authorization server trusts the IdP’s issuer + JWKSYou set this up once (see below)
Client ↔ RASOAuth client registration at your authorization serverExercised per run via --registration

Before you run: make the issuer reachable

The CLI signs ID-JAGs with a local key pair (~/.mcpjam/xaa-idp-private.pem; override the directory with XAA_IDP_KEY_DIR). Your authorization server must be able to fetch the matching public key, so --issuer-base-url must be an origin that publishes that same key — not your real IdP’s URL. The local MCPJam inspector serves exactly this: it publishes the issuer metadata and JWKS from the same key directory at /api/mcp/xaa/.well-known/openid-configuration and /api/mcp/xaa/.well-known/jwks.json, no authentication required.
  • Local authorization server: pass --issuer-base-url http://localhost:6274/api/mcp.
  • Cloud authorization server: it cannot reach your localhost. Expose the inspector origin through a tunnel and pass the public origin instead.
Then register the issuer in your authorization server: trust <issuer-base-url>/xaa as an ID-JAG issuer and point it at the JWKS URL above. The first flow step, verify_issuer_publication, fails fast if the issuer origin is unreachable or publishes a different key — nothing is sent to your servers until it passes.

What a run checks

Each run walks the grant chain and reports every step:
  1. verify_issuer_publication — the configured issuer publishes the CLI’s local signing key
  2. discover_resource_metadata — protected-resource metadata (RFC 9728) names the authorization server protecting --url
  3. discover_authz_metadata — authorization-server metadata (RFC 8414) provides the token endpoint and capability advertisements
  4. mint_id_jag — the mock IdP exchanges the simulated user’s identity assertion for an ID-JAG (typ: oauth-id-jag+jwt, audience = your authorization server, resource = your MCP server)
  5. redeem_id_jag — the ID-JAG is presented at your token endpoint via the JWT bearer grant (RFC 7523); your server validates it and issues its own access token
  6. authenticated_mcp_request — an MCP initialize with the issued token, advertising the Enterprise-Managed Authorization extension
The result also records capability evidence separately from operational outcomes: whether your authorization server advertises the ID-JAG grant profile and the JWT bearer grant, which token-endpoint auth method was selected, and whether your MCP server advertises the enterprise-managed authorization extension back. Missing advertisements are reported as findings but never fail a flow that operationally succeeds — redemption is the verdict, advertisement is evidence. The decoded ID-JAG claims and a local signature-verification verdict are included in the result, so you can inspect exactly what your authorization server received. Raw tokens, assertions, and secrets are always redacted from the output — including when a server reflects them back inside error bodies.

Registration strategies

--registration selects how the CLI identifies itself to your authorization server, mirroring the client-registration models MCP clients use:
StrategyCredentials neededPosture notes
preregistered (default)--client-id (+ optional --client-secret)Matches the draft’s recommended deployment
dcrnoneA diagnostic: the CLI performs open RFC 7591 registration and supplies the IdP→RAS client mapping itself. Each run may leave a registration behind. RFC 7591 conformance findings (e.g. missing Cache-Control: no-store) are reported as warnings
cimdnonePublic client by default — the run completes but is flagged: the draft recommends confidential clients
cimd + --client-auth private-key-jwtnoneConfidential CIMD: the CLI generates a local EC P-256 key, publishes it through the hosted reflector, and signs a client_assertion. The private key never leaves your machine
For confidential CIMD, the key is the identity: the reflector URL derived from the public key becomes the client_id. Deleting ~/.mcpjam/xaa-client-private.pem (or changing XAA_CLIENT_PRIVATE_KEY) mints a new identity, and any allowlisting on your authorization server must be updated.

Identity assertion formats

--assertion-format selects the identity rail the simulated enterprise uses:
  • oidc (default) — the mock IdP mints an OIDC ID token as the token-exchange subject token.
  • saml — the mock IdP mints a SAML 2.0 assertion as the subject token, and the ID-JAG carries a saml-nameid sub_id claim so a SAML-federated authorization server can resolve the user.
The ID-JAG itself is always a JWT; the format flag changes the SSO leg and the subject identifier, not the grant. Either format composes with any registration strategy. Use --sub (and optionally --email) to control the simulated user, and --scopes for the permissions requested in both the ID-JAG and the token request.

Scenarios

First run against a local authorization server

Confidential client without pre-registration

SAML-federated enterprise

CI

The JSON result goes to stdout; progress and advisory notes go to stderr. The exit code is 0 when the flow completes and 1 otherwise, so a run can gate a pipeline directly. Pass --quiet to suppress the advisory notes.

Skipping discovery

  • --authz-server-issuer pins the authorization server and skips protected-resource discovery (useful while your MCP server’s RFC 9728 metadata is still in progress).
  • --token-endpoint pins the token endpoint and skips authorization-server discovery entirely. Not valid with dcr or cimd, which need the metadata document for the registration endpoint / CIMD advertisement.
  • --https-only rejects non-HTTPS and private targets; by default the CLI allows http://localhost for local development.

What this is not

These are targeted debugging checks for the current ID-JAG draft, not a conformance suite. The negative-test scorecard — sending deliberately broken ID-JAGs (bad signature, wrong audience, expired, and six more) and verifying your authorization server rejects each — lives in the inspector’s XAA Debugger, which also visualizes the flow and inspects the ID-JAG interactively before it is sent.