test(connections): route MCP fixtures through test transport

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-08-21 01:55:23 +00:00
1 parent 59dcb5f294
commit ce5791dd03
3 files changed
+18 -6

No files matched your search

@@ -156,7 +156,12 @@ function createRouteApp(
};
next();
});
app.use("/api", toolAccessRoutes(db, { toolGateway, ...deployment }));
app.use("/api", toolAccessRoutes(db, {
toolGateway,
remoteHttpEndpointLookup: async () => [{ address: "8.8.8.8", family: 4 }],
remoteHttpRequest: async (url, init) => fetch(url, init),
...deployment,
}));
app.use(errorHandler);
return app;
}
+3
View File
@@ -112,6 +112,9 @@ export function toolAccessRoutes(
authPublicBaseUrl?: string | null;
trustedLocalStdioRuntimeHost?: string | null;
toolGateway?: ToolGatewayService;
/** Test-only seams forwarded to the tool access service. */
remoteHttpEndpointLookup?: NonNullable<Parameters<typeof toolAccessService>[1]>["remoteHttpEndpointLookup"];
remoteHttpRequest?: NonNullable<Parameters<typeof toolAccessService>[1]>["remoteHttpRequest"];
} = {},
) {
const router = Router();
+9 -5
View File
@@ -1828,6 +1828,12 @@ export function toolAccessService(db: Db, options: ToolAccessServiceOptions = {}
};
}
async function requestRemoteHttpEndpoint(endpoint: URL, init: RequestInit): Promise<Response> {
return options.remoteHttpRequest
? options.remoteHttpRequest(endpoint.toString(), { ...init, redirect: "manual" })
: guardedRemoteHttpFetch(endpoint, init, remoteHttpFetchOptions());
}
/**
* Fetch an operator-supplied remote URL with the egress guard bound to the
* connection itself.
@@ -1843,9 +1849,7 @@ export function toolAccessService(db: Db, options: ToolAccessServiceOptions = {}
const method = (init.method ?? "GET").toUpperCase();
for (let redirectCount = 0; redirectCount <= MAX_REMOTE_HTTP_REDIRECTS; redirectCount += 1) {
const endpoint = parseRemoteHttpEndpoint(currentUrl, (message, code) => badRequest(message, { code }));
const response = options.remoteHttpRequest
? await options.remoteHttpRequest(endpoint.toString(), { ...init, redirect: "manual" })
: await guardedRemoteHttpFetch(endpoint, init, remoteHttpFetchOptions());
const response = await requestRemoteHttpEndpoint(endpoint, init);
const location = REMOTE_HTTP_REDIRECT_STATUSES.has(response.status)
? response.headers?.get?.("location") ?? null
: null;
@@ -3947,7 +3951,7 @@ export function toolAccessService(db: Db, options: ToolAccessServiceOptions = {}
// Pinned to the address the guard approved: `config.url` is operator-supplied,
// so a second DNS resolution here would reopen the rebinding window that
// PAP-17098 closed for the OAuth endpoints.
const response = await guardedRemoteHttpFetch(remoteEndpoint(connection.config), {
const response = await requestRemoteHttpEndpoint(new URL(remoteEndpoint(connection.config)), {
method: "POST",
// MCP Streamable HTTP requires advertising that we accept both a JSON body
// and an SSE stream; spec-compliant servers 406 without it (see mcp-http.ts).
@@ -3958,7 +3962,7 @@ export function toolAccessService(db: Db, options: ToolAccessServiceOptions = {}
method: "tools/list",
params: {},
}),
}, remoteHttpFetchOptions());
});
if (!response.ok) {
const authenticate = response.headers.get("www-authenticate") ?? "";
if (response.status === 401 && /bearer|oauth|authorization/i.test(authenticate)) {