@ffschrattenecker/tm1-mcp-server 7.0.2 → 8.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.
Files changed (109) hide show
  1. package/CHANGELOG.md +83 -1
  2. package/README.md +5 -5
  3. package/dist/config.js +34 -17
  4. package/dist/connections.d.ts +18 -1
  5. package/dist/connections.js +34 -18
  6. package/dist/http-transport.js +51 -4
  7. package/dist/lib/callgraph/referenceIndex.js +2 -1
  8. package/dist/lib/callgraph/rulesLinter.d.ts +0 -19
  9. package/dist/lib/callgraph/rulesLinter.js +0 -590
  10. package/dist/lib/callgraph/tiParser.js +10 -5
  11. package/dist/lib/callgraph/tm1-adapter.d.ts +5 -1
  12. package/dist/lib/callgraph/tm1-adapter.js +41 -9
  13. package/dist/lib/callgraph/variableEnv.js +3 -2
  14. package/dist/lib/cell-address.d.ts +1 -1
  15. package/dist/lib/cell-address.js +2 -2
  16. package/dist/lib/complexity/antipatterns.js +3 -1
  17. package/dist/lib/complexity/comment-classifier.js +2 -1
  18. package/dist/lib/feeders/element-type-cache.js +4 -6
  19. package/dist/lib/naming/odata-filter.js +2 -1
  20. package/dist/lib/pro-parser.js +13 -4
  21. package/dist/lib/safe-regex.d.ts +0 -13
  22. package/dist/lib/safe-regex.js +40 -13
  23. package/dist/lib/ti-identifier.d.ts +11 -0
  24. package/dist/lib/ti-identifier.js +11 -0
  25. package/dist/lib/tm1-name.d.ts +9 -0
  26. package/dist/lib/tm1-name.js +9 -0
  27. package/dist/lib/v12-compat/deprecated-ti.js +2 -2
  28. package/dist/session-manager.d.ts +1 -0
  29. package/dist/session-manager.js +24 -0
  30. package/dist/tm1-client/connection/profile.js +2 -4
  31. package/dist/tm1-client/dispatcher.d.ts +1 -1
  32. package/dist/tm1-client/dispatcher.js +18 -6
  33. package/dist/tm1-client/http.d.ts +21 -0
  34. package/dist/tm1-client/http.js +39 -30
  35. package/dist/tm1-client/services/cell-service.d.ts +9 -7
  36. package/dist/tm1-client/services/cell-service.js +51 -25
  37. package/dist/tm1-client/services/chore-service.js +8 -9
  38. package/dist/tm1-client/services/cube-service.d.ts +14 -18
  39. package/dist/tm1-client/services/cube-service.js +51 -45
  40. package/dist/tm1-client/services/dimension-order.d.ts +13 -0
  41. package/dist/tm1-client/services/dimension-order.js +42 -0
  42. package/dist/tm1-client/services/dimension-service.js +4 -6
  43. package/dist/tm1-client/services/element-service.d.ts +35 -11
  44. package/dist/tm1-client/services/element-service.js +124 -60
  45. package/dist/tm1-client/services/file-service.d.ts +42 -6
  46. package/dist/tm1-client/services/file-service.js +225 -28
  47. package/dist/tm1-client/services/hierarchy-service.d.ts +19 -9
  48. package/dist/tm1-client/services/hierarchy-service.js +118 -12
  49. package/dist/tm1-client/services/monitoring-service.js +2 -5
  50. package/dist/tm1-client/services/odata-page.d.ts +6 -0
  51. package/dist/tm1-client/services/odata-page.js +8 -0
  52. package/dist/tm1-client/services/process-service.d.ts +1 -1
  53. package/dist/tm1-client/services/process-service.js +26 -26
  54. package/dist/tm1-client/services/security-service.js +8 -9
  55. package/dist/tm1-client/services/server-service.js +14 -15
  56. package/dist/tm1-client/services/subset-service.d.ts +23 -10
  57. package/dist/tm1-client/services/subset-service.js +82 -26
  58. package/dist/tm1-client/services/view-service.js +12 -13
  59. package/dist/tm1-client.js +5 -2
  60. package/dist/tools/analysis/check-v12-readiness.js +3 -3
  61. package/dist/tools/celldata/check-feeders.js +6 -6
  62. package/dist/tools/celldata/check-writable-coords.js +33 -22
  63. package/dist/tools/celldata/execute-mdx.js +10 -9
  64. package/dist/tools/celldata/get-view.js +10 -9
  65. package/dist/tools/celldata/member-ref.d.ts +15 -0
  66. package/dist/tools/celldata/member-ref.js +67 -0
  67. package/dist/tools/celldata/trace-cell-calculation.js +6 -6
  68. package/dist/tools/celldata/trace-feeders.js +6 -6
  69. package/dist/tools/celldata/write-cells.js +62 -12
  70. package/dist/tools/dimension-management/create-element-attribute.js +1 -1
  71. package/dist/tools/dimension-management/delete-hierarchy.js +3 -4
  72. package/dist/tools/dimension-management/get-element-attribute-values.js +7 -2
  73. package/dist/tools/dimension-management/list-element-attributes.js +1 -1
  74. package/dist/tools/dimension-management/update-element-attribute-value.js +8 -3
  75. package/dist/tools/dimension-management/update-element.js +14 -7
  76. package/dist/tools/fileops/container.d.ts +8 -0
  77. package/dist/tools/fileops/container.js +11 -0
  78. package/dist/tools/fileops/delete-file.js +4 -2
  79. package/dist/tools/fileops/get-file-content.js +45 -7
  80. package/dist/tools/fileops/list-files.js +5 -2
  81. package/dist/tools/fileops/search-files.js +4 -1
  82. package/dist/tools/fileops/upload-file.js +5 -2
  83. package/dist/tools/index.js +0 -2
  84. package/dist/tools/model-building/check-cube-rule.js +3 -2
  85. package/dist/tools/model-building/clear-cube.js +35 -26
  86. package/dist/tools/model-building/set-cube-rules.js +13 -20
  87. package/dist/tools/model-building/unload-cube.js +1 -1
  88. package/dist/tools/operations/get-cube-stats.js +1 -1
  89. package/dist/tools/operations/get-transaction-log.js +1 -1
  90. package/dist/tools/operations/list-error-logs.js +27 -2
  91. package/dist/tools/schemas/items-fileops.d.ts +4 -0
  92. package/dist/tools/schemas/items-fileops.js +1 -0
  93. package/dist/tools/security/list-clients.js +5 -5
  94. package/dist/tools/security/list-groups.js +1 -1
  95. package/dist/tools/subsets/create-subset.js +9 -5
  96. package/dist/tools/subsets/delete-subset.js +8 -3
  97. package/dist/tools/subsets/update-subset.js +9 -9
  98. package/dist/tools/ti-development/diff-process-with-file.js +4 -29
  99. package/dist/tools/ti-development/diff-processes.js +9 -0
  100. package/dist/tools/ti-development/export-process-to-git.js +9 -7
  101. package/dist/tools/ti-development/export-process-to-pro.js +15 -8
  102. package/dist/tools/ti-development/import-pro-file.js +10 -21
  103. package/dist/tools/ti-development/import-process-from-git.js +8 -18
  104. package/dist/tools/ti-development/install-pro-bundle.js +2 -2
  105. package/dist/tools/ti-development/upsert-process.js +26 -5
  106. package/npm-shrinkwrap.json +10 -9
  107. package/package.json +9 -5
  108. package/dist/tools/dimension-management/move-element.d.ts +0 -2
  109. package/dist/tools/dimension-management/move-element.js +0 -28
