fix(mcp): preserve authorized sessions during login (#122129)

Follow-up to #122115: startMcpOAuthAuthorization suppressed stored tokens
unconditionally, forcing a browser authorization on every mcp login even with a
valid session. Suppression is again gated on a recorded authorization-required
challenge; start returns a closed authorized|redirect result and the CLI
early-returns the already-logged-in outcome.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
This commit is contained in:
Ayaan Zaidi
2026-08-11 21:53:23 +05:30
committed by GitHub
parent 0a406faefc
commit 93f686f681
4 changed files with 77 additions and 8 deletions
+16
View File
@@ -80,6 +80,7 @@ function mockRedirectFlow(redirectUrl: string): void {
authorizationUrl.searchParams.set("redirect_uri", redirectUrl);
authorizationUrl.searchParams.set("state", "state-1234567890");
mocks.startMcpOAuthAuthorization.mockResolvedValue({
status: "redirect",
authorizationUrl: authorizationUrl.toString(),
redirectUrl,
state: "state-1234567890",
@@ -140,6 +141,21 @@ describe("mcp login loopback callback", () => {
});
});
it("reports an existing session without starting the loopback", async () => {
await withTempHome("openclaw-cli-mcp-loopback-home-", async () => {
await configureServer();
mocks.startMcpOAuthAuthorization.mockResolvedValue({ status: "authorized" });
await program.parseAsync(["mcp", "login", "docs"], { from: "user" });
expect(mocks.runtime.log).toHaveBeenCalledWith('MCP OAuth credentials saved for "docs".');
expect(mocks.completeMcpOAuthAuthorization).not.toHaveBeenCalled();
expect(
mocks.runtime.log.mock.calls.some(([line]) => String(line).includes("Open this URL")),
).toBe(false);
});
});
it("falls back immediately to the printed manual command when binding fails", async () => {
await withTempHome("openclaw-cli-mcp-loopback-home-", async () => {
await configureServer();
+4
View File
@@ -1333,6 +1333,10 @@ export function registerMcpCli(program: Command) {
const manualCommand = formatCliCommand(`openclaw mcp login ${name} --code <code>`);
try {
const session = await startMcpOAuthAuthorization(identity, resolved, {});
if (session.status === "authorized") {
defaultRuntime.log(`MCP OAuth credentials saved for "${name}".`);
return;
}
if (session.state.length >= 16) {
try {
callbackServer = await startOAuthLoopbackCallbackServer({