@forestadmin/mcp-server 0.1.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/README.md +128 -0
- package/dist/__mocks__/version.d.ts +3 -0
- package/dist/__mocks__/version.js +7 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +14 -0
- package/dist/factory.d.ts +51 -0
- package/dist/factory.js +40 -0
- package/dist/forest-oauth-provider.d.ts +44 -0
- package/dist/forest-oauth-provider.js +253 -0
- package/dist/forest-oauth-provider.test.d.ts +2 -0
- package/dist/forest-oauth-provider.test.js +590 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +13 -0
- package/dist/mcp-paths.d.ts +5 -0
- package/dist/mcp-paths.js +11 -0
- package/dist/polyfills.d.ts +12 -0
- package/dist/polyfills.js +27 -0
- package/dist/schemas/filter.d.ts +4 -0
- package/dist/schemas/filter.js +70 -0
- package/dist/schemas/filter.test.d.ts +2 -0
- package/dist/schemas/filter.test.js +234 -0
- package/dist/server.d.ts +87 -0
- package/dist/server.js +341 -0
- package/dist/server.test.d.ts +2 -0
- package/dist/server.test.js +901 -0
- package/dist/test-utils/mock-server.d.ts +62 -0
- package/dist/test-utils/mock-server.js +187 -0
- package/dist/tools/list.d.ts +4 -0
- package/dist/tools/list.js +98 -0
- package/dist/tools/list.test.d.ts +2 -0
- package/dist/tools/list.test.js +385 -0
- package/dist/utils/activity-logs-creator.d.ts +9 -0
- package/dist/utils/activity-logs-creator.js +65 -0
- package/dist/utils/activity-logs-creator.test.d.ts +2 -0
- package/dist/utils/activity-logs-creator.test.js +239 -0
- package/dist/utils/agent-caller.d.ts +13 -0
- package/dist/utils/agent-caller.js +24 -0
- package/dist/utils/agent-caller.test.d.ts +2 -0
- package/dist/utils/agent-caller.test.js +102 -0
- package/dist/utils/error-parser.d.ts +10 -0
- package/dist/utils/error-parser.js +56 -0
- package/dist/utils/error-parser.test.d.ts +2 -0
- package/dist/utils/error-parser.test.js +124 -0
- package/dist/utils/schema-fetcher.d.ts +53 -0
- package/dist/utils/schema-fetcher.js +85 -0
- package/dist/utils/schema-fetcher.test.d.ts +2 -0
- package/dist/utils/schema-fetcher.test.js +212 -0
- package/dist/utils/sse-error-logger.d.ts +14 -0
- package/dist/utils/sse-error-logger.js +112 -0
- package/dist/utils/tool-with-logging.d.ts +44 -0
- package/dist/utils/tool-with-logging.js +66 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.js +43 -0
- package/package.json +49 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
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.isMcpRoute = exports.MCP_PATHS = exports.ForestMCPServer = void 0;
|
|
7
|
+
// Library exports only - no side effects
|
|
8
|
+
var server_1 = require("./server");
|
|
9
|
+
Object.defineProperty(exports, "ForestMCPServer", { enumerable: true, get: function () { return __importDefault(server_1).default; } });
|
|
10
|
+
var mcp_paths_1 = require("./mcp-paths");
|
|
11
|
+
Object.defineProperty(exports, "MCP_PATHS", { enumerable: true, get: function () { return mcp_paths_1.MCP_PATHS; } });
|
|
12
|
+
Object.defineProperty(exports, "isMcpRoute", { enumerable: true, get: function () { return mcp_paths_1.isMcpRoute; } });
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEseUNBQXlDO0FBQ3pDLG1DQUFzRDtBQUE3QywwSEFBQSxPQUFPLE9BQW1CO0FBRW5DLHlDQUFvRDtBQUEzQyxzR0FBQSxTQUFTLE9BQUE7QUFBRSx1R0FBQSxVQUFVLE9BQUEifQ==
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MCP_PATHS = void 0;
|
|
4
|
+
exports.isMcpRoute = isMcpRoute;
|
|
5
|
+
/** MCP-specific paths that should be handled by the MCP server */
|
|
6
|
+
exports.MCP_PATHS = ['/.well-known/', '/oauth/', '/mcp'];
|
|
7
|
+
/** Check if a URL is an MCP route */
|
|
8
|
+
function isMcpRoute(url) {
|
|
9
|
+
return exports.MCP_PATHS.some(p => url === p || url.startsWith(p));
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLXBhdGhzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL21jcC1wYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFJQSxnQ0FFQztBQU5ELGtFQUFrRTtBQUNyRCxRQUFBLFNBQVMsR0FBRyxDQUFDLGVBQWUsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFFOUQscUNBQXFDO0FBQ3JDLFNBQWdCLFVBQVUsQ0FBQyxHQUFXO0lBQ3BDLE9BQU8saUJBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3RCxDQUFDIn0=
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polyfill for URL.canParse
|
|
3
|
+
*
|
|
4
|
+
* The MCP SDK's OAuth handler uses URL.canParse in Zod schema validation.
|
|
5
|
+
* Some environments (like certain Koa/Express proxy setups) may have a different
|
|
6
|
+
* URL implementation that doesn't include the canParse static method
|
|
7
|
+
* (added in Node.js 19.9.0 / 20.0.0).
|
|
8
|
+
*
|
|
9
|
+
* This polyfill must be imported BEFORE any MCP SDK imports.
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=polyfills.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Polyfill for URL.canParse
|
|
4
|
+
*
|
|
5
|
+
* The MCP SDK's OAuth handler uses URL.canParse in Zod schema validation.
|
|
6
|
+
* Some environments (like certain Koa/Express proxy setups) may have a different
|
|
7
|
+
* URL implementation that doesn't include the canParse static method
|
|
8
|
+
* (added in Node.js 19.9.0 / 20.0.0).
|
|
9
|
+
*
|
|
10
|
+
* This polyfill must be imported BEFORE any MCP SDK imports.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
// Check if URL.canParse exists on the global URL
|
|
14
|
+
if (typeof URL.canParse !== 'function') {
|
|
15
|
+
// Provide a fallback polyfill implementation
|
|
16
|
+
URL.canParse = (url, base) => {
|
|
17
|
+
try {
|
|
18
|
+
// eslint-disable-next-line no-new
|
|
19
|
+
new URL(url, base);
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9seWZpbGxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3BvbHlmaWxscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7OztHQVNHOztBQUVILGlEQUFpRDtBQUNqRCxJQUFJLE9BQU8sR0FBRyxDQUFDLFFBQVEsS0FBSyxVQUFVLEVBQUUsQ0FBQztJQUN2Qyw2Q0FBNkM7SUFDNUMsR0FBd0UsQ0FBQyxRQUFRLEdBQUcsQ0FDbkYsR0FBVyxFQUNYLElBQWEsRUFDSixFQUFFO1FBQ1gsSUFBSSxDQUFDO1lBQ0gsa0NBQWtDO1lBQ2xDLElBQUksR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUVuQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7SUFDSCxDQUFDLENBQUM7QUFDSixDQUFDIn0=
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const zod_1 = require("zod");
|
|
4
|
+
const operatorEnum = zod_1.z.enum([
|
|
5
|
+
'Equal',
|
|
6
|
+
'NotEqual',
|
|
7
|
+
'LessThan',
|
|
8
|
+
'GreaterThan',
|
|
9
|
+
'LessThanOrEqual',
|
|
10
|
+
'GreaterThanOrEqual',
|
|
11
|
+
'Match',
|
|
12
|
+
'NotContains',
|
|
13
|
+
'NotIContains',
|
|
14
|
+
'LongerThan',
|
|
15
|
+
'ShorterThan',
|
|
16
|
+
'IncludesAll',
|
|
17
|
+
'IncludesNone',
|
|
18
|
+
'Today',
|
|
19
|
+
'Yesterday',
|
|
20
|
+
'PreviousMonth',
|
|
21
|
+
'PreviousQuarter',
|
|
22
|
+
'PreviousWeek',
|
|
23
|
+
'PreviousYear',
|
|
24
|
+
'PreviousMonthToDate',
|
|
25
|
+
'PreviousQuarterToDate',
|
|
26
|
+
'PreviousWeekToDate',
|
|
27
|
+
'PreviousXDaysToDate',
|
|
28
|
+
'PreviousXDays',
|
|
29
|
+
'PreviousYearToDate',
|
|
30
|
+
'Present',
|
|
31
|
+
'Blank',
|
|
32
|
+
'Missing',
|
|
33
|
+
'In',
|
|
34
|
+
'NotIn',
|
|
35
|
+
'StartsWith',
|
|
36
|
+
'EndsWith',
|
|
37
|
+
'Contains',
|
|
38
|
+
'IStartsWith',
|
|
39
|
+
'IEndsWith',
|
|
40
|
+
'IContains',
|
|
41
|
+
'Like',
|
|
42
|
+
'ILike',
|
|
43
|
+
'Before',
|
|
44
|
+
'After',
|
|
45
|
+
'AfterXHoursAgo',
|
|
46
|
+
'BeforeXHoursAgo',
|
|
47
|
+
'Future',
|
|
48
|
+
'Past',
|
|
49
|
+
]);
|
|
50
|
+
const aggregatorEnum = zod_1.z.enum(['And', 'Or']);
|
|
51
|
+
// Leaf condition (e.g., { field: 'name', operator: 'Equal', value: 'John' })
|
|
52
|
+
const leafSchema = zod_1.z.object({
|
|
53
|
+
field: zod_1.z.string(),
|
|
54
|
+
operator: operatorEnum,
|
|
55
|
+
value: zod_1.z.unknown().optional(),
|
|
56
|
+
});
|
|
57
|
+
// Build nested branch schemas iteratively (avoids z.lazy() which causes $ref issues)
|
|
58
|
+
const MAX_NESTING_DEPTH = 3;
|
|
59
|
+
let conditionSchema = leafSchema;
|
|
60
|
+
for (let i = 0; i < MAX_NESTING_DEPTH; i += 1) {
|
|
61
|
+
conditionSchema = zod_1.z.union([
|
|
62
|
+
leafSchema,
|
|
63
|
+
zod_1.z.object({
|
|
64
|
+
aggregator: aggregatorEnum,
|
|
65
|
+
conditions: zod_1.z.array(conditionSchema),
|
|
66
|
+
}),
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
exports.default = Object.freeze(conditionSchema);
|
|
70
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NjaGVtYXMvZmlsdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQXdCO0FBRXhCLE1BQU0sWUFBWSxHQUFHLE9BQUMsQ0FBQyxJQUFJLENBQUM7SUFDMUIsT0FBTztJQUNQLFVBQVU7SUFDVixVQUFVO0lBQ1YsYUFBYTtJQUNiLGlCQUFpQjtJQUNqQixvQkFBb0I7SUFDcEIsT0FBTztJQUNQLGFBQWE7SUFDYixjQUFjO0lBQ2QsWUFBWTtJQUNaLGFBQWE7SUFDYixhQUFhO0lBQ2IsY0FBYztJQUNkLE9BQU87SUFDUCxXQUFXO0lBQ1gsZUFBZTtJQUNmLGlCQUFpQjtJQUNqQixjQUFjO0lBQ2QsY0FBYztJQUNkLHFCQUFxQjtJQUNyQix1QkFBdUI7SUFDdkIsb0JBQW9CO0lBQ3BCLHFCQUFxQjtJQUNyQixlQUFlO0lBQ2Ysb0JBQW9CO0lBQ3BCLFNBQVM7SUFDVCxPQUFPO0lBQ1AsU0FBUztJQUNULElBQUk7SUFDSixPQUFPO0lBQ1AsWUFBWTtJQUNaLFVBQVU7SUFDVixVQUFVO0lBQ1YsYUFBYTtJQUNiLFdBQVc7SUFDWCxXQUFXO0lBQ1gsTUFBTTtJQUNOLE9BQU87SUFDUCxRQUFRO0lBQ1IsT0FBTztJQUNQLGdCQUFnQjtJQUNoQixpQkFBaUI7SUFDakIsUUFBUTtJQUNSLE1BQU07Q0FDUCxDQUFDLENBQUM7QUFFSCxNQUFNLGNBQWMsR0FBRyxPQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7QUFFN0MsNkVBQTZFO0FBQzdFLE1BQU0sVUFBVSxHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDMUIsS0FBSyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUU7SUFDakIsUUFBUSxFQUFFLFlBQVk7SUFDdEIsS0FBSyxFQUFFLE9BQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDOUIsQ0FBQyxDQUFDO0FBRUgscUZBQXFGO0FBQ3JGLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0FBRTVCLElBQUksZUFBZSxHQUFpQixVQUFVLENBQUM7QUFFL0MsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGlCQUFpQixFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxlQUFlLEdBQUcsT0FBQyxDQUFDLEtBQUssQ0FBQztRQUN4QixVQUFVO1FBQ1YsT0FBQyxDQUFDLE1BQU0sQ0FBQztZQUNQLFVBQVUsRUFBRSxjQUFjO1lBQzFCLFVBQVUsRUFBRSxPQUFDLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQztTQUNyQyxDQUFDO0tBQ0gsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELGtCQUFlLE1BQU0sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMifQ==
|
|
@@ -0,0 +1,234 @@
|
|
|
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
|
+
const filter_1 = __importDefault(require("./filter"));
|
|
7
|
+
describe('filterSchema', () => {
|
|
8
|
+
describe('leaf conditions', () => {
|
|
9
|
+
it('should accept valid leaf condition with Equal operator', () => {
|
|
10
|
+
const condition = {
|
|
11
|
+
aggregator: 'And',
|
|
12
|
+
conditions: [{ field: 'name', operator: 'Equal', value: 'John' }],
|
|
13
|
+
};
|
|
14
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
15
|
+
});
|
|
16
|
+
it('should accept leaf condition without value for operators that do not require it', () => {
|
|
17
|
+
const condition = {
|
|
18
|
+
aggregator: 'And',
|
|
19
|
+
conditions: [{ field: 'deletedAt', operator: 'Present' }],
|
|
20
|
+
};
|
|
21
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
22
|
+
});
|
|
23
|
+
it.each([
|
|
24
|
+
'Equal',
|
|
25
|
+
'NotEqual',
|
|
26
|
+
'LessThan',
|
|
27
|
+
'GreaterThan',
|
|
28
|
+
'LessThanOrEqual',
|
|
29
|
+
'GreaterThanOrEqual',
|
|
30
|
+
'Match',
|
|
31
|
+
'NotContains',
|
|
32
|
+
'NotIContains',
|
|
33
|
+
'LongerThan',
|
|
34
|
+
'ShorterThan',
|
|
35
|
+
'IncludesAll',
|
|
36
|
+
'IncludesNone',
|
|
37
|
+
'Today',
|
|
38
|
+
'Yesterday',
|
|
39
|
+
'PreviousMonth',
|
|
40
|
+
'PreviousQuarter',
|
|
41
|
+
'PreviousWeek',
|
|
42
|
+
'PreviousYear',
|
|
43
|
+
'PreviousMonthToDate',
|
|
44
|
+
'PreviousQuarterToDate',
|
|
45
|
+
'PreviousWeekToDate',
|
|
46
|
+
'PreviousXDaysToDate',
|
|
47
|
+
'PreviousXDays',
|
|
48
|
+
'PreviousYearToDate',
|
|
49
|
+
'Present',
|
|
50
|
+
'Blank',
|
|
51
|
+
'Missing',
|
|
52
|
+
'In',
|
|
53
|
+
'NotIn',
|
|
54
|
+
'StartsWith',
|
|
55
|
+
'EndsWith',
|
|
56
|
+
'Contains',
|
|
57
|
+
'IStartsWith',
|
|
58
|
+
'IEndsWith',
|
|
59
|
+
'IContains',
|
|
60
|
+
'Like',
|
|
61
|
+
'ILike',
|
|
62
|
+
'Before',
|
|
63
|
+
'After',
|
|
64
|
+
'AfterXHoursAgo',
|
|
65
|
+
'BeforeXHoursAgo',
|
|
66
|
+
'Future',
|
|
67
|
+
'Past',
|
|
68
|
+
])('should accept operator "%s"', operator => {
|
|
69
|
+
const condition = {
|
|
70
|
+
aggregator: 'And',
|
|
71
|
+
conditions: [{ field: 'testField', operator, value: 'test' }],
|
|
72
|
+
};
|
|
73
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
74
|
+
});
|
|
75
|
+
it('should reject invalid operator', () => {
|
|
76
|
+
const condition = {
|
|
77
|
+
aggregator: 'And',
|
|
78
|
+
conditions: [{ field: 'name', operator: 'InvalidOperator', value: 'John' }],
|
|
79
|
+
};
|
|
80
|
+
expect(() => filter_1.default.parse(condition)).toThrow();
|
|
81
|
+
});
|
|
82
|
+
it('should require field property', () => {
|
|
83
|
+
const condition = {
|
|
84
|
+
aggregator: 'And',
|
|
85
|
+
conditions: [{ operator: 'Equal', value: 'John' }],
|
|
86
|
+
};
|
|
87
|
+
expect(() => filter_1.default.parse(condition)).toThrow();
|
|
88
|
+
});
|
|
89
|
+
it('should require operator property', () => {
|
|
90
|
+
const condition = {
|
|
91
|
+
aggregator: 'And',
|
|
92
|
+
conditions: [{ field: 'name', value: 'John' }],
|
|
93
|
+
};
|
|
94
|
+
expect(() => filter_1.default.parse(condition)).toThrow();
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
describe('branch conditions', () => {
|
|
98
|
+
it('should accept And aggregator', () => {
|
|
99
|
+
const condition = {
|
|
100
|
+
aggregator: 'And',
|
|
101
|
+
conditions: [{ field: 'name', operator: 'Equal', value: 'John' }],
|
|
102
|
+
};
|
|
103
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
104
|
+
});
|
|
105
|
+
it('should accept Or aggregator', () => {
|
|
106
|
+
const condition = {
|
|
107
|
+
aggregator: 'Or',
|
|
108
|
+
conditions: [{ field: 'name', operator: 'Equal', value: 'John' }],
|
|
109
|
+
};
|
|
110
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
111
|
+
});
|
|
112
|
+
it('should reject invalid aggregator', () => {
|
|
113
|
+
const condition = {
|
|
114
|
+
aggregator: 'Xor',
|
|
115
|
+
conditions: [{ field: 'name', operator: 'Equal', value: 'John' }],
|
|
116
|
+
};
|
|
117
|
+
expect(() => filter_1.default.parse(condition)).toThrow();
|
|
118
|
+
});
|
|
119
|
+
it('should require conditions array', () => {
|
|
120
|
+
const condition = {
|
|
121
|
+
aggregator: 'And',
|
|
122
|
+
};
|
|
123
|
+
expect(() => filter_1.default.parse(condition)).toThrow();
|
|
124
|
+
});
|
|
125
|
+
it('should accept empty conditions array', () => {
|
|
126
|
+
const condition = {
|
|
127
|
+
aggregator: 'And',
|
|
128
|
+
conditions: [],
|
|
129
|
+
};
|
|
130
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
describe('nested conditions', () => {
|
|
134
|
+
it('should accept nested branch conditions', () => {
|
|
135
|
+
const condition = {
|
|
136
|
+
aggregator: 'And',
|
|
137
|
+
conditions: [
|
|
138
|
+
{ field: 'name', operator: 'Equal', value: 'John' },
|
|
139
|
+
{
|
|
140
|
+
aggregator: 'Or',
|
|
141
|
+
conditions: [
|
|
142
|
+
{ field: 'age', operator: 'GreaterThan', value: 18 },
|
|
143
|
+
{ field: 'status', operator: 'Equal', value: 'adult' },
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
149
|
+
});
|
|
150
|
+
it('should accept deeply nested conditions', () => {
|
|
151
|
+
const condition = {
|
|
152
|
+
aggregator: 'And',
|
|
153
|
+
conditions: [
|
|
154
|
+
{
|
|
155
|
+
aggregator: 'Or',
|
|
156
|
+
conditions: [
|
|
157
|
+
{
|
|
158
|
+
aggregator: 'And',
|
|
159
|
+
conditions: [
|
|
160
|
+
{ field: 'a', operator: 'Equal', value: 1 },
|
|
161
|
+
{ field: 'b', operator: 'Equal', value: 2 },
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
{ field: 'c', operator: 'Equal', value: 3 },
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
};
|
|
169
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
170
|
+
});
|
|
171
|
+
it('should accept mixed leaf and branch conditions', () => {
|
|
172
|
+
const condition = {
|
|
173
|
+
aggregator: 'And',
|
|
174
|
+
conditions: [
|
|
175
|
+
{ field: 'active', operator: 'Equal', value: true },
|
|
176
|
+
{
|
|
177
|
+
aggregator: 'Or',
|
|
178
|
+
conditions: [
|
|
179
|
+
{ field: 'role', operator: 'Equal', value: 'admin' },
|
|
180
|
+
{ field: 'role', operator: 'Equal', value: 'superuser' },
|
|
181
|
+
],
|
|
182
|
+
},
|
|
183
|
+
{ field: 'verified', operator: 'Equal', value: true },
|
|
184
|
+
],
|
|
185
|
+
};
|
|
186
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
describe('value types', () => {
|
|
190
|
+
it('should accept string values', () => {
|
|
191
|
+
const condition = {
|
|
192
|
+
aggregator: 'And',
|
|
193
|
+
conditions: [{ field: 'name', operator: 'Equal', value: 'John' }],
|
|
194
|
+
};
|
|
195
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
196
|
+
});
|
|
197
|
+
it('should accept number values', () => {
|
|
198
|
+
const condition = {
|
|
199
|
+
aggregator: 'And',
|
|
200
|
+
conditions: [{ field: 'age', operator: 'GreaterThan', value: 25 }],
|
|
201
|
+
};
|
|
202
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
203
|
+
});
|
|
204
|
+
it('should accept boolean values', () => {
|
|
205
|
+
const condition = {
|
|
206
|
+
aggregator: 'And',
|
|
207
|
+
conditions: [{ field: 'active', operator: 'Equal', value: true }],
|
|
208
|
+
};
|
|
209
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
210
|
+
});
|
|
211
|
+
it('should accept null values', () => {
|
|
212
|
+
const condition = {
|
|
213
|
+
aggregator: 'And',
|
|
214
|
+
conditions: [{ field: 'deletedAt', operator: 'Equal', value: null }],
|
|
215
|
+
};
|
|
216
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
217
|
+
});
|
|
218
|
+
it('should accept array values for In operator', () => {
|
|
219
|
+
const condition = {
|
|
220
|
+
aggregator: 'And',
|
|
221
|
+
conditions: [{ field: 'status', operator: 'In', value: ['active', 'pending', 'approved'] }],
|
|
222
|
+
};
|
|
223
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
224
|
+
});
|
|
225
|
+
it('should accept date string values', () => {
|
|
226
|
+
const condition = {
|
|
227
|
+
aggregator: 'And',
|
|
228
|
+
conditions: [{ field: 'createdAt', operator: 'After', value: '2024-01-01T00:00:00Z' }],
|
|
229
|
+
};
|
|
230
|
+
expect(() => filter_1.default.parse(condition)).not.toThrow();
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NoZW1hcy9maWx0ZXIudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHNEQUFvQztBQUVwQyxRQUFRLENBQUMsY0FBYyxFQUFFLEdBQUcsRUFBRTtJQUM1QixRQUFRLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFO1FBQy9CLEVBQUUsQ0FBQyx3REFBd0QsRUFBRSxHQUFHLEVBQUU7WUFDaEUsTUFBTSxTQUFTLEdBQUc7Z0JBQ2hCLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixVQUFVLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUM7YUFDbEUsQ0FBQztZQUVGLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxnQkFBWSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM1RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxpRkFBaUYsRUFBRSxHQUFHLEVBQUU7WUFDekYsTUFBTSxTQUFTLEdBQUc7Z0JBQ2hCLFVBQVUsRUFBRSxLQUFLO2dCQUNqQixVQUFVLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxDQUFDO2FBQzFELENBQUM7WUFFRixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsZ0JBQVksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDNUQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQ04sT0FBTztZQUNQLFVBQVU7WUFDVixVQUFVO1lBQ1YsYUFBYTtZQUNiLGlCQUFpQjtZQUNqQixvQkFBb0I7WUFDcEIsT0FBTztZQUNQ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
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import './polyfills';
|
|
2
|
+
import type { Express } from 'express';
|
|
3
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
5
|
+
import * as http from 'http';
|
|
6
|
+
export type LogLevel = 'Debug' | 'Info' | 'Warn' | 'Error';
|
|
7
|
+
export type Logger = (level: LogLevel, message: string) => void;
|
|
8
|
+
export type HttpCallback = (req: http.IncomingMessage, res: http.ServerResponse, next?: () => void) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Options for configuring the Forest Admin MCP Server
|
|
11
|
+
*/
|
|
12
|
+
export interface ForestMCPServerOptions {
|
|
13
|
+
/** Forest Admin server URL */
|
|
14
|
+
forestServerUrl?: string;
|
|
15
|
+
/** Forest Admin app URL (for OAuth redirects) */
|
|
16
|
+
forestAppUrl?: string;
|
|
17
|
+
/** Forest Admin environment secret */
|
|
18
|
+
envSecret?: string;
|
|
19
|
+
/** Forest Admin authentication secret */
|
|
20
|
+
authSecret?: string;
|
|
21
|
+
/** Optional logger function. Defaults to console logging. */
|
|
22
|
+
logger?: Logger;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Forest Admin MCP Server
|
|
26
|
+
*
|
|
27
|
+
* This server provides HTTP REST API access to Forest Admin operations
|
|
28
|
+
* with OAuth authentication support.
|
|
29
|
+
*
|
|
30
|
+
* Environment Variables (used as fallback when options not provided):
|
|
31
|
+
* - FOREST_ENV_SECRET: Your Forest Admin environment secret (required)
|
|
32
|
+
* - FOREST_AUTH_SECRET: Your Forest Admin authentication secret, it must be the same one as the one on your agent (required)
|
|
33
|
+
* - FOREST_SERVER_URL: Forest Admin server URL (optional)
|
|
34
|
+
* - MCP_SERVER_PORT: Port for the HTTP server (default: 3931)
|
|
35
|
+
*/
|
|
36
|
+
export default class ForestMCPServer {
|
|
37
|
+
mcpServer: McpServer;
|
|
38
|
+
mcpTransport?: StreamableHTTPServerTransport;
|
|
39
|
+
httpServer?: http.Server;
|
|
40
|
+
expressApp?: Express;
|
|
41
|
+
forestServerUrl: string;
|
|
42
|
+
forestAppUrl: string;
|
|
43
|
+
private envSecret?;
|
|
44
|
+
private authSecret?;
|
|
45
|
+
private logger;
|
|
46
|
+
constructor(options?: ForestMCPServerOptions);
|
|
47
|
+
private setupTools;
|
|
48
|
+
private ensureSecretsAreSet;
|
|
49
|
+
/**
|
|
50
|
+
* Filters tool arguments to only include non-sensitive fields for logging.
|
|
51
|
+
* Prevents accidentally logging sensitive data like search queries or filters.
|
|
52
|
+
*/
|
|
53
|
+
private filterArgsForLogging;
|
|
54
|
+
/**
|
|
55
|
+
* Logs tool call information if the request is a tools/call method.
|
|
56
|
+
*/
|
|
57
|
+
private logToolCallIfPresent;
|
|
58
|
+
/**
|
|
59
|
+
* Handles an incoming MCP request.
|
|
60
|
+
* Logs the request, intercepts the response for error logging, and delegates to the transport.
|
|
61
|
+
*/
|
|
62
|
+
private handleMcpRequest;
|
|
63
|
+
/**
|
|
64
|
+
* Build and return the Express app without starting a standalone server.
|
|
65
|
+
* Useful for embedding the MCP server into another application.
|
|
66
|
+
*
|
|
67
|
+
* @param baseUrl - Optional base URL override. If not provided, will use the
|
|
68
|
+
* environmentApiEndpoint from Forest Admin API.
|
|
69
|
+
* @returns The configured Express application
|
|
70
|
+
*/
|
|
71
|
+
buildExpressApp(baseUrl?: URL): Promise<Express>;
|
|
72
|
+
/**
|
|
73
|
+
* Build and return an HTTP callback that can be used as middleware.
|
|
74
|
+
* The callback will handle MCP-related routes (/.well-known/*, /oauth/*, /mcp)
|
|
75
|
+
* and call next() for other routes.
|
|
76
|
+
*
|
|
77
|
+
* @param baseUrl - Optional base URL override. If not provided, will use the
|
|
78
|
+
* environmentApiEndpoint from Forest Admin API.
|
|
79
|
+
* @returns An HTTP callback function
|
|
80
|
+
*/
|
|
81
|
+
getHttpCallback(baseUrl?: URL): Promise<HttpCallback>;
|
|
82
|
+
/**
|
|
83
|
+
* Run the MCP server as a standalone HTTP server.
|
|
84
|
+
*/
|
|
85
|
+
run(): Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=server.d.ts.map
|