cli: whoami reports organization: null for the organization every other command resolves
Summary
Three places in the CLI resolve the active organization. Two fall back to the account default; mcp-use whoami does not.
src/commands/identity.ts:277-280:
const config = await readCloudConfig();
const identity = await (await CloudApi.create()).identity();
const organization =
identity.organizations.find((item) => item.id === config.orgId) ?? null;src/commands/organizations.ts:85-88, for org current:
const organization =
identity.organizations.find(
(item) => item.id === (config.orgId ?? identity.defaultOrganizationId)
) ?? null;src/commands/cloud-api.ts:262-268, in cloudApiForOrganization, which every servers and deployments command goes through:
: identity.organizations.find(
(item) => item.id === (config.orgId ?? identity.defaultOrganizationId)
);The Problem
The divergence is reachable without any unusual setup.
CloudApi.createacceptsMCP_USE_API_KEYfrom the environment, so authentication does not requiremcp-use loginto have ever writtenconfig.json. With no local config,config.orgIdisundefinedand the account default is used everywhere exceptwhoami.whoamithen denies the organization the CLI is actively using:export MCP_USE_API_KEY=mcp_... # never ran `mcp-use login` mcp-use whoami --json # {"userId":...,"email":...,"organization":null} mcp-use org current # Acme (acme) mcp-use servers list # lists Acme's serversThe human output at
src/commands/identity.ts:286-290also drops the— <name>suffix, sowhoamiprints only the email.whoamiis the command users run to answer "who am I and where am I pointed", which is precisely the question it answers incorrectly here. It is also the natural thing to check before a destructive command likeservers delete, where believing no organization is selected is the wrong impression to leave.
Reproduced on main at dcaa0b8. With readCloudConfig returning {} and identity.defaultOrganizationId set to org_1, runIdentity("whoami", ["--json"]) prints:
{"userId":"user_1","email":"[email protected]","organization":null}Test coverage: none. tests/commands/identity.test.ts covers logout and login --device-code only; whoami appears nowhere except tests/commands/help-contract.test.ts, which just checks -h.
Proposed fix
Use the same expression the other two resolvers already use:
const organization =
identity.organizations.find(
(item) => item.id === (config.orgId ?? identity.defaultOrganizationId)
) ?? null;An explicit mcp-use org use selection still wins, since config.orgId is checked first. The only behaviour change is that whoami now names the organization it is actually pointed at instead of reporting none.
Worth noting one alternative reading: that whoami deliberately reports only local config, and null means "nothing selected locally". If that is the intent, the inconsistency is still worth closing, because org current reads local config too and does apply the fallback. Happy to take it in whichever direction you prefer.
Source: mcp-use/mcp-use