@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.
56 lines (55 loc) • 1.72 kB
JavaScript
import { MCPEventConfigError } from "../errors.js";
//#region src/events/secret.ts
var PREFIX = "whsec_";
var MIN_BYTES = 24;
var MAX_BYTES = 64;
var GENERATED_BYTES = 32;
function bytesToBase64(bytes) {
let binary = "";
for (const byte of bytes) binary += String.fromCharCode(byte);
return btoa(binary);
}
function base64ToBytes(value) {
const padded = value + "=".repeat((4 - value.length % 4) % 4);
try {
const binary = atob(padded);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
return bytes;
} catch {
throw new MCPEventConfigError("MCP event secret is not valid base64");
}
}
/**
* Generate a Standard Webhooks secret: `whsec_` plus 32 random bytes.
*
* @experimental
*
* @example
* ```ts
* import { createMCPEventSecret } from '@tanstack/ai-mcp/events'
*
* const secret = createMCPEventSecret()
* ```
*/
function createMCPEventSecret() {
const bytes = new Uint8Array(GENERATED_BYTES);
crypto.getRandomValues(bytes);
return `${PREFIX}${bytesToBase64(bytes)}`;
}
/**
* Decode a `whsec_` secret to the raw HMAC key.
*
* @experimental
*/
function decodeMCPEventSecret(secret) {
if (!secret.startsWith(PREFIX)) throw new MCPEventConfigError("MCP event secret must start with whsec_");
const encoded = secret.slice(6);
if (encoded.length === 0) throw new MCPEventConfigError("MCP event secret is not valid base64");
const bytes = base64ToBytes(encoded);
if (bytes.byteLength < MIN_BYTES || bytes.byteLength > MAX_BYTES) throw new MCPEventConfigError("MCP event secret must decode to 24 to 64 bytes");
return bytes;
}
//#endregion
export { createMCPEventSecret, decodeMCPEventSecret };
//# sourceMappingURL=secret.js.map