Skip to content

Instantly share code, notes, and snippets.

@plavjanik
Created June 18, 2026 06:49
Show Gist options
  • Select an option

  • Save plavjanik/b3d505203623a0b48079ef30826dab62 to your computer and use it in GitHub Desktop.

Select an option

Save plavjanik/b3d505203623a0b48079ef30826dab62 to your computer and use it in GitHub Desktop.

Zowe CLI Profiles across Explorer, the MCP CLI bridge, and Endevor

Prompt used to create this document:

What are Zowe CLI profiles? How they are used in Zowe Explorer? How they are used in zowe mcp cli bridge? How they are used in Zowe CLi endevor plugin? What makes sense for the Zowe MCP to do for local and remote deployments. Do not make any changes

This document explains what Zowe CLI profiles are, how they are used by Zowe Explorer, the Zowe MCP CLI bridge, and the Zowe CLI Endevor plugin, and what makes sense for the Zowe MCP server to do for local vs. remote deployments. Source links are provided for sections 1, 3, and 4.

Repository links are pinned to commit e0d19e4 so line numbers stay stable. Some docs.zowe.org slugs shift between releases; the /stable/ landing pages are the durable entry points if a deep link 404s.


1. What are Zowe CLI profiles?

A profile is a named, reusable bundle of connection details and credentials for a z/OS service, so you don't repeat --host/--port/--user/--password on every command.

Two generations exist:

  • V1 "classic" profiles (deprecated): one YAML file per profile under ~/.zowe/profiles/<type>/<name>.yaml. Each profile has a type (zosmf, tso, ssh, db2, endevor, …).
  • V2 "team config" (current): a single zowe.config.json file holding all profiles, defaults, and a layered/nested structure. Secrets (passwords, tokens) are not stored in the JSON — they're held in the OS secure credential store (keytar/keyring) and referenced via autoStore.

Key concepts that matter for this discussion:

  • Profile types — zosmf (z/OSMF REST), ssh, tso, zftp, and plugin types like db2, endevor, cics. Each type has its own schema of fields.
  • Base profile — a shared parent holding common values (host, rejectUnauthorized) and, importantly, tokenType/tokenValue for API Mediation Layer (API ML) SSO. Service profiles inherit from it.
  • Defaults — defaults: { zosmf: "lpar1", ssh: "lpar1-ssh", base: "my-apiml" } picks which named profile is used when none is specified.
  • Config layering — global (~/.zowe/zowe.config.json), project-local (<workspace>/zowe.config.json), and user variants (*.user.json). Project-local overrides global. This is how a repo can ship its own connection profile.
  • Resolution API — @zowe/imperative's ProfileInfo class reads all layers from disk, merges arguments, and resolves secrets. mergeArgsForProfile() returns the final host/user/etc. for a profile. The CLI also exposes zowe config list --rfj.

Two connectivity models flow through profiles:

  • Direct-to-LPAR: host:port + basic auth (user/password) straight to z/OSMF.
  • Through API ML: host:port of the gateway + a token (JWT/LTPA) in the base profile, enabling SSO across services and MFA/PassTicket scenarios.

Sources


2. How Zowe Explorer uses profiles

Zowe Explorer (the VS Code extension) is the canonical team-config consumer:

  • On activation it instantiates ProfileInfo('zowe') and readProfilesFromDisk() across global + workspace layers.
  • The tree views (Data Sets, USS, Jobs) are organized by profile — each top-level node is a zosmf (or compatible) profile. Expanding a profile node triggers a connection using that profile's merged args + secure-store credentials.
  • Default profile seeds the initial tree; users add more profiles via the + picker, which lists getAllProfiles('zosmf').
  • Credentials/tokens are pulled from the secure credential store; on 401 it prompts and can refresh API ML tokens, then writes back via autoStore.
  • Other extensions (Explorer for IBM CICS, Db2, Explorer for Endevor) register additional profile types through Zowe Explorer's extender API, reusing the same team-config file and secure store.

The mental model: profile = a configured system you click on. The extension never asks you to type connection details inline; it reads them from team config.


3. How the Zowe MCP CLI bridge uses profiles

This is where this repo deliberately diverges from Explorer. The CLI bridge (packages/zowe-mcp-server/src/tools/cli-bridge/) dynamically turns Zowe CLI plugin commands into MCP tools driven by YAML metadata. Its profile model is its own, not Zowe team config:

  • Named profiles live in a separate connection JSON, not zowe.config.json. The shape is CliPluginProfilesFile = Record<typeKey, { profiles: CliNamedProfile[]; default?: string }>. Profile types and their fields are declared per-plugin in YAML (e.g. db2-tools.yaml defines connection with host/port/user/database).
  • Invocation shells out to the zowe binary via spawnSync, building --<cliOption> <value> args from the selected profile (buildProfileArgs) and passing them on the command line — rather than relying on --zosmf-profile <name> resolution inside the CLI.
  • Profile selection is explicit and stateful at the MCP layer: each profile type gets generated tools — …ListConnections, …SetConnection, optionally …AddProfile/…RemoveProfile. The active profile is tracked in state.activeProfileId; a single profile auto-selects; per-call overrides via <typeKey>Id are supported. "Location" style types (perToolOverride: true, e.g. Endevor env/stage) use a virtual context primed by a Set… tool and injected as defaults.
  • Passwords never go in argv. They're resolved out-of-band and injected via the ZOWE_OPT_PASSWORD env var, so they're invisible in ps. The resolver chain is: VS Code extension elicitation → legacy VS Code store → standalone env (ZOWE_MCP_PASSWORD_<USER>_<HOST>, ZOWE_MCP_CREDENTIALS JSON map, Vault KV).