@@ -4,7 +4,7 @@ import { z } from "zod";
4
4
  import { TM1Error, TM1ErrorCode } from "../../types.js";
5
5
  import { parseProFile } from "../../lib/pro-parser.js";
6
6
  import { withToolHint } from "../error-format.js";
7
- import { IDEMPOTENT_DESTRUCTIVE, withVersion } from "../annotations.js";
7
+ import { IDEMPOTENT_DESTRUCTIVE } from "../annotations.js";
8
8
  import { ImportProFileResultSchema } from "../schemas/items.js";
9
9
  import { defineTool } from "../define-tool.js";
10
10
  import { OVERWRITE_CONFIRM_SCHEMA, requireOverwriteConfirm, } from "../confirm.js";
@@ -13,7 +13,7 @@ import { backupProcess } from "./process-backup.js";
13
13
  export const registerImportProFile = defineTool({
14
14
  name: "tm1_import_pro_file",
15
15
  description: "Parse a TM1 .pro file (Tabs / Parameters / Variables / DataSource) and deploy the process in one call. Provide either filePath (absolute path on the MCP host) or content (the .pro file body as string). Modes: 'create' (fail if exists), 'update' (fail if missing), 'upsert' (default — create or update). A .pro carries an ODBC password only when it came from tm1_export_process_to_pro against a v12 database, which writes it in clear; TM1's own Datadir .pro encodes slot 565 in a form that cannot be replayed over REST, and v11 exports never contain a password at all. Pass dataSourcePassword in every other case.",
16
- annotations: withVersion(IDEMPOTENT_DESTRUCTIVE, "v11"),
16
+ annotations: IDEMPOTENT_DESTRUCTIVE,
17
17
  output: ImportProFileResultSchema,
18
18
  input: {
19
19
  filePath: z
@@ -108,25 +108,14 @@ export const registerImportProFile = defineTool({
108
108
  data: parsed.data,
109
109
  epilog: parsed.epilog,
110
110
  }), `Code update failed after process '${processName}' was ${exists ? "located" : "created"}. PARTIAL APPLY: the process shell exists but tabs are stale/empty. Re-run tm1_import_pro_file with mode=update once root cause fixed, or tm1_delete_process to roll back.`);
111
- // On an update the file replaces the whole definition, as the code tabs
112
- // already do: an empty parameter list, variable layout or a None
113
- // datasource is applied, not skipped. Skipping left the newer values in
114
- // place, so importing an older version (a backup) did not restore it.
115
- if (exists || parsed.parameters.length > 0) {
116
- await withToolHint(tm1Client.processes.updateParameters(processName, parsed.parameters), `Parameter update failed for '${processName}'. Code applied but parameters missing. Inspect parsed parameters and re-run tm1_upsert_process with mode=update + parameters=[...] to recover.`);
117
- }
118
- // Ignored columns live only in the UI data, so a file can carry column
119
- // layout with an empty variable list — patch on either.
120
- if (exists ||
121
- parsed.variables.length > 0 ||
122
- parsed.variablesUIData.length > 0) {
123
- await withToolHint(tm1Client.processes.updateVariables(processName, parsed.variables, parsed.variablesUIData.length > 0 || parsed.variables.length === 0
124
- ? parsed.variablesUIData
125
- : undefined), `Variable update failed for '${processName}'. Code+parameters applied but variables missing. tm1_upsert_process with mode=update + variables=[...] to recover.`);
126
- }
127
- if (exists || parsed.dataSource.type !== "None") {
128
- await withToolHint(tm1Client.processes.updateDataSource(processName, parsed.dataSource), `Datasource update failed for '${processName}' (type=${parsed.dataSource.type}). Code+params+vars applied. Verify datasource credentials/path (ASCII file existence, ODBC DSN, view name) and re-run tm1_upsert_process with mode=update + dataSource={...} to recover.`);
129
- }
111
+ // The file is the whole truth: an empty list or a None source is sent as
112
+ // well, because TM1 applies both (measured on 11.8 and 12.5) and skipping
113
+ // them left the removed parameters, variables and source on the server.
114
+ await withToolHint(tm1Client.processes.updateParameters(processName, parsed.parameters), `Parameter update failed for '${processName}'. Code applied but parameters missing. Inspect parsed parameters and re-run tm1_upsert_process with mode=update + parameters=[...] to recover.`);
115
+ // A file without a column-layout block leaves the server's layout as it
116
+ // is; one that carries it replaces it.
117
+ await withToolHint(tm1Client.processes.updateVariables(processName, parsed.variables, parsed.variablesUIData.length > 0 ? parsed.variablesUIData : undefined), `Variable update failed for '${processName}'. Code+parameters applied but variables missing. tm1_upsert_process with mode=update + variables=[...] to recover.`);
118
+ await withToolHint(tm1Client.processes.updateDataSource(processName, parsed.dataSource), `Datasource update failed for '${processName}' (type=${parsed.dataSource.type}). Code+params+vars applied. Verify datasource credentials/path (ASCII file existence, ODBC DSN, view name) and re-run tm1_upsert_process with mode=update + dataSource={...} to recover.`);
130
119
  return {
131
120
  content: [
132
121
  {
@@ -148,24 +148,14 @@ export const registerImportProcessFromGit = defineTool({
148
148
  // The parsed tabs were preflighted above; unplacedBlobContent() made
149
149
  // sure they cover this blob exactly, so what was checked is what deploys.
150
150
  await withToolHint(tm1Client.processes.updateCodeBlob(processName, ti.replace(/\r?\n/g, "\r\n")), `Code update failed after process '${processName}' was ${exists ? "located" : "created"}. PARTIAL APPLY: shell exists but tabs are stale/empty. Re-run with mode=update once root cause fixed, or tm1_delete_process to roll back.`);
151
- // On an update the file replaces the whole definition, as the code tabs
152
- // already do: an empty parameter list, variable layout or a None
153
- // datasource is applied, not skipped. Skipping left the newer values in
154
- // place, so importing an older version (a backup) did not restore it.
155
- if (exists || parsed.parameters.length > 0) {
156
- await withToolHint(tm1Client.processes.updateParameters(processName, parsed.parameters), `Parameter update failed for '${processName}'. Code applied but parameters missing. tm1_upsert_process with mode=update + parameters=[...] to recover.`);
157
- }
158
- // Ignored columns live only in the UI data, so a .json can carry column
159
- // layout with an empty variable list — patch on either.
160
- if (exists ||
161
- parsed.variables.length > 0 ||
162
- (parsed.variablesUIData?.length ?? 0) > 0) {
163
- await withToolHint(tm1Client.processes.updateVariables(processName, parsed.variables, parsed.variablesUIData ??
164
- (parsed.variables.length === 0 ? [] : undefined)), `Variable update failed for '${processName}'. Code+parameters applied but variables missing. tm1_upsert_process with mode=update + variables=[...] to recover.`);
165
- }
166
- if (exists || dataSource.type !== "None") {
167
- await withToolHint(tm1Client.processes.updateDataSource(processName, dataSource), `Datasource update failed for '${processName}' (type=${dataSource.type}). Code+params+vars applied. For ODBC verify dataSourcePassword/DSN and re-run with mode=update.`);
168
- }
151
+ // The file is the whole truth: an empty list or a None source is sent as
152
+ // well, because TM1 applies both (measured on 11.8 and 12.5) and skipping
153
+ // them left the removed parameters, variables and source on the server.
154
+ await withToolHint(tm1Client.processes.updateParameters(processName, parsed.parameters), `Parameter update failed for '${processName}'. Code applied but parameters missing. tm1_upsert_process with mode=update + parameters=[...] to recover.`);
155
+ // An export without variablesUIData (older format) leaves the server's
156
+ // column layout as it is; one that carries it replaces it.
157
+ await withToolHint(tm1Client.processes.updateVariables(processName, parsed.variables, parsed.variablesUIData), `Variable update failed for '${processName}'. Code+parameters applied but variables missing. tm1_upsert_process with mode=update + variables=[...] to recover.`);
158
+ await withToolHint(tm1Client.processes.updateDataSource(processName, dataSource), `Datasource update failed for '${processName}' (type=${dataSource.type}). Code+params+vars applied. For ODBC verify dataSourcePassword/DSN and re-run with mode=update.`);
169
159
  if (parsed.hasSecurityAccess !== undefined) {
170
160
  await withToolHint(tm1Client.processes.updateSecurityAccess(processName, parsed.hasSecurityAccess), `HasSecurityAccess update failed for '${processName}'. Code+params+vars+datasource applied. Re-run with mode=update once root cause fixed.`);
171
161
  }
@@ -5,7 +5,7 @@ import { TM1Error, TM1ErrorCode } from "../../types.js";
5
5
  import { compileUserRegex } from "../../lib/safe-regex.js";
6
6
  import { parseProFile } from "../../lib/pro-parser.js";
7
7
  import { resolveLocalPath } from "../local-file.js";
8
- import { IDEMPOTENT_DESTRUCTIVE, withVersion } from "../annotations.js";
8
+ import { IDEMPOTENT_DESTRUCTIVE } from "../annotations.js";
9
9
  import { InstallProBundleResultSchema } from "../schemas/items.js";
10
10
  import { defineTool } from "../define-tool.js";
11
11
  import { runPreflight } from "./preflight.js";
@@ -13,7 +13,7 @@ import { backupProcess } from "./process-backup.js";
13
13
  export const registerInstallProBundle = defineTool({
14
14
  name: "tm1_install_pro_bundle",
15
15
  description: "Install all .pro files from a directory in one call. Iterates the directory (non-recursive by default), applies tm1_import_pro_file logic per file, and reports per-file outcome. Stops on first failure unless continueOnError=true. Useful for Bedrock or library deployments.",
16
- annotations: withVersion(IDEMPOTENT_DESTRUCTIVE, "v11"),
16
+ annotations: IDEMPOTENT_DESTRUCTIVE,
17
17
  output: InstallProBundleResultSchema,
18
18
  input: {
19
19
  directory: z
@@ -42,7 +42,14 @@ export const registerUpsertProcess = defineTool({
42
42
  data: z.string().optional(),
43
43
  epilog: z.string().optional(),
44
44
  parameters: z.array(parameterSchema).optional(),
45
- variables: z.array(variableSchema).optional(),
45
+ variables: z
46
+ .array(variableSchema)
47
+ .optional()
48
+ .describe("Replaces the complete variable list; [] removes every variable."),
49
+ variablesUIData: z
50
+ .array(z.string())
51
+ .optional()
52
+ .describe("Raw per-column layout (VariablesUIData), one entry per source column including ignored ones, sent verbatim. Take it from tm1_get_process_variables or an export; do not construct entries. Omitted: the server keeps its current layout."),
46
53
  dataSource: dataSourceSchema.optional(),
47
54
  hasSecurityAccess: z
48
55
  .boolean()
@@ -66,7 +73,7 @@ export const registerUpsertProcess = defineTool({
66
73
  .default(false)
67
74
  .describe("Write nothing. Run the syntax AND reference check on the process as it would be after this call (both reported, neither stops the other) and diff it against the installed version (credentials masked). Needs no confirm and is not one: the real call still needs it. Replaces a separate check_process_code + validate_process_refs + diff before the risk assessment."),
68
75
  },
69
- handler: async ({ processName, prolog, metadata, data, epilog, parameters, variables, dataSource, hasSecurityAccess, mode, preflight, autoCompile, dryRun, confirm, }, tm1Client) => {
76
+ handler: async ({ processName, prolog, metadata, data, epilog, parameters, variables, variablesUIData, dataSource, hasSecurityAccess, mode, preflight, autoCompile, dryRun, confirm, }, tm1Client) => {
70
77
  const trail = [];
71
78
  const exists = await tm1Client.processes.exists(processName);
72
79
  if (mode === "create" && exists) {
@@ -199,8 +206,21 @@ export const registerUpsertProcess = defineTool({
199
206
  await tm1Client.processes.updateParameters(processName, parameters);
200
207
  trail.push("updateProcessParameters");
201
208
  }
202
- if (variables !== undefined && variables.length > 0) {
203
- await tm1Client.processes.updateVariables(processName, variables);
209
+ let warning;
210
+ if (variables !== undefined || variablesUIData !== undefined) {
211
+ // A Variables PATCH alone leaves the server's VariablesUIData in place
212
+ // (measured on 11.8 and 12.5). When the new variable count no longer
213
+ // matches the kept layout's non-ignored columns, the ignore markers
214
+ // point at the wrong columns — say so rather than guess a layout.
215
+ if (exists && variables !== undefined && variablesUIData === undefined) {
216
+ const layout = await tm1Client.processes.getVariableLayout(processName);
217
+ const kept = layout.variablesUIData?.length ?? 0;
218
+ const used = kept - layout.ignoredColumns.length;
219
+ if (kept > 0 && used !== variables.length) {
220
+ warning = `VariablesUIData left as on the server: it describes ${used} used and ${layout.ignoredColumns.length} ignored column(s), but ${variables.length} variable(s) were written. Pass variablesUIData to replace the column layout.`;
221
+ }
222
+ }
223
+ await tm1Client.processes.updateVariables(processName, variables, variablesUIData);
204
224
  trail.push("updateProcessVariables");
205
225
  }
206
226
  if (dataSource !== undefined) {
@@ -213,7 +233,7 @@ export const registerUpsertProcess = defineTool({
213
233
  }
214
234
  // Process body/parameters/datasource may have changed call sites — drop the
215
235
  // 60s callgraph TTL so the next analysis sees fresh references instead of stale graph.
216
- const { cleared: callgraphEntriesCleared } = invalidateCallgraphCache();
236
+ const { cleared: callgraphEntriesCleared } = invalidateCallgraphCache(tm1Client.connectionId);
217
237
  // Read the code back: TM1 stores what REST sent, so a mismatch means the
218
238
  // write did not land as sent. Saves the caller a get_process turn.
219
239
  const sent = { prolog, metadata, data, epilog };
@@ -247,6 +267,7 @@ export const registerUpsertProcess = defineTool({
247
267
  ...(backup ? { backup } : {}),
248
268
  ...(verified !== undefined ? { verified } : {}),
249
269
  ...(compile !== undefined ? { compile } : {}),
270
+ ...(warning !== undefined ? { warning } : {}),
250
271
  }, null, 2),
251
272
  },
252
273
  ],
@@ -1,17 +1,18 @@
1
1
  {
2
2
  "name": "@ffschrattenecker/tm1-mcp-server",
3
- "version": "7.0.2",
3
+ "version": "8.0.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@ffschrattenecker/tm1-mcp-server",
9
- "version": "7.0.2",
9
+ "version": "8.0.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "@modelcontextprotocol/sdk": "1.30.0",
12
+ "@modelcontextprotocol/sdk": "1.30.1",
13
13
  "dotenv": "^18.0.0",
14
14
  "pino": "^10.3.1",
15
+ "regexp-tree": "^0.1.27",
15
16
  "safe-regex": "^2.1.1",
16
17
  "undici": "^8.10.2",
17
18
  "zod": "4.6.5"
@@ -822,9 +823,9 @@
822
823
  "license": "MIT"
823
824
  },
824
825
  "node_modules/@modelcontextprotocol/sdk": {
825
- "version": "1.30.0",
826
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz",
827
- "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==",
826
+ "version": "1.30.1",
827
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.1.tgz",
828
+ "integrity": "sha512-H2HxLvC3HDNybePJaLdSrU1hhUK5iQw+WvV1b01myFyI7sdVGe1u/IPTE5D9fGCiJDVtgMV/lmFkQXLmQyIFYA==",
828
829
  "license": "MIT",
829
830
  "dependencies": {
830
831
  "@hono/node-server": "^1.19.9 || ^2.0.5",
@@ -2404,9 +2405,9 @@
2404
2405
  "license": "MIT"
2405
2406
  },
2406
2407
  "node_modules/fast-uri": {
2407
- "version": "3.1.8",
2408
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
2409
- "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
2408
+ "version": "4.2.1",
2409
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.2.1.tgz",
2410
+ "integrity": "sha512-TmHQgewjHtMq1E5QKA0tOE0yeYGQs25KZC/ziJpubRtWI15W92e6vPFydWOeZBVROSHBYw/QhD9d5OefdD6LDg==",
2410
2411
  "funding": [
2411
2412
  {
2412
2413
  "type": "github",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ffschrattenecker/tm1-mcp-server",
3
- "version": "7.0.2",
3
+ "version": "8.0.0",
4
4
  "description": "MCP server for IBM Planning Analytics / TM1 — full model lifecycle via REST API",
5
5
  "repository": {
6
6
  "type": "git",
@@ -43,6 +43,7 @@
43
43
  "test:unit": "vitest run tests/unit",
44
44
  "test:property": "vitest run tests/property",
45
45
  "test:live": "vitest run --config vitest.live.config.ts",
46
+ "test:live:for": "tsx scripts/run-live-for.ts",
46
47
  "test:live:nightly": "node scripts/run-live-nightly.mjs",
47
48
  "contracts:record": "node scripts/record-wire-contracts.mjs",
48
49
  "contracts:verify": "node scripts/record-wire-contracts.mjs tm1-test --verify",
@@ -58,14 +59,16 @@
58
59
  "lint:tool-registration": "node scripts/check-tool-registration.mjs",
59
60
  "lint:input-naming": "node scripts/check-no-bare-name-input.mjs",
60
61
  "lint:mutation-envelope": "node scripts/check-mutation-envelope.mjs",
62
+ "lint:no-local-enc": "node scripts/check-no-local-enc.mjs",
61
63
  "lint:format": "prettier --check .",
62
64
  "format": "prettier --write .",
63
- "verify": "npm run typecheck && npm run typecheck:tests && npm run lint:no-flat-api && npm run lint:output-schema-budget && npm run lint:tool-surface-budget && npm run lint:tool-registration && npm run lint:input-naming && npm run lint:mutation-envelope && npm run lint:format && npm run lint:eslint && npm run coverage:check",
65
+ "audit:prod": "npm audit --omit=dev --audit-level=high",
66
+ "verify": "npm run audit:prod && npm run typecheck && npm run typecheck:tests && npm run lint:no-flat-api && npm run lint:output-schema-budget && npm run lint:tool-surface-budget && npm run lint:tool-registration && npm run lint:input-naming && npm run lint:mutation-envelope && npm run lint:no-local-enc && npm run lint:format && npm run lint:eslint && npm run coverage:check",
64
67
  "tools:list": "node scripts/gen-tool-list.mjs",
65
68
  "tools:update-readme": "node scripts/gen-tool-list.mjs --write-readme",
66
69
  "lint:eslint": "eslint .",
67
70
  "measure:tools": "node scripts/measure-tool-surface.mjs",
68
- "lint:tool-surface-budget": "node scripts/measure-tool-surface.mjs --top 0 --budget 133000"
71
+ "lint:tool-surface-budget": "node scripts/measure-tool-surface.mjs --top 0 --budget 140000"
69
72
  },
70
73
  "keywords": [
71
74
  "mcp",
@@ -78,13 +81,14 @@
78
81
  "node": ">=22.19.0"
79
82
  },
80
83
  "overrides": {
81
- "fast-uri": "^3.1.5",
84
+ "fast-uri": "^4.2.1",
82
85
  "ip-address": "^10.4.0"
83
86
  },
84
87
  "dependencies": {
85
- "@modelcontextprotocol/sdk": "1.30.0",
88
+ "@modelcontextprotocol/sdk": "1.30.1",
86
89
  "dotenv": "^18.0.0",
87
90
  "pino": "^10.3.1",
91
+ "regexp-tree": "^0.1.27",
88
92
  "safe-regex": "^2.1.1",
89
93
  "undici": "^8.10.2",
90
94
  "zod": "4.6.5"
@@ -1,2 +0,0 @@
1
- export declare const registerMoveElement: import("../define-tool.js").ToolRegistrar;
2
- //# sourceMappingURL=move-element.d.ts.map
@@ -1,28 +0,0 @@
1
- import { z } from "zod";
2
- import { actionResponse } from "../format.js";
3
- import { MutationResultSchema } from "../schemas/items.js";
4
- import { WRITE } from "../annotations.js";
5
- import { defineTool } from "../define-tool.js";
6
- import { HIERARCHY_NAME_OPTIONAL, resolveHierarchy } from "../hierarchy.js";
7
- export const registerMoveElement = defineTool({
8
- name: "tm1_move_element",
9
- description: "Move an element to a new parent within a TM1 dimension hierarchy",
10
- annotations: WRITE,
11
- output: MutationResultSchema,
12
- input: {
13
- dimensionName: z.string().describe("Name of the dimension"),
14
- ...HIERARCHY_NAME_OPTIONAL,
15
- elementName: z.string().describe("Name of the element to move"),
16
- newParent: z.string().describe("Name of the new parent element"),
17
- weight: z
18
- .number()
19
- .optional()
20
- .describe("Weight for the parent-child relationship (default: 1)"),
21
- },
22
- handler: async ({ dimensionName, hierarchyName, elementName, newParent, weight }, tm1Client) => {
23
- const hierarchy = resolveHierarchy(dimensionName, hierarchyName);
24
- await tm1Client.elements.move(dimensionName, hierarchy, elementName, newParent, weight);
25
- return actionResponse({ success: true, elementName, newParent });
26
- },
27
- });
28
- //# sourceMappingURL=move-element.js.map