@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
127 lines (126 loc) • 3.9 kB
JavaScript
;
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