fix(cli): distinguish MCP servers in auth login

This commit is contained in:
rekram1-node
2026-09-24 00:42:44 +00:00
parent 8d5eb3bf9c
commit 8eb75cee5b
2 changed files with 62 additions and 16 deletions
@@ -74,30 +74,40 @@ const findIntegration = Effect.fn("cli.auth.login.integration")(function* (clien
}
const integrations = yield* loadIntegrations(client)
if (target) return yield* resolveIntegration(integrations, target)
const available = integrations
const options = loginOptions(integrations)
if (options.length === 0) return yield* Effect.fail(new Error("No authentication integrations are available"))
const id = yield* prompt<string>(() =>
autocomplete({
message: "Select an AI provider or MCP server",
maxItems: 8,
options,
}),
)
return yield* resolveIntegration(integrations, id)
})
export function loginOptions(integrations: IntegrationInfo[]) {
return integrations
.filter((integration) => connectMethods(integration).length > 0)
.toSorted(
(a, b) =>
Number(b.metadata?.source === "mcp") - Number(a.metadata?.source === "mcp") ||
(integrationPriority.get(a.id) ?? integrationPriority.size) -
(integrationPriority.get(b.id) ?? integrationPriority.size) ||
a.name.localeCompare(b.name) ||
a.id.localeCompare(b.id),
)
if (available.length === 0) return yield* Effect.fail(new Error("No authentication integrations are available"))
const id = yield* prompt<string>(() =>
autocomplete({
message: "Select integration",
maxItems: 8,
options: available.map((integration) => {
const option = { value: integration.id, label: integration.name, hint: integration.id }
if (integration.connections.length > 0) return { ...option, hint: "connected" }
if (integration.id === "opencode") return { ...option, hint: "recommended" }
return option
}),
}),
)
return yield* resolveIntegration(available, id)
})
.map((integration) => ({
value: integration.id,
label: `${integration.metadata?.source === "mcp" ? "MCP server" : "AI provider"} · ${integration.name}`,
hint:
integration.connections.length > 0
? "connected"
: integration.id === "opencode"
? "recommended"
: integration.id,
}))
}
const chooseMethod = Effect.fn("cli.auth.login.method")(function* (methods: ConnectMethod[], target?: string) {
if (target) return yield* resolveMethod(methods, target)
@@ -0,0 +1,36 @@
import { expect, test } from "bun:test"
import type { IntegrationInfo } from "@opencode/client"
import { loginOptions } from "../src/commands/handlers/auth/login"
const integration = (value: Partial<IntegrationInfo> & Pick<IntegrationInfo, "id" | "name">): IntegrationInfo => ({
methods: [{ type: "key" }],
connections: [],
...value,
})
test("distinguishes MCP servers from AI providers while retaining login targets and status", () => {
expect(
loginOptions([
integration({ id: "openai", name: "OpenAI" }),
integration({ id: "linear", name: "Linear", metadata: { source: "mcp" } }),
integration({ id: "opencode", name: "OpenCode Zen" }),
integration({ id: "opencode-go", name: "OpenCode Go", connections: [{ type: "env", name: "GO_KEY" }] }),
integration({ id: "unused", name: "Unused", methods: [{ type: "env", names: ["UNUSED_KEY"] }] }),
]),
).toEqual([
{ value: "linear", label: "MCP server · Linear", hint: "linear" },
{ value: "opencode-go", label: "AI provider · OpenCode Go", hint: "connected" },
{ value: "opencode", label: "AI provider · OpenCode Zen", hint: "recommended" },
{ value: "openai", label: "AI provider · OpenAI", hint: "openai" },
])
})
test("sorts MCP servers by name ahead of providers regardless of ID", () => {
expect(
loginOptions([
integration({ id: "openai", name: "OpenAI" }),
integration({ id: "zulu", name: "Zulu", metadata: { source: "mcp" } }),
integration({ id: "alpha", name: "Alpha", metadata: { source: "mcp" } }),
]).map((option) => option.value),
).toEqual(["alpha", "zulu", "openai"])
})