Files
jiang 6a49d2209e feat(agent): unify MCP tools and adopt Responses delivery
Move project and host queries into native MCP with host-owned OAuth/context,
while retaining memory, skills, actions and publication plugins. Add nearby-model
queries and explicit chat/task/learning model defaults.

Adopt Responses HTTP/SSE and native steer/queue inbox delivery, preserving scoped
session ownership, pending input edits and investigation communication.

Disable local-provider discovery: Server /health allowed native vLLM to probe
/v1/models on port 8000. A native before/after regression prevents recurrence.

Validation: 170 focused Bun tests; service/plugin typechecks; native discovery,
provider-discovery and input-inbox smoke checks; no paid model inference.
2026-10-19 18:46:58 +08:00

79 lines
6.1 KiB
TypeScript

import { expect, it } from "bun:test";
import { McpAuthDiscovery, type McpHttpFetch } from "../../src/product/mcp-auth-discovery.js";
const settings = { resource: "https://water.example/mcp", issuer: "https://identity.example/realm/water" };
const metadata = { issuer: settings.issuer, authorization_endpoint: "https://identity.example/authorize", response_types_supported: ["code"], token_endpoint: "https://identity.example/custom/token", token_endpoint_auth_methods_supported: ["client_secret_post"] };
it("uses the challenge resource metadata and discovers a non-Keycloak endpoint", async () => {
const requests: string[] = [];
const discovery = new McpAuthDiscovery(settings, (async (url, init) => {
requests.push(String(url));
expect(new Headers(init?.headers).has("Authorization")).toBeFalse();
expect(init?.body ? String(init.body).includes("secret") : false).toBeFalse();
if (String(url) === settings.resource) return new Response(null, { status: 401, headers: { "WWW-Authenticate": 'Basic realm="gateway", Bearer resource_metadata="https://water.example/auth/metadata", scope="mcp.catalog.read"' } });
if (String(url).endsWith("/auth/metadata")) return Response.json({ resource: settings.resource, authorization_servers: [settings.issuer] });
if (String(url).includes("oauth-authorization-server")) return Response.json(metadata);
throw new Error("unexpected endpoint");
}) as McpHttpFetch);
expect(await discovery.resolve()).toEqual({ tokenEndpoint: metadata.token_endpoint, authMethod: "client_secret_post" });
await discovery.resolve();
expect(requests).toEqual([settings.resource, "https://water.example/auth/metadata", "https://identity.example/.well-known/oauth-authorization-server/realm/water"]);
});
it("falls back through resource path, resource root and OAuth/OIDC issuer metadata", async () => {
const requests: string[] = [];
const discovery = new McpAuthDiscovery(settings, (async (url) => {
const path = String(url); requests.push(path);
if (path === settings.resource) return new Response(null, { status: 401 });
if (path === "https://water.example/.well-known/oauth-protected-resource") return Response.json({ resource: settings.resource, authorization_servers: [settings.issuer] });
if (path.endsWith("/realm/water/.well-known/openid-configuration")) return Response.json({ ...metadata, authorization_endpoint: "https://identity.example/authorize", jwks_uri: "https://identity.example/keys", response_types_supported: ["code"], subject_types_supported: ["public"], id_token_signing_alg_values_supported: ["RS256"] });
return new Response(null, { status: 404 });
}) as McpHttpFetch);
expect((await discovery.resolve()).tokenEndpoint).toBe(metadata.token_endpoint);
expect(requests).toEqual([
settings.resource, "https://water.example/.well-known/oauth-protected-resource/mcp", "https://water.example/.well-known/oauth-protected-resource",
"https://identity.example/.well-known/oauth-authorization-server/realm/water", "https://identity.example/.well-known/openid-configuration/realm/water", "https://identity.example/realm/water/.well-known/openid-configuration",
]);
});
it.each(["resource", "authority", "issuer", "endpoint", "method"])("rejects invalid %s metadata before credentials can be sent", async (kind) => {
const discovery = new McpAuthDiscovery(settings, (async (url) => {
if (String(url) === settings.resource) return new Response(null, { status: 401 });
if (String(url).includes("oauth-protected-resource")) return Response.json({ resource: kind === "resource" ? "https://other.example/mcp" : settings.resource, authorization_servers: [kind === "authority" ? "https://attacker.example" : settings.issuer] });
expect(String(url).startsWith("https://identity.example/")).toBeTrue();
return Response.json({ ...metadata, ...(kind === "issuer" ? { issuer: `${settings.issuer}/` } : {}), ...(kind === "endpoint" ? { token_endpoint: "http://attacker.example/token" } : {}), ...(kind === "method" ? { token_endpoint_auth_methods_supported: ["none"] } : {}) });
}) as McpHttpFetch);
await expect(discovery.resolve()).rejects.toMatchObject({ status: 503 });
});
it("rechecks the configured issuer after metadata invalidation", async () => {
let changed = false;
const discovery = new McpAuthDiscovery(settings, (async (url) => {
if (String(url) === settings.resource) return new Response(null, { status: 401 });
if (String(url).includes("oauth-protected-resource")) return Response.json({ resource: settings.resource, authorization_servers: [changed ? "https://new.example" : settings.issuer] });
return Response.json(metadata);
}) as McpHttpFetch);
await discovery.resolve();
changed = true; discovery.invalidate();
await expect(discovery.resolve()).rejects.toMatchObject({ status: 503 });
});
it.each(["allowed", "other-host", "other-port", "production"])("bounds development HTTP discovery: %s", async (kind) => {
const issuer = "http://192.168.1.114:8088/realms/tjwater";
let requests = 0;
const discovery = new McpAuthDiscovery({ ...settings, issuer, devHttpIssuer: issuer,
runtimeEnvironment: kind === "production" ? "production" : "development" }, (async (url, init) => {
requests++;
expect(new Headers(init?.headers).has("Authorization")).toBeFalse();
expect(init?.redirect).toBe("error");
if (String(url) === settings.resource) return new Response(null, { status: 401 });
if (String(url).includes("oauth-protected-resource")) return Response.json({ resource: settings.resource, authorization_servers: [issuer] });
expect(String(url).startsWith("http://192.168.1.114:8088/")).toBeTrue();
return Response.json({ ...metadata, issuer, token_endpoint: kind === "other-host" ? "http://192.168.1.115:8088/token" :
kind === "other-port" ? "http://192.168.1.114:8089/token" : `${issuer}/protocol/openid-connect/token` });
}) as McpHttpFetch);
if (kind === "allowed") expect((await discovery.resolve()).tokenEndpoint).toBe(`${issuer}/protocol/openid-connect/token`);
else await expect(discovery.resolve()).rejects.toMatchObject({ status: 503 });
if (kind === "production") expect(requests).toBe(0);
});