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
e0d19e4so line numbers stay stable. Somedocs.zowe.orgslugs shift between releases; the/stable/landing pages are the durable entry points if a deep link 404s.
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 atype(zosmf,tso,ssh,db2,endevor, …). - V2 "team config" (current): a single
zowe.config.jsonfile 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 viaautoStore.
Key concepts that matter for this discussion:
- Profile types —
zosmf(z/OSMF REST),ssh,tso,zftp, and plugin types likedb2,endevor,cics. Each type has its own schema of fields. - Base profile — a shared parent holding common values (
host,rejectUnauthorized) and, importantly,tokenType/tokenValuefor 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'sProfileInfoclass reads all layers from disk, merges arguments, and resolves secrets.mergeArgsForProfile()returns the finalhost/user/etc. for a profile. The CLI also exposeszowe 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:portof the gateway + a token (JWT/LTPA) in the base profile, enabling SSO across services and MFA/PassTicket scenarios.
- Team config / profiles user guide — https://docs.zowe.org/stable/user-guide/cli-using-using-team-profiles
- Initializing & managing team config — https://docs.zowe.org/stable/user-guide/cli-using-initializing-team-configuration
- Base profiles & API ML token auth — https://docs.zowe.org/stable/user-guide/cli-using-integrating-apiml
- Profile types /
zowe configcommand group (Web Help) — https://docs.zowe.org/stable/web_help/index.html ProfileInforesolution API (source) — https://github.com/zowe/zowe-cli/blob/master/packages/imperative/src/config/src/ProfileInfo.ts
Zowe Explorer (the VS Code extension) is the canonical team-config consumer:
- On activation it instantiates
ProfileInfo('zowe')andreadProfilesFromDisk()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 listsgetAllProfiles('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.
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 isCliPluginProfilesFile = Record<typeKey, { profiles: CliNamedProfile[]; default?: string }>. Profile types and their fields are declared per-plugin in YAML (e.g.db2-tools.yamldefinesconnectionwithhost/port/user/database). - Invocation shells out to the
zowebinary viaspawnSync, 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 instate.activeProfileId; a single profile auto-selects; per-call overrides via<typeKey>Idare supported. "Location" style types (perToolOverride: true, e.g. Endevor env/stage) use a virtual context primed by aSet…tool and injected as defaults. - Passwords never go in argv. They're resolved out-of-band and injected via the
ZOWE_OPT_PASSWORDenv var, so they're invisible inps. The resolver chain is: VS Code extension elicitation → legacy VS Code store → standalone env (ZOWE_MCP_PASSWORD_<USER>_<HOST>,ZOWE_MCP_CREDENTIALSJSON 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.
- Named-profile data model (
CliPluginProfilesFile,CliNamedProfile) — https://github.com/zowe/zowe-mcp/blob/e0d19e4/packages/zowe-mcp-server/src/tools/cli-bridge/types.ts#L166-L194 - Profile-type / field schema (
ProfileTypeDef,required,perToolOverride,isUsername) — https://github.com/zowe/zowe-mcp/blob/e0d19e4/packages/zowe-mcp-server/src/tools/cli-bridge/types.ts#L114-L156 - CLI invocation +
ZOWE_OPT_PASSWORDinjection — https://github.com/zowe/zowe-mcp/blob/e0d19e4/packages/zowe-mcp-server/src/tools/cli-bridge/cli-invoker.ts#L130-L216 buildProfileArgs(--<cliOption> <value>) — https://github.com/zowe/zowe-mcp/blob/e0d19e4/packages/zowe-mcp-server/src/tools/cli-bridge/cli-invoker.ts#L104-L118- Active-profile state, auto-select, per-call override — https://github.com/zowe/zowe-mcp/blob/e0d19e4/packages/zowe-mcp-server/src/tools/cli-bridge/cli-tool-loader.ts#L1854-L1862
- Password resolver chain (VS Code elicitation → env →
ZOWE_MCP_CREDENTIALS→ Vault) — https://github.com/zowe/zowe-mcp/blob/e0d19e4/packages/zowe-mcp-server/src/index.ts#L1597-L1632 - Example plugin YAML (Db2: connection type + fields) — https://github.com/zowe/zowe-mcp/blob/e0d19e4/packages/zowe-mcp-vscode/server/tools/cli-bridge/plugins/db2-tools.yaml
- VS Code side reading real team config via
ProfileInfo— https://github.com/zowe/zowe-mcp/blob/e0d19e4/packages/zowe-mcp-vscode/src/zowe-profile.ts - How-to-add-a-plugin guide (in-repo) — https://github.com/zowe/zowe-mcp/blob/e0d19e4/docs/how-to-add-cli-plugin.md
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.
- Endevor plugin source (GitHub) — https://github.com/BroadcomMFD/endevor-for-zowe-cli
endevorvsendevor-locationprofile schemas (source tree) — https://github.com/BroadcomMFD/endevor-for-zowe-cli/tree/main/packages/endevor/src- npm package — https://www.npmjs.com/package/@broadcom/endevor-for-zowe-cli
- Broadcom Endevor + Zowe CLI documentation — https://techdocs.broadcom.com/ (search "Endevor Zowe CLI plug-in")
- Authoritative field reference — the plug-in's own
zowe endevor --helpWeb Help, generated by the installed plugin, documents both profile types and all--ndvr-*/location options.
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.
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.
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
ProfileInfoplumbing (zowe-profile.ts); extending the bridge to optionally resolve a namedzosmf/endevorprofile (and its secure-store secret) would mean "it just works" with what Zowe Explorer/CLI users already configured — including project-localzowe.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.
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 globalzowe.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.
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.