Closes #1666 #1575 shipped `--print-handoff` with an interim deep-link shape (hardcoded `transport: "http"`, marked `TODO(#1576)`). Now that #1576 owns the canonical `?serverUrl&transport&autoConnect` format, `--print-handoff` emits exactly it: - New `deepLinkTransport(serverUrl, transport)` helper derives `http`|`sse` from the resolved server — explicit `--transport` wins, else auto-detect from the URL path (`/sse` → sse), else default `http`. Unlike the core resolver it defaults instead of throwing (the handoff is best-effort; the web parser defaults an unknown transport to http too). - `buildHandoff` takes the transport, emits the normalized serverUrl + derived transport in the query, and keeps `autoConnect=<token>` (which #1576 adopted as the canonical CSRF gate, so the interim guess was already correct). - Removed the `TODO(#1576)` marker; updated the doc comment + CLI README. Tests: handoff emits `transport=http` for `/mcp`, `transport=sse` for `/sse` and for explicit `--transport sse`; `deepLinkTransport` unit tests cover the explicit/auto/default/stdio/unparseable branches. CLI coverage gate green (cli.ts 100/92.8/100/100). Part of the #1579 decomposition (Wave 4). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BrihGWcrM9JGRyu41nzZYw
This commit is contained in:
parent
0e93b13426
commit
93f3fb64f2
1 changed files with 96 additions and 13 deletions
|
|
@ -4,7 +4,7 @@ import { join, dirname } from "node:path";
|
|||
import { tmpdir } from "node:os";
|
||||
import { runCli } from "./helpers/cli-runner.js";
|
||||
import { expectCliFailure, expectCliSuccess } from "./helpers/assertions.js";
|
||||
import { normalizeServerUrl } from "../src/cli.js";
|
||||
import { normalizeServerUrl, deepLinkTransport } from "../src/cli.js";
|
||||
import {
|
||||
createTestServerHttp,
|
||||
createEchoTool,
|
||||
|
|
@ -36,6 +36,27 @@ describe("normalizeServerUrl", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("deepLinkTransport", () => {
|
||||
it("honors an explicit sse/http transport over the URL path", () => {
|
||||
expect(deepLinkTransport("https://x.example/mcp", "sse")).toBe("sse");
|
||||
expect(deepLinkTransport("https://x.example/sse", "http")).toBe("http");
|
||||
});
|
||||
|
||||
it("auto-detects sse from a /sse path when no transport is given", () => {
|
||||
expect(deepLinkTransport("https://x.example/sse", undefined)).toBe("sse");
|
||||
});
|
||||
|
||||
it("defaults to http for a /mcp path, an ambiguous path, or stdio", () => {
|
||||
expect(deepLinkTransport("https://x.example/mcp", undefined)).toBe("http");
|
||||
expect(deepLinkTransport("https://x.example/", undefined)).toBe("http");
|
||||
expect(deepLinkTransport("https://x.example/mcp", "stdio")).toBe("http");
|
||||
});
|
||||
|
||||
it("defaults to http for an unparseable URL without throwing", () => {
|
||||
expect(deepLinkTransport("not a url", undefined)).toBe("http");
|
||||
});
|
||||
});
|
||||
|
||||
describe("--use-stored-auth", () => {
|
||||
let server: ReturnType<typeof createTestServerHttp>;
|
||||
let serverUrl: string;
|
||||
|
|
@ -258,6 +279,8 @@ describe("--print-handoff", () => {
|
|||
expect(out.serverUrl).toBe("https://x.example/mcp");
|
||||
expect(out.deepLink).toContain("autoConnect=tok123");
|
||||
expect(out.deepLink).toContain("serverUrl=https%3A%2F%2Fx.example%2Fmcp");
|
||||
// Canonical #1576 deep-link: a `/mcp` server hands off `transport=http`.
|
||||
expect(out.deepLink).toContain("transport=http");
|
||||
expect(out.portForwardCmd).toContain("--tcp 16274:16274");
|
||||
expect(out.portForwardCmd).toContain("--tcp 16275:16275");
|
||||
expect(out.oauthStatePath).toBe(
|
||||
|
|
@ -266,6 +289,33 @@ describe("--print-handoff", () => {
|
|||
expect(out.apiToken).toBe("tok123");
|
||||
});
|
||||
|
||||
it("derives transport=sse for an SSE server (auto-detected from the /sse path)", async () => {
|
||||
const result = await runCli(
|
||||
["--print-handoff", "--server-url", "https://x.example/sse"],
|
||||
{ env: { MCP_INSPECTOR_API_TOKEN: "tok123" } },
|
||||
);
|
||||
expectCliSuccess(result);
|
||||
const out = JSON.parse(result.stdout) as { deepLink: string };
|
||||
expect(out.deepLink).toContain("transport=sse");
|
||||
expect(out.deepLink).not.toContain("transport=http");
|
||||
});
|
||||
|
||||
it("honors an explicit --transport sse over the URL path", async () => {
|
||||
const result = await runCli(
|
||||
[
|
||||
"--print-handoff",
|
||||
"--server-url",
|
||||
"https://x.example/mcp",
|
||||
"--transport",
|
||||
"sse",
|
||||
],
|
||||
{ env: { MCP_INSPECTOR_API_TOKEN: "tok123" } },
|
||||
);
|
||||
expectCliSuccess(result);
|
||||
const out = JSON.parse(result.stdout) as { deepLink: string };
|
||||
expect(out.deepLink).toContain("transport=sse");
|
||||
});
|
||||
|
||||
it("includes a note when MCP_INSPECTOR_API_TOKEN is unset", async () => {
|
||||
const result = await runCli(
|
||||
["--print-handoff", "--server-url", "https://x.example/mcp"],
|
||||
|
|
|
|||
Loading…
Reference in a new issue