@tanstack/ai-mcp
Version:
Host-side Model Context Protocol client for TanStack AI: discover and run MCP server tools, resources, and prompts in any adapter's chat() loop, with generated end-to-end types.
64 lines (63 loc) • 2.18 kB
JavaScript
import { MCPEventConfigError } from "../errors.js";
//#region src/events/callback-url.ts
/**
* Query parameter that routes a webhook to a local subscription key.
*
* @experimental
*/
var MCP_EVENT_CALLBACK_KEY_PARAM = "mcp_event_subscription";
var LOOPBACK = /* @__PURE__ */ new Set([
"127.0.0.1",
"[::1]",
"::1"
]);
/**
* Validate a webhook callback URL.
*
* https is required. http is allowed only for `127.0.0.1` and `[::1]` when
* `allowInsecureLocalhost` is set. Credentials, fragments, and an existing
* `mcp_event_subscription` parameter are rejected.
*
* @experimental
*/
function validateCallbackUrl(url, opts = {}) {
let parsed;
try {
parsed = new URL(url);
} catch {
throw new MCPEventConfigError("Callback URL is not a valid URL");
}
if (parsed.username !== "" || parsed.password !== "") throw new MCPEventConfigError("Callback URL must not include credentials");
if (parsed.hash !== "") throw new MCPEventConfigError("Callback URL must not include a fragment");
if (parsed.searchParams.has("mcp_event_subscription")) throw new MCPEventConfigError(`Callback URL must not already include ${MCP_EVENT_CALLBACK_KEY_PARAM}`);
if (parsed.protocol === "https:") return parsed;
if (parsed.protocol !== "http:") throw new MCPEventConfigError("Callback URL must use https");
if (!opts.allowInsecureLocalhost || !LOOPBACK.has(parsed.hostname)) throw new MCPEventConfigError("http callback URLs are only allowed for 127.0.0.1 and [::1] when allowInsecureLocalhost is set");
return parsed;
}
/**
* Append `mcp_event_subscription=<key>` to a validated callback URL.
*
* @experimental
*/
function withCallbackKey(url, key) {
const next = new URL(url.href);
next.searchParams.set(MCP_EVENT_CALLBACK_KEY_PARAM, key);
return next.href;
}
/**
* Read the subscription key from a callback URL.
*
* @experimental
*/
function readCallbackKey(url) {
try {
const value = new URL(url).searchParams.get(MCP_EVENT_CALLBACK_KEY_PARAM);
return value === null || value.length === 0 ? void 0 : value;
} catch {
return;
}
}
//#endregion
export { MCP_EVENT_CALLBACK_KEY_PARAM, readCallbackKey, validateCallbackUrl, withCallbackKey };
//# sourceMappingURL=callback-url.js.map