UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

127 lines (126 loc) 3.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _index = _interopRequireDefault(require("core-js-pure/stable/url/index.js")); var _mcp = require("@modelcontextprotocol/sdk/server/mcp.js"); var _webStandardStreamableHttp = require("@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js"); var _mcpDocsServer = require("../mcp-docs-server.js"); var _docsSource = require("../docs-source.js"); var _docsBundle = _interopRequireDefault(require("./docs.bundle.json")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const docsSource = (0, _docsSource.createBundledDocsSource)(_docsBundle.default, { label: 'worker:docs.bundle.json' }); let validatedOnce = false; async function ensureValidated() { if (!validatedOnce) { await (0, _mcpDocsServer.validateDocsSource)(docsSource); validatedOnce = true; } } function authResponse() { return new Response(JSON.stringify({ jsonrpc: '2.0', error: { code: -32001, message: 'Unauthorized' }, id: null }), { status: 401, headers: { 'content-type': 'application/json', 'www-authenticate': 'Bearer realm="eufemia-mcp"' } }); } async function safeEqual(a, b) { const encoder = new TextEncoder(); const keyData = encoder.encode(a); const key = await crypto.subtle.importKey('raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign', 'verify']); const sig = await crypto.subtle.sign('HMAC', key, encoder.encode(a)); return crypto.subtle.verify('HMAC', key, sig, encoder.encode(b)); } async function checkAuth(request, env) { var _request$headers$get; const token = env.MCP_AUTH_TOKEN; if (!token) { return null; } const header = (_request$headers$get = request.headers.get('authorization')) !== null && _request$headers$get !== void 0 ? _request$headers$get : ''; const expected = `Bearer ${token}`; if (header.length === expected.length && (await safeEqual(header, expected))) { return null; } return authResponse(); } async function handleMcp(request, env) { const unauthorized = await checkAuth(request, env); if (unauthorized) { return unauthorized; } const tools = (0, _mcpDocsServer.createDocsTools)({ source: docsSource }); const server = new _mcp.McpServer(_mcpDocsServer.SERVER_INFO); (0, _mcpDocsServer.registerDocsTools)(server, tools); const transport = new _webStandardStreamableHttp.WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: undefined, enableJsonResponse: true }); await server.connect(transport); try { return await transport.handleRequest(request); } finally { try { await transport.close(); } catch {} } } function handleHealth() { return new Response(JSON.stringify({ ok: true, name: _mcpDocsServer.SERVER_INFO.name, version: _mcpDocsServer.SERVER_INFO.version, transports: ['streamable-http'], runtime: 'cloudflare-worker' }), { status: 200, headers: { 'content-type': 'application/json' } }); } const handler = { async fetch(request, env) { const url = new _index.default(request.url); if (url.pathname === '/healthz' && request.method === 'GET') { return handleHealth(); } if (url.pathname === '/mcp') { try { await ensureValidated(); } catch (e) { return new Response(`Eufemia MCP misconfigured: ${e.message}`, { status: 500 }); } if (request.method !== 'POST' && request.method !== 'GET' && request.method !== 'DELETE') { return new Response('Method Not Allowed', { status: 405 }); } return handleMcp(request, env); } return new Response('Not Found', { status: 404 }); } }; var _default = exports.default = handler; //# sourceMappingURL=index.js.map