jxp 4.1.1 → 5.0.0
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/.env.sample +30 -0
- package/README.md +2 -0
- package/dist/bin/index_audit.d.ts +3 -0
- package/dist/bin/index_audit.d.ts.map +1 -0
- package/dist/bin/index_audit.js +66 -0
- package/dist/bin/index_audit.js.map +1 -0
- package/dist/bin/mcp-stdio-bridge.d.ts +3 -0
- package/dist/bin/mcp-stdio-bridge.d.ts.map +1 -0
- package/dist/bin/mcp-stdio-bridge.js +87 -0
- package/dist/bin/mcp-stdio-bridge.js.map +1 -0
- package/dist/bin/server.d.ts.map +1 -1
- package/dist/bin/server.js +8 -2
- package/dist/bin/server.js.map +1 -1
- package/dist/libs/builtin_models.d.ts +21 -0
- package/dist/libs/builtin_models.d.ts.map +1 -0
- package/dist/libs/builtin_models.js +125 -0
- package/dist/libs/builtin_models.js.map +1 -0
- package/dist/libs/docs-auth.d.ts.map +1 -1
- package/dist/libs/docs-auth.js +6 -2
- package/dist/libs/docs-auth.js.map +1 -1
- package/dist/libs/docs.js +105 -44
- package/dist/libs/docs.js.map +1 -1
- package/dist/libs/groups.js +3 -4
- package/dist/libs/groups.js.map +1 -1
- package/dist/libs/index_diagnostics.d.ts +144 -0
- package/dist/libs/index_diagnostics.d.ts.map +1 -0
- package/dist/libs/index_diagnostics.js +671 -0
- package/dist/libs/index_diagnostics.js.map +1 -0
- package/dist/libs/jxp.d.ts.map +1 -1
- package/dist/libs/jxp.js +97 -331
- package/dist/libs/jxp.js.map +1 -1
- package/dist/libs/load-config.d.ts +2 -0
- package/dist/libs/load-config.d.ts.map +1 -1
- package/dist/libs/load-config.js +10 -0
- package/dist/libs/load-config.js.map +1 -1
- package/dist/libs/login.js +3 -8
- package/dist/libs/login.js.map +1 -1
- package/dist/libs/mcp/auth.d.ts +4 -0
- package/dist/libs/mcp/auth.d.ts.map +1 -0
- package/dist/libs/mcp/auth.js +49 -0
- package/dist/libs/mcp/auth.js.map +1 -0
- package/dist/libs/mcp/config.d.ts +21 -0
- package/dist/libs/mcp/config.d.ts.map +1 -0
- package/dist/libs/mcp/config.js +66 -0
- package/dist/libs/mcp/config.js.map +1 -0
- package/dist/libs/mcp/context.d.ts +5 -0
- package/dist/libs/mcp/context.d.ts.map +1 -0
- package/dist/libs/mcp/context.js +14 -0
- package/dist/libs/mcp/context.js.map +1 -0
- package/dist/libs/mcp/describe.d.ts +13 -0
- package/dist/libs/mcp/describe.d.ts.map +1 -0
- package/dist/libs/mcp/describe.js +36 -0
- package/dist/libs/mcp/describe.js.map +1 -0
- package/dist/libs/mcp/docs_auth.d.ts +5 -0
- package/dist/libs/mcp/docs_auth.d.ts.map +1 -0
- package/dist/libs/mcp/docs_auth.js +36 -0
- package/dist/libs/mcp/docs_auth.js.map +1 -0
- package/dist/libs/mcp/dynamic_import.d.ts +6 -0
- package/dist/libs/mcp/dynamic_import.d.ts.map +1 -0
- package/dist/libs/mcp/dynamic_import.js +12 -0
- package/dist/libs/mcp/dynamic_import.js.map +1 -0
- package/dist/libs/mcp/execute_tool.d.ts +10 -0
- package/dist/libs/mcp/execute_tool.d.ts.map +1 -0
- package/dist/libs/mcp/execute_tool.js +65 -0
- package/dist/libs/mcp/execute_tool.js.map +1 -0
- package/dist/libs/mcp/guides/default.md +67 -0
- package/dist/libs/mcp/guides.d.ts +14 -0
- package/dist/libs/mcp/guides.d.ts.map +1 -0
- package/dist/libs/mcp/guides.js +127 -0
- package/dist/libs/mcp/guides.js.map +1 -0
- package/dist/libs/mcp/model_visibility.d.ts +31 -0
- package/dist/libs/mcp/model_visibility.d.ts.map +1 -0
- package/dist/libs/mcp/model_visibility.js +73 -0
- package/dist/libs/mcp/model_visibility.js.map +1 -0
- package/dist/libs/mcp/mount.d.ts +10 -0
- package/dist/libs/mcp/mount.d.ts.map +1 -0
- package/dist/libs/mcp/mount.js +68 -0
- package/dist/libs/mcp/mount.js.map +1 -0
- package/dist/libs/mcp/read_service.d.ts +23 -0
- package/dist/libs/mcp/read_service.d.ts.map +1 -0
- package/dist/libs/mcp/read_service.js +141 -0
- package/dist/libs/mcp/read_service.js.map +1 -0
- package/dist/libs/mcp/server.d.ts +23 -0
- package/dist/libs/mcp/server.d.ts.map +1 -0
- package/dist/libs/mcp/server.js +111 -0
- package/dist/libs/mcp/server.js.map +1 -0
- package/dist/libs/parse_byte_size.d.ts +10 -0
- package/dist/libs/parse_byte_size.d.ts.map +1 -0
- package/dist/libs/parse_byte_size.js +80 -0
- package/dist/libs/parse_byte_size.js.map +1 -0
- package/dist/libs/query_limits.js +99 -13
- package/dist/libs/query_limits.js.map +1 -1
- package/dist/libs/read_handlers.d.ts +13 -0
- package/dist/libs/read_handlers.d.ts.map +1 -0
- package/dist/libs/read_handlers.js +381 -0
- package/dist/libs/read_handlers.js.map +1 -0
- package/dist/libs/schema.js +2 -2
- package/dist/libs/schema.js.map +1 -1
- package/dist/libs/schema_serialize.d.ts +3 -0
- package/dist/libs/schema_serialize.d.ts.map +1 -0
- package/dist/libs/schema_serialize.js +45 -0
- package/dist/libs/schema_serialize.js.map +1 -0
- package/dist/libs/security.js +7 -11
- package/dist/libs/security.js.map +1 -1
- package/dist/libs/setup.js +3 -4
- package/dist/libs/setup.js.map +1 -1
- package/dist/libs/startup.d.ts +4 -0
- package/dist/libs/startup.d.ts.map +1 -1
- package/dist/libs/startup.js +17 -0
- package/dist/libs/startup.js.map +1 -1
- package/dist/models/indexquerylog_model.d.ts +19 -0
- package/dist/models/indexquerylog_model.d.ts.map +1 -0
- package/dist/models/indexquerylog_model.js +32 -0
- package/dist/models/indexquerylog_model.js.map +1 -0
- package/dist/types/jxp-config.d.ts +29 -0
- package/dist/types/jxp-config.d.ts.map +1 -1
- package/dist/types/schema-fields.d.ts +4 -0
- package/dist/types/schema-fields.d.ts.map +1 -1
- package/docs/api.md +16 -2
- package/docs/changelog.md +101 -1
- package/docs/configuration.md +39 -0
- package/docs/index.md +2 -0
- package/docs/index_diagnostics.md +127 -0
- package/docs/mcp.md +134 -0
- package/docs/schemas.md +3 -1
- package/mkdocs.yml +2 -0
- package/package.json +26 -9
- package/templates/assets/diagnostics.js +352 -0
- package/templates/assets/docs.css +107 -0
- package/templates/assets/mcp-console.js +343 -0
- package/templates/diagnostics.pug +94 -0
- package/templates/index.pug +38 -0
- package/templates/mcp.pug +112 -0
- package/templates/navbar.pug +2 -0
- package/templates/sidebar.pug +12 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe.js","sourceRoot":"","sources":["../../../src/libs/mcp/describe.ts"],"names":[],"mappings":";;AAaA,8CAkCC;AA9CD,0DAAqD;AAYrD,SAAgB,iBAAiB,CAAC,IAAY,EAAE,KAAqB;IACpE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,MAAM,UAAU,GAAsD,EAAE,CAAC;IACzE,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,gBAAgB,GAAa,EAAE,CAAC;IAEtC,KAAK,MAAM,SAAS,IAAI,MAAM,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3C,UAAU,CAAC,SAAS,CAAC,GAAG,IAAA,iCAAc,EAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;YACzB,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,KAAK,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;YACxD,MAAM,WAAW,GAAG,MAAM,CACzB,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAC9E,CAAC;YACF,aAAa,CAAC,IAAI,CAAC,YAAY,SAAS,YAAY,CAAC,CAAC;YACtD,aAAa,CAAC,IAAI,CAAC,YAAY,WAAW,YAAY,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;IAED,OAAO;QACN,IAAI;QACJ,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI;QACjC,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE,UAAU;QAClB,cAAc,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3C,iBAAiB,EAAE,gBAAgB;QACnC,KAAK,EAAE;YACN,oEAAoE;YACpE,wFAAwF;YACxF,sDAAsD;SACtD;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { JXPRequest } from "../../types/jxp-config";
|
|
2
|
+
import type { McpAuthContext } from "./model_visibility";
|
|
3
|
+
/** Resolve MCP auth for docs playground: navbar key, then HttpOnly session. */
|
|
4
|
+
export declare function authenticateDocsMcpRequest(req: JXPRequest): Promise<McpAuthContext>;
|
|
5
|
+
//# sourceMappingURL=docs_auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs_auth.d.ts","sourceRoot":"","sources":["../../../src/libs/mcp/docs_auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AASzD,+EAA+E;AAC/E,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAmBzF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.authenticateDocsMcpRequest = authenticateDocsMcpRequest;
|
|
7
|
+
const restify_errors_1 = __importDefault(require("restify-errors"));
|
|
8
|
+
const docs_auth_1 = require("../docs-auth");
|
|
9
|
+
const auth_1 = require("./auth");
|
|
10
|
+
const config_1 = require("./config");
|
|
11
|
+
function headerApiKey(req) {
|
|
12
|
+
const raw = req.headers["x-api-key"];
|
|
13
|
+
if (Array.isArray(raw))
|
|
14
|
+
return raw[0]?.trim() || undefined;
|
|
15
|
+
return typeof raw === "string" && raw.trim() ? raw.trim() : undefined;
|
|
16
|
+
}
|
|
17
|
+
/** Resolve MCP auth for docs playground: navbar key, then HttpOnly session. */
|
|
18
|
+
async function authenticateDocsMcpRequest(req) {
|
|
19
|
+
const mcpConfig = (0, config_1.getMcpConfig)();
|
|
20
|
+
const fromHeader = headerApiKey(req);
|
|
21
|
+
if (fromHeader) {
|
|
22
|
+
req.headers["x-api-key"] = fromHeader;
|
|
23
|
+
return (0, auth_1.authenticateMcpRequest)(req, mcpConfig.requireApiKey);
|
|
24
|
+
}
|
|
25
|
+
const session = req.docsSession
|
|
26
|
+
?? (0, docs_auth_1.verifyDocsSession)(req);
|
|
27
|
+
if (session?.apikey) {
|
|
28
|
+
req.headers["x-api-key"] = session.apikey;
|
|
29
|
+
return (0, auth_1.authenticateMcpRequest)(req, mcpConfig.requireApiKey);
|
|
30
|
+
}
|
|
31
|
+
if (mcpConfig.requireApiKey) {
|
|
32
|
+
throw new restify_errors_1.default.UnauthorizedError("API key required (top bar or sign in)");
|
|
33
|
+
}
|
|
34
|
+
return (0, auth_1.authenticateMcpRequest)(req, false);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=docs_auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs_auth.js","sourceRoot":"","sources":["../../../src/libs/mcp/docs_auth.ts"],"names":[],"mappings":";;;;;AAcA,gEAmBC;AAjCD,oEAAoC;AAEpC,4CAAiD;AACjD,iCAAgD;AAEhD,qCAAwC;AAExC,SAAS,YAAY,CAAC,GAAe;IACpC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAC3D,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACvE,CAAC;AAED,+EAA+E;AACxE,KAAK,UAAU,0BAA0B,CAAC,GAAe;IAC/D,MAAM,SAAS,GAAG,IAAA,qBAAY,GAAE,CAAC;IACjC,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,UAAU,EAAE,CAAC;QAChB,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,UAAU,CAAC;QACtC,OAAO,IAAA,6BAAsB,EAAC,GAAqD,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;IAC/G,CAAC;IAED,MAAM,OAAO,GAAI,GAAyD,CAAC,WAAW;WAClF,IAAA,6BAAiB,EAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACrB,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;QAC1C,OAAO,IAAA,6BAAsB,EAAC,GAAqD,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;IAC/G,CAAC;IAED,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,wBAAM,CAAC,iBAAiB,CAAC,uCAAuC,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,IAAA,6BAAsB,EAAC,GAAqD,EAAE,KAAK,CAAC,CAAC;AAC7F,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load ESM-only packages from CommonJS output without TypeScript rewriting
|
|
3
|
+
* `import()` to `require()` (which breaks @modelcontextprotocol/* v2).
|
|
4
|
+
*/
|
|
5
|
+
export declare function dynamicImport<T = Record<string, unknown>>(specifier: string): Promise<T>;
|
|
6
|
+
//# sourceMappingURL=dynamic_import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic_import.d.ts","sourceRoot":"","sources":["../../../src/libs/mcp/dynamic_import.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAGxF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dynamicImport = dynamicImport;
|
|
4
|
+
/**
|
|
5
|
+
* Load ESM-only packages from CommonJS output without TypeScript rewriting
|
|
6
|
+
* `import()` to `require()` (which breaks @modelcontextprotocol/* v2).
|
|
7
|
+
*/
|
|
8
|
+
function dynamicImport(specifier) {
|
|
9
|
+
const fn = new Function("specifier", "return import(specifier)");
|
|
10
|
+
return fn(specifier);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=dynamic_import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic_import.js","sourceRoot":"","sources":["../../../src/libs/mcp/dynamic_import.ts"],"names":[],"mappings":";;AAIA,sCAGC;AAPD;;;GAGG;AACH,SAAgB,aAAa,CAA8B,SAAiB;IAC3E,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,WAAW,EAAE,0BAA0B,CAA8B,CAAC;IAC9F,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { JXPConfig } from "../../types/jxp-config";
|
|
2
|
+
import type { ModelRegistry } from "../builtin_models";
|
|
3
|
+
import { type McpAuthContext } from "./model_visibility";
|
|
4
|
+
export type McpToolResult = {
|
|
5
|
+
text: string;
|
|
6
|
+
isError?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function isAllowedMcpTool(name: string): boolean;
|
|
9
|
+
export declare function executeMcpTool(name: string, args: Record<string, unknown>, config: JXPConfig, models: ModelRegistry, auth: McpAuthContext): Promise<McpToolResult>;
|
|
10
|
+
//# sourceMappingURL=execute_tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute_tool.d.ts","sourceRoot":"","sources":["../../../src/libs/mcp/execute_tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIvD,OAAO,EAA4C,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGnG,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAUhE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,wBAAsB,cAAc,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,cAAc,GAClB,OAAO,CAAC,aAAa,CAAC,CAyDxB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isAllowedMcpTool = isAllowedMcpTool;
|
|
4
|
+
exports.executeMcpTool = executeMcpTool;
|
|
5
|
+
const config_1 = require("./config");
|
|
6
|
+
const context_1 = require("./context");
|
|
7
|
+
const describe_1 = require("./describe");
|
|
8
|
+
const model_visibility_1 = require("./model_visibility");
|
|
9
|
+
const read_service_1 = require("./read_service");
|
|
10
|
+
const ALLOWED_TOOLS = new Set([
|
|
11
|
+
"jxp_list_models",
|
|
12
|
+
"jxp_describe_model",
|
|
13
|
+
"jxp_find",
|
|
14
|
+
"jxp_count",
|
|
15
|
+
"jxp_export_csv",
|
|
16
|
+
]);
|
|
17
|
+
function isAllowedMcpTool(name) {
|
|
18
|
+
return ALLOWED_TOOLS.has(name);
|
|
19
|
+
}
|
|
20
|
+
async function executeMcpTool(name, args, config, models, auth) {
|
|
21
|
+
if (!isAllowedMcpTool(name)) {
|
|
22
|
+
return { text: `Unknown MCP tool: ${name}`, isError: true };
|
|
23
|
+
}
|
|
24
|
+
const mcpConfig = (0, config_1.getMcpConfig)();
|
|
25
|
+
try {
|
|
26
|
+
return await context_1.mcpAuthStorage.run(auth, async () => {
|
|
27
|
+
switch (name) {
|
|
28
|
+
case "jxp_list_models": {
|
|
29
|
+
const list = await (0, model_visibility_1.listVisibleModels)(models, auth, mcpConfig);
|
|
30
|
+
return { text: JSON.stringify(list, null, 2) };
|
|
31
|
+
}
|
|
32
|
+
case "jxp_describe_model": {
|
|
33
|
+
const slug = String(args.model ?? "");
|
|
34
|
+
if (!slug)
|
|
35
|
+
throw new Error("model is required");
|
|
36
|
+
const Model = models[slug];
|
|
37
|
+
if (!Model)
|
|
38
|
+
throw new Error(`Model "${slug}" not found`);
|
|
39
|
+
await (0, model_visibility_1.assertModelVisibleMcp)(slug, Model, auth, mcpConfig);
|
|
40
|
+
return { text: JSON.stringify((0, describe_1.describeModelJson)(slug, Model), null, 2) };
|
|
41
|
+
}
|
|
42
|
+
case "jxp_find": {
|
|
43
|
+
const result = await (0, read_service_1.mcpFind)(models, config, auth, args);
|
|
44
|
+
return {
|
|
45
|
+
text: typeof result === "string" ? result : JSON.stringify(result, null, 2),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
case "jxp_count": {
|
|
49
|
+
const result = await (0, read_service_1.mcpCount)(models, config, auth, args);
|
|
50
|
+
return { text: JSON.stringify(result, null, 2) };
|
|
51
|
+
}
|
|
52
|
+
case "jxp_export_csv": {
|
|
53
|
+
const csv = await (0, read_service_1.mcpExportCsv)(models, config, auth, args);
|
|
54
|
+
return { text: csv };
|
|
55
|
+
}
|
|
56
|
+
default:
|
|
57
|
+
return { text: `Unknown MCP tool: ${name}`, isError: true };
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
return { text: err instanceof Error ? err.message : String(err), isError: true };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=execute_tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute_tool.js","sourceRoot":"","sources":["../../../src/libs/mcp/execute_tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# JXP MCP usage guide
|
|
2
|
+
|
|
3
|
+
Read-only access to JXP REST data via five fixed tools. Permissions match the authenticated user's API key.
|
|
4
|
+
|
|
5
|
+
## Workflow
|
|
6
|
+
|
|
7
|
+
1. **`jxp_list_models`** — discover model slugs available to this caller.
|
|
8
|
+
2. **`jxp_describe_model`** — field types, indexed/filterable fields, link/populate hints.
|
|
9
|
+
3. **`jxp_count`** — check result size before fetching (especially large collections).
|
|
10
|
+
4. **`jxp_find`** — list or get by `id`; always set `fields` and a low `limit`.
|
|
11
|
+
5. **`jxp_export_csv`** — small CSV exports when JSON is awkward; no populate.
|
|
12
|
+
|
|
13
|
+
Never guess model names. Never fetch large collections without `fields` and `limit`.
|
|
14
|
+
|
|
15
|
+
## Query parameters (jxp_find / jxp_count / jxp_export_csv)
|
|
16
|
+
|
|
17
|
+
### filter
|
|
18
|
+
|
|
19
|
+
Mongo-style filter object. Examples:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{ "filter": { "email": "user@example.com" } }
|
|
23
|
+
{ "filter": { "created": { "$gte": "2024-01-01" } } }
|
|
24
|
+
{ "filter": { "status": { "$in": ["active", "trial"] } } }
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Use `jxp_describe_model` to see indexed fields worth filtering on.
|
|
28
|
+
|
|
29
|
+
### search
|
|
30
|
+
|
|
31
|
+
Full-text or field search (same as REST `?search=`).
|
|
32
|
+
|
|
33
|
+
### populate
|
|
34
|
+
|
|
35
|
+
Link expansion: `"populate[user]=name,email"` or object `{ "user": "name,email" }`.
|
|
36
|
+
Autopopulate is disabled for MCP by default (`MCP_DISABLE_AUTOPOPULATE=true`).
|
|
37
|
+
|
|
38
|
+
### fields
|
|
39
|
+
|
|
40
|
+
Comma-separated projection — **always use** for list queries:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{ "model": "reader", "fields": "_id,email,name", "limit": 10 }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### sort, limit, page, skip
|
|
47
|
+
|
|
48
|
+
- `limit` — defaults to MCP default; hard-capped at MCP max.
|
|
49
|
+
- `page` / `skip` — pagination.
|
|
50
|
+
- `sort` — e.g. `-created` for newest first.
|
|
51
|
+
|
|
52
|
+
## Limits and safety
|
|
53
|
+
|
|
54
|
+
- MCP enforces stricter limits than HTTP (`MCP_DEFAULT_LIMIT`, `MCP_MAX_LIMIT`).
|
|
55
|
+
- JSON responses are capped (`MCP_MAX_RESPONSE_SIZE`); long strings are truncated.
|
|
56
|
+
- CSV exports are capped (`MCP_MAX_CSV_SIZE`).
|
|
57
|
+
- **Read-only** — no create, update, delete, aggregate, or stored procedures via MCP.
|
|
58
|
+
|
|
59
|
+
## Hidden models
|
|
60
|
+
|
|
61
|
+
Built-in auth collections (`user`, `apikey`, `token`, etc.) and `internal: true` schemas are hidden unless whitelisted via `MCP_MODEL_WHITELIST`. Blacklist always wins.
|
|
62
|
+
|
|
63
|
+
## Single document by id
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{ "model": "reader", "id": "507f1f77bcf86cd799439011" }
|
|
67
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { JXPConfig } from "../../types/jxp-config";
|
|
2
|
+
import type { McpConfig } from "./config";
|
|
3
|
+
export declare const MCP_GUIDE_URI = "jxp://guide";
|
|
4
|
+
export declare const MCP_GUIDE_RESOURCE_NAME = "jxp-guide";
|
|
5
|
+
export interface McpGuideContext {
|
|
6
|
+
config: JXPConfig;
|
|
7
|
+
mcpConfig: McpConfig;
|
|
8
|
+
}
|
|
9
|
+
export declare function loadGuideFiles(paths: string[]): string[];
|
|
10
|
+
export declare function buildMcpGuideMarkdown(ctx: McpGuideContext): string;
|
|
11
|
+
export declare function buildMcpInstructions(ctx: McpGuideContext): string;
|
|
12
|
+
/** Clear cached guide (for tests). */
|
|
13
|
+
export declare function clearMcpGuideCache(): void;
|
|
14
|
+
//# sourceMappingURL=guides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guides.d.ts","sourceRoot":"","sources":["../../../src/libs/mcp/guides.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAC3C,eAAO,MAAM,uBAAuB,cAAc,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;CACrB;AA8BD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAkBxD;AAcD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAsBlE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CA8BjE;AAED,sCAAsC;AACtC,wBAAgB,kBAAkB,IAAI,IAAI,CAGzC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MCP_GUIDE_RESOURCE_NAME = exports.MCP_GUIDE_URI = void 0;
|
|
7
|
+
exports.loadGuideFiles = loadGuideFiles;
|
|
8
|
+
exports.buildMcpGuideMarkdown = buildMcpGuideMarkdown;
|
|
9
|
+
exports.buildMcpInstructions = buildMcpInstructions;
|
|
10
|
+
exports.clearMcpGuideCache = clearMcpGuideCache;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
exports.MCP_GUIDE_URI = "jxp://guide";
|
|
14
|
+
exports.MCP_GUIDE_RESOURCE_NAME = "jxp-guide";
|
|
15
|
+
let cachedGuideMarkdown = null;
|
|
16
|
+
let cachedGuideKey = null;
|
|
17
|
+
function resolveGuidePath(filePath) {
|
|
18
|
+
if (path_1.default.isAbsolute(filePath))
|
|
19
|
+
return filePath;
|
|
20
|
+
return path_1.default.resolve(process.cwd(), filePath);
|
|
21
|
+
}
|
|
22
|
+
function defaultGuidePath() {
|
|
23
|
+
return path_1.default.join(__dirname, "guides", "default.md");
|
|
24
|
+
}
|
|
25
|
+
function collectGuideFilePaths(config) {
|
|
26
|
+
const paths = [];
|
|
27
|
+
const fromConfig = config.mcp?.guideFiles || [];
|
|
28
|
+
for (const p of fromConfig) {
|
|
29
|
+
if (p?.trim())
|
|
30
|
+
paths.push(p.trim());
|
|
31
|
+
}
|
|
32
|
+
const fromEnv = process.env.MCP_GUIDE_FILES?.trim();
|
|
33
|
+
if (fromEnv) {
|
|
34
|
+
for (const p of fromEnv.split(",")) {
|
|
35
|
+
const t = p.trim();
|
|
36
|
+
if (t)
|
|
37
|
+
paths.push(t);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return paths;
|
|
41
|
+
}
|
|
42
|
+
function loadGuideFiles(paths) {
|
|
43
|
+
const parts = [];
|
|
44
|
+
const defaultPath = defaultGuidePath();
|
|
45
|
+
if (fs_1.default.existsSync(defaultPath)) {
|
|
46
|
+
parts.push(fs_1.default.readFileSync(defaultPath, "utf8"));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.warn(new Date(), `MCP default guide not found at ${defaultPath}`);
|
|
50
|
+
}
|
|
51
|
+
for (const filePath of paths) {
|
|
52
|
+
const resolved = resolveGuidePath(filePath);
|
|
53
|
+
try {
|
|
54
|
+
parts.push(fs_1.default.readFileSync(resolved, "utf8"));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
console.warn(new Date(), `MCP guide file not found: ${resolved}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return parts;
|
|
61
|
+
}
|
|
62
|
+
function guideCacheKey(ctx) {
|
|
63
|
+
return JSON.stringify({
|
|
64
|
+
files: collectGuideFilePaths(ctx.config),
|
|
65
|
+
append: process.env.MCP_INSTRUCTIONS_APPEND || "",
|
|
66
|
+
appInstructions: ctx.config.mcp?.instructions || "",
|
|
67
|
+
limits: {
|
|
68
|
+
default: ctx.mcpConfig.defaultLimit,
|
|
69
|
+
max: ctx.mcpConfig.maxLimit,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function buildMcpGuideMarkdown(ctx) {
|
|
74
|
+
const key = guideCacheKey(ctx);
|
|
75
|
+
if (cachedGuideMarkdown !== null && cachedGuideKey === key) {
|
|
76
|
+
return cachedGuideMarkdown;
|
|
77
|
+
}
|
|
78
|
+
const parts = loadGuideFiles(collectGuideFilePaths(ctx.config));
|
|
79
|
+
const runtime = [
|
|
80
|
+
"",
|
|
81
|
+
"## Runtime limits",
|
|
82
|
+
"",
|
|
83
|
+
`- Default \`limit\`: ${ctx.mcpConfig.defaultLimit}`,
|
|
84
|
+
`- Max \`limit\`: ${ctx.mcpConfig.maxLimit}`,
|
|
85
|
+
`- Max JSON response: ${ctx.mcpConfig.maxResponseBytes} bytes`,
|
|
86
|
+
`- Max CSV response: ${ctx.mcpConfig.maxCsvBytes} bytes`,
|
|
87
|
+
`- String truncation at: ${ctx.mcpConfig.truncateStringsAt} characters`,
|
|
88
|
+
"",
|
|
89
|
+
];
|
|
90
|
+
cachedGuideMarkdown = [...parts, runtime.join("\n")].filter(Boolean).join("\n\n---\n\n");
|
|
91
|
+
cachedGuideKey = key;
|
|
92
|
+
return cachedGuideMarkdown;
|
|
93
|
+
}
|
|
94
|
+
function buildMcpInstructions(ctx) {
|
|
95
|
+
const { mcpConfig } = ctx;
|
|
96
|
+
const lines = [
|
|
97
|
+
"You have read-only access to a JXP REST API via MCP tools.",
|
|
98
|
+
"",
|
|
99
|
+
"Required workflow:",
|
|
100
|
+
"1. jxp_list_models — discover available model slugs for this user.",
|
|
101
|
+
"2. jxp_describe_model — inspect fields, filters, and populate hints before querying.",
|
|
102
|
+
"3. jxp_count — estimate result size on large collections before jxp_find.",
|
|
103
|
+
"4. jxp_find — use fields + low limit; pass id for a single document.",
|
|
104
|
+
"5. jxp_export_csv — small tabular exports only (no populate).",
|
|
105
|
+
"",
|
|
106
|
+
`Limits: default limit ${mcpConfig.defaultLimit}, max ${mcpConfig.maxLimit}. Responses are size-capped; strings may be truncated.`,
|
|
107
|
+
"Filter syntax matches MongoDB ($gte, $in, $regex, etc.). Use populate[field]=a,b for links.",
|
|
108
|
+
"Do not mutate data — MCP is read-only.",
|
|
109
|
+
"",
|
|
110
|
+
"For the full guide, read MCP resource jxp-guide (uri jxp://guide).",
|
|
111
|
+
];
|
|
112
|
+
const appInstructions = ctx.config.mcp?.instructions?.trim();
|
|
113
|
+
if (appInstructions) {
|
|
114
|
+
lines.push("", appInstructions);
|
|
115
|
+
}
|
|
116
|
+
const envAppend = process.env.MCP_INSTRUCTIONS_APPEND?.trim();
|
|
117
|
+
if (envAppend) {
|
|
118
|
+
lines.push("", envAppend);
|
|
119
|
+
}
|
|
120
|
+
return lines.join("\n");
|
|
121
|
+
}
|
|
122
|
+
/** Clear cached guide (for tests). */
|
|
123
|
+
function clearMcpGuideCache() {
|
|
124
|
+
cachedGuideMarkdown = null;
|
|
125
|
+
cachedGuideKey = null;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=guides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guides.js","sourceRoot":"","sources":["../../../src/libs/mcp/guides.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Model } from "mongoose";
|
|
2
|
+
import type { ModelRegistry } from "../builtin_models";
|
|
3
|
+
import type { McpConfig } from "./config";
|
|
4
|
+
export interface McpAuthUser {
|
|
5
|
+
_id: unknown;
|
|
6
|
+
email?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
admin?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface McpAuthContext {
|
|
11
|
+
user: McpAuthUser | null;
|
|
12
|
+
groups: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare function isDefaultHiddenModel(slug: string, model: Model<unknown>, config: McpConfig): boolean;
|
|
15
|
+
export declare function isVisibilityOverridden(slug: string, config: McpConfig): boolean;
|
|
16
|
+
export declare function isBlacklisted(slug: string, config: McpConfig): boolean;
|
|
17
|
+
export declare function canReadModel(auth: McpAuthContext, model: Model<unknown>, itemId?: string): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Whether a model should appear in MCP list/describe and accept read tools.
|
|
20
|
+
* Whitelist overrides default-hidden only; never grants read permission.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isModelVisibleMcp(slug: string, model: Model<unknown>, auth: McpAuthContext, config: McpConfig, itemId?: string): Promise<boolean>;
|
|
23
|
+
export declare function assertModelVisibleMcp(slug: string, model: Model<unknown>, auth: McpAuthContext, config: McpConfig, itemId?: string): Promise<void>;
|
|
24
|
+
export declare function listVisibleModels(models: ModelRegistry, auth: McpAuthContext, config: McpConfig): Promise<{
|
|
25
|
+
slug: string;
|
|
26
|
+
collection: string;
|
|
27
|
+
permissions: {
|
|
28
|
+
read: boolean;
|
|
29
|
+
};
|
|
30
|
+
}[]>;
|
|
31
|
+
//# sourceMappingURL=model_visibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model_visibility.d.ts","sourceRoot":"","sources":["../../../src/libs/mcp/model_visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAI1C,MAAM,WAAW,WAAW;IAC3B,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAGpG;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAE/E;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAEtE;AAED,wBAAsB,YAAY,CACjC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EACrB,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACtC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EACrB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED,wBAAsB,qBAAqB,CAC1C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EACrB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAsB,iBAAiB,CACtC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,SAAS,GACf,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,EAAE,CAAC,CAcjF"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isDefaultHiddenModel = isDefaultHiddenModel;
|
|
4
|
+
exports.isVisibilityOverridden = isVisibilityOverridden;
|
|
5
|
+
exports.isBlacklisted = isBlacklisted;
|
|
6
|
+
exports.canReadModel = canReadModel;
|
|
7
|
+
exports.isModelVisibleMcp = isModelVisibleMcp;
|
|
8
|
+
exports.assertModelVisibleMcp = assertModelVisibleMcp;
|
|
9
|
+
exports.listVisibleModels = listVisibleModels;
|
|
10
|
+
const builtin_models_1 = require("../builtin_models");
|
|
11
|
+
const security = require("../security");
|
|
12
|
+
function isDefaultHiddenModel(slug, model, config) {
|
|
13
|
+
if ((0, builtin_models_1.isInternalModel)(model))
|
|
14
|
+
return true;
|
|
15
|
+
return config.defaultHiddenModels.has(slug.toLowerCase());
|
|
16
|
+
}
|
|
17
|
+
function isVisibilityOverridden(slug, config) {
|
|
18
|
+
return config.modelWhitelist.has(slug.toLowerCase());
|
|
19
|
+
}
|
|
20
|
+
function isBlacklisted(slug, config) {
|
|
21
|
+
return config.modelBlacklist.has(slug.toLowerCase());
|
|
22
|
+
}
|
|
23
|
+
async function canReadModel(auth, model, itemId) {
|
|
24
|
+
try {
|
|
25
|
+
await security.check_perms(auth.user, auth.groups, model, "r", itemId);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Whether a model should appear in MCP list/describe and accept read tools.
|
|
34
|
+
* Whitelist overrides default-hidden only; never grants read permission.
|
|
35
|
+
*/
|
|
36
|
+
async function isModelVisibleMcp(slug, model, auth, config, itemId) {
|
|
37
|
+
if (!(await canReadModel(auth, model, itemId)))
|
|
38
|
+
return false;
|
|
39
|
+
if (isBlacklisted(slug, config))
|
|
40
|
+
return false;
|
|
41
|
+
if (isDefaultHiddenModel(slug, model, config) && !isVisibilityOverridden(slug, config)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
async function assertModelVisibleMcp(slug, model, auth, config, itemId) {
|
|
47
|
+
const errors = require("restify-errors");
|
|
48
|
+
if (!(await canReadModel(auth, model, itemId))) {
|
|
49
|
+
throw new errors.ForbiddenError(`No read access to model "${slug}"`);
|
|
50
|
+
}
|
|
51
|
+
if (isBlacklisted(slug, config)) {
|
|
52
|
+
throw new errors.ForbiddenError(`Model "${slug}" is not available via MCP`);
|
|
53
|
+
}
|
|
54
|
+
if (isDefaultHiddenModel(slug, model, config) && !isVisibilityOverridden(slug, config)) {
|
|
55
|
+
throw new errors.NotFoundError(`Model "${slug}" not found`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function listVisibleModels(models, auth, config) {
|
|
59
|
+
const slugs = Object.keys(models).sort();
|
|
60
|
+
const out = [];
|
|
61
|
+
for (const slug of slugs) {
|
|
62
|
+
const model = models[slug];
|
|
63
|
+
if (await isModelVisibleMcp(slug, model, auth, config)) {
|
|
64
|
+
out.push({
|
|
65
|
+
slug,
|
|
66
|
+
collection: model.collection.name,
|
|
67
|
+
permissions: { read: true },
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=model_visibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model_visibility.js","sourceRoot":"","sources":["../../../src/libs/mcp/model_visibility.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Server } from "restify";
|
|
2
|
+
import type { JXPConfig } from "../../types/jxp-config";
|
|
3
|
+
import type { ModelRegistry } from "../builtin_models";
|
|
4
|
+
import { isMcpEnabled } from "./config";
|
|
5
|
+
export declare function mountMcp(server: Server, opts: {
|
|
6
|
+
config: JXPConfig;
|
|
7
|
+
models: ModelRegistry;
|
|
8
|
+
}): void;
|
|
9
|
+
export { isMcpEnabled };
|
|
10
|
+
//# sourceMappingURL=mount.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../../src/libs/mcp/mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAgB,YAAY,EAAE,MAAM,UAAU,CAAC;AAgEtD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG,IAAI,CAwBjG;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isMcpEnabled = void 0;
|
|
4
|
+
exports.mountMcp = mountMcp;
|
|
5
|
+
const config_1 = require("./config");
|
|
6
|
+
Object.defineProperty(exports, "isMcpEnabled", { enumerable: true, get: function () { return config_1.isMcpEnabled; } });
|
|
7
|
+
const auth_1 = require("./auth");
|
|
8
|
+
const context_1 = require("./context");
|
|
9
|
+
const server_1 = require("./server");
|
|
10
|
+
const dynamic_import_1 = require("./dynamic_import");
|
|
11
|
+
let serverPromise = null;
|
|
12
|
+
let nodeTransportModule = null;
|
|
13
|
+
async function getMcpServer(config, models) {
|
|
14
|
+
if (!serverPromise) {
|
|
15
|
+
serverPromise = (0, server_1.createMcpServer)(config, models);
|
|
16
|
+
}
|
|
17
|
+
return serverPromise;
|
|
18
|
+
}
|
|
19
|
+
async function createStatelessTransport() {
|
|
20
|
+
if (!nodeTransportModule) {
|
|
21
|
+
nodeTransportModule = (0, dynamic_import_1.dynamicImport)("@modelcontextprotocol/node");
|
|
22
|
+
}
|
|
23
|
+
const { NodeStreamableHTTPServerTransport } = await nodeTransportModule;
|
|
24
|
+
return new NodeStreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
25
|
+
}
|
|
26
|
+
async function handleMcpRequest(req, res, parsedBody, config, models) {
|
|
27
|
+
const mcpConfig = (0, config_1.getMcpConfig)();
|
|
28
|
+
let auth;
|
|
29
|
+
try {
|
|
30
|
+
auth = await (0, auth_1.authenticateMcpRequest)(req, mcpConfig.requireApiKey);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
const status = err.statusCode || 401;
|
|
34
|
+
res.writeHead(status, { "Content-Type": "application/json" });
|
|
35
|
+
res.end(JSON.stringify({ error: err.message || String(err) }));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const mcpServer = await getMcpServer(config, models);
|
|
39
|
+
const transport = await createStatelessTransport();
|
|
40
|
+
await mcpServer.connect(transport);
|
|
41
|
+
await context_1.mcpAuthStorage.run(auth, async () => {
|
|
42
|
+
await transport.handleRequest(req, res, parsedBody);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function mountMcp(server, opts) {
|
|
46
|
+
if (!(0, config_1.isMcpEnabled)()) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const mcpPath = (0, config_1.getMcpConfig)().path;
|
|
50
|
+
console.log(new Date(), `MCP enabled at ${mcpPath}`);
|
|
51
|
+
const handler = async (req, res) => {
|
|
52
|
+
try {
|
|
53
|
+
const nodeReq = req;
|
|
54
|
+
const nodeRes = res;
|
|
55
|
+
await handleMcpRequest(nodeReq, nodeRes, req.body, opts.config, opts.models);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
59
|
+
if (!res.headersSent) {
|
|
60
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
61
|
+
res.end(JSON.stringify({ error: message }));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
server.get(mcpPath, handler);
|
|
66
|
+
server.post(mcpPath, handler);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=mount.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../../../src/libs/mcp/mount.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { JXPConfig } from "../../types/jxp-config";
|
|
2
|
+
import type { ModelRegistry } from "../builtin_models";
|
|
3
|
+
import { type McpAuthContext } from "./model_visibility";
|
|
4
|
+
export interface FindParams {
|
|
5
|
+
model: string;
|
|
6
|
+
id?: string;
|
|
7
|
+
filter?: Record<string, unknown>;
|
|
8
|
+
search?: string | Record<string, unknown>;
|
|
9
|
+
populate?: string | Record<string, string>;
|
|
10
|
+
fields?: string;
|
|
11
|
+
sort?: string;
|
|
12
|
+
limit?: number;
|
|
13
|
+
page?: number;
|
|
14
|
+
skip?: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function mcpFind(models: ModelRegistry, baseConfig: JXPConfig, auth: McpAuthContext, params: FindParams): Promise<unknown>;
|
|
17
|
+
export declare function mcpCount(models: ModelRegistry, baseConfig: JXPConfig, auth: McpAuthContext, params: {
|
|
18
|
+
model: string;
|
|
19
|
+
filter?: Record<string, unknown>;
|
|
20
|
+
search?: string | Record<string, unknown>;
|
|
21
|
+
}): Promise<unknown>;
|
|
22
|
+
export declare function mcpExportCsv(models: ModelRegistry, baseConfig: JXPConfig, auth: McpAuthContext, params: Omit<FindParams, "id">): Promise<string>;
|
|
23
|
+
//# sourceMappingURL=read_service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read_service.d.ts","sourceRoot":"","sources":["../../../src/libs/mcp/read_service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAevD,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIhF,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AA+DD,wBAAsB,OAAO,CAC5B,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,SAAS,EACrB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,UAAU,GAChB,OAAO,CAAC,OAAO,CAAC,CAyBlB;AAED,wBAAsB,QAAQ,CAC7B,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,SAAS,EACrB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACpG,OAAO,CAAC,OAAO,CAAC,CAkBlB;AAED,wBAAsB,YAAY,CACjC,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,SAAS,EACrB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAC5B,OAAO,CAAC,MAAM,CAAC,CA0BjB"}
|