@softacus-software/elwis-data-mcp 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.
Files changed (118) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +6 -0
  3. package/README.md +183 -0
  4. package/dist/app-scope.js +92 -0
  5. package/dist/app-scope.js.map +1 -0
  6. package/dist/artifact-read.js +114 -0
  7. package/dist/artifact-read.js.map +1 -0
  8. package/dist/audit.js +36 -0
  9. package/dist/audit.js.map +1 -0
  10. package/dist/builders/artifact-type-execute.js +100 -0
  11. package/dist/builders/artifact-type-execute.js.map +1 -0
  12. package/dist/builders/artifact-type-plan.js +139 -0
  13. package/dist/builders/artifact-type-plan.js.map +1 -0
  14. package/dist/builders/design-interview.js +246 -0
  15. package/dist/builders/design-interview.js.map +1 -0
  16. package/dist/builders/entity-lifecycle-execute.js +12 -0
  17. package/dist/builders/entity-lifecycle-execute.js.map +1 -0
  18. package/dist/builders/entity-lifecycle-plan.js +345 -0
  19. package/dist/builders/entity-lifecycle-plan.js.map +1 -0
  20. package/dist/builders/links-execute.js +50 -0
  21. package/dist/builders/links-execute.js.map +1 -0
  22. package/dist/builders/links-plan.js +62 -0
  23. package/dist/builders/links-plan.js.map +1 -0
  24. package/dist/builders/page-execute.js +38 -0
  25. package/dist/builders/page-execute.js.map +1 -0
  26. package/dist/builders/page-plan.js +148 -0
  27. package/dist/builders/page-plan.js.map +1 -0
  28. package/dist/builders/records-execute.js +24 -0
  29. package/dist/builders/records-execute.js.map +1 -0
  30. package/dist/builders/records-lifecycle-execute.js +30 -0
  31. package/dist/builders/records-lifecycle-execute.js.map +1 -0
  32. package/dist/builders/records-lifecycle-plan.js +199 -0
  33. package/dist/builders/records-lifecycle-plan.js.map +1 -0
  34. package/dist/builders/records-plan.js +74 -0
  35. package/dist/builders/records-plan.js.map +1 -0
  36. package/dist/builders/update-page-execute.js +38 -0
  37. package/dist/builders/update-page-execute.js.map +1 -0
  38. package/dist/builders/update-page-plan.js +137 -0
  39. package/dist/builders/update-page-plan.js.map +1 -0
  40. package/dist/builders/workflow-execute.js +11 -0
  41. package/dist/builders/workflow-execute.js.map +1 -0
  42. package/dist/builders/workflow-plan.js +115 -0
  43. package/dist/builders/workflow-plan.js.map +1 -0
  44. package/dist/cli/client-configs.js +98 -0
  45. package/dist/cli/client-configs.js.map +1 -0
  46. package/dist/cli/login.js +64 -0
  47. package/dist/cli/login.js.map +1 -0
  48. package/dist/cli/prompter.js +77 -0
  49. package/dist/cli/prompter.js.map +1 -0
  50. package/dist/cli/setup.js +214 -0
  51. package/dist/cli/setup.js.map +1 -0
  52. package/dist/config.js +38 -0
  53. package/dist/config.js.map +1 -0
  54. package/dist/confirm.js +22 -0
  55. package/dist/confirm.js.map +1 -0
  56. package/dist/elwis-api.js +96 -0
  57. package/dist/elwis-api.js.map +1 -0
  58. package/dist/http-client.js +142 -0
  59. package/dist/http-client.js.map +1 -0
  60. package/dist/index.js +20 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/jwt.js +18 -0
  63. package/dist/jwt.js.map +1 -0
  64. package/dist/prune.js +9 -0
  65. package/dist/prune.js.map +1 -0
  66. package/dist/resolve.js +71 -0
  67. package/dist/resolve.js.map +1 -0
  68. package/dist/result.js +16 -0
  69. package/dist/result.js.map +1 -0
  70. package/dist/server.js +82 -0
  71. package/dist/server.js.map +1 -0
  72. package/dist/session-store.js +51 -0
  73. package/dist/session-store.js.map +1 -0
  74. package/dist/tools/build-artifact-type.js +36 -0
  75. package/dist/tools/build-artifact-type.js.map +1 -0
  76. package/dist/tools/build-links.js +33 -0
  77. package/dist/tools/build-links.js.map +1 -0
  78. package/dist/tools/build-page.js +40 -0
  79. package/dist/tools/build-page.js.map +1 -0
  80. package/dist/tools/build-workflow.js +36 -0
  81. package/dist/tools/build-workflow.js.map +1 -0
  82. package/dist/tools/create-application.js +44 -0
  83. package/dist/tools/create-application.js.map +1 -0
  84. package/dist/tools/create-artifacts.js +33 -0
  85. package/dist/tools/create-artifacts.js.map +1 -0
  86. package/dist/tools/create-folder.js +55 -0
  87. package/dist/tools/create-folder.js.map +1 -0
  88. package/dist/tools/delete-artifacts.js +33 -0
  89. package/dist/tools/delete-artifacts.js.map +1 -0
  90. package/dist/tools/delete-entity.js +35 -0
  91. package/dist/tools/delete-entity.js.map +1 -0
  92. package/dist/tools/explain-access.js +40 -0
  93. package/dist/tools/explain-access.js.map +1 -0
  94. package/dist/tools/get-entity.js +36 -0
  95. package/dist/tools/get-entity.js.map +1 -0
  96. package/dist/tools/get-page.js +75 -0
  97. package/dist/tools/get-page.js.map +1 -0
  98. package/dist/tools/list-apps.js +22 -0
  99. package/dist/tools/list-apps.js.map +1 -0
  100. package/dist/tools/list-entities.js +43 -0
  101. package/dist/tools/list-entities.js.map +1 -0
  102. package/dist/tools/propose-page-design.js +17 -0
  103. package/dist/tools/propose-page-design.js.map +1 -0
  104. package/dist/tools/raw-api.js +132 -0
  105. package/dist/tools/raw-api.js.map +1 -0
  106. package/dist/tools/read-artifacts.js +197 -0
  107. package/dist/tools/read-artifacts.js.map +1 -0
  108. package/dist/tools/resolve-entity.js +22 -0
  109. package/dist/tools/resolve-entity.js.map +1 -0
  110. package/dist/tools/update-artifacts.js +33 -0
  111. package/dist/tools/update-artifacts.js.map +1 -0
  112. package/dist/tools/update-entity.js +41 -0
  113. package/dist/tools/update-entity.js.map +1 -0
  114. package/dist/tools/update-page.js +40 -0
  115. package/dist/tools/update-page.js.map +1 -0
  116. package/dist/write-gate.js +25 -0
  117. package/dist/write-gate.js.map +1 -0
  118. package/package.json +55 -0
