jxp 4.2.0 → 5.0.2

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.
Files changed (104) hide show
  1. package/.env.sample +16 -0
  2. package/README.md +2 -0
  3. package/dist/bin/mcp-stdio-bridge.d.ts +3 -0
  4. package/dist/bin/mcp-stdio-bridge.d.ts.map +1 -0
  5. package/dist/bin/mcp-stdio-bridge.js +87 -0
  6. package/dist/bin/mcp-stdio-bridge.js.map +1 -0
  7. package/dist/bin/server.d.ts.map +1 -1
  8. package/dist/bin/server.js +2 -1
  9. package/dist/bin/server.js.map +1 -1
  10. package/dist/globals.d.ts +2 -2
  11. package/dist/globals.d.ts.map +1 -1
  12. package/dist/libs/docs-auth.d.ts.map +1 -1
  13. package/dist/libs/docs-auth.js +4 -2
  14. package/dist/libs/docs-auth.js.map +1 -1
  15. package/dist/libs/docs.js +74 -43
  16. package/dist/libs/docs.js.map +1 -1
  17. package/dist/libs/jxp.d.ts.map +1 -1
  18. package/dist/libs/jxp.js +22 -321
  19. package/dist/libs/jxp.js.map +1 -1
  20. package/dist/libs/load-config.d.ts +1 -1
  21. package/dist/libs/load-config.d.ts.map +1 -1
  22. package/dist/libs/load-config.js +2 -2
  23. package/dist/libs/load-config.js.map +1 -1
  24. package/dist/libs/mcp/auth.d.ts +4 -0
  25. package/dist/libs/mcp/auth.d.ts.map +1 -0
  26. package/dist/libs/mcp/auth.js +49 -0
  27. package/dist/libs/mcp/auth.js.map +1 -0
  28. package/dist/libs/mcp/config.d.ts +21 -0
  29. package/dist/libs/mcp/config.d.ts.map +1 -0
  30. package/dist/libs/mcp/config.js +66 -0
  31. package/dist/libs/mcp/config.js.map +1 -0
  32. package/dist/libs/mcp/context.d.ts +5 -0
  33. package/dist/libs/mcp/context.d.ts.map +1 -0
  34. package/dist/libs/mcp/context.js +14 -0
  35. package/dist/libs/mcp/context.js.map +1 -0
  36. package/dist/libs/mcp/describe.d.ts +13 -0
  37. package/dist/libs/mcp/describe.d.ts.map +1 -0
  38. package/dist/libs/mcp/describe.js +36 -0
  39. package/dist/libs/mcp/describe.js.map +1 -0
  40. package/dist/libs/mcp/docs_auth.d.ts +5 -0
  41. package/dist/libs/mcp/docs_auth.d.ts.map +1 -0
  42. package/dist/libs/mcp/docs_auth.js +36 -0
  43. package/dist/libs/mcp/docs_auth.js.map +1 -0
  44. package/dist/libs/mcp/dynamic_import.d.ts +6 -0
  45. package/dist/libs/mcp/dynamic_import.d.ts.map +1 -0
  46. package/dist/libs/mcp/dynamic_import.js +12 -0
  47. package/dist/libs/mcp/dynamic_import.js.map +1 -0
  48. package/dist/libs/mcp/execute_tool.d.ts +10 -0
  49. package/dist/libs/mcp/execute_tool.d.ts.map +1 -0
  50. package/dist/libs/mcp/execute_tool.js +65 -0
  51. package/dist/libs/mcp/execute_tool.js.map +1 -0
  52. package/dist/libs/mcp/guides/default.md +67 -0
  53. package/dist/libs/mcp/guides.d.ts +14 -0
  54. package/dist/libs/mcp/guides.d.ts.map +1 -0
  55. package/dist/libs/mcp/guides.js +127 -0
  56. package/dist/libs/mcp/guides.js.map +1 -0
  57. package/dist/libs/mcp/model_visibility.d.ts +31 -0
  58. package/dist/libs/mcp/model_visibility.d.ts.map +1 -0
  59. package/dist/libs/mcp/model_visibility.js +73 -0
  60. package/dist/libs/mcp/model_visibility.js.map +1 -0
  61. package/dist/libs/mcp/mount.d.ts +10 -0
  62. package/dist/libs/mcp/mount.d.ts.map +1 -0
  63. package/dist/libs/mcp/mount.js +68 -0
  64. package/dist/libs/mcp/mount.js.map +1 -0
  65. package/dist/libs/mcp/read_service.d.ts +23 -0
  66. package/dist/libs/mcp/read_service.d.ts.map +1 -0
  67. package/dist/libs/mcp/read_service.js +141 -0
  68. package/dist/libs/mcp/read_service.js.map +1 -0
  69. package/dist/libs/mcp/server.d.ts +23 -0
  70. package/dist/libs/mcp/server.d.ts.map +1 -0
  71. package/dist/libs/mcp/server.js +111 -0
  72. package/dist/libs/mcp/server.js.map +1 -0
  73. package/dist/libs/read_handlers.d.ts +13 -0
  74. package/dist/libs/read_handlers.d.ts.map +1 -0
  75. package/dist/libs/read_handlers.js +381 -0
  76. package/dist/libs/read_handlers.js.map +1 -0
  77. package/dist/libs/request_log.d.ts +2 -0
  78. package/dist/libs/request_log.d.ts.map +1 -1
  79. package/dist/libs/request_log.js +7 -1
  80. package/dist/libs/request_log.js.map +1 -1
  81. package/dist/libs/schema.d.ts.map +1 -1
  82. package/dist/libs/schema.js +5 -8
  83. package/dist/libs/schema.js.map +1 -1
  84. package/dist/libs/schema_description.d.ts +7 -1
  85. package/dist/libs/schema_description.d.ts.map +1 -1
  86. package/dist/libs/schema_description.js +24 -25
  87. package/dist/libs/schema_description.js.map +1 -1
  88. package/dist/libs/schema_serialize.d.ts +3 -0
  89. package/dist/libs/schema_serialize.d.ts.map +1 -0
  90. package/dist/libs/schema_serialize.js +45 -0
  91. package/dist/libs/schema_serialize.js.map +1 -0
  92. package/dist/types/jxp-config.d.ts +7 -0
  93. package/dist/types/jxp-config.d.ts.map +1 -1
  94. package/docs/changelog.md +61 -0
  95. package/docs/index.md +1 -0
  96. package/docs/mcp.md +134 -0
  97. package/mkdocs.yml +1 -0
  98. package/package.json +31 -26
  99. package/templates/assets/docs.css +107 -0
  100. package/templates/assets/mcp-console.js +343 -0
  101. package/templates/index.pug +37 -0
  102. package/templates/mcp.pug +112 -0
  103. package/templates/navbar.pug +2 -0
  104. package/templates/sidebar.pug +4 -0
@@ -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"}