So the bridge treats the CLI as a command executor, and owns connection/credential state itself rather than delegating to the CLI's profile resolution. Note one place it does read real team config: the VS Code extension side (zowe-profile.ts) uses ProfileInfo / zowe config list --rfj to discover zosmf/ssh profile names and match one to an MCP "system" (user@host) — used for building zowe-ds editor URIs, not for the bridge's own execution.

Sources (github.com/zowe/zowe-mcp)


4. How the Zowe CLI Endevor plugin uses profiles

The Endevor Broadcom plugin (@broadcom/endevor-for-zowe-cli) adds two profile types:

  • endevor — the connection/session: host, port, user, password, protocol (http/https), rejectUnauthorized, basePath. Points at the Endevor Web Services (or through API ML).
  • endevor-location — the inventory coordinates, not a connection: instance (Endevor config/datasource), environment, system, subsystem, stageNumber, type, ccid, comment.

This connection-vs-location split is the important pattern. A command like zowe endevor list elements needs both an endevor profile (where to connect) and an endevor-location profile (which inventory to look at). You can have one connection profile and many location profiles. API ML/token auth flows through the endevor (base) profile just like other services.

This maps directly onto the CLI bridge's design: required: true connection types (must pick one, like endevor) vs perToolOverride: true location types (primed as virtual context, like endevor-location) — the bridge was clearly modeled to accommodate exactly this two-axis plugin shape.

Sources

The npm package and GitHub org/repo are stable; the exact in-repo path for the profile definitions may differ by branch/refactor, so the repo tree link is the reliable starting point.


5. What makes sense for Zowe MCP — local vs. remote

The repo already recognizes three deployment modes (mcp-deployment-mode.ts): stdio-vscode, stdio-standalone, and http. The right profile strategy differs by who owns the identity.

Local deployments (stdio: VS Code extension or standalone CLI)

Here the MCP runs as the single user, on their machine, with their ~/.zowe and OS keystore available. The sensible posture:

  • Reuse the user's existing Zowe team config rather than maintaining a parallel connection store. The extension already has the ProfileInfo plumbing (zowe-profile.ts); extending the bridge to optionally resolve a named zosmf/endevor profile (and its secure-store secret) would mean "it just works" with what Zowe Explorer/CLI users already configured — including project-local zowe.config.json.
  • Honor defaults and the secure credential store; fall back to the bridge's own connection JSON + ZOWE_OPT_PASSWORD/Vault only when no team config exists.
  • Keep credential resolution interactive (the existing VS Code elicitation path) so MFA/expired-token prompts surface to the human at the keyboard.

Net: local = delegate to Zowe team config + keytar; treat the bridge's own profile store as a fallback.

Remote deployments (HTTP, multi-user / shared server)

Here a single server process serves many users, so a shared ~/.zowe is wrong and dangerous (one user's stored credentials must never serve another's request). The repo already leans the right way:

  • Per-tenant isolation keyed off the JWT sub (ZOWE_MCP_TENANT_STORE_DIR, tenantKeyFromSub) — each authenticated user has their own connection list. This is the correct unit of isolation and should remain the boundary for all profile/credential state.
  • OAuth/OIDC for the MCP edge (ZOWE_MCP_JWT_ISSUER/JWKS_URI), distinct from the z/OS credential. The bearer token authenticates the user to the MCP server; it does not authenticate to z/OS.
  • For the z/OS hop, the strategic fit is API ML token / identity mapping rather than per-tenant stored basic-auth passwords — i.e. exchange the user's OIDC identity for a z/OSMF token (see docs/future-zos-identity-mapping.md). Stored passwords/Vault KV are the pragmatic interim, but should always be per-tenant, encrypted at rest (tenant-store-crypto.ts), never a global zowe.config.json.
  • No team-config reuse on the server — team config is a single-user, single-machine artifact; on a shared host it should be ignored in favor of per-tenant stores.

Net: remote = identity is per-request (JWT sub); never share one profile/keystore; prefer token/identity-mapping to z/OS over stored passwords, and keep all credential state tenant-scoped.

The unifying recommendation

Keep the bridge's abstract profile model (named connection types + location types + a pluggable passwordResolver/connection source), and vary only the backing store by mode:

Mode Connection source Credential source Identity unit
Local (stdio) user's zowe.config.json (preferred) → bridge JSON OS secure store → env/Vault the local OS user
Remote (http) per-tenant store (TENANT_STORE_DIR) per-tenant encrypted store / Vault; ideally API ML token via identity mapping JWT sub

That preserves a single tool surface (the LLM always sees …SetConnection/…ListConnections) while the trust model underneath is appropriate to each deployment — which is exactly the seam the existing passwordResolver abstraction and deployment-mode detection were built to support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment