drizzle-cube 0.4.44 → 0.4.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/express/index.cjs +1 -1
- package/dist/adapters/express/index.js +23 -22
- package/dist/adapters/fastify/index.cjs +1 -1
- package/dist/adapters/fastify/index.js +23 -22
- package/dist/adapters/hono/index.cjs +1 -1
- package/dist/adapters/hono/index.js +25 -24
- package/dist/adapters/mcp-tools.cjs +1 -1
- package/dist/adapters/mcp-tools.d.ts +2 -0
- package/dist/adapters/mcp-tools.js +39 -29
- package/dist/adapters/mcp-transport-DbLtza1I.cjs +70 -0
- package/dist/adapters/{mcp-transport--zhJJHJc.js → mcp-transport-DoNg50eG.js} +122 -59
- package/dist/adapters/mcp-transport.d.ts +61 -1
- package/dist/adapters/nextjs/index.cjs +1 -1
- package/dist/adapters/nextjs/index.js +25 -24
- package/dist/adapters/utils.d.ts +2 -0
- package/dist/mcp-app/mcp-app.html +186 -0
- package/package.json +7 -2
- package/dist/adapters/mcp-transport-MOoCDu2M.cjs +0 -58
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-tNZ6Cvzw.cjs`),t=require(`../compiler-CA6iopu7.cjs`),n=require(`../mcp-transport-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-tNZ6Cvzw.cjs`),t=require(`../compiler-CA6iopu7.cjs`),n=require(`../mcp-transport-DbLtza1I.cjs`);let r=require(`express`);r=e.g(r);let i=require(`cors`);i=e.g(i);function a(a){let{cubes:o,drizzle:s,schema:c,extractSecurityContext:l,engineType:u,cors:d,basePath:f=`/cubejs-api/v1`,jsonLimit:p=`10mb`,cache:m,mcp:h={enabled:!0},agent:g}=a;if(!o||o.length===0)throw Error(`At least one cube must be provided in the cubes array`);let _=(0,r.Router)();d&&_.use((0,i.default)(d)),_.use(r.default.json({limit:p})),_.use(r.default.urlencoded({extended:!0,limit:p}));let v=new t.t({drizzle:s,schema:c,engineType:u,cache:m,rlsSetup:a.rlsSetup});if(o.forEach(e=>{v.registerCube(e)}),_.post(`${f}/load`,async(t,n)=>{try{let r=t.body.query||t.body,i=await l(t,n),a=v.validateQuery(r);if(!a.isValid)return n.status(400).json(e.i(`Query validation failed: ${a.errors.join(`, `)}`,400));let o=t.headers[`x-cache-control`]===`no-cache`,s=await v.executeMultiCubeQuery(r,i,{skipCache:o});n.json(e.r(r,s,v))}catch(t){console.error(`Query execution error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Query execution failed`,500))}}),_.get(`${f}/load`,async(t,n)=>{try{let r=t.query.query;if(!r)return n.status(400).json(e.i(`Query parameter is required`,400));let i;try{i=JSON.parse(r)}catch{return n.status(400).json(e.i(`Invalid JSON in query parameter`,400))}let a=await l(t,n),o=v.validateQuery(i);if(!o.isValid)return n.status(400).json(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=t.headers[`x-cache-control`]===`no-cache`,c=await v.executeMultiCubeQuery(i,a,{skipCache:s});n.json(e.r(i,c,v))}catch(t){console.error(`Query execution error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Query execution failed`,500))}}),_.post(`${f}/batch`,async(t,n)=>{try{let{queries:r}=t.body;if(!r||!Array.isArray(r))return n.status(400).json(e.i(`Request body must contain a "queries" array`,400));if(r.length===0)return n.status(400).json(e.i(`Queries array cannot be empty`,400));let i=await e.u(r,await l(t,n),v,{skipCache:t.headers[`x-cache-control`]===`no-cache`});n.json(i)}catch(t){console.error(`Batch execution error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Batch execution failed`,500))}}),_.get(`${f}/meta`,(t,n)=>{try{let t=v.getMetadata();n.json(e.a(t))}catch(t){console.error(`Metadata error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Failed to fetch metadata`,500))}}),_.post(`${f}/sql`,async(t,n)=>{try{let r=t.body,i=await l(t,n),a=v.validateQuery(r);if(!a.isValid)return n.status(400).json(e.i(`Query validation failed: ${a.errors.join(`, `)}`,400));let o=r.measures?.[0]||r.dimensions?.[0];if(!o)return n.status(400).json(e.i(`No measures or dimensions specified`,400));let s=o.split(`.`)[0],c=await v.generateSQL(s,r,i);n.json(e.o(r,c))}catch(t){console.error(`SQL generation error:`,String(t).replace(/\n|\r/g,``)),n.status(500).json(e.i(t instanceof Error?t.message:`SQL generation failed`,500))}}),_.get(`${f}/sql`,async(t,n)=>{try{let r=t.query.query;if(!r)return n.status(400).json(e.i(`Query parameter is required`,400));let i=JSON.parse(r),a=await l(t,n),o=v.validateQuery(i);if(!o.isValid)return n.status(400).json(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=i.measures?.[0]||i.dimensions?.[0];if(!s)return n.status(400).json(e.i(`No measures or dimensions specified`,400));let c=s.split(`.`)[0],u=await v.generateSQL(c,i,a);n.json(e.o(i,u))}catch(t){console.error(`SQL generation error:`,String(t).replace(/\n|\r/g,``)),n.status(500).json(e.i(t instanceof Error?t.message:`SQL generation failed`,500))}}),_.post(`${f}/dry-run`,async(t,n)=>{try{let r=await e.f(t.body.query||t.body,await l(t,n),v);n.json(r)}catch(e){console.error(`Dry-run error:`,e),n.status(400).json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),_.get(`${f}/dry-run`,async(t,n)=>{try{let r=t.query.query;if(!r)return n.status(400).json({error:`Query parameter is required`,valid:!1});let i=await e.f(JSON.parse(r),await l(t,n),v);n.json(i)}catch(e){console.error(`Dry-run error:`,e),n.status(400).json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),_.post(`${f}/explain`,async(e,t)=>{try{let n=e.body.query||e.body,r=e.body.options||{},i=await l(e,t),a=v.validateQuery(n);if(!a.isValid)return t.status(400).json({error:`Query validation failed: ${a.errors.join(`, `)}`});let o=await v.explainQuery(n,i,r);t.json(o)}catch(e){console.error(`Explain error:`,e),t.status(500).json({error:e instanceof Error?e.message:`Explain query failed`})}}),g&&_.post(`${f}/agent/chat`,async(e,t)=>{try{let{handleAgentChat:n}=await Promise.resolve().then(()=>require(`../handler-BO2nq6IS.cjs`)),{message:r,sessionId:i,history:a}=e.body;if(!r||typeof r!=`string`)return t.status(400).json({error:`message is required and must be a string`});let o=(g.apiKey||``).trim();if(g.allowClientApiKey){let t=e.headers[`x-agent-api-key`];t&&(o=t.trim())}if(!o)return t.status(401).json({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`});let s=g.allowClientApiKey?e.headers[`x-agent-provider`]:void 0,c=g.allowClientApiKey?e.headers[`x-agent-model`]:void 0,u=g.allowClientApiKey?e.headers[`x-agent-provider-endpoint`]:void 0,d=await l(e,t),f=g.buildSystemContext?.(d);t.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});try{let e=n({message:r,sessionId:i,history:a,semanticLayer:v,securityContext:d,agentConfig:g,apiKey:o,systemContext:f,providerOverride:s,modelOverride:c,baseURLOverride:u});for await(let n of e)t.write(`data: ${JSON.stringify(n)}\n\n`)}catch(e){let n={type:`error`,data:{message:e instanceof Error?e.message:`Stream failed`}};t.write(`data: ${JSON.stringify(n)}\n\n`)}finally{t.end()}}catch(e){console.error(`Agent chat error:`,e),t.headersSent||t.status(500).json({error:e instanceof Error?e.message:`Agent chat failed`})}}),h.enabled!==!1){let e=h.basePath??`/mcp`;_.post(`${e}`,async(e,t)=>{let r=n._(e.headers.origin,h.allowedOrigins?{allowedOrigins:h.allowedOrigins}:{});if(!r.valid)return t.status(403).json(n.i(null,-32600,r.reason));let i=e.headers.accept;if(!n.g(i))return t.status(400).json(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`));let a=n.f(e.headers);if(!a.ok)return t.status(426).json({error:`Unsupported MCP protocol version`,supported:a.supported});let o=n.p(e.body);if(!o)return t.status(400).json(n.i(null,-32600,`Invalid JSON-RPC 2.0 request`));let s=n.v(i),c=o.method===`initialize`;try{let r=await n.s(o.method,o.params,{semanticLayer:v,extractSecurityContext:l,rawRequest:e,rawResponse:t,negotiatedProtocol:a.negotiated,appEnabled:!!h.app});if(n.d(o))return t.status(202).end();let i=c&&r&&typeof r==`object`&&`sessionId`in r?r.sessionId:void 0;i&&t.setHeader(n.r,i);let u=n.a(o.id??null,r);if(s){let e=n.m();return t.status(200),t.setHeader(`Content-Type`,`text/event-stream`),t.setHeader(`Cache-Control`,`no-cache`),t.setHeader(`Connection`,`keep-alive`),t.write(`id: ${e}\n\n`),t.write(n.h(u,e)),t.end()}return t.json(u)}catch(e){if(n.d(o))return console.error(`MCP notification processing error:`,String(e).replace(/\n|\r/g,``)),t.status(202).end();console.error(`MCP RPC error:`,String(e).replace(/\n|\r/g,``));let r=e?.code??-32603,i=e?.data,a=e.message||`MCP request failed`,c=n.i(o.id??null,r,a,i);if(s){let e=n.m();return t.status(200),t.setHeader(`Content-Type`,`text/event-stream`),t.setHeader(`Cache-Control`,`no-cache`),t.setHeader(`Connection`,`keep-alive`),t.write(`id: ${e}\n\n`),t.write(n.h(c,e)),t.end()}return t.status(200).json(c)}}),_.get(`${e}`,async(e,t)=>{let r=n.m();t.status(200),t.setHeader(`Content-Type`,`text/event-stream`),t.setHeader(`Cache-Control`,`no-cache`),t.setHeader(`Connection`,`keep-alive`),t.write(n.h({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},r,15e3));let i=setInterval(()=>{t.write(`: keep-alive
|
|
2
2
|
|
|
3
3
|
`)},15e3);e.on(`close`,()=>{clearInterval(i)})}),_.delete(`${e}`,(e,t)=>t.status(405).json({error:`Session termination not supported`}))}return _.use((t,n,r,i)=>{console.error(`Express adapter error:`,t),r.headersSent||r.status(500).json(e.i(t,500))}),_}function o(e,t){let n=a(t);return e.use(`/`,n),e}function s(e){return o((0,r.default)(),e)}exports.createCubeApp=s,exports.createCubeRouter=a,exports.mountCubeRoutes=o;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as e, f as t, i as n, o as r, r as i, u as a } from "../utils-C7Nrw9Wb.js";
|
|
2
2
|
import { t as o } from "../compiler-O3T1u7jl.js";
|
|
3
|
-
import {
|
|
3
|
+
import { _ as s, a as c, d as l, f as u, g as d, h as f, i as p, m, p as h, r as g, s as _, v } from "../mcp-transport-DoNg50eG.js";
|
|
4
4
|
import y, { Router as b } from "express";
|
|
5
5
|
import x from "cors";
|
|
6
6
|
//#region src/adapters/express/index.ts
|
|
@@ -168,48 +168,49 @@ function S(S) {
|
|
|
168
168
|
}), M.enabled !== !1) {
|
|
169
169
|
let e = M.basePath ?? "/mcp";
|
|
170
170
|
P.post(`${e}`, async (e, t) => {
|
|
171
|
-
let n =
|
|
172
|
-
if (!n.valid) return t.status(403).json(
|
|
171
|
+
let n = s(e.headers.origin, M.allowedOrigins ? { allowedOrigins: M.allowedOrigins } : {});
|
|
172
|
+
if (!n.valid) return t.status(403).json(p(null, -32600, n.reason));
|
|
173
173
|
let r = e.headers.accept;
|
|
174
|
-
if (!
|
|
175
|
-
let i =
|
|
174
|
+
if (!d(r)) return t.status(400).json(p(null, -32600, "Accept header must include both application/json and text/event-stream"));
|
|
175
|
+
let i = u(e.headers);
|
|
176
176
|
if (!i.ok) return t.status(426).json({
|
|
177
177
|
error: "Unsupported MCP protocol version",
|
|
178
178
|
supported: i.supported
|
|
179
179
|
});
|
|
180
|
-
let a =
|
|
181
|
-
if (!a) return t.status(400).json(
|
|
182
|
-
let o =
|
|
180
|
+
let a = h(e.body);
|
|
181
|
+
if (!a) return t.status(400).json(p(null, -32600, "Invalid JSON-RPC 2.0 request"));
|
|
182
|
+
let o = v(r), y = a.method === "initialize";
|
|
183
183
|
try {
|
|
184
|
-
let n = await
|
|
184
|
+
let n = await _(a.method, a.params, {
|
|
185
185
|
semanticLayer: F,
|
|
186
186
|
extractSecurityContext: E,
|
|
187
187
|
rawRequest: e,
|
|
188
188
|
rawResponse: t,
|
|
189
|
-
negotiatedProtocol: i.negotiated
|
|
189
|
+
negotiatedProtocol: i.negotiated,
|
|
190
|
+
appEnabled: !!M.app
|
|
190
191
|
});
|
|
191
|
-
if (
|
|
192
|
+
if (l(a)) return t.status(202).end();
|
|
192
193
|
let r = y && n && typeof n == "object" && "sessionId" in n ? n.sessionId : void 0;
|
|
193
|
-
r && t.setHeader(
|
|
194
|
-
let
|
|
194
|
+
r && t.setHeader(g, r);
|
|
195
|
+
let s = c(a.id ?? null, n);
|
|
195
196
|
if (o) {
|
|
196
|
-
let e =
|
|
197
|
-
return t.status(200), t.setHeader("Content-Type", "text/event-stream"), t.setHeader("Cache-Control", "no-cache"), t.setHeader("Connection", "keep-alive"), t.write(`id: ${e}\n\n`), t.write(
|
|
197
|
+
let e = m();
|
|
198
|
+
return t.status(200), t.setHeader("Content-Type", "text/event-stream"), t.setHeader("Cache-Control", "no-cache"), t.setHeader("Connection", "keep-alive"), t.write(`id: ${e}\n\n`), t.write(f(s, e)), t.end();
|
|
198
199
|
}
|
|
199
|
-
return t.json(
|
|
200
|
+
return t.json(s);
|
|
200
201
|
} catch (e) {
|
|
201
|
-
if (
|
|
202
|
+
if (l(a)) return console.error("MCP notification processing error:", String(e).replace(/\n|\r/g, "")), t.status(202).end();
|
|
202
203
|
console.error("MCP RPC error:", String(e).replace(/\n|\r/g, ""));
|
|
203
|
-
let n = e?.code ?? -32603, r = e?.data, i = e.message || "MCP request failed", s =
|
|
204
|
+
let n = e?.code ?? -32603, r = e?.data, i = e.message || "MCP request failed", s = p(a.id ?? null, n, i, r);
|
|
204
205
|
if (o) {
|
|
205
|
-
let e =
|
|
206
|
-
return t.status(200), t.setHeader("Content-Type", "text/event-stream"), t.setHeader("Cache-Control", "no-cache"), t.setHeader("Connection", "keep-alive"), t.write(`id: ${e}\n\n`), t.write(
|
|
206
|
+
let e = m();
|
|
207
|
+
return t.status(200), t.setHeader("Content-Type", "text/event-stream"), t.setHeader("Cache-Control", "no-cache"), t.setHeader("Connection", "keep-alive"), t.write(`id: ${e}\n\n`), t.write(f(s, e)), t.end();
|
|
207
208
|
}
|
|
208
209
|
return t.status(200).json(s);
|
|
209
210
|
}
|
|
210
211
|
}), P.get(`${e}`, async (e, t) => {
|
|
211
|
-
let n =
|
|
212
|
-
t.status(200), t.setHeader("Content-Type", "text/event-stream"), t.setHeader("Cache-Control", "no-cache"), t.setHeader("Connection", "keep-alive"), t.write(
|
|
212
|
+
let n = m();
|
|
213
|
+
t.status(200), t.setHeader("Content-Type", "text/event-stream"), t.setHeader("Cache-Control", "no-cache"), t.setHeader("Connection", "keep-alive"), t.write(f({
|
|
213
214
|
jsonrpc: "2.0",
|
|
214
215
|
method: "mcp/ready",
|
|
215
216
|
params: { protocol: "streamable-http" }
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-tNZ6Cvzw.cjs`),t=require(`../compiler-CA6iopu7.cjs`),n=require(`../mcp-transport-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-tNZ6Cvzw.cjs`),t=require(`../compiler-CA6iopu7.cjs`),n=require(`../mcp-transport-DbLtza1I.cjs`);var r=function(r,i,a){let{cubes:o,drizzle:s,schema:c,extractSecurityContext:l,engineType:u,cors:d,basePath:f=`/cubejs-api/v1`,bodyLimit:p=10485760,cache:m,mcp:h={enabled:!0},agent:g}=i;if(!o||o.length===0)return a(Error(`At least one cube must be provided in the cubes array`));d&&r.register(import(`@fastify/cors`),d),r.addHook(`onRequest`,async(e,t)=>{e.method===`POST`&&(e.body=void 0)});let _=new t.t({drizzle:s,schema:c,engineType:u,cache:m,rlsSetup:i.rlsSetup});if(o.forEach(e=>{_.registerCube(e)}),r.post(`${f}/load`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(t,n)=>{try{let r=t.body,i=r.query||r,a=await l(t),o=_.validateQuery(i);if(!o.isValid)return n.status(400).send(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=t.headers[`x-cache-control`]===`no-cache`;return e.r(i,await _.executeMultiCubeQuery(i,a,{skipCache:s}),_)}catch(r){return t.log.error(r,`Query execution error`),n.status(500).send(e.i(r instanceof Error?r.message:`Query execution failed`,500))}}),r.get(`${f}/load`,{schema:{querystring:{type:`object`,properties:{query:{type:`string`}},required:[`query`]}}},async(t,n)=>{try{let{query:r}=t.query,i;try{i=JSON.parse(r)}catch{return n.status(400).send(e.i(`Invalid JSON in query parameter`,400))}let a=await l(t),o=_.validateQuery(i);if(!o.isValid)return n.status(400).send(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=t.headers[`x-cache-control`]===`no-cache`,c=await _.executeMultiCubeQuery(i,a,{skipCache:s});return e.r(i,c,_)}catch(r){return t.log.error(r,`Query execution error`),n.status(500).send(e.i(r instanceof Error?r.message:`Query execution failed`,500))}}),r.post(`${f}/batch`,{bodyLimit:p,schema:{body:{type:`object`,required:[`queries`],properties:{queries:{type:`array`,items:{type:`object`}}}}}},async(t,n)=>{try{let{queries:r}=t.body;return!r||!Array.isArray(r)?n.status(400).send(e.i(`Request body must contain a "queries" array`,400)):r.length===0?n.status(400).send(e.i(`Queries array cannot be empty`,400)):await e.u(r,await l(t),_,{skipCache:t.headers[`x-cache-control`]===`no-cache`})}catch(r){return t.log.error(r,`Batch execution error`),n.status(500).send(e.i(r instanceof Error?r.message:`Batch execution failed`,500))}}),r.get(`${f}/meta`,async(t,n)=>{try{return e.a(_.getMetadata())}catch(r){return t.log.error(r,`Metadata error`),n.status(500).send(e.i(r instanceof Error?r.message:`Failed to fetch metadata`,500))}}),r.post(`${f}/sql`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(t,n)=>{try{let r=t.body,i=await l(t),a=_.validateQuery(r);if(!a.isValid)return n.status(400).send(e.i(`Query validation failed: ${a.errors.join(`, `)}`,400));let o=r.measures?.[0]||r.dimensions?.[0];if(!o)return n.status(400).send(e.i(`No measures or dimensions specified`,400));let s=o.split(`.`)[0];return e.o(r,await _.generateSQL(s,r,i))}catch(r){return t.log.error({err:String(r).replace(/\n|\r/g,``)},`SQL generation error`),n.status(500).send(e.i(r instanceof Error?r.message:`SQL generation failed`,500))}}),r.get(`${f}/sql`,{schema:{querystring:{type:`object`,properties:{query:{type:`string`}},required:[`query`]}}},async(t,n)=>{try{let{query:r}=t.query,i=JSON.parse(r),a=await l(t),o=_.validateQuery(i);if(!o.isValid)return n.status(400).send(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=i.measures?.[0]||i.dimensions?.[0];if(!s)return n.status(400).send(e.i(`No measures or dimensions specified`,400));let c=s.split(`.`)[0];return e.o(i,await _.generateSQL(c,i,a))}catch(r){return t.log.error({err:String(r).replace(/\n|\r/g,``)},`SQL generation error`),n.status(500).send(e.i(r instanceof Error?r.message:`SQL generation failed`,500))}}),r.post(`${f}/dry-run`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(t,n)=>{try{let n=t.body;return await e.f(n.query||n,await l(t),_)}catch(e){return t.log.error(e,`Dry-run error`),n.status(400).send({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),r.get(`${f}/dry-run`,{schema:{querystring:{type:`object`,properties:{query:{type:`string`}},required:[`query`]}}},async(t,n)=>{try{let{query:n}=t.query;return await e.f(JSON.parse(n),await l(t),_)}catch(e){return t.log.error(e,`Dry-run error`),n.status(400).send({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),r.post(`${f}/explain`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(e,t)=>{try{let n=e.body,r=n.query||n,i=n.options||{},a=await l(e),o=_.validateQuery(r);return o.isValid?await _.explainQuery(r,a,i):t.status(400).send({error:`Query validation failed: ${o.errors.join(`, `)}`})}catch(n){return e.log.error(n,`Explain error`),t.status(500).send({error:n instanceof Error?n.message:`Explain query failed`})}}),g&&r.post(`${f}/agent/chat`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(e,t)=>{try{let{handleAgentChat:n}=await Promise.resolve().then(()=>require(`../handler-BO2nq6IS.cjs`)),{message:r,sessionId:i,history:a}=e.body;if(!r||typeof r!=`string`)return t.status(400).send({error:`message is required and must be a string`});let o=(g.apiKey||``).trim();if(g.allowClientApiKey){let t=e.headers[`x-agent-api-key`];t&&(o=t.trim())}if(!o)return t.status(401).send({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`});let s=g.allowClientApiKey?e.headers[`x-agent-provider`]:void 0,c=g.allowClientApiKey?e.headers[`x-agent-model`]:void 0,u=g.allowClientApiKey?e.headers[`x-agent-provider-endpoint`]:void 0,d=await l(e),f=g.buildSystemContext?.(d);t.raw.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});try{let e=n({message:r,sessionId:i,history:a,semanticLayer:_,securityContext:d,agentConfig:g,apiKey:o,systemContext:f,providerOverride:s,modelOverride:c,baseURLOverride:u});for await(let n of e)t.raw.write(`data: ${JSON.stringify(n)}\n\n`)}catch(e){let n={type:`error`,data:{message:e instanceof Error?e.message:`Stream failed`}};t.raw.write(`data: ${JSON.stringify(n)}\n\n`)}finally{t.raw.end()}}catch(n){if(e.log.error(n,`Agent chat error`),!t.raw.headersSent)return t.status(500).send({error:n instanceof Error?n.message:`Agent chat failed`})}}),h.enabled!==!1){let e=h.basePath??`/mcp`;r.post(`${e}`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(e,t)=>{let r=n._(e.headers.origin,h.allowedOrigins?{allowedOrigins:h.allowedOrigins}:{});if(!r.valid)return t.status(403).send(n.i(null,-32600,r.reason));let i=e.headers.accept;if(!n.g(i))return t.status(400).send(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`));let a=n.f(e.headers);if(!a.ok)return t.status(426).send({error:`Unsupported MCP protocol version`,supported:a.supported});let o=n.p(e.body);if(!o)return t.status(400).send(n.i(null,-32600,`Invalid JSON-RPC 2.0 request`));let s=n.v(i),c=o.method===`initialize`;try{let r=await n.s(o.method,o.params,{semanticLayer:_,extractSecurityContext:l,rawRequest:e,rawResponse:t,negotiatedProtocol:a.negotiated,appEnabled:!!h.app});if(n.d(o))return t.status(202).send();let i=c&&r&&typeof r==`object`&&`sessionId`in r?r.sessionId:void 0;i&&t.header(n.r,i);let u=n.a(o.id??null,r);if(s){let e=n.m();t.header(`Content-Type`,`text/event-stream`).header(`Cache-Control`,`no-cache`).header(`Connection`,`keep-alive`).send(`id: ${e}\n\n${n.h(u,e)}`);return}return t.send(u)}catch(r){if(n.d(o))return e.log.error({err:String(r).replace(/\n|\r/g,``)},`MCP notification processing error`),t.status(202).send();e.log.error({err:String(r).replace(/\n|\r/g,``)},`MCP RPC error`);let i=r?.code??-32603,a=r?.data,c=r.message||`MCP request failed`,l=n.i(o.id??null,i,c,a);if(s){let e=n.m();t.header(`Content-Type`,`text/event-stream`).header(`Cache-Control`,`no-cache`).header(`Connection`,`keep-alive`).send(`id: ${e}\n\n${n.h(l,e)}`);return}return t.send(l)}}),r.get(`${e}`,async(e,t)=>{let r=n.m();t.raw.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}),t.raw.write(n.h({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},r,15e3));let i=setInterval(()=>{t.raw.write(`: keep-alive
|
|
2
2
|
|
|
3
3
|
`)},15e3);e.raw.on(`close`,()=>{clearInterval(i)})}),r.delete(`${e}`,async(e,t)=>t.status(405).send({error:`Session termination not supported`}))}r.setErrorHandler(async(t,n,r)=>(n.log.error(t,`Fastify cube adapter error`),r.statusCode<400&&r.status(500),e.i(t instanceof Error?t:String(t),r.statusCode))),a()};async function i(e,t){await e.register(r,t)}function a(e){let t=require(`fastify`)({logger:!0});return t.register(r,e),t}exports.createCubeApp=a,exports.cubePlugin=r,exports.registerCubeRoutes=i;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as e, f as t, g as n, i as r, o as i, r as a, u as o } from "../utils-C7Nrw9Wb.js";
|
|
2
2
|
import { t as s } from "../compiler-O3T1u7jl.js";
|
|
3
|
-
import {
|
|
3
|
+
import { _ as c, a as l, d as u, f as d, g as f, h as p, i as m, m as h, p as g, r as _, s as v, v as y } from "../mcp-transport-DoNg50eG.js";
|
|
4
4
|
//#region src/adapters/fastify/index.ts
|
|
5
5
|
var b = function(n, b, x) {
|
|
6
6
|
let { cubes: S, drizzle: C, schema: w, extractSecurityContext: T, engineType: E, cors: D, basePath: O = "/cubejs-api/v1", bodyLimit: k = 10485760, cache: A, mcp: j = { enabled: !0 }, agent: M } = b;
|
|
@@ -207,54 +207,55 @@ var b = function(n, b, x) {
|
|
|
207
207
|
additionalProperties: !0
|
|
208
208
|
} }
|
|
209
209
|
}, async (e, t) => {
|
|
210
|
-
let n =
|
|
211
|
-
if (!n.valid) return t.status(403).send(
|
|
210
|
+
let n = c(e.headers.origin, j.allowedOrigins ? { allowedOrigins: j.allowedOrigins } : {});
|
|
211
|
+
if (!n.valid) return t.status(403).send(m(null, -32600, n.reason));
|
|
212
212
|
let r = e.headers.accept;
|
|
213
|
-
if (!
|
|
214
|
-
let i =
|
|
213
|
+
if (!f(r)) return t.status(400).send(m(null, -32600, "Accept header must include both application/json and text/event-stream"));
|
|
214
|
+
let i = d(e.headers);
|
|
215
215
|
if (!i.ok) return t.status(426).send({
|
|
216
216
|
error: "Unsupported MCP protocol version",
|
|
217
217
|
supported: i.supported
|
|
218
218
|
});
|
|
219
|
-
let a =
|
|
220
|
-
if (!a) return t.status(400).send(
|
|
221
|
-
let o =
|
|
219
|
+
let a = g(e.body);
|
|
220
|
+
if (!a) return t.status(400).send(m(null, -32600, "Invalid JSON-RPC 2.0 request"));
|
|
221
|
+
let o = y(r), s = a.method === "initialize";
|
|
222
222
|
try {
|
|
223
|
-
let n = await
|
|
223
|
+
let n = await v(a.method, a.params, {
|
|
224
224
|
semanticLayer: N,
|
|
225
225
|
extractSecurityContext: T,
|
|
226
226
|
rawRequest: e,
|
|
227
227
|
rawResponse: t,
|
|
228
|
-
negotiatedProtocol: i.negotiated
|
|
228
|
+
negotiatedProtocol: i.negotiated,
|
|
229
|
+
appEnabled: !!j.app
|
|
229
230
|
});
|
|
230
|
-
if (
|
|
231
|
+
if (u(a)) return t.status(202).send();
|
|
231
232
|
let r = s && n && typeof n == "object" && "sessionId" in n ? n.sessionId : void 0;
|
|
232
|
-
r && t.header(
|
|
233
|
-
let
|
|
233
|
+
r && t.header(_, r);
|
|
234
|
+
let c = l(a.id ?? null, n);
|
|
234
235
|
if (o) {
|
|
235
|
-
let e =
|
|
236
|
-
t.header("Content-Type", "text/event-stream").header("Cache-Control", "no-cache").header("Connection", "keep-alive").send(`id: ${e}\n\n${
|
|
236
|
+
let e = h();
|
|
237
|
+
t.header("Content-Type", "text/event-stream").header("Cache-Control", "no-cache").header("Connection", "keep-alive").send(`id: ${e}\n\n${p(c, e)}`);
|
|
237
238
|
return;
|
|
238
239
|
}
|
|
239
|
-
return t.send(
|
|
240
|
+
return t.send(c);
|
|
240
241
|
} catch (n) {
|
|
241
|
-
if (
|
|
242
|
+
if (u(a)) return e.log.error({ err: String(n).replace(/\n|\r/g, "") }, "MCP notification processing error"), t.status(202).send();
|
|
242
243
|
e.log.error({ err: String(n).replace(/\n|\r/g, "") }, "MCP RPC error");
|
|
243
|
-
let r = n?.code ?? -32603, i = n?.data, s = n.message || "MCP request failed", c =
|
|
244
|
+
let r = n?.code ?? -32603, i = n?.data, s = n.message || "MCP request failed", c = m(a.id ?? null, r, s, i);
|
|
244
245
|
if (o) {
|
|
245
|
-
let e =
|
|
246
|
-
t.header("Content-Type", "text/event-stream").header("Cache-Control", "no-cache").header("Connection", "keep-alive").send(`id: ${e}\n\n${
|
|
246
|
+
let e = h();
|
|
247
|
+
t.header("Content-Type", "text/event-stream").header("Cache-Control", "no-cache").header("Connection", "keep-alive").send(`id: ${e}\n\n${p(c, e)}`);
|
|
247
248
|
return;
|
|
248
249
|
}
|
|
249
250
|
return t.send(c);
|
|
250
251
|
}
|
|
251
252
|
}), n.get(`${e}`, async (e, t) => {
|
|
252
|
-
let n =
|
|
253
|
+
let n = h();
|
|
253
254
|
t.raw.writeHead(200, {
|
|
254
255
|
"Content-Type": "text/event-stream",
|
|
255
256
|
"Cache-Control": "no-cache",
|
|
256
257
|
Connection: "keep-alive"
|
|
257
|
-
}), t.raw.write(
|
|
258
|
+
}), t.raw.write(p({
|
|
258
259
|
jsonrpc: "2.0",
|
|
259
260
|
method: "mcp/ready",
|
|
260
261
|
params: { protocol: "streamable-http" }
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-tNZ6Cvzw.cjs`),t=require(`../compiler-CA6iopu7.cjs`),n=require(`../mcp-transport-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-tNZ6Cvzw.cjs`),t=require(`../compiler-CA6iopu7.cjs`),n=require(`../mcp-transport-DbLtza1I.cjs`);let r=require(`hono`);var i=e=>{let t={origin:`*`,allowMethods:[`GET`,`HEAD`,`PUT`,`POST`,`DELETE`,`PATCH`],allowHeaders:[],exposeHeaders:[],...e},n=(e=>typeof e==`string`?e===`*`?t.credentials?e=>e||null:()=>e:t=>e===t?t:null:typeof e==`function`?e:t=>e.includes(t)?t:null)(t.origin),r=(e=>typeof e==`function`?e:Array.isArray(e)?()=>e:()=>[])(t.allowMethods);return async function(e,i){function a(t,n){e.res.headers.set(t,n)}let o=await n(e.req.header(`origin`)||``,e);if(o&&a(`Access-Control-Allow-Origin`,o),t.credentials&&a(`Access-Control-Allow-Credentials`,`true`),t.exposeHeaders?.length&&a(`Access-Control-Expose-Headers`,t.exposeHeaders.join(`,`)),e.req.method===`OPTIONS`){(t.origin!==`*`||t.credentials)&&a(`Vary`,`Origin`),t.maxAge!=null&&a(`Access-Control-Max-Age`,t.maxAge.toString());let n=await r(e.req.header(`origin`)||``,e);n.length&&a(`Access-Control-Allow-Methods`,n.join(`,`));let i=t.allowHeaders;if(!i?.length){let t=e.req.header(`Access-Control-Request-Headers`);t&&(i=t.split(/\s*,\s*/))}return i?.length&&(a(`Access-Control-Allow-Headers`,i.join(`,`)),e.res.headers.append(`Vary`,`Access-Control-Request-Headers`)),e.res.headers.delete(`Content-Length`),e.res.headers.delete(`Content-Type`),new Response(null,{headers:e.res.headers,status:204,statusText:`No Content`})}await i(),(t.origin!==`*`||t.credentials)&&e.header(`Vary`,`Origin`,{append:!0})}};function a(a){let{cubes:o,drizzle:s,schema:c,extractSecurityContext:l,engineType:u,cors:d,basePath:f=`/cubejs-api/v1`,cache:p,mcp:m={enabled:!0},agent:h}=a;if(!a.semanticLayer&&(!o||o.length===0))throw Error(`Either semanticLayer or a non-empty cubes array must be provided`);let g=new r.Hono;d&&g.use(`/*`,i(d));let _=a.semanticLayer??new t.t({drizzle:s,schema:c,engineType:u,cache:p,rlsSetup:a.rlsSetup});if(!a.semanticLayer&&o&&o.forEach(e=>{_.registerCube(e)}),g.post(`${f}/load`,async t=>{try{let n=await t.req.json(),r=n.query||n,i=await l(t),a=_.validateQuery(r);if(!a.isValid)return t.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=t.req.header(`x-cache-control`)===`no-cache`,s=await _.executeMultiCubeQuery(r,i,{skipCache:o});return t.json(e.r(r,s,_))}catch(e){return console.error(`Query execution error:`,e),t.json({error:e instanceof Error?e.message:`Query execution failed`},500)}}),g.get(`${f}/load`,async t=>{try{let n=t.req.query(`query`);if(!n)return t.json({error:`Query parameter is required`},400);let r;try{r=JSON.parse(n)}catch{return t.json({error:`Invalid JSON in query parameter`},400)}let i=await l(t),a=_.validateQuery(r);if(!a.isValid)return t.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=t.req.header(`x-cache-control`)===`no-cache`,s=await _.executeMultiCubeQuery(r,i,{skipCache:o});return t.json(e.r(r,s,_))}catch(e){return console.error(`Query execution error:`,e),t.json({error:e instanceof Error?e.message:`Query execution failed`},500)}}),g.post(`${f}/batch`,async t=>{try{let{queries:n}=await t.req.json();if(!n||!Array.isArray(n))return t.json({error:`Request body must contain a "queries" array`},400);if(n.length===0)return t.json({error:`Queries array cannot be empty`},400);let r=await e.u(n,await l(t),_,{skipCache:t.req.header(`x-cache-control`)===`no-cache`});return t.json(r)}catch(e){return console.error(`Batch execution error:`,e),t.json({error:e instanceof Error?e.message:`Batch execution failed`},500)}}),g.get(`${f}/meta`,t=>{try{let n=_.getMetadata();return t.json(e.a(n))}catch(e){return console.error(`Metadata error:`,e),t.json({error:e instanceof Error?e.message:`Failed to fetch metadata`},500)}}),g.post(`${f}/sql`,async t=>{try{let n=await t.req.json(),r=await l(t),i=_.validateQuery(n);if(!i.isValid)return t.json({error:`Query validation failed: ${i.errors.join(`, `)}`},400);let a=n.measures?.[0]||n.dimensions?.[0];if(!a)return t.json({error:`No measures or dimensions specified`},400);let o=a.split(`.`)[0],s=await _.generateSQL(o,n,r);return t.json(e.o(n,s))}catch(e){return console.error(`SQL generation error:`,e),t.json({error:e instanceof Error?e.message:`SQL generation failed`},500)}}),g.get(`${f}/sql`,async t=>{try{let n=t.req.query(`query`);if(!n)return t.json({error:`Query parameter is required`},400);let r=JSON.parse(n),i=await l(t),a=_.validateQuery(r);if(!a.isValid)return t.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=r.measures?.[0]||r.dimensions?.[0];if(!o)return t.json({error:`No measures or dimensions specified`},400);let s=o.split(`.`)[0],c=await _.generateSQL(s,r,i);return t.json(e.o(r,c))}catch(e){return console.error(`SQL generation error:`,e),t.json({error:e instanceof Error?e.message:`SQL generation failed`},500)}}),g.post(`${f}/dry-run`,async t=>{try{let n=await t.req.json(),r=await e.f(n.query||n,await l(t),_);return t.json(r)}catch(e){return console.error(`Dry-run error:`,e),t.json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1},400)}}),g.get(`${f}/dry-run`,async t=>{try{let n=t.req.query(`query`);if(!n)return t.json({error:`Query parameter is required`,valid:!1},400);let r=await e.f(JSON.parse(n),await l(t),_);return t.json(r)}catch(e){return console.error(`Dry-run error:`,e),t.json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1},400)}}),g.post(`${f}/explain`,async e=>{try{let t=await e.req.json(),n=t.query||t,r=t.options||{},i=await l(e),a=_.validateQuery(n);if(!a.isValid)return e.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=await _.explainQuery(n,i,r);return e.json(o)}catch(t){return console.error(`Explain error:`,t),e.json({error:t instanceof Error?t.message:`Explain query failed`},500)}}),h&&g.post(`${f}/agent/chat`,async e=>{try{let{handleAgentChat:t}=await Promise.resolve().then(()=>require(`../handler-BO2nq6IS.cjs`)),{message:n,sessionId:r,history:i}=await e.req.json();if(!n||typeof n!=`string`)return e.json({error:`message is required and must be a string`},400);let a=(h.apiKey||``).trim();if(h.allowClientApiKey){let t=e.req.header(`x-agent-api-key`);t&&(a=t.trim())}if(!a)return e.json({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`},401);let o=h.allowClientApiKey?e.req.header(`x-agent-provider`):void 0,s=h.allowClientApiKey?e.req.header(`x-agent-model`):void 0,c=h.allowClientApiKey?e.req.header(`x-agent-provider-endpoint`):void 0,u=await l(e),d=h.buildSystemContext?.(u),f=new TextEncoder,p=new ReadableStream({async start(e){try{let l=t({message:n,sessionId:r,history:i,semanticLayer:_,securityContext:u,agentConfig:h,apiKey:a,systemContext:d,providerOverride:o,modelOverride:s,baseURLOverride:c});for await(let t of l){let n=`data: ${JSON.stringify(t)}\n\n`;e.enqueue(f.encode(n))}}catch(t){let n={type:`error`,data:{message:t instanceof Error?t.message:`Stream failed`}};e.enqueue(f.encode(`data: ${JSON.stringify(n)}\n\n`))}finally{e.close()}}});return new Response(p,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}})}catch(t){return console.error(`Agent chat error:`,t),e.json({error:t instanceof Error?t.message:`Agent chat failed`},500)}}),m.enabled!==!1){let e={uri:`drizzle-cube://schema`,name:`Cube Schema`,description:`Current cube metadata as JSON`,mimeType:`application/json`,text:JSON.stringify(_.getMetadata(),null,2)},t=[...n.l(),e],r=n.c(),i=m.basePath??`/mcp`;g.post(`${i}`,async e=>{let i=n._(e.req.header(`origin`),m.allowedOrigins?{allowedOrigins:m.allowedOrigins}:{});if(!i.valid)return e.json(n.i(null,-32600,i.reason),403);let a=e.req.header(`accept`);if(!n.g(a))return e.json(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`),400);let o=n.f(e.req.header());if(!o.ok)return e.json({error:`Unsupported MCP protocol version`,supported:o.supported},426);let s=n.p(await e.req.json().catch(()=>null));if(!s)return e.json(n.i(null,-32600,`Invalid JSON-RPC 2.0 request`),400);let c=n.v(a),u=s.method===`initialize`;try{let i=await n.s(s.method,s.params,{semanticLayer:_,extractSecurityContext:l,rawRequest:e,rawResponse:null,negotiatedProtocol:o.negotiated,resources:t,prompts:r,appEnabled:!!m.app});if(n.d(s))return e.body(null,202);let a=n.a(s.id??null,i),d=u&&i&&typeof i==`object`&&`sessionId`in i?i.sessionId:void 0,f={};if(d&&(f[n.r]=d),c){let e=new TextEncoder,t=n.m(),r=new ReadableStream({start(r){r.enqueue(e.encode(`id: ${t}\n\n`)),r.enqueue(e.encode(n.h(a,t))),r.close()}});return new Response(r,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`,...f}})}return e.json(a,200,f)}catch(t){if(n.d(s))return console.error(`MCP notification processing error:`,t),e.body(null,202);console.error(`MCP RPC error:`,t);let r=t?.code??-32603,i=t?.data,a=t.message||`MCP request failed`,o=n.i(s.id??null,r,a,i);if(c){let e=new TextEncoder,t=n.m(),r=new ReadableStream({start(r){r.enqueue(e.encode(`id: ${t}\n\n`)),r.enqueue(e.encode(n.h(o,t))),r.close()}});return new Response(r,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}})}return e.json(o,200)}}),g.delete(`${i}`,e=>e.json({error:`Session termination not supported`},405)),g.get(`${i}`,e=>{let t=new TextEncoder,r=n.m(),i,a=new ReadableStream({start(e){e.enqueue(t.encode(n.h({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},r,15e3))),i=setInterval(()=>{e.enqueue(t.encode(`: keep-alive
|
|
2
2
|
|
|
3
3
|
`))},15e3)},cancel(){clearInterval(i)}});return new Response(a,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}})})}return g}function o(e,t){let n=a(t);return e.route(`/`,n),e}function s(e){return o(new r.Hono,e)}exports.createCubeApp=s,exports.createCubeRoutes=a,exports.mountCubeRoutes=o;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as e, f as t, o as n, r, u as i } from "../utils-C7Nrw9Wb.js";
|
|
2
2
|
import { t as a } from "../compiler-O3T1u7jl.js";
|
|
3
|
-
import {
|
|
3
|
+
import { _ as o, a as s, c, d as l, f as u, g as d, h as f, i as p, l as m, m as h, p as g, r as _, s as v, v as y } from "../mcp-transport-DoNg50eG.js";
|
|
4
4
|
import { Hono as b } from "hono";
|
|
5
5
|
//#region node_modules/hono/dist/middleware/cors/index.js
|
|
6
6
|
var x = (e) => {
|
|
@@ -215,35 +215,36 @@ function S(S) {
|
|
|
215
215
|
description: "Current cube metadata as JSON",
|
|
216
216
|
mimeType: "application/json",
|
|
217
217
|
text: JSON.stringify(P.getMetadata(), null, 2)
|
|
218
|
-
}, t = [...
|
|
218
|
+
}, t = [...m(), e], n = c(), r = j.basePath ?? "/mcp";
|
|
219
219
|
N.post(`${r}`, async (e) => {
|
|
220
|
-
let r =
|
|
220
|
+
let r = o(e.req.header("origin"), j.allowedOrigins ? { allowedOrigins: j.allowedOrigins } : {});
|
|
221
221
|
if (!r.valid) return e.json(p(null, -32600, r.reason), 403);
|
|
222
222
|
let i = e.req.header("accept");
|
|
223
|
-
if (!
|
|
224
|
-
let a =
|
|
223
|
+
if (!d(i)) return e.json(p(null, -32600, "Accept header must include both application/json and text/event-stream"), 400);
|
|
224
|
+
let a = u(e.req.header());
|
|
225
225
|
if (!a.ok) return e.json({
|
|
226
226
|
error: "Unsupported MCP protocol version",
|
|
227
227
|
supported: a.supported
|
|
228
228
|
}, 426);
|
|
229
|
-
let
|
|
230
|
-
if (!
|
|
231
|
-
let
|
|
229
|
+
let c = g(await e.req.json().catch(() => null));
|
|
230
|
+
if (!c) return e.json(p(null, -32600, "Invalid JSON-RPC 2.0 request"), 400);
|
|
231
|
+
let m = y(i), b = c.method === "initialize";
|
|
232
232
|
try {
|
|
233
|
-
let r = await
|
|
233
|
+
let r = await v(c.method, c.params, {
|
|
234
234
|
semanticLayer: P,
|
|
235
235
|
extractSecurityContext: E,
|
|
236
236
|
rawRequest: e,
|
|
237
237
|
rawResponse: null,
|
|
238
238
|
negotiatedProtocol: a.negotiated,
|
|
239
239
|
resources: t,
|
|
240
|
-
prompts: n
|
|
240
|
+
prompts: n,
|
|
241
|
+
appEnabled: !!j.app
|
|
241
242
|
});
|
|
242
|
-
if (
|
|
243
|
-
let i =
|
|
244
|
-
if (
|
|
245
|
-
let e = new TextEncoder(), t =
|
|
246
|
-
n.enqueue(e.encode(`id: ${t}\n\n`)), n.enqueue(e.encode(
|
|
243
|
+
if (l(c)) return e.body(null, 202);
|
|
244
|
+
let i = s(c.id ?? null, r), o = b && r && typeof r == "object" && "sessionId" in r ? r.sessionId : void 0, u = {};
|
|
245
|
+
if (o && (u[_] = o), m) {
|
|
246
|
+
let e = new TextEncoder(), t = h(), n = new ReadableStream({ start(n) {
|
|
247
|
+
n.enqueue(e.encode(`id: ${t}\n\n`)), n.enqueue(e.encode(f(i, t))), n.close();
|
|
247
248
|
} });
|
|
248
249
|
return new Response(n, {
|
|
249
250
|
status: 200,
|
|
@@ -251,18 +252,18 @@ function S(S) {
|
|
|
251
252
|
"Content-Type": "text/event-stream",
|
|
252
253
|
"Cache-Control": "no-cache",
|
|
253
254
|
Connection: "keep-alive",
|
|
254
|
-
...
|
|
255
|
+
...u
|
|
255
256
|
}
|
|
256
257
|
});
|
|
257
258
|
}
|
|
258
|
-
return e.json(i, 200,
|
|
259
|
+
return e.json(i, 200, u);
|
|
259
260
|
} catch (t) {
|
|
260
|
-
if (
|
|
261
|
+
if (l(c)) return console.error("MCP notification processing error:", t), e.body(null, 202);
|
|
261
262
|
console.error("MCP RPC error:", t);
|
|
262
|
-
let n = t?.code ?? -32603, r = t?.data, i = t.message || "MCP request failed", a = p(
|
|
263
|
-
if (
|
|
264
|
-
let e = new TextEncoder(), t =
|
|
265
|
-
n.enqueue(e.encode(`id: ${t}\n\n`)), n.enqueue(e.encode(
|
|
263
|
+
let n = t?.code ?? -32603, r = t?.data, i = t.message || "MCP request failed", a = p(c.id ?? null, n, i, r);
|
|
264
|
+
if (m) {
|
|
265
|
+
let e = new TextEncoder(), t = h(), n = new ReadableStream({ start(n) {
|
|
266
|
+
n.enqueue(e.encode(`id: ${t}\n\n`)), n.enqueue(e.encode(f(a, t))), n.close();
|
|
266
267
|
} });
|
|
267
268
|
return new Response(n, {
|
|
268
269
|
status: 200,
|
|
@@ -276,9 +277,9 @@ function S(S) {
|
|
|
276
277
|
return e.json(a, 200);
|
|
277
278
|
}
|
|
278
279
|
}), N.delete(`${r}`, (e) => e.json({ error: "Session termination not supported" }, 405)), N.get(`${r}`, (e) => {
|
|
279
|
-
let t = new TextEncoder(), n =
|
|
280
|
+
let t = new TextEncoder(), n = h(), r, i = new ReadableStream({
|
|
280
281
|
start(e) {
|
|
281
|
-
e.enqueue(t.encode(
|
|
282
|
+
e.enqueue(t.encode(f({
|
|
282
283
|
jsonrpc: "2.0",
|
|
283
284
|
method: "mcp/ready",
|
|
284
285
|
params: { protocol: "streamable-http" }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./utils-tNZ6Cvzw.cjs`),t=require(`./mcp-transport-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./utils-tNZ6Cvzw.cjs`),t=require(`./mcp-transport-DbLtza1I.cjs`);function n(e){return{content:[{type:`text`,text:typeof e==`string`?e:JSON.stringify(e)}],isError:!1}}function r(e){return{content:[{type:`text`,text:e instanceof Error?e.message:String(e)}],isError:!0}}function i(i){let{semanticLayer:o,getSecurityContext:s,toolPrefix:c=`drizzle_cube_`,tools:l=[`discover`,`validate`,`load`],prompts:u=t.c(),resources:d,app:f=!1}=i,p=d??t.l(),m=f?[...p,...a()]:p,h=t.o({appEnabled:f}),g=new Map(h.map(e=>[e.name,e])),_=l.filter(e=>g.has(e)).map(e=>{let t=g.get(e),n={name:`${c}${e}`,description:t.description,inputSchema:t.inputSchema},r=t._meta;return r&&(n._meta=r),n}),v=_.map(e=>e.name),y=new Set;for(let e of l)y.add(e),y.add(`${c}${e}`);function b(e){return y.has(e)}async function x(t,i,a){let u=t.startsWith(c)?t.slice(c.length):t;if(!l.includes(u))return r(`Unknown tool: ${t}`);try{switch(u){case`discover`:return n(await e.d(o,i||{}));case`validate`:{let t=i||{};return t.query?n(await e.h(o,t)):r(`query is required`)}case`load`:{let t=i||{};return t.query?n(await e.p(o,await s(a),t)):r(`query is required`)}default:return r(`Unknown tool: ${t}`)}}catch(e){return r(e)}}return{definitions:_,handle:x,handles:b,prompts:u,resources:m,toolNames:v}}function a(){let e=t.u();return e?[{uri:t.n,name:`Drizzle Cube Visualization`,description:`Interactive chart visualization for query results`,mimeType:t.t,text:e}]:[]}exports.getCubeTools=i;
|
|
@@ -55,6 +55,8 @@ export interface GetCubeToolsOptions {
|
|
|
55
55
|
prompts?: MCPPrompt[];
|
|
56
56
|
/** Custom MCP resources (defaults to built-in drizzle-cube resources) */
|
|
57
57
|
resources?: MCPResource[];
|
|
58
|
+
/** Enable MCP App visualization for the load tool (default: false) */
|
|
59
|
+
app?: boolean;
|
|
58
60
|
}
|
|
59
61
|
/**
|
|
60
62
|
* The composable tools object returned by getCubeTools()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { d as e, h as t, p as n } from "./utils-C7Nrw9Wb.js";
|
|
2
|
-
import {
|
|
2
|
+
import { c as r, l as i, n as a, o, t as s, u as c } from "./mcp-transport-DoNg50eG.js";
|
|
3
3
|
//#region src/adapters/mcp-tools.ts
|
|
4
|
-
function
|
|
4
|
+
function l(e) {
|
|
5
5
|
return {
|
|
6
6
|
content: [{
|
|
7
7
|
type: "text",
|
|
@@ -10,7 +10,7 @@ function o(e) {
|
|
|
10
10
|
isError: !1
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function u(e) {
|
|
14
14
|
return {
|
|
15
15
|
content: [{
|
|
16
16
|
type: "text",
|
|
@@ -19,51 +19,61 @@ function s(e) {
|
|
|
19
19
|
isError: !0
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
-
function
|
|
23
|
-
let { semanticLayer:
|
|
22
|
+
function d(a) {
|
|
23
|
+
let { semanticLayer: s, getSecurityContext: c, toolPrefix: d = "drizzle_cube_", tools: p = [
|
|
24
24
|
"discover",
|
|
25
25
|
"validate",
|
|
26
26
|
"load"
|
|
27
|
-
], prompts:
|
|
28
|
-
let t =
|
|
29
|
-
return {
|
|
27
|
+
], prompts: m = r(), resources: h, app: g = !1 } = a, _ = h ?? i(), v = g ? [..._, ...f()] : _, y = o({ appEnabled: g }), b = new Map(y.map((e) => [e.name, e])), x = p.filter((e) => b.has(e)).map((e) => {
|
|
28
|
+
let t = b.get(e), n = {
|
|
30
29
|
name: `${d}${e}`,
|
|
31
30
|
description: t.description,
|
|
32
31
|
inputSchema: t.inputSchema
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
}, r = t._meta;
|
|
33
|
+
return r && (n._meta = r), n;
|
|
34
|
+
}), S = x.map((e) => e.name), C = /* @__PURE__ */ new Set();
|
|
35
|
+
for (let e of p) C.add(e), C.add(`${d}${e}`);
|
|
36
|
+
function w(e) {
|
|
37
|
+
return C.has(e);
|
|
38
38
|
}
|
|
39
|
-
async function
|
|
40
|
-
let
|
|
41
|
-
if (!
|
|
39
|
+
async function T(r, i, a) {
|
|
40
|
+
let o = r.startsWith(d) ? r.slice(d.length) : r;
|
|
41
|
+
if (!p.includes(o)) return u(`Unknown tool: ${r}`);
|
|
42
42
|
try {
|
|
43
|
-
switch (
|
|
44
|
-
case "discover": return
|
|
43
|
+
switch (o) {
|
|
44
|
+
case "discover": return l(await e(s, i || {}));
|
|
45
45
|
case "validate": {
|
|
46
46
|
let e = i || {};
|
|
47
|
-
return e.query ?
|
|
47
|
+
return e.query ? l(await t(s, e)) : u("query is required");
|
|
48
48
|
}
|
|
49
49
|
case "load": {
|
|
50
50
|
let e = i || {};
|
|
51
|
-
return e.query ?
|
|
51
|
+
return e.query ? l(await n(s, await c(a), e)) : u("query is required");
|
|
52
52
|
}
|
|
53
|
-
default: return
|
|
53
|
+
default: return u(`Unknown tool: ${r}`);
|
|
54
54
|
}
|
|
55
55
|
} catch (e) {
|
|
56
|
-
return
|
|
56
|
+
return u(e);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
return {
|
|
60
|
-
definitions:
|
|
61
|
-
handle:
|
|
62
|
-
handles:
|
|
63
|
-
prompts:
|
|
64
|
-
resources:
|
|
65
|
-
toolNames:
|
|
60
|
+
definitions: x,
|
|
61
|
+
handle: T,
|
|
62
|
+
handles: w,
|
|
63
|
+
prompts: m,
|
|
64
|
+
resources: v,
|
|
65
|
+
toolNames: S
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
|
+
function f() {
|
|
69
|
+
let e = c();
|
|
70
|
+
return e ? [{
|
|
71
|
+
uri: a,
|
|
72
|
+
name: "Drizzle Cube Visualization",
|
|
73
|
+
description: "Interactive chart visualization for query results",
|
|
74
|
+
mimeType: s,
|
|
75
|
+
text: e
|
|
76
|
+
}] : [];
|
|
77
|
+
}
|
|
68
78
|
//#endregion
|
|
69
|
-
export {
|
|
79
|
+
export { d as getCubeTools };
|