@itm-platform/mcp-server 1.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/README.md +193 -0
- package/bin/mcp-server.js +2 -0
- package/dist/audit-config.d.ts +2 -0
- package/dist/audit-config.d.ts.map +1 -0
- package/dist/audit-config.js +4 -0
- package/dist/audit-config.js.map +1 -0
- package/dist/auth/api-key-auth.d.ts +3 -0
- package/dist/auth/api-key-auth.d.ts.map +1 -0
- package/dist/auth/api-key-auth.js +53 -0
- package/dist/auth/api-key-auth.js.map +1 -0
- package/dist/auth/effective-user-context.d.ts +16 -0
- package/dist/auth/effective-user-context.d.ts.map +1 -0
- package/dist/auth/effective-user-context.js +9 -0
- package/dist/auth/effective-user-context.js.map +1 -0
- package/dist/auth/license-resolver.d.ts +6 -0
- package/dist/auth/license-resolver.d.ts.map +1 -0
- package/dist/auth/license-resolver.js +12 -0
- package/dist/auth/license-resolver.js.map +1 -0
- package/dist/auth/oauth-auth.d.ts +22 -0
- package/dist/auth/oauth-auth.d.ts.map +1 -0
- package/dist/auth/oauth-auth.js +34 -0
- package/dist/auth/oauth-auth.js.map +1 -0
- package/dist/auth/oauth-metadata.d.ts +11 -0
- package/dist/auth/oauth-metadata.d.ts.map +1 -0
- package/dist/auth/oauth-metadata.js +14 -0
- package/dist/auth/oauth-metadata.js.map +1 -0
- package/dist/auth/token-extraction.d.ts +2 -0
- package/dist/auth/token-extraction.d.ts.map +1 -0
- package/dist/auth/token-extraction.js +7 -0
- package/dist/auth/token-extraction.js.map +1 -0
- package/dist/clients/audit-client.d.ts +25 -0
- package/dist/clients/audit-client.d.ts.map +1 -0
- package/dist/clients/audit-client.js +37 -0
- package/dist/clients/audit-client.js.map +1 -0
- package/dist/clients/datamart-client.d.ts +16 -0
- package/dist/clients/datamart-client.d.ts.map +1 -0
- package/dist/clients/datamart-client.js +32 -0
- package/dist/clients/datamart-client.js.map +1 -0
- package/dist/clients/index.d.ts +18 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/clients/index.js +11 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/clients/rest-client.d.ts +14 -0
- package/dist/clients/rest-client.d.ts.map +1 -0
- package/dist/clients/rest-client.js +29 -0
- package/dist/clients/rest-client.js.map +1 -0
- package/dist/gateway.d.ts +2 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +6 -0
- package/dist/gateway.js.map +1 -0
- package/dist/instrument-server.d.ts +11 -0
- package/dist/instrument-server.d.ts.map +1 -0
- package/dist/instrument-server.js +51 -0
- package/dist/instrument-server.js.map +1 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +39 -0
- package/dist/logger.js.map +1 -0
- package/dist/prompts/portfolio-overview.d.ts +3 -0
- package/dist/prompts/portfolio-overview.d.ts.map +1 -0
- package/dist/prompts/portfolio-overview.js +21 -0
- package/dist/prompts/portfolio-overview.js.map +1 -0
- package/dist/prompts/project-status.d.ts +3 -0
- package/dist/prompts/project-status.d.ts.map +1 -0
- package/dist/prompts/project-status.js +24 -0
- package/dist/prompts/project-status.js.map +1 -0
- package/dist/prompts/risk-analysis.d.ts +3 -0
- package/dist/prompts/risk-analysis.d.ts.map +1 -0
- package/dist/prompts/risk-analysis.js +23 -0
- package/dist/prompts/risk-analysis.js.map +1 -0
- package/dist/prompts/team-workload.d.ts +3 -0
- package/dist/prompts/team-workload.d.ts.map +1 -0
- package/dist/prompts/team-workload.js +29 -0
- package/dist/prompts/team-workload.js.map +1 -0
- package/dist/resources/calendars.d.ts +4 -0
- package/dist/resources/calendars.d.ts.map +1 -0
- package/dist/resources/calendars.js +18 -0
- package/dist/resources/calendars.js.map +1 -0
- package/dist/resources/schemas.d.ts +4 -0
- package/dist/resources/schemas.d.ts.map +1 -0
- package/dist/resources/schemas.js +34 -0
- package/dist/resources/schemas.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +243 -0
- package/dist/server.js.map +1 -0
- package/dist/src/auth/api-key-auth.d.ts +3 -0
- package/dist/src/auth/api-key-auth.d.ts.map +1 -0
- package/dist/src/auth/api-key-auth.js +53 -0
- package/dist/src/auth/api-key-auth.js.map +1 -0
- package/dist/src/auth/effective-user-context.d.ts +16 -0
- package/dist/src/auth/effective-user-context.d.ts.map +1 -0
- package/dist/src/auth/effective-user-context.js +9 -0
- package/dist/src/auth/effective-user-context.js.map +1 -0
- package/dist/src/auth/license-resolver.d.ts +6 -0
- package/dist/src/auth/license-resolver.d.ts.map +1 -0
- package/dist/src/auth/license-resolver.js +12 -0
- package/dist/src/auth/license-resolver.js.map +1 -0
- package/dist/src/auth/oauth-auth.d.ts +22 -0
- package/dist/src/auth/oauth-auth.d.ts.map +1 -0
- package/dist/src/auth/oauth-auth.js +34 -0
- package/dist/src/auth/oauth-auth.js.map +1 -0
- package/dist/src/auth/oauth-metadata.d.ts +10 -0
- package/dist/src/auth/oauth-metadata.d.ts.map +1 -0
- package/dist/src/auth/oauth-metadata.js +8 -0
- package/dist/src/auth/oauth-metadata.js.map +1 -0
- package/dist/src/auth/token-extraction.d.ts +2 -0
- package/dist/src/auth/token-extraction.d.ts.map +1 -0
- package/dist/src/auth/token-extraction.js +7 -0
- package/dist/src/auth/token-extraction.js.map +1 -0
- package/dist/src/clients/audit-client.d.ts +25 -0
- package/dist/src/clients/audit-client.d.ts.map +1 -0
- package/dist/src/clients/audit-client.js +37 -0
- package/dist/src/clients/audit-client.js.map +1 -0
- package/dist/src/clients/datamart-client.d.ts +16 -0
- package/dist/src/clients/datamart-client.d.ts.map +1 -0
- package/dist/src/clients/datamart-client.js +32 -0
- package/dist/src/clients/datamart-client.js.map +1 -0
- package/dist/src/clients/index.d.ts +18 -0
- package/dist/src/clients/index.d.ts.map +1 -0
- package/dist/src/clients/index.js +11 -0
- package/dist/src/clients/index.js.map +1 -0
- package/dist/src/clients/rest-client.d.ts +14 -0
- package/dist/src/clients/rest-client.d.ts.map +1 -0
- package/dist/src/clients/rest-client.js +29 -0
- package/dist/src/clients/rest-client.js.map +1 -0
- package/dist/src/logger.d.ts +3 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +37 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/prompts/portfolio-overview.d.ts +3 -0
- package/dist/src/prompts/portfolio-overview.d.ts.map +1 -0
- package/dist/src/prompts/portfolio-overview.js +21 -0
- package/dist/src/prompts/portfolio-overview.js.map +1 -0
- package/dist/src/prompts/project-status.d.ts +3 -0
- package/dist/src/prompts/project-status.d.ts.map +1 -0
- package/dist/src/prompts/project-status.js +24 -0
- package/dist/src/prompts/project-status.js.map +1 -0
- package/dist/src/prompts/risk-analysis.d.ts +3 -0
- package/dist/src/prompts/risk-analysis.d.ts.map +1 -0
- package/dist/src/prompts/risk-analysis.js +23 -0
- package/dist/src/prompts/risk-analysis.js.map +1 -0
- package/dist/src/prompts/team-workload.d.ts +3 -0
- package/dist/src/prompts/team-workload.d.ts.map +1 -0
- package/dist/src/prompts/team-workload.js +29 -0
- package/dist/src/prompts/team-workload.js.map +1 -0
- package/dist/src/resources/calendars.d.ts +4 -0
- package/dist/src/resources/calendars.d.ts.map +1 -0
- package/dist/src/resources/calendars.js +18 -0
- package/dist/src/resources/calendars.js.map +1 -0
- package/dist/src/resources/schemas.d.ts +4 -0
- package/dist/src/resources/schemas.d.ts.map +1 -0
- package/dist/src/resources/schemas.js +34 -0
- package/dist/src/resources/schemas.js.map +1 -0
- package/dist/src/server.d.ts +2 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +213 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/tools/datamart.d.ts +17 -0
- package/dist/src/tools/datamart.d.ts.map +1 -0
- package/dist/src/tools/datamart.js +68 -0
- package/dist/src/tools/datamart.js.map +1 -0
- package/dist/src/tools/financials.d.ts +4 -0
- package/dist/src/tools/financials.d.ts.map +1 -0
- package/dist/src/tools/financials.js +50 -0
- package/dist/src/tools/financials.js.map +1 -0
- package/dist/src/tools/graphql-queries.d.ts +22 -0
- package/dist/src/tools/graphql-queries.d.ts.map +1 -0
- package/dist/src/tools/graphql-queries.js +26 -0
- package/dist/src/tools/graphql-queries.js.map +1 -0
- package/dist/src/tools/portfolio.d.ts +10 -0
- package/dist/src/tools/portfolio.d.ts.map +1 -0
- package/dist/src/tools/portfolio.js +54 -0
- package/dist/src/tools/portfolio.js.map +1 -0
- package/dist/src/tools/projects.d.ts +42 -0
- package/dist/src/tools/projects.d.ts.map +1 -0
- package/dist/src/tools/projects.js +73 -0
- package/dist/src/tools/projects.js.map +1 -0
- package/dist/src/tools/reference-data.d.ts +4 -0
- package/dist/src/tools/reference-data.d.ts.map +1 -0
- package/dist/src/tools/reference-data.js +19 -0
- package/dist/src/tools/reference-data.js.map +1 -0
- package/dist/src/tools/risks-issues.d.ts +4 -0
- package/dist/src/tools/risks-issues.d.ts.map +1 -0
- package/dist/src/tools/risks-issues.js +33 -0
- package/dist/src/tools/risks-issues.js.map +1 -0
- package/dist/src/tools/services.d.ts +41 -0
- package/dist/src/tools/services.d.ts.map +1 -0
- package/dist/src/tools/services.js +67 -0
- package/dist/src/tools/services.js.map +1 -0
- package/dist/src/tools/tasks.d.ts +4 -0
- package/dist/src/tools/tasks.d.ts.map +1 -0
- package/dist/src/tools/tasks.js +17 -0
- package/dist/src/tools/tasks.js.map +1 -0
- package/dist/src/tools/users.d.ts +4 -0
- package/dist/src/tools/users.d.ts.map +1 -0
- package/dist/src/tools/users.js +30 -0
- package/dist/src/tools/users.js.map +1 -0
- package/dist/src/tools/write-tools.d.ts +75 -0
- package/dist/src/tools/write-tools.d.ts.map +1 -0
- package/dist/src/tools/write-tools.js +193 -0
- package/dist/src/tools/write-tools.js.map +1 -0
- package/dist/src/validation/query-validator.d.ts +15 -0
- package/dist/src/validation/query-validator.d.ts.map +1 -0
- package/dist/src/validation/query-validator.js +141 -0
- package/dist/src/validation/query-validator.js.map +1 -0
- package/dist/startup-mode.d.ts +13 -0
- package/dist/startup-mode.d.ts.map +1 -0
- package/dist/startup-mode.js +17 -0
- package/dist/startup-mode.js.map +1 -0
- package/dist/tools/datamart.d.ts +17 -0
- package/dist/tools/datamart.d.ts.map +1 -0
- package/dist/tools/datamart.js +68 -0
- package/dist/tools/datamart.js.map +1 -0
- package/dist/tools/financials.d.ts +4 -0
- package/dist/tools/financials.d.ts.map +1 -0
- package/dist/tools/financials.js +50 -0
- package/dist/tools/financials.js.map +1 -0
- package/dist/tools/graphql-queries.d.ts +22 -0
- package/dist/tools/graphql-queries.d.ts.map +1 -0
- package/dist/tools/graphql-queries.js +26 -0
- package/dist/tools/graphql-queries.js.map +1 -0
- package/dist/tools/portfolio.d.ts +10 -0
- package/dist/tools/portfolio.d.ts.map +1 -0
- package/dist/tools/portfolio.js +54 -0
- package/dist/tools/portfolio.js.map +1 -0
- package/dist/tools/projects.d.ts +42 -0
- package/dist/tools/projects.d.ts.map +1 -0
- package/dist/tools/projects.js +73 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/reference-data.d.ts +4 -0
- package/dist/tools/reference-data.d.ts.map +1 -0
- package/dist/tools/reference-data.js +20 -0
- package/dist/tools/reference-data.js.map +1 -0
- package/dist/tools/risks-issues.d.ts +4 -0
- package/dist/tools/risks-issues.d.ts.map +1 -0
- package/dist/tools/risks-issues.js +33 -0
- package/dist/tools/risks-issues.js.map +1 -0
- package/dist/tools/services.d.ts +41 -0
- package/dist/tools/services.d.ts.map +1 -0
- package/dist/tools/services.js +67 -0
- package/dist/tools/services.js.map +1 -0
- package/dist/tools/tasks.d.ts +4 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +17 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/users.d.ts +4 -0
- package/dist/tools/users.d.ts.map +1 -0
- package/dist/tools/users.js +30 -0
- package/dist/tools/users.js.map +1 -0
- package/dist/tools/write-tools.d.ts +74 -0
- package/dist/tools/write-tools.d.ts.map +1 -0
- package/dist/tools/write-tools.js +342 -0
- package/dist/tools/write-tools.js.map +1 -0
- package/dist/validation/query-validator.d.ts +15 -0
- package/dist/validation/query-validator.d.ts.map +1 -0
- package/dist/validation/query-validator.js +141 -0
- package/dist/validation/query-validator.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { hasScope } from '../auth/effective-user-context.js';
|
|
3
|
+
export const STALE_AFTER_WRITE_NOTICE = 'Note: DataMart reads (search_projects, get_project, list_project_tasks, etc.) ' +
|
|
4
|
+
'may return stale data for 5-60 seconds after a write due to eventual consistency. ' +
|
|
5
|
+
'The confirmed state above is from the v2 REST API (source of truth).';
|
|
6
|
+
export function buildInsufficientScopeResponse() {
|
|
7
|
+
return {
|
|
8
|
+
content: [{ type: 'text', text: 'Error: insufficient_scope -- the mcp:write scope is required for write operations' }],
|
|
9
|
+
isError: true,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function buildWriteResponse(data) {
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{ type: 'text', text: JSON.stringify(data, null, 2) },
|
|
16
|
+
{ type: 'text', text: STALE_AFTER_WRITE_NOTICE },
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function hasSuppliedField(body, field) {
|
|
21
|
+
return Object.prototype.hasOwnProperty.call(body, field) && body[field] !== undefined;
|
|
22
|
+
}
|
|
23
|
+
function formatValue(value) {
|
|
24
|
+
return JSON.stringify(value);
|
|
25
|
+
}
|
|
26
|
+
function numericValue(value) {
|
|
27
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
28
|
+
return value;
|
|
29
|
+
if (typeof value === 'string' && value.trim() !== '' && Number.isFinite(Number(value)))
|
|
30
|
+
return Number(value);
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
function dateOnly(value) {
|
|
34
|
+
if (value instanceof Date && !Number.isNaN(value.valueOf()))
|
|
35
|
+
return value.toISOString().slice(0, 10);
|
|
36
|
+
if (typeof value !== 'string')
|
|
37
|
+
return undefined;
|
|
38
|
+
const match = value.match(/^(\d{4}-\d{2}-\d{2})(?:T.*)?$/);
|
|
39
|
+
return match?.[1];
|
|
40
|
+
}
|
|
41
|
+
function valuesMatch(expected, actual) {
|
|
42
|
+
if (expected === actual)
|
|
43
|
+
return true;
|
|
44
|
+
const expectedNumber = numericValue(expected);
|
|
45
|
+
const actualNumber = numericValue(actual);
|
|
46
|
+
if (expectedNumber !== undefined && actualNumber !== undefined)
|
|
47
|
+
return expectedNumber === actualNumber;
|
|
48
|
+
const expectedDate = dateOnly(expected);
|
|
49
|
+
const actualDate = dateOnly(actual);
|
|
50
|
+
if (expectedDate && actualDate)
|
|
51
|
+
return expectedDate === actualDate;
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
function normalizeAlias(body, alias, canonical) {
|
|
55
|
+
const hasAlias = hasSuppliedField(body, alias);
|
|
56
|
+
const hasCanonical = hasSuppliedField(body, canonical);
|
|
57
|
+
if (hasAlias && hasCanonical && !valuesMatch(body[alias], body[canonical])) {
|
|
58
|
+
throw new Error(`${alias} and ${canonical} cannot both be supplied with different values`);
|
|
59
|
+
}
|
|
60
|
+
if (hasAlias && !hasCanonical) {
|
|
61
|
+
body[canonical] = body[alias];
|
|
62
|
+
}
|
|
63
|
+
if (Object.prototype.hasOwnProperty.call(body, alias)) {
|
|
64
|
+
delete body[alias];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function rejectUnsupportedFields(toolName, body, unsupported) {
|
|
68
|
+
for (const [field, reason] of Object.entries(unsupported)) {
|
|
69
|
+
if (hasSuppliedField(body, field)) {
|
|
70
|
+
throw new Error(`${field} is not supported by ${toolName}: ${reason}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function requireSuppliedField(toolName, body, field, reason) {
|
|
75
|
+
if (!hasSuppliedField(body, field)) {
|
|
76
|
+
throw new Error(`${field} is required by ${toolName}: ${reason}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export function splitCreateTaskArgs(args) {
|
|
80
|
+
const { projectId, ...body } = args;
|
|
81
|
+
normalizeAlias(body, 'Description', 'Details');
|
|
82
|
+
rejectUnsupportedFields('create_task', body, {
|
|
83
|
+
AssignedToUserId: 'task assignment is managed by task team endpoints, not the task create route',
|
|
84
|
+
PercentComplete: 'task progress is managed through follow-up/progress APIs, not task create',
|
|
85
|
+
});
|
|
86
|
+
return { path: `projects/${projectId}/tasks`, body };
|
|
87
|
+
}
|
|
88
|
+
export function splitUpdateTaskArgs(args) {
|
|
89
|
+
const { projectId, taskId, ...body } = args;
|
|
90
|
+
normalizeAlias(body, 'Description', 'Details');
|
|
91
|
+
rejectUnsupportedFields('update_task', body, {
|
|
92
|
+
AssignedToUserId: 'task assignment is managed by task team endpoints, not the task PATCH route',
|
|
93
|
+
PercentComplete: 'task progress is managed through follow-up/progress APIs, not task PATCH',
|
|
94
|
+
});
|
|
95
|
+
return { path: `projects/${projectId}/tasks/${taskId}`, body };
|
|
96
|
+
}
|
|
97
|
+
export function splitCreateRiskArgs(args) {
|
|
98
|
+
const { projectId, ...body } = args;
|
|
99
|
+
normalizeAlias(body, 'Impact', 'ImpactId');
|
|
100
|
+
normalizeAlias(body, 'Probability', 'ProbabilityId');
|
|
101
|
+
requireSuppliedField('create_risk', body, 'LevelId', 'the v2 risk create route validates risk level, and there is not currently a v2 risklevels reference endpoint');
|
|
102
|
+
return { path: `projects/${projectId}/risks`, body };
|
|
103
|
+
}
|
|
104
|
+
export function splitCreateIssueArgs(args) {
|
|
105
|
+
const { projectId, ...body } = args;
|
|
106
|
+
normalizeAlias(body, 'TypeId', 'Type');
|
|
107
|
+
normalizeAlias(body, 'StatusId', 'Status');
|
|
108
|
+
normalizeAlias(body, 'Resolution', 'FinalResolution');
|
|
109
|
+
rejectUnsupportedFields('create_issue', body, {
|
|
110
|
+
Severity: 'the v2 issue create route has no severity field',
|
|
111
|
+
});
|
|
112
|
+
return { path: `projects/${projectId}/issues`, body };
|
|
113
|
+
}
|
|
114
|
+
export function splitUpdateProjectArgs(args) {
|
|
115
|
+
const { projectId, ...body } = args;
|
|
116
|
+
normalizeAlias(body, 'StatusId', 'ProjectStatusId');
|
|
117
|
+
return { path: `projects/${projectId}`, body };
|
|
118
|
+
}
|
|
119
|
+
function getPathValue(source, path) {
|
|
120
|
+
if (source === null || typeof source !== 'object')
|
|
121
|
+
return undefined;
|
|
122
|
+
let current = source;
|
|
123
|
+
for (const segment of path.split('.')) {
|
|
124
|
+
if (current === null || typeof current !== 'object')
|
|
125
|
+
return undefined;
|
|
126
|
+
if (!Object.prototype.hasOwnProperty.call(current, segment))
|
|
127
|
+
return undefined;
|
|
128
|
+
current = current[segment];
|
|
129
|
+
}
|
|
130
|
+
return current;
|
|
131
|
+
}
|
|
132
|
+
export function verifyRequestedFields(requested, readback, fields, entityLabel) {
|
|
133
|
+
const mismatches = [];
|
|
134
|
+
for (const field of fields) {
|
|
135
|
+
if (!hasSuppliedField(requested, field.requestField))
|
|
136
|
+
continue;
|
|
137
|
+
const expected = requested[field.requestField];
|
|
138
|
+
const actualValues = field.readPaths
|
|
139
|
+
.map(path => getPathValue(readback, path))
|
|
140
|
+
.filter(value => value !== undefined);
|
|
141
|
+
if (!actualValues.length) {
|
|
142
|
+
mismatches.push(`${field.label ?? field.requestField} expected ${formatValue(expected)} but readback did not include ${field.readPaths.join(' or ')}`);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (!actualValues.some(actual => valuesMatch(expected, actual))) {
|
|
146
|
+
mismatches.push(`${field.label ?? field.requestField} expected ${formatValue(expected)} but read back ${actualValues.map(formatValue).join(' / ')}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (mismatches.length) {
|
|
150
|
+
throw new Error(`Source-of-truth write verification failed for ${entityLabel}: ${mismatches.join('; ')}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
export function mapReferenceIdToBaseId(value, referenceData) {
|
|
154
|
+
if (!Array.isArray(referenceData))
|
|
155
|
+
return value;
|
|
156
|
+
for (const item of referenceData) {
|
|
157
|
+
if (item === null || typeof item !== 'object')
|
|
158
|
+
continue;
|
|
159
|
+
const record = item;
|
|
160
|
+
const id = record.Id ?? record.id;
|
|
161
|
+
const baseId = record.BaseId ?? record.baseId;
|
|
162
|
+
if (baseId !== undefined && valuesMatch(value, baseId))
|
|
163
|
+
return baseId;
|
|
164
|
+
if (id !== undefined && valuesMatch(value, id))
|
|
165
|
+
return baseId ?? id;
|
|
166
|
+
}
|
|
167
|
+
return value;
|
|
168
|
+
}
|
|
169
|
+
async function normalizeReferenceIds(clients, body, mappings) {
|
|
170
|
+
for (const { field, entity } of mappings) {
|
|
171
|
+
if (!hasSuppliedField(body, field))
|
|
172
|
+
continue;
|
|
173
|
+
const referenceData = await clients.rest.get(entity);
|
|
174
|
+
body[field] = mapReferenceIdToBaseId(body[field], referenceData);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function extractResponseId(data, label) {
|
|
178
|
+
if (data && typeof data === 'object') {
|
|
179
|
+
const record = data;
|
|
180
|
+
const id = record.Id ?? record.id ?? record.ProjectId ?? record.projectId ?? record.TaskId ?? record.taskId;
|
|
181
|
+
if (typeof id === 'number' || typeof id === 'string')
|
|
182
|
+
return id;
|
|
183
|
+
}
|
|
184
|
+
throw new Error(`Could not read ${label} id from REST write response`);
|
|
185
|
+
}
|
|
186
|
+
const PROJECT_VERIFICATION_FIELDS = [
|
|
187
|
+
{ requestField: 'Name', readPaths: ['Name'] },
|
|
188
|
+
{ requestField: 'Description', readPaths: ['Description'] },
|
|
189
|
+
{ requestField: 'ProjectStatusId', readPaths: ['Status.Id', 'ProjectStatusId', 'StatusId'], label: 'StatusId' },
|
|
190
|
+
{ requestField: 'PriorityId', readPaths: ['Priority.Id', 'PriorityId'] },
|
|
191
|
+
{ requestField: 'StartDate', readPaths: ['StartDate'] },
|
|
192
|
+
{ requestField: 'EndDate', readPaths: ['EndDate'] },
|
|
193
|
+
];
|
|
194
|
+
const TASK_VERIFICATION_FIELDS = [
|
|
195
|
+
{ requestField: 'Name', readPaths: ['Name'] },
|
|
196
|
+
{ requestField: 'Details', readPaths: ['Details', 'Description'], label: 'Description' },
|
|
197
|
+
{ requestField: 'StatusId', readPaths: ['Status.Id', 'StatusId'] },
|
|
198
|
+
{ requestField: 'TypeId', readPaths: ['Type.Id', 'TypeId'] },
|
|
199
|
+
{ requestField: 'PriorityId', readPaths: ['Priority.Id', 'PriorityId'] },
|
|
200
|
+
{ requestField: 'StartDate', readPaths: ['StartDate'] },
|
|
201
|
+
{ requestField: 'EndDate', readPaths: ['EndDate'] },
|
|
202
|
+
];
|
|
203
|
+
const RISK_VERIFICATION_FIELDS = [
|
|
204
|
+
{ requestField: 'Name', readPaths: ['Name'] },
|
|
205
|
+
{ requestField: 'Description', readPaths: ['Description'] },
|
|
206
|
+
{ requestField: 'StatusId', readPaths: ['Status.BaseId', 'Status.Id', 'StatusId'] },
|
|
207
|
+
{ requestField: 'TypeId', readPaths: ['Type.BaseId', 'Type.Id', 'TypeId'] },
|
|
208
|
+
{ requestField: 'ImpactId', readPaths: ['Impact.BaseId', 'Impact.Id', 'ImpactId'] },
|
|
209
|
+
{ requestField: 'ProbabilityId', readPaths: ['Probability.BaseId', 'Probability.Id', 'ProbabilityId'] },
|
|
210
|
+
{ requestField: 'LevelId', readPaths: ['Level.BaseId', 'Level.Id', 'LevelId'] },
|
|
211
|
+
{ requestField: 'MitigationPlan', readPaths: ['MitigationPlan'] },
|
|
212
|
+
];
|
|
213
|
+
const ISSUE_VERIFICATION_FIELDS = [
|
|
214
|
+
{ requestField: 'Name', readPaths: ['Name'] },
|
|
215
|
+
{ requestField: 'Description', readPaths: ['Description'] },
|
|
216
|
+
{ requestField: 'Type', readPaths: ['Type.BaseId', 'Type.Id', 'Type'], label: 'TypeId' },
|
|
217
|
+
{ requestField: 'Status', readPaths: ['Status.BaseId', 'Status.Id', 'Status'], label: 'StatusId' },
|
|
218
|
+
{ requestField: 'FinalResolution', readPaths: ['FinalResolution'], label: 'Resolution' },
|
|
219
|
+
];
|
|
220
|
+
export function registerWriteTools(server, clients, effectiveUserContext) {
|
|
221
|
+
server.registerTool('create_task', {
|
|
222
|
+
description: 'Create a new task in a project. Returns the created task read back from v2 REST (source of truth). Use get_reference_data with entity "gettaskstatuses", "gettasktypes", or "gettaskpriorities" to discover valid IDs.',
|
|
223
|
+
inputSchema: {
|
|
224
|
+
projectId: z.number().describe('The project ID to create the task in'),
|
|
225
|
+
Name: z.string().describe('Task name (required)'),
|
|
226
|
+
Description: z.string().optional().describe('Task description. Compatibility alias for the v2 REST Details field.'),
|
|
227
|
+
Details: z.string().optional().describe('Task details/description field used by v2 REST'),
|
|
228
|
+
StatusId: z.number().optional().describe('Task status ID'),
|
|
229
|
+
TypeId: z.number().optional().describe('Task type ID'),
|
|
230
|
+
PriorityId: z.number().optional().describe('Task priority ID'),
|
|
231
|
+
StartDate: z.string().optional().describe('Start date (ISO 8601)'),
|
|
232
|
+
EndDate: z.string().optional().describe('End date (ISO 8601)'),
|
|
233
|
+
},
|
|
234
|
+
}, async (args) => {
|
|
235
|
+
if (effectiveUserContext && !hasScope(effectiveUserContext, 'mcp:write'))
|
|
236
|
+
return buildInsufficientScopeResponse();
|
|
237
|
+
const { path, body } = splitCreateTaskArgs(args);
|
|
238
|
+
const data = await clients.rest.post(path, body);
|
|
239
|
+
const taskId = extractResponseId(data, 'created task');
|
|
240
|
+
const readback = await clients.rest.get(`${path}/${taskId}`);
|
|
241
|
+
verifyRequestedFields(body, readback, TASK_VERIFICATION_FIELDS, 'create_task');
|
|
242
|
+
return buildWriteResponse(readback);
|
|
243
|
+
});
|
|
244
|
+
server.registerTool('update_task', {
|
|
245
|
+
description: 'Update task fields via PATCH. Only send the fields you want to change. Returns the updated task read back from v2 REST.',
|
|
246
|
+
inputSchema: {
|
|
247
|
+
projectId: z.number().describe('The project ID containing the task'),
|
|
248
|
+
taskId: z.number().describe('The task ID to update'),
|
|
249
|
+
Name: z.string().optional().describe('New task name'),
|
|
250
|
+
Description: z.string().optional().describe('New description. Compatibility alias for the v2 REST Details field.'),
|
|
251
|
+
Details: z.string().optional().describe('New task details/description field used by v2 REST'),
|
|
252
|
+
StatusId: z.number().optional().describe('New status ID'),
|
|
253
|
+
TypeId: z.number().optional().describe('New type ID'),
|
|
254
|
+
PriorityId: z.number().optional().describe('New priority ID'),
|
|
255
|
+
StartDate: z.string().optional().describe('New start date (ISO 8601)'),
|
|
256
|
+
EndDate: z.string().optional().describe('New end date (ISO 8601)'),
|
|
257
|
+
},
|
|
258
|
+
}, async (args) => {
|
|
259
|
+
if (effectiveUserContext && !hasScope(effectiveUserContext, 'mcp:write'))
|
|
260
|
+
return buildInsufficientScopeResponse();
|
|
261
|
+
const { path, body } = splitUpdateTaskArgs(args);
|
|
262
|
+
await clients.rest.patch(path, body);
|
|
263
|
+
const readback = await clients.rest.get(path);
|
|
264
|
+
verifyRequestedFields(body, readback, TASK_VERIFICATION_FIELDS, 'update_task');
|
|
265
|
+
return buildWriteResponse(readback);
|
|
266
|
+
});
|
|
267
|
+
server.registerTool('create_risk', {
|
|
268
|
+
description: 'Log a new risk in a project. Returns the created risk read back from v2 REST. Use get_reference_data with entity "riskstatuses", "risktypes", "riskimpacts", or "riskprobabilities" to discover IDs; the tool accepts localized Id values and normalizes them to BaseId values where v2 REST requires them.',
|
|
269
|
+
inputSchema: {
|
|
270
|
+
projectId: z.number().describe('The project ID to create the risk in'),
|
|
271
|
+
Name: z.string().describe('Risk name (required)'),
|
|
272
|
+
Description: z.string().optional().describe('Risk description'),
|
|
273
|
+
StatusId: z.number().optional().describe('Risk status ID'),
|
|
274
|
+
TypeId: z.number().optional().describe('Risk type ID'),
|
|
275
|
+
ProbabilityId: z.number().optional().describe('Risk probability ID'),
|
|
276
|
+
ImpactId: z.number().optional().describe('Risk impact ID'),
|
|
277
|
+
LevelId: z.number().describe('Risk level base ID required by v2 REST. No v2 risklevels reference endpoint currently exists.'),
|
|
278
|
+
MitigationPlan: z.string().optional().describe('Mitigation plan description'),
|
|
279
|
+
},
|
|
280
|
+
}, async (args) => {
|
|
281
|
+
if (effectiveUserContext && !hasScope(effectiveUserContext, 'mcp:write'))
|
|
282
|
+
return buildInsufficientScopeResponse();
|
|
283
|
+
const { path, body } = splitCreateRiskArgs(args);
|
|
284
|
+
await normalizeReferenceIds(clients, body, [
|
|
285
|
+
{ field: 'TypeId', entity: 'risktypes' },
|
|
286
|
+
{ field: 'StatusId', entity: 'riskstatuses' },
|
|
287
|
+
{ field: 'ImpactId', entity: 'riskimpacts' },
|
|
288
|
+
{ field: 'ProbabilityId', entity: 'riskprobabilities' },
|
|
289
|
+
]);
|
|
290
|
+
const data = await clients.rest.post(path, body);
|
|
291
|
+
const riskId = extractResponseId(data, 'created risk');
|
|
292
|
+
const readback = await clients.rest.get(`${path}/${riskId}`);
|
|
293
|
+
verifyRequestedFields(body, readback, RISK_VERIFICATION_FIELDS, 'create_risk');
|
|
294
|
+
return buildWriteResponse(readback);
|
|
295
|
+
});
|
|
296
|
+
server.registerTool('create_issue', {
|
|
297
|
+
description: 'Log a new issue in a project. Returns the created issue read back from v2 REST. Use get_reference_data with entity "issuestatuses" or "issuetypes" to discover IDs; the tool accepts localized Id values and normalizes them to BaseId values where v2 REST requires them.',
|
|
298
|
+
inputSchema: {
|
|
299
|
+
projectId: z.number().describe('The project ID to create the issue in'),
|
|
300
|
+
Name: z.string().describe('Issue name (required)'),
|
|
301
|
+
Description: z.string().optional().describe('Issue description'),
|
|
302
|
+
StatusId: z.number().optional().describe('Issue status ID. Mapped to the v2 REST Status field.'),
|
|
303
|
+
TypeId: z.number().optional().describe('Issue type ID. Mapped to the v2 REST Type field.'),
|
|
304
|
+
Resolution: z.string().optional().describe('Resolution description. Mapped to the v2 REST FinalResolution field.'),
|
|
305
|
+
},
|
|
306
|
+
}, async (args) => {
|
|
307
|
+
if (effectiveUserContext && !hasScope(effectiveUserContext, 'mcp:write'))
|
|
308
|
+
return buildInsufficientScopeResponse();
|
|
309
|
+
const { path, body } = splitCreateIssueArgs(args);
|
|
310
|
+
await normalizeReferenceIds(clients, body, [
|
|
311
|
+
{ field: 'Type', entity: 'issuetypes' },
|
|
312
|
+
{ field: 'Status', entity: 'issuestatuses' },
|
|
313
|
+
]);
|
|
314
|
+
const data = await clients.rest.post(path, body);
|
|
315
|
+
const issueId = extractResponseId(data, 'created issue');
|
|
316
|
+
const readback = await clients.rest.get(`${path}/${issueId}`);
|
|
317
|
+
verifyRequestedFields(body, readback, ISSUE_VERIFICATION_FIELDS, 'create_issue');
|
|
318
|
+
return buildWriteResponse(readback);
|
|
319
|
+
});
|
|
320
|
+
server.registerTool('update_project', {
|
|
321
|
+
description: 'Update project fields via PATCH. Only send the fields you want to change. Returns the updated project read back from v2 REST.',
|
|
322
|
+
inputSchema: {
|
|
323
|
+
projectId: z.number().describe('The project ID to update'),
|
|
324
|
+
Name: z.string().optional().describe('New project name'),
|
|
325
|
+
Description: z.string().optional().describe('New project description'),
|
|
326
|
+
StatusId: z.number().optional().describe('New project status ID. Compatibility alias mapped to ProjectStatusId before calling v2 REST.'),
|
|
327
|
+
ProjectStatusId: z.number().optional().describe('New project status ID field used by v2 REST'),
|
|
328
|
+
PriorityId: z.number().optional().describe('New priority ID'),
|
|
329
|
+
StartDate: z.string().optional().describe('New start date (ISO 8601)'),
|
|
330
|
+
EndDate: z.string().optional().describe('New end date (ISO 8601)'),
|
|
331
|
+
},
|
|
332
|
+
}, async (args) => {
|
|
333
|
+
if (effectiveUserContext && !hasScope(effectiveUserContext, 'mcp:write'))
|
|
334
|
+
return buildInsufficientScopeResponse();
|
|
335
|
+
const { path, body } = splitUpdateProjectArgs(args);
|
|
336
|
+
await clients.rest.patch(path, body);
|
|
337
|
+
const readback = await clients.rest.get(path);
|
|
338
|
+
verifyRequestedFields(body, readback, PROJECT_VERIFICATION_FIELDS, 'update_project');
|
|
339
|
+
return buildWriteResponse(readback);
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=write-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-tools.js","sourceRoot":"","sources":["../../src/tools/write-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface ValidationResult {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
error?: {
|
|
4
|
+
code: string;
|
|
5
|
+
message: string;
|
|
6
|
+
};
|
|
7
|
+
warning?: string;
|
|
8
|
+
}
|
|
9
|
+
interface DataMartBody {
|
|
10
|
+
query?: string;
|
|
11
|
+
variables?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export declare function validateDataMartQuery(body: DataMartBody | null | undefined): ValidationResult;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=query-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-validator.d.ts","sourceRoot":"","sources":["../../src/validation/query-validator.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAiGD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,gBAAgB,CA8C7F"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// SYNC: Ported from ITM.PMPilot (inference/datamart/validators.js).
|
|
2
|
+
// If you change the allowed operators or aggregation stages here, update the PMPilot copy too.
|
|
3
|
+
//
|
|
4
|
+
// Differences from PMPilot's copy:
|
|
5
|
+
// - TypeScript types
|
|
6
|
+
// - Adds $not to ALLOWED_WHERE_OPERATORS (allowed by DataMart's validate.ts)
|
|
7
|
+
const ALLOWED_WHERE_OPERATORS = new Set([
|
|
8
|
+
'$eq', '$ne', '$in', '$nin', '$gt', '$gte', '$lt', '$lte',
|
|
9
|
+
'$regex', '$options', '$exists', '$not', '$and', '$or', '$nor',
|
|
10
|
+
]);
|
|
11
|
+
const ALLOWED_AGG_STAGES = new Set([
|
|
12
|
+
'$match', '$project', '$group', '$sort', '$limit', '$skip',
|
|
13
|
+
'$unwind', '$addFields', '$set', '$unset',
|
|
14
|
+
]);
|
|
15
|
+
function isAggregateQuery(query) {
|
|
16
|
+
return /\baggregateComponents\s*\(/.test(query);
|
|
17
|
+
}
|
|
18
|
+
function isListQuery(query) {
|
|
19
|
+
return /\bcomponents\s*\(/.test(query) && !isAggregateQuery(query);
|
|
20
|
+
}
|
|
21
|
+
function selectsJsonSubfields(query) {
|
|
22
|
+
return /\bcomponent\s*\{/.test(query)
|
|
23
|
+
|| /\bcomponents\s*\{/.test(query)
|
|
24
|
+
|| /\baggregateComponents\s*\{/.test(query);
|
|
25
|
+
}
|
|
26
|
+
function pipelineHasFacet(p) {
|
|
27
|
+
return p.some(st => st && typeof st === 'object' && Object.prototype.hasOwnProperty.call(st, '$facet'));
|
|
28
|
+
}
|
|
29
|
+
function validateWhereObject(whereObj, path = '$') {
|
|
30
|
+
if (whereObj == null || typeof whereObj !== 'object')
|
|
31
|
+
return { ok: true };
|
|
32
|
+
for (const [key, value] of Object.entries(whereObj)) {
|
|
33
|
+
if (key.startsWith('$')) {
|
|
34
|
+
if (!ALLOWED_WHERE_OPERATORS.has(key)) {
|
|
35
|
+
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: `Disallowed operator ${key} at ${path}` } };
|
|
36
|
+
}
|
|
37
|
+
if (key === '$and' || key === '$or' || key === '$nor') {
|
|
38
|
+
if (Array.isArray(value)) {
|
|
39
|
+
for (let i = 0; i < value.length; i++) {
|
|
40
|
+
const res = validateWhereObject(value[i], `${path}.${key}[${i}]`);
|
|
41
|
+
if (!res.ok)
|
|
42
|
+
return res;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
// $not wraps a single condition object
|
|
48
|
+
if (key === '$not') {
|
|
49
|
+
if (value && typeof value === 'object') {
|
|
50
|
+
const res = validateWhereObject(value, `${path}.${key}`);
|
|
51
|
+
if (!res.ok)
|
|
52
|
+
return res;
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (value && typeof value === 'object') {
|
|
58
|
+
const res = validateWhereObject(value, `${path}.${key}`);
|
|
59
|
+
if (!res.ok)
|
|
60
|
+
return res;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return { ok: true };
|
|
64
|
+
}
|
|
65
|
+
function validatePipeline(pipeline) {
|
|
66
|
+
if (!Array.isArray(pipeline)) {
|
|
67
|
+
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Aggregation pipeline must be an array' } };
|
|
68
|
+
}
|
|
69
|
+
if (pipeline.length === 0) {
|
|
70
|
+
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Aggregation pipeline must include a final $limit stage' } };
|
|
71
|
+
}
|
|
72
|
+
for (let i = 0; i < pipeline.length; i++) {
|
|
73
|
+
const stage = pipeline[i];
|
|
74
|
+
const keys = stage && typeof stage === 'object' ? Object.keys(stage) : [];
|
|
75
|
+
if (keys.length !== 1) {
|
|
76
|
+
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: `Aggregation stage at index ${i} must have exactly one key` } };
|
|
77
|
+
}
|
|
78
|
+
if (!ALLOWED_AGG_STAGES.has(keys[0])) {
|
|
79
|
+
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: `Forbidden stage ${keys[0]} at index ${i}` } };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const last = pipeline[pipeline.length - 1];
|
|
83
|
+
const lastKey = last && typeof last === 'object' ? Object.keys(last)[0] : null;
|
|
84
|
+
if (lastKey !== '$limit') {
|
|
85
|
+
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Aggregation must end with a final $limit stage' } };
|
|
86
|
+
}
|
|
87
|
+
const limitVal = last['$limit'];
|
|
88
|
+
if (typeof limitVal !== 'number' || !Number.isFinite(limitVal) || limitVal <= 0) {
|
|
89
|
+
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Final $limit must be a positive number' } };
|
|
90
|
+
}
|
|
91
|
+
if (limitVal > 1000) {
|
|
92
|
+
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Final $limit must be ≤ 1000' } };
|
|
93
|
+
}
|
|
94
|
+
return { ok: true };
|
|
95
|
+
}
|
|
96
|
+
export function validateDataMartQuery(body) {
|
|
97
|
+
if (!body || typeof body !== 'object')
|
|
98
|
+
return { ok: true };
|
|
99
|
+
const query = body.query ?? '';
|
|
100
|
+
const variables = (body.variables ?? {});
|
|
101
|
+
if (selectsJsonSubfields(query)) {
|
|
102
|
+
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Do not select subfields of JSON; project fields via variables (proj / w / p) instead.' } };
|
|
103
|
+
}
|
|
104
|
+
if (isAggregateQuery(query)) {
|
|
105
|
+
const pipeline = variables.p ?? variables.pipeline;
|
|
106
|
+
const res = validatePipeline(pipeline);
|
|
107
|
+
if (!res.ok)
|
|
108
|
+
return res;
|
|
109
|
+
if (pipelineHasFacet(pipeline)) {
|
|
110
|
+
return {
|
|
111
|
+
ok: false,
|
|
112
|
+
error: {
|
|
113
|
+
code: 'CLIENT_VALIDATION',
|
|
114
|
+
message: 'Forbidden stage $facet. For totals use components(where...).total with limit=1, or run separate $count pipelines.',
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return { ok: true };
|
|
119
|
+
}
|
|
120
|
+
if (isListQuery(query)) {
|
|
121
|
+
const limit = variables.limit;
|
|
122
|
+
if (typeof limit === 'number' && limit > 100) {
|
|
123
|
+
return { ok: true, warning: 'High limit requested (>100). Server may clamp to 200.' };
|
|
124
|
+
}
|
|
125
|
+
const whereObj = variables.w ?? variables.where;
|
|
126
|
+
if (whereObj) {
|
|
127
|
+
const res = validateWhereObject(whereObj, '$.w');
|
|
128
|
+
if (!res.ok)
|
|
129
|
+
return res;
|
|
130
|
+
}
|
|
131
|
+
return { ok: true };
|
|
132
|
+
}
|
|
133
|
+
const genericWhere = variables.w ?? variables.where;
|
|
134
|
+
if (genericWhere) {
|
|
135
|
+
const res = validateWhereObject(genericWhere, '$.w');
|
|
136
|
+
if (!res.ok)
|
|
137
|
+
return res;
|
|
138
|
+
}
|
|
139
|
+
return { ok: true };
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=query-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-validator.js","sourceRoot":"","sources":["../../src/validation/query-validator.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@itm-platform/mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for ITM Platform",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/server.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mcp-server": "bin/mcp-server.js"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/itmplatform/mcp-server.git"
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"bin",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"dev": "cross-env PORT=6170 node --env-file=.env --import tsx src/server.ts",
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"start": "node dist/server.js",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
29
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
33
|
+
"pino": "^10.1.0",
|
|
34
|
+
"pino-pretty": "^13.1.2",
|
|
35
|
+
"pino-roll": "^4.0.0",
|
|
36
|
+
"zod": "^3.24.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^22.15.0",
|
|
40
|
+
"cross-env": "^7.0.3",
|
|
41
|
+
"tsx": "^4.20.6",
|
|
42
|
+
"typescript": "^5.8.0",
|
|
43
|
+
"vitest": "^3.1.0"
|
|
44
|
+
}
|
|
45
|
+
}
|