@@ -0,0 +1,197 @@
1
+ import { z } from 'zod';
2
+ import { AppScopeError } from '../app-scope.js';
3
+ import { RequireApplicationId, ResolveOneId } from '../resolve.js';
4
+ import { LoadAttributeMap, ResolveAttributeId, ResolveUnknownAttributeNames, BuildWhereClauses, EscapeRegex, SummarizeArtifact, TranslateArtifact, PageMeta } from '../artifact-read.js';
5
+ import { Text, ErrorResult } from '../result.js';
6
+ const READ_ONLY = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true };
7
+ const MAP_CACHE_TTL_MS = 60000;
8
+ const WherePrimitive = z.union([z.string(), z.number(), z.boolean(), z.null()]);
9
+ const WhereInput = z.object({
10
+ attribute: z.string().describe('Attribute name or 24-char hex id'),
11
+ op: z.enum(['equals', 'contains', 'gt', 'gte', 'lt', 'lte', 'in']).optional().describe('Comparison operator (default equals)'),
12
+ value: z.union([WherePrimitive, z.array(WherePrimitive)]).describe('Primitive value, or an array of primitives for the in operator'),
13
+ });
14
+ class ReadContext {
15
+ api;
16
+ sysAttrs = null;
17
+ maps = new Map();
18
+ typeApps = new Map();
19
+ constructor(api) {
20
+ this.api = api;
21
+ }
22
+ systemAttributes() {
23
+ this.sysAttrs = this.sysAttrs ?? this.api.systemAttributes();
24
+ return this.sysAttrs;
25
+ }
26
+ attributeMap(applicationId) {
27
+ const hit = this.maps.get(applicationId);
28
+ if (hit && Date.now() - hit.at < MAP_CACHE_TTL_MS)
29
+ return hit.map;
30
+ const map = LoadAttributeMap(this.api, applicationId);
31
+ this.maps.set(applicationId, { at: Date.now(), map });
32
+ return map;
33
+ }
34
+ applicationOfType(artifactTypeId) {
35
+ let hit = this.typeApps.get(artifactTypeId);
36
+ if (!hit) {
37
+ hit = this.api.getOne('artifact-type', artifactTypeId)
38
+ .then(t => (t.applicationId ? String(t.applicationId) : null))
39
+ .catch(() => null);
40
+ this.typeApps.set(artifactTypeId, hit);
41
+ }
42
+ return hit;
43
+ }
44
+ }
45
+ async function AssertArtifactInScope(ctx, scope, artifact) {
46
+ const applicationId = await ctx.applicationOfType(String(artifact.artifactTypeId));
47
+ if (!scope.restricted)
48
+ return applicationId;
49
+ if (!applicationId)
50
+ throw new Error('The record has no resolvable owning application; a scoped deployment cannot serve it');
51
+ try {
52
+ await scope.assertAllowed(applicationId);
53
+ }
54
+ catch (e) {
55
+ if (e instanceof AppScopeError)
56
+ throw new Error('The record is outside the configured application allowlist (ELWIS_ALLOWED_APPS)');
57
+ throw e;
58
+ }
59
+ return applicationId;
60
+ }
61
+ async function CounterpartInScope(ctx, scope, artifact) {
62
+ if (!scope.restricted || !artifact)
63
+ return true;
64
+ const applicationId = await ctx.applicationOfType(String(artifact.artifactTypeId));
65
+ if (!applicationId)
66
+ return false;
67
+ const allowed = await scope.allowedIds();
68
+ return allowed === null || allowed.has(applicationId);
69
+ }
70
+ export function RegisterReadArtifacts(server, api, scope) {
71
+ const ctx = new ReadContext(api);
72
+ server.registerTool('list_elwis_artifacts', {
73
+ title: 'List ELWIS artifacts',
74
+ description: 'List or search live data records (artifacts) the configured user can access. Scope by application (required) and optionally by artifact type, folder path, a name substring, and attribute-value conditions combined with AND (attribute names are resolved for you; values must be primitives). Returns compact summaries with total/hasMore pagination metadata; fetch full records with get_elwis_artifact.',
75
+ inputSchema: {
76
+ applicationId: z.string().optional(),
77
+ applicationName: z.string().optional(),
78
+ artifactType: z.string().optional().describe('Artifact type name or id; when omitted, all types of the application are searched'),
79
+ nameContains: z.string().optional().describe('Case-insensitive substring match on the record name'),
80
+ folderPathContains: z.string().optional().describe('Case-insensitive substring match on the folder path'),
81
+ where: z.array(WhereInput).optional().describe('Attribute-value conditions, combined with AND'),
82
+ sortBy: z.string().optional().describe('Attribute name or id to sort by'),
83
+ sortOrder: z.enum(['asc', 'desc']).optional(),
84
+ limit: z.number().int().positive().max(100).optional().describe('Page size (default 25)'),
85
+ skip: z.number().int().min(0).optional(),
86
+ },
87
+ annotations: READ_ONLY,
88
+ }, async (raw) => {
89
+ try {
90
+ const applicationId = await RequireApplicationId(api, raw);
91
+ await scope.assertAllowed(applicationId);
92
+ const map = await ctx.attributeMap(applicationId);
93
+ const sys = await ctx.systemAttributes();
94
+ const and = [];
95
+ if (raw.artifactType) {
96
+ and.push({ artifactTypeId: { $oid: await ResolveOneId(api, 'artifact-type', applicationId, raw.artifactType) } });
97
+ }
98
+ else {
99
+ const types = await api.list('artifact-type', { applicationId: { $oid: applicationId } }, 501);
100
+ if (types.length > 500)
101
+ throw new Error('The application has more than 500 artifact types; pass an explicit artifactType');
102
+ and.push({ artifactTypeId: { $in: types.map(t => ({ $oid: t.id })) } });
103
+ }
104
+ if (raw.nameContains)
105
+ and.push({ [`attributes.${sys.nameAttributeId}.value`]: { $regex: EscapeRegex(raw.nameContains), $options: 'i' } });
106
+ if (raw.folderPathContains)
107
+ and.push({ 'folderData.path': { $regex: EscapeRegex(raw.folderPathContains), $options: 'i' } });
108
+ if (raw.where?.length)
109
+ and.push(...BuildWhereClauses(map, raw.where));
110
+ const sort = raw.sortBy
111
+ ? { [`attributes.${ResolveAttributeId(map, raw.sortBy)}.value`]: raw.sortOrder === 'desc' ? -1 : 1 }
112
+ : undefined;
113
+ const page = await api.listRecords('artifact', { $and: and }, { sort, skip: raw.skip ?? 0, limit: raw.limit ?? 25 });
114
+ const results = page.data.map(a => SummarizeArtifact(a, sys.nameAttributeId));
115
+ return Text({ status: 'ok', ...PageMeta(page.meta, results.length), results });
116
+ }
117
+ catch (e) {
118
+ return ErrorResult(e);
119
+ }
120
+ });
121
+ server.registerTool('get_elwis_artifact', {
122
+ title: 'Get one ELWIS artifact',
123
+ description: 'Get one data record (artifact) by id with its attribute values translated to attribute names. Long values and long arrays are truncated with explicit markers; values whose attribute name is unknown or collides stay addressable in unmappedValuesById.',
124
+ inputSchema: { id: z.string().describe('Artifact id from list_elwis_artifacts') },
125
+ annotations: READ_ONLY,
126
+ }, async ({ id }) => {
127
+ try {
128
+ const artifact = await api.getOne('artifact', id);
129
+ const applicationId = await AssertArtifactInScope(ctx, scope, artifact);
130
+ const artifactTypeName = applicationId === null ? null : (await api.getOne('artifact-type', String(artifact.artifactTypeId))).name;
131
+ const map = applicationId ? await ctx.attributeMap(applicationId) : { byId: new Map(), byName: new Map() };
132
+ await ResolveUnknownAttributeNames(api, map, Object.keys(artifact.attributes ?? {}));
133
+ return Text({ status: 'ok', applicationId, artifactTypeName, ...TranslateArtifact(artifact, map) });
134
+ }
135
+ catch (e) {
136
+ return ErrorResult(e);
137
+ }
138
+ });
139
+ server.registerTool('list_elwis_artifact_links', {
140
+ title: 'List links of an ELWIS artifact',
141
+ description: 'List the links (relationships) of one artifact: link type, direction, and the record on the other side with its name. Counterparts living outside the configured application allowlist are redacted and marked outOfScope. Paginated.',
142
+ inputSchema: {
143
+ id: z.string().describe('Artifact id'),
144
+ direction: z.enum(['source', 'destination', 'both']).optional().describe('Restrict to links where this artifact is the source or the destination (default both)'),
145
+ limit: z.number().int().positive().max(100).optional(),
146
+ skip: z.number().int().min(0).optional(),
147
+ },
148
+ annotations: READ_ONLY,
149
+ }, async ({ id, direction, limit, skip }) => {
150
+ try {
151
+ const artifact = await api.getOne('artifact', id);
152
+ await AssertArtifactInScope(ctx, scope, artifact);
153
+ const clauses = [];
154
+ if (direction !== 'destination')
155
+ clauses.push({ sourceArtifactId: { $oid: id } });
156
+ if (direction !== 'source')
157
+ clauses.push({ destinationArtifactId: { $oid: id } });
158
+ const page = await api.listRecords('link', { $or: clauses }, { skip: skip ?? 0, limit: limit ?? 25 });
159
+ if (page.data.length === 0)
160
+ return Text({ status: 'ok', ...PageMeta(page.meta, 0), results: [] });
161
+ const sys = await ctx.systemAttributes();
162
+ const counterpartIds = [...new Set(page.data.map(l => String(String(l.sourceArtifactId) === id ? l.destinationArtifactId : l.sourceArtifactId)))];
163
+ const counterparts = new Map();
164
+ await Promise.all(counterpartIds.map(async (cid) => {
165
+ try {
166
+ counterparts.set(cid, await api.getOne('artifact', cid));
167
+ }
168
+ catch {
169
+ counterparts.set(cid, null);
170
+ }
171
+ }));
172
+ const linkTypeNames = new Map();
173
+ const results = await Promise.all(page.data.map(async (link) => {
174
+ const ltId = String(link.linkTypeId);
175
+ if (!linkTypeNames.has(ltId))
176
+ linkTypeNames.set(ltId, api.getOne('link-type', ltId).then(lt => lt.name).catch(() => ltId));
177
+ const isSource = String(link.sourceArtifactId) === id;
178
+ const otherId = String(isSource ? link.destinationArtifactId : link.sourceArtifactId);
179
+ const other = counterparts.get(otherId) ?? null;
180
+ const inScope = await CounterpartInScope(ctx, scope, other);
181
+ return {
182
+ linkId: link.id,
183
+ linkType: await linkTypeNames.get(ltId),
184
+ direction: isSource ? 'outgoing' : 'incoming',
185
+ ...(inScope
186
+ ? { otherArtifactId: otherId, otherArtifactName: other?.attributes?.[sys.nameAttributeId]?.value ?? null }
187
+ : { otherArtifactId: null, otherArtifactName: null, outOfScope: true }),
188
+ };
189
+ }));
190
+ return Text({ status: 'ok', ...PageMeta(page.meta, results.length), results });
191
+ }
192
+ catch (e) {
193
+ return ErrorResult(e);
194
+ }
195
+ });
196
+ }
197
+ //# sourceMappingURL=read-artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-artifacts.js","sourceRoot":"","sources":["../../src/tools/read-artifacts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+ import { ResolveEntity, RequireApplicationId } from '../resolve.js';
3
+ import { Text, ErrorResult } from '../result.js';
4
+ const KIND = z.enum(['dataType', 'attribute', 'artifactType', 'linkType', 'folder', 'page']);
5
+ const MAP = { dataType: 'data-type', attribute: 'attribute', artifactType: 'artifact-type', linkType: 'link-type', folder: 'folder', page: 'page' };
6
+ export function RegisterResolveEntity(server, api, scope) {
7
+ server.registerTool('resolve_elwis_entity', {
8
+ description: 'Resolve a data type / attribute / artifact type / link type / folder / page by name or alias within an application to its stable id. Active records only.',
9
+ inputSchema: { applicationId: z.string().optional(), applicationName: z.string().optional(), kind: KIND, nameOrAlias: z.string() },
10
+ annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
11
+ }, async ({ applicationId, applicationName, kind, nameOrAlias }) => {
12
+ try {
13
+ const appId = await RequireApplicationId(api, { applicationId, applicationName });
14
+ await scope.assertAllowed(appId);
15
+ return Text({ status: 'ok', ...(await ResolveEntity(api, MAP[kind], appId, nameOrAlias)) });
16
+ }
17
+ catch (e) {
18
+ return ErrorResult(e);
19
+ }
20
+ });
21
+ }
22
+ //# sourceMappingURL=resolve-entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-entity.js","sourceRoot":"","sources":["../../src/tools/resolve-entity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAC7F,MAAM,GAAG,GAA+B,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAEhL,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,GAAa,EAAE,KAAe;IACrF,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,WAAW,EAAE,2JAA2J;QACxK,WAAW,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;QAClI,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KAC/E,EACD,KAAK,EAAE,EAAE,aAAa,EAAE,eAAe,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;QAC9D,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC,CAAC;YAClF,MAAM,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9F,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { UpdateArtifactsInput, BuildUpdatePlan } from '../builders/records-lifecycle-plan.js';
2
+ import { ExecuteUpdatePlan } from '../builders/records-lifecycle-execute.js';
3
+ import { AssertWriteEnabled, CheckConfirmation, CONFIRMATION_MESSAGE, DRY_RUN_MESSAGE } from '../write-gate.js';
4
+ import { PlanToken } from '../confirm.js';
5
+ import { AuditedExecute } from '../audit.js';
6
+ import { RequireApplicationId } from '../resolve.js';
7
+ import { Text, ErrorResult } from '../result.js';
8
+ export function RegisterUpdateArtifacts(server, api, cfg, scope) {
9
+ server.registerTool('update_elwis_artifacts', {
10
+ description: 'Update existing data records (artifacts) in one batch call (up to 50), the tool for requests like "mark the order as paid", "change the price to 120", or "rename this record". Records are addressed by name (scoped by artifactType when names repeat; one artifactType scope per call, split mixed-type batches) or by id. Only the attributes you pass change; everything else keeps its current value. Attribute keys are names (resolved case-insensitively) or ids; a key that is not assigned to the record\'s type is an error listing the assignable names, the tool never writes to a guessed field. Use rename to change the record\'s Name. A record whose name does not resolve is a clean error: nothing else gets modified in its place. Use dryRun to preview exactly which records and attributes would change.',
11
+ inputSchema: UpdateArtifactsInput.shape,
12
+ annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
13
+ }, async (raw) => {
14
+ try {
15
+ const applicationId = await RequireApplicationId(api, raw);
16
+ await scope.assertAllowed(applicationId);
17
+ const plan = await BuildUpdatePlan(api, raw, applicationId);
18
+ const token = PlanToken(cfg, 'update_elwis_artifacts', plan);
19
+ if (raw.dryRun)
20
+ return Text({ status: 'dry-run', dryRun: true, confirmationToken: token, message: DRY_RUN_MESSAGE, plan });
21
+ AssertWriteEnabled(cfg);
22
+ if (CheckConfirmation(cfg, token, raw.confirm) === 'pending') {
23
+ return Text({ status: 'confirmation-required', confirmationToken: token, plan, message: CONFIRMATION_MESSAGE });
24
+ }
25
+ const report = await AuditedExecute(cfg, scope, 'update_elwis_artifacts', token, () => ExecuteUpdatePlan(api, plan), (r) => ({ updated: r.updated }));
26
+ return Text({ status: 'ok', ...report });
27
+ }
28
+ catch (e) {
29
+ return ErrorResult(e);
30
+ }
31
+ });
32
+ }
33
+ //# sourceMappingURL=update-artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-artifacts.js","sourceRoot":"","sources":["../../src/tools/update-artifacts.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAC9F,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,GAAa,EAAE,GAAgB,EAAE,KAAe;IACzG,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,WAAW,EAAE,myBAAmyB;QAChzB,WAAW,EAAE,oBAAoB,CAAC,KAAK;QACvC,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACvG,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;YAC5D,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,wBAAwB,EAAE,IAAI,CAAC,CAAC;YAC7D,IAAI,GAAG,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3H,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;YAClH,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACtJ,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { UpdateEntityInput, BuildEntityUpdatePlan } from '../builders/entity-lifecycle-plan.js';
2
+ import { ExecuteEntityUpdatePlan } from '../builders/entity-lifecycle-execute.js';
3
+ import { AssertWriteEnabled, CheckConfirmation, CONFIRMATION_MESSAGE, DRY_RUN_MESSAGE } from '../write-gate.js';
4
+ import { PlanToken } from '../confirm.js';
5
+ import { AuditedExecute } from '../audit.js';
6
+ import { RequireApplicationId, ResolveApplicationId } from '../resolve.js';
7
+ import { Text, ErrorResult } from '../result.js';
8
+ export function RegisterUpdateEntity(server, api, cfg, scope) {
9
+ server.registerTool('update_elwis_entity', {
10
+ description: 'Update one configuration entity: an application, data type, attribute, artifact type, link type, workflow, or folder (rename, move via parentFolderId, an id, resolve it with get_elwis_entity, or reorder via folderSequence), the tool for requests like "rename the application", "rename the Status attribute", "add a value to the Priority enum" (enum values live on the data type, in its values array), "change the workflow trigger", or "fix the description". For entity "application", target IS the application (applicationId/applicationName are ignored). The entity is addressed by name, alias, or id within an application (workflows are tenant-wide by name). Read-modify-write: only the fields you pass change, everything else keeps its current value, read the entity first when editing structured fields like values or actions, then send the whole corrected field. id and applicationId cannot be changed. The backend validates the result; a rejected change is a clean error and nothing is modified. Use dryRun to preview the before/after diff of exactly what would change.',
11
+ inputSchema: UpdateEntityInput.shape,
12
+ annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
13
+ }, async (raw) => {
14
+ try {
15
+ const applicationId = raw.entity === 'application'
16
+ ? await ResolveApplicationId(api, raw.target)
17
+ : await RequireApplicationId(api, raw);
18
+ await scope.assertAllowed(applicationId);
19
+ const plan = await BuildEntityUpdatePlan(api, raw, { applicationId, restricted: scope.restricted });
20
+ if (!plan.changedFields.length) {
21
+ return Text({ status: 'no-change', message: 'Every field already has the requested value; nothing was written.', plan: Preview(plan) });
22
+ }
23
+ const token = PlanToken(cfg, 'update_elwis_entity', plan);
24
+ if (raw.dryRun)
25
+ return Text({ status: 'dry-run', dryRun: true, confirmationToken: token, message: DRY_RUN_MESSAGE, plan: Preview(plan) });
26
+ AssertWriteEnabled(cfg);
27
+ if (CheckConfirmation(cfg, token, raw.confirm) === 'pending') {
28
+ return Text({ status: 'confirmation-required', confirmationToken: token, plan: Preview(plan), message: CONFIRMATION_MESSAGE });
29
+ }
30
+ const report = await AuditedExecute(cfg, scope, 'update_elwis_entity', token, () => ExecuteEntityUpdatePlan(api, plan), (r) => r.updated);
31
+ return Text({ status: 'ok', ...report });
32
+ }
33
+ catch (e) {
34
+ return ErrorResult(e);
35
+ }
36
+ });
37
+ }
38
+ function Preview(plan) {
39
+ return { entity: plan.entity, id: plan.id, name: plan.name, changedFields: plan.changedFields };
40
+ }
41
+ //# sourceMappingURL=update-entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-entity.js","sourceRoot":"","sources":["../../src/tools/update-entity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { UpdatePageInput, BuildUpdatePagePlan } from '../builders/update-page-plan.js';
2
+ import { ExecuteUpdatePagePlan } from '../builders/update-page-execute.js';
3
+ import { AssertWriteEnabled, CheckConfirmation, CONFIRMATION_MESSAGE, DRY_RUN_MESSAGE } from '../write-gate.js';
4
+ import { PlanToken } from '../confirm.js';
5
+ import { AuditedExecute } from '../audit.js';
6
+ import { RequireApplicationId } from '../resolve.js';
7
+ import { Text, ErrorResult } from '../result.js';
8
+ export function RegisterUpdatePage(server, api, cfg, scope) {
9
+ server.registerTool('update_elwis_page', {
10
+ description: `Change an existing page in place, the tool for requests like "make the background darker", "change the header text", "add a banner", or "remove the second section". Call get_elwis_page first to see the structure and widget ids.
11
+
12
+ OPERATIONS: sectionStyles (merge or replace a section's CSS), widgetTexts (replace a TEXT widget's HTML content), addSections / removeSections, rename / alias / isPublic. sectionStyles and removeSections use the section numbers get_elwis_page returned; addSections positions are evaluated after removals.
13
+
14
+ STYLE VOCABULARY, users speak plainly, not in CSS; translate their words: "beautiful/modern" = rounded corners (12-14px), soft shadows, generous padding, a restrained palette; "animated/alive" = :hover transitions and @keyframes fade or slide-in inside the widget's <style> block (script tags never execute, interactivity only via inline on* attributes); "dark mode/carbon/black" = backgroundColor around #0f0f14, panels #1a1524, light text #e0e0e0; "darker/lighter" alone = shift the CURRENT backgroundColor (visible in get_elwis_page section styles) a step in that direction, not a jump to the dark palette; "warmer" = cream/beige backgrounds (#faf6f0) with an amber accent, "cooler" = blue-gray tones; "cleaner/minimal" = remove shadows and borders, white background, one accent color, larger headings, MORE padding; "bigger" = one step up in font-size and padding; "more space/air" = outerContainer paddingTop/paddingBottom 24-48px. Backgrounds and spacing belong on section outerContainer styles; visual detail (cards, buttons, animations) lives inside widget HTML via widgetTexts.
15
+
16
+ BEFORE WRITING: widgetTexts replaces the ENTIRE widget content, first fetch the current HTML with get_elwis_page fullTextWidgets:[id] and modify it; never regenerate a widget from its excerpt. removeSections and widgetTexts cannot be undone: always call with dryRun:true first, show the user the change summary, and repeat without dryRun only after they confirm. When the request is vague, propose 2-3 concrete options (which section, what colors, what text) and make your first call with dryRun:true so the user confirms the actual change, not a paraphrase of it.`,
17
+ inputSchema: UpdatePageInput.shape,
18
+ annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
19
+ }, async (raw) => {
20
+ try {
21
+ const applicationId = await RequireApplicationId(api, raw);
22
+ await scope.assertAllowed(applicationId);
23
+ const plan = await BuildUpdatePagePlan(api, raw, applicationId);
24
+ const token = PlanToken(cfg, 'update_elwis_page', plan);
25
+ if (raw.dryRun) {
26
+ return Text({ status: 'dry-run', dryRun: true, confirmationToken: token, message: DRY_RUN_MESSAGE, page: plan.page, changes: plan.summary, newWidgets: plan.newWidgets.length });
27
+ }
28
+ AssertWriteEnabled(cfg);
29
+ if (CheckConfirmation(cfg, token, raw.confirm) === 'pending') {
30
+ return Text({ status: 'confirmation-required', confirmationToken: token, page: plan.page, changes: plan.summary, message: CONFIRMATION_MESSAGE });
31
+ }
32
+ const report = await AuditedExecute(cfg, scope, 'update_elwis_page', token, () => ExecuteUpdatePagePlan(api, plan), (r) => ({ page: r.page, applied: r.applied, createdWidgets: r.createdWidgets.length, updatedWidgets: r.updatedWidgets }));
33
+ return Text({ status: 'ok', ...report });
34
+ }
35
+ catch (e) {
36
+ return ErrorResult(e);
37
+ }
38
+ });
39
+ }
40
+ //# sourceMappingURL=update-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-page.js","sourceRoot":"","sources":["../../src/tools/update-page.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,GAAa,EAAE,GAAgB,EAAE,KAAe;IACpG,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,WAAW,EAAE;;;;;;qjBAMkiB;QAC/iB,WAAW,EAAE,eAAe,CAAC,KAAK;QAClC,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;KACxG,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;YAChE,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC;YACxD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;YACnL,CAAC;YACD,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACpJ,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;YAC9O,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ export const DRY_RUN_MESSAGE = 'Preview only, nothing was written. Summarize the plan for the user in plain language. After they approve, call again without dryRun and with confirm set to this confirmationToken; one approval is enough, do not ask twice.';
2
+ export const CONFIRMATION_MESSAGE = 'Not executed yet. Summarize this plan for the user in plain language, what will be created or changed, with names and counts, no raw JSON or ids, and ask one clear yes/no question. Never show or mention the confirmationToken; it is internal to your next tool call. Once the user agrees, call this tool again with the same arguments plus confirm set to the confirmationToken. If the user already approved this exact plan earlier in the conversation (the dryRun preview carrying this same confirmationToken), that approval counts, execute now instead of asking again.';
3
+ export class WriteDisabledError extends Error {
4
+ constructor() { super('Writes are disabled. Set ELWIS_WRITE_ENABLED=true to allow build tools.'); this.name = 'WriteDisabledError'; }
5
+ }
6
+ export class StalePlanError extends Error {
7
+ constructor() {
8
+ super('Nothing was written. This plan is not the one that was confirmed, either the underlying data changed since the preview, or the arguments differ from what was previewed. Run the preview again, show the user the current plan in plain language, and get a fresh approval before executing.');
9
+ this.name = 'StalePlanError';
10
+ }
11
+ }
12
+ export function AssertWriteEnabled(cfg) {
13
+ if (!cfg.writeEnabled)
14
+ throw new WriteDisabledError();
15
+ }
16
+ export function CheckConfirmation(cfg, token, confirm) {
17
+ if (!cfg.requireConfirmation)
18
+ return 'execute';
19
+ if (!confirm)
20
+ return 'pending';
21
+ if (confirm !== token)
22
+ throw new StalePlanError();
23
+ return 'execute';
24
+ }
25
+ //# sourceMappingURL=write-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-gate.js","sourceRoot":"","sources":["../src/write-gate.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAC1B,+NAA+N,CAAC;AAElO,MAAM,CAAC,MAAM,oBAAoB,GAC/B,ujBAAujB,CAAC;AAE1jB,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,gBAAgB,KAAK,CAAC,yEAAyE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC,CAAC,CAAC;CACtI;AAED,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC;QACE,KAAK,CAAC,8RAA8R,CAAC,CAAC;QACtS,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAgB;IACjD,IAAI,CAAC,GAAG,CAAC,YAAY;QAAE,MAAM,IAAI,kBAAkB,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAgB,EAAE,KAAa,EAAE,OAA2B;IAC5F,IAAI,CAAC,GAAG,CAAC,mBAAmB;QAAE,OAAO,SAAS,CAAC;IAC/C,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,IAAI,OAAO,KAAK,KAAK;QAAE,MAAM,IAAI,cAAc,EAAE,CAAC;IAClD,OAAO,SAAS,CAAC;AACnB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@softacus-software/elwis-data-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Write-capable Model Context Protocol server for building ELWIS configuration over the ELWIS HTTP API.",
5
+ "type": "module",
6
+ "bin": {
7
+ "elwis-data-mcp": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "README.md",
12
+ "CHANGELOG.md",
13
+ "LICENSE"
14
+ ],
15
+ "engines": {
16
+ "node": ">=22"
17
+ },
18
+ "scripts": {
19
+ "build": "shx rm -rf dist && tsc && shx chmod +x dist/index.js",
20
+ "watch": "tsc --watch",
21
+ "lint": "eslint .",
22
+ "start": "node dist/index.js",
23
+ "dev": "tsx src/index.ts",
24
+ "test": "tsx --test test/*.test.ts",
25
+ "prepack": "npm run build",
26
+ "prepare": "npm run build"
27
+ },
28
+ "dependencies": {
29
+ "@modelcontextprotocol/sdk": "^1.29.0",
30
+ "zod": "^4.4.3"
31
+ },
32
+ "devDependencies": {
33
+ "@eslint/js": "^10.0.1",
34
+ "@types/node": "^26.0.1",
35
+ "eslint": "^10.6.0",
36
+ "shx": "^0.4.0",
37
+ "tsx": "^4.22.4",
38
+ "typescript": "^6.0.3",
39
+ "typescript-eslint": "^8.62.1"
40
+ },
41
+ "publishConfig": {
42
+ "access": "restricted"
43
+ },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://git.softacus.com/elwis/manage-data-mcp.git"
47
+ },
48
+ "keywords": [
49
+ "modelcontextprotocol",
50
+ "mcp",
51
+ "elwis",
52
+ "softacus"
53
+ ],
54
+ "license": "UNLICENSED"
55
+ }