postgresai 0.15.0-dev.1 → 0.15.0-dev.10
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 +3 -1
- package/bin/postgres-ai.ts +606 -105
- package/bun.lock +4 -4
- package/dist/bin/postgres-ai.js +2355 -577
- package/instances.demo.yml +14 -0
- package/lib/checkup-api.ts +25 -6
- package/lib/checkup.ts +241 -10
- package/lib/config.ts +3 -0
- package/lib/init.ts +196 -4
- package/lib/issues.ts +72 -72
- package/lib/mcp-server.ts +90 -0
- package/lib/metrics-loader.ts +3 -1
- package/lib/reports.ts +373 -0
- package/lib/storage.ts +291 -0
- package/lib/supabase.ts +8 -1
- package/lib/util.ts +7 -1
- package/package.json +4 -4
- package/scripts/embed-checkup-dictionary.ts +9 -0
- package/scripts/embed-metrics.ts +2 -0
- package/test/PERMISSION_CHECK_TEST_SUMMARY.md +139 -0
- package/test/checkup.test.ts +1316 -2
- package/test/compose-cmd.test.ts +120 -0
- package/test/config-consistency.test.ts +321 -5
- package/test/init.integration.test.ts +27 -28
- package/test/init.test.ts +534 -6
- package/test/issues.cli.test.ts +230 -1
- package/test/mcp-server.test.ts +459 -0
- package/test/monitoring.test.ts +78 -0
- package/test/permission-check-sql.test.ts +116 -0
- package/test/reports.cli.test.ts +793 -0
- package/test/reports.test.ts +977 -0
- package/test/schema-validation.test.ts +81 -0
- package/test/storage.test.ts +761 -0
- package/test/test-utils.ts +51 -2
- package/test/upgrade.test.ts +422 -0
package/test/mcp-server.test.ts
CHANGED
|
@@ -75,6 +75,7 @@ describe("MCP Server", () => {
|
|
|
75
75
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
76
76
|
apiKey: null,
|
|
77
77
|
baseUrl: null,
|
|
78
|
+
storageBaseUrl: null,
|
|
78
79
|
orgId: null,
|
|
79
80
|
defaultProject: null,
|
|
80
81
|
projectName: null,
|
|
@@ -92,6 +93,7 @@ describe("MCP Server", () => {
|
|
|
92
93
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
93
94
|
apiKey: null,
|
|
94
95
|
baseUrl: null,
|
|
96
|
+
storageBaseUrl: null,
|
|
95
97
|
orgId: null,
|
|
96
98
|
defaultProject: null,
|
|
97
99
|
projectName: null,
|
|
@@ -121,6 +123,7 @@ describe("MCP Server", () => {
|
|
|
121
123
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
122
124
|
apiKey: "config-api-key",
|
|
123
125
|
baseUrl: null,
|
|
126
|
+
storageBaseUrl: null,
|
|
124
127
|
orgId: null,
|
|
125
128
|
defaultProject: null,
|
|
126
129
|
projectName: null,
|
|
@@ -151,6 +154,7 @@ describe("MCP Server", () => {
|
|
|
151
154
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
152
155
|
apiKey: null,
|
|
153
156
|
baseUrl: null,
|
|
157
|
+
storageBaseUrl: null,
|
|
154
158
|
orgId: null,
|
|
155
159
|
defaultProject: null,
|
|
156
160
|
projectName: null,
|
|
@@ -186,6 +190,7 @@ describe("MCP Server", () => {
|
|
|
186
190
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
187
191
|
apiKey: "test-key",
|
|
188
192
|
baseUrl: null,
|
|
193
|
+
storageBaseUrl: null,
|
|
189
194
|
orgId: null,
|
|
190
195
|
defaultProject: null,
|
|
191
196
|
projectName: null,
|
|
@@ -214,6 +219,7 @@ describe("MCP Server", () => {
|
|
|
214
219
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
215
220
|
apiKey: "test-key",
|
|
216
221
|
baseUrl: null,
|
|
222
|
+
storageBaseUrl: null,
|
|
217
223
|
orgId: null,
|
|
218
224
|
defaultProject: null,
|
|
219
225
|
projectName: null,
|
|
@@ -242,6 +248,7 @@ describe("MCP Server", () => {
|
|
|
242
248
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
243
249
|
apiKey: "test-key",
|
|
244
250
|
baseUrl: null,
|
|
251
|
+
storageBaseUrl: null,
|
|
245
252
|
orgId: null,
|
|
246
253
|
defaultProject: null,
|
|
247
254
|
projectName: null,
|
|
@@ -259,6 +266,7 @@ describe("MCP Server", () => {
|
|
|
259
266
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
260
267
|
apiKey: "test-key",
|
|
261
268
|
baseUrl: null,
|
|
269
|
+
storageBaseUrl: null,
|
|
262
270
|
orgId: null,
|
|
263
271
|
defaultProject: null,
|
|
264
272
|
projectName: null,
|
|
@@ -276,6 +284,7 @@ describe("MCP Server", () => {
|
|
|
276
284
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
277
285
|
apiKey: "test-key",
|
|
278
286
|
baseUrl: null,
|
|
287
|
+
storageBaseUrl: null,
|
|
279
288
|
orgId: null,
|
|
280
289
|
defaultProject: null,
|
|
281
290
|
projectName: null,
|
|
@@ -306,6 +315,7 @@ describe("MCP Server", () => {
|
|
|
306
315
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
307
316
|
apiKey: "test-key",
|
|
308
317
|
baseUrl: null,
|
|
318
|
+
storageBaseUrl: null,
|
|
309
319
|
orgId: null,
|
|
310
320
|
defaultProject: null,
|
|
311
321
|
projectName: null,
|
|
@@ -347,6 +357,7 @@ describe("MCP Server", () => {
|
|
|
347
357
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
348
358
|
apiKey: "test-key",
|
|
349
359
|
baseUrl: null,
|
|
360
|
+
storageBaseUrl: null,
|
|
350
361
|
orgId: null,
|
|
351
362
|
defaultProject: null,
|
|
352
363
|
projectName: null,
|
|
@@ -366,6 +377,7 @@ describe("MCP Server", () => {
|
|
|
366
377
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
367
378
|
apiKey: "test-key",
|
|
368
379
|
baseUrl: null,
|
|
380
|
+
storageBaseUrl: null,
|
|
369
381
|
orgId: null,
|
|
370
382
|
defaultProject: null,
|
|
371
383
|
projectName: null,
|
|
@@ -385,6 +397,7 @@ describe("MCP Server", () => {
|
|
|
385
397
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
386
398
|
apiKey: "test-key",
|
|
387
399
|
baseUrl: null,
|
|
400
|
+
storageBaseUrl: null,
|
|
388
401
|
orgId: null,
|
|
389
402
|
defaultProject: null,
|
|
390
403
|
projectName: null,
|
|
@@ -419,6 +432,7 @@ describe("MCP Server", () => {
|
|
|
419
432
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
420
433
|
apiKey: "test-key",
|
|
421
434
|
baseUrl: null,
|
|
435
|
+
storageBaseUrl: null,
|
|
422
436
|
orgId: null,
|
|
423
437
|
defaultProject: null,
|
|
424
438
|
projectName: null,
|
|
@@ -457,6 +471,7 @@ describe("MCP Server", () => {
|
|
|
457
471
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
458
472
|
apiKey: "test-key",
|
|
459
473
|
baseUrl: null,
|
|
474
|
+
storageBaseUrl: null,
|
|
460
475
|
orgId: 1,
|
|
461
476
|
defaultProject: null,
|
|
462
477
|
projectName: null,
|
|
@@ -474,6 +489,7 @@ describe("MCP Server", () => {
|
|
|
474
489
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
475
490
|
apiKey: "test-key",
|
|
476
491
|
baseUrl: null,
|
|
492
|
+
storageBaseUrl: null,
|
|
477
493
|
orgId: 1,
|
|
478
494
|
defaultProject: null,
|
|
479
495
|
projectName: null,
|
|
@@ -491,6 +507,7 @@ describe("MCP Server", () => {
|
|
|
491
507
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
492
508
|
apiKey: "test-key",
|
|
493
509
|
baseUrl: null,
|
|
510
|
+
storageBaseUrl: null,
|
|
494
511
|
orgId: null,
|
|
495
512
|
defaultProject: null,
|
|
496
513
|
projectName: null,
|
|
@@ -508,6 +525,7 @@ describe("MCP Server", () => {
|
|
|
508
525
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
509
526
|
apiKey: "test-key",
|
|
510
527
|
baseUrl: null,
|
|
528
|
+
storageBaseUrl: null,
|
|
511
529
|
orgId: 42,
|
|
512
530
|
defaultProject: null,
|
|
513
531
|
projectName: null,
|
|
@@ -537,6 +555,7 @@ describe("MCP Server", () => {
|
|
|
537
555
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
538
556
|
apiKey: "test-key",
|
|
539
557
|
baseUrl: null,
|
|
558
|
+
storageBaseUrl: null,
|
|
540
559
|
orgId: 1,
|
|
541
560
|
defaultProject: null,
|
|
542
561
|
projectName: null,
|
|
@@ -572,6 +591,7 @@ describe("MCP Server", () => {
|
|
|
572
591
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
573
592
|
apiKey: "test-key",
|
|
574
593
|
baseUrl: null,
|
|
594
|
+
storageBaseUrl: null,
|
|
575
595
|
orgId: null,
|
|
576
596
|
defaultProject: null,
|
|
577
597
|
projectName: null,
|
|
@@ -616,6 +636,7 @@ describe("MCP Server", () => {
|
|
|
616
636
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
617
637
|
apiKey: "test-key",
|
|
618
638
|
baseUrl: null,
|
|
639
|
+
storageBaseUrl: null,
|
|
619
640
|
orgId: null,
|
|
620
641
|
defaultProject: null,
|
|
621
642
|
projectName: null,
|
|
@@ -635,6 +656,7 @@ describe("MCP Server", () => {
|
|
|
635
656
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
636
657
|
apiKey: "test-key",
|
|
637
658
|
baseUrl: null,
|
|
659
|
+
storageBaseUrl: null,
|
|
638
660
|
orgId: null,
|
|
639
661
|
defaultProject: null,
|
|
640
662
|
projectName: null,
|
|
@@ -652,6 +674,7 @@ describe("MCP Server", () => {
|
|
|
652
674
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
653
675
|
apiKey: "test-key",
|
|
654
676
|
baseUrl: null,
|
|
677
|
+
storageBaseUrl: null,
|
|
655
678
|
orgId: null,
|
|
656
679
|
defaultProject: null,
|
|
657
680
|
projectName: null,
|
|
@@ -671,6 +694,7 @@ describe("MCP Server", () => {
|
|
|
671
694
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
672
695
|
apiKey: "test-key",
|
|
673
696
|
baseUrl: null,
|
|
697
|
+
storageBaseUrl: null,
|
|
674
698
|
orgId: null,
|
|
675
699
|
defaultProject: null,
|
|
676
700
|
projectName: null,
|
|
@@ -690,6 +714,7 @@ describe("MCP Server", () => {
|
|
|
690
714
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
691
715
|
apiKey: "test-key",
|
|
692
716
|
baseUrl: null,
|
|
717
|
+
storageBaseUrl: null,
|
|
693
718
|
orgId: null,
|
|
694
719
|
defaultProject: null,
|
|
695
720
|
projectName: null,
|
|
@@ -726,6 +751,7 @@ describe("MCP Server", () => {
|
|
|
726
751
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
727
752
|
apiKey: "test-key",
|
|
728
753
|
baseUrl: null,
|
|
754
|
+
storageBaseUrl: null,
|
|
729
755
|
orgId: null,
|
|
730
756
|
defaultProject: null,
|
|
731
757
|
projectName: null,
|
|
@@ -753,6 +779,7 @@ describe("MCP Server", () => {
|
|
|
753
779
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
754
780
|
apiKey: "test-key",
|
|
755
781
|
baseUrl: null,
|
|
782
|
+
storageBaseUrl: null,
|
|
756
783
|
orgId: null,
|
|
757
784
|
defaultProject: null,
|
|
758
785
|
projectName: null,
|
|
@@ -785,6 +812,7 @@ describe("MCP Server", () => {
|
|
|
785
812
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
786
813
|
apiKey: "test-key",
|
|
787
814
|
baseUrl: null,
|
|
815
|
+
storageBaseUrl: null,
|
|
788
816
|
orgId: null,
|
|
789
817
|
defaultProject: null,
|
|
790
818
|
projectName: null,
|
|
@@ -817,6 +845,7 @@ describe("MCP Server", () => {
|
|
|
817
845
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
818
846
|
apiKey: "test-key",
|
|
819
847
|
baseUrl: null,
|
|
848
|
+
storageBaseUrl: null,
|
|
820
849
|
orgId: null,
|
|
821
850
|
defaultProject: null,
|
|
822
851
|
projectName: null,
|
|
@@ -851,6 +880,7 @@ describe("MCP Server", () => {
|
|
|
851
880
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
852
881
|
apiKey: "test-key",
|
|
853
882
|
baseUrl: null,
|
|
883
|
+
storageBaseUrl: null,
|
|
854
884
|
orgId: null,
|
|
855
885
|
defaultProject: null,
|
|
856
886
|
projectName: null,
|
|
@@ -870,6 +900,7 @@ describe("MCP Server", () => {
|
|
|
870
900
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
871
901
|
apiKey: "test-key",
|
|
872
902
|
baseUrl: null,
|
|
903
|
+
storageBaseUrl: null,
|
|
873
904
|
orgId: null,
|
|
874
905
|
defaultProject: null,
|
|
875
906
|
projectName: null,
|
|
@@ -889,6 +920,7 @@ describe("MCP Server", () => {
|
|
|
889
920
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
890
921
|
apiKey: "test-key",
|
|
891
922
|
baseUrl: null,
|
|
923
|
+
storageBaseUrl: null,
|
|
892
924
|
orgId: null,
|
|
893
925
|
defaultProject: null,
|
|
894
926
|
projectName: null,
|
|
@@ -923,6 +955,7 @@ describe("MCP Server", () => {
|
|
|
923
955
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
924
956
|
apiKey: "test-key",
|
|
925
957
|
baseUrl: null,
|
|
958
|
+
storageBaseUrl: null,
|
|
926
959
|
orgId: null,
|
|
927
960
|
defaultProject: null,
|
|
928
961
|
projectName: null,
|
|
@@ -957,6 +990,7 @@ describe("MCP Server", () => {
|
|
|
957
990
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
958
991
|
apiKey: "test-key",
|
|
959
992
|
baseUrl: null,
|
|
993
|
+
storageBaseUrl: null,
|
|
960
994
|
orgId: null,
|
|
961
995
|
defaultProject: null,
|
|
962
996
|
projectName: null,
|
|
@@ -974,6 +1008,7 @@ describe("MCP Server", () => {
|
|
|
974
1008
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
975
1009
|
apiKey: "test-key",
|
|
976
1010
|
baseUrl: null,
|
|
1011
|
+
storageBaseUrl: null,
|
|
977
1012
|
orgId: null,
|
|
978
1013
|
defaultProject: null,
|
|
979
1014
|
projectName: null,
|
|
@@ -991,6 +1026,7 @@ describe("MCP Server", () => {
|
|
|
991
1026
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
992
1027
|
apiKey: "test-key",
|
|
993
1028
|
baseUrl: null,
|
|
1029
|
+
storageBaseUrl: null,
|
|
994
1030
|
orgId: null,
|
|
995
1031
|
defaultProject: null,
|
|
996
1032
|
projectName: null,
|
|
@@ -1008,6 +1044,7 @@ describe("MCP Server", () => {
|
|
|
1008
1044
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1009
1045
|
apiKey: "test-key",
|
|
1010
1046
|
baseUrl: null,
|
|
1047
|
+
storageBaseUrl: null,
|
|
1011
1048
|
orgId: null,
|
|
1012
1049
|
defaultProject: null,
|
|
1013
1050
|
projectName: null,
|
|
@@ -1025,6 +1062,7 @@ describe("MCP Server", () => {
|
|
|
1025
1062
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1026
1063
|
apiKey: "test-key",
|
|
1027
1064
|
baseUrl: null,
|
|
1065
|
+
storageBaseUrl: null,
|
|
1028
1066
|
orgId: null,
|
|
1029
1067
|
defaultProject: null,
|
|
1030
1068
|
projectName: null,
|
|
@@ -1063,6 +1101,7 @@ describe("MCP Server", () => {
|
|
|
1063
1101
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1064
1102
|
apiKey: "test-key",
|
|
1065
1103
|
baseUrl: null,
|
|
1104
|
+
storageBaseUrl: null,
|
|
1066
1105
|
orgId: null,
|
|
1067
1106
|
defaultProject: null,
|
|
1068
1107
|
projectName: null,
|
|
@@ -1098,6 +1137,7 @@ describe("MCP Server", () => {
|
|
|
1098
1137
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1099
1138
|
apiKey: "test-key",
|
|
1100
1139
|
baseUrl: null,
|
|
1140
|
+
storageBaseUrl: null,
|
|
1101
1141
|
orgId: null,
|
|
1102
1142
|
defaultProject: null,
|
|
1103
1143
|
projectName: null,
|
|
@@ -1133,6 +1173,7 @@ describe("MCP Server", () => {
|
|
|
1133
1173
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1134
1174
|
apiKey: "test-key",
|
|
1135
1175
|
baseUrl: null,
|
|
1176
|
+
storageBaseUrl: null,
|
|
1136
1177
|
orgId: null,
|
|
1137
1178
|
defaultProject: null,
|
|
1138
1179
|
projectName: null,
|
|
@@ -1150,6 +1191,7 @@ describe("MCP Server", () => {
|
|
|
1150
1191
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1151
1192
|
apiKey: "test-key",
|
|
1152
1193
|
baseUrl: null,
|
|
1194
|
+
storageBaseUrl: null,
|
|
1153
1195
|
orgId: null,
|
|
1154
1196
|
defaultProject: null,
|
|
1155
1197
|
projectName: null,
|
|
@@ -1172,6 +1214,7 @@ describe("MCP Server", () => {
|
|
|
1172
1214
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1173
1215
|
apiKey: "test-key",
|
|
1174
1216
|
baseUrl: null,
|
|
1217
|
+
storageBaseUrl: null,
|
|
1175
1218
|
orgId: null,
|
|
1176
1219
|
defaultProject: null,
|
|
1177
1220
|
projectName: null,
|
|
@@ -1202,6 +1245,7 @@ describe("MCP Server", () => {
|
|
|
1202
1245
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1203
1246
|
apiKey: "test-key",
|
|
1204
1247
|
baseUrl: null,
|
|
1248
|
+
storageBaseUrl: null,
|
|
1205
1249
|
orgId: null,
|
|
1206
1250
|
defaultProject: null,
|
|
1207
1251
|
projectName: null,
|
|
@@ -1221,6 +1265,7 @@ describe("MCP Server", () => {
|
|
|
1221
1265
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1222
1266
|
apiKey: "test-key",
|
|
1223
1267
|
baseUrl: null,
|
|
1268
|
+
storageBaseUrl: null,
|
|
1224
1269
|
orgId: null,
|
|
1225
1270
|
defaultProject: null,
|
|
1226
1271
|
projectName: null,
|
|
@@ -1240,6 +1285,7 @@ describe("MCP Server", () => {
|
|
|
1240
1285
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1241
1286
|
apiKey: "test-key",
|
|
1242
1287
|
baseUrl: null,
|
|
1288
|
+
storageBaseUrl: null,
|
|
1243
1289
|
orgId: null,
|
|
1244
1290
|
defaultProject: null,
|
|
1245
1291
|
projectName: null,
|
|
@@ -1276,6 +1322,7 @@ describe("MCP Server", () => {
|
|
|
1276
1322
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1277
1323
|
apiKey: "test-key",
|
|
1278
1324
|
baseUrl: null,
|
|
1325
|
+
storageBaseUrl: null,
|
|
1279
1326
|
orgId: null,
|
|
1280
1327
|
defaultProject: null,
|
|
1281
1328
|
projectName: null,
|
|
@@ -1318,6 +1365,7 @@ describe("MCP Server", () => {
|
|
|
1318
1365
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1319
1366
|
apiKey: "test-key",
|
|
1320
1367
|
baseUrl: null,
|
|
1368
|
+
storageBaseUrl: null,
|
|
1321
1369
|
orgId: null,
|
|
1322
1370
|
defaultProject: null,
|
|
1323
1371
|
projectName: null,
|
|
@@ -1356,6 +1404,7 @@ describe("MCP Server", () => {
|
|
|
1356
1404
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1357
1405
|
apiKey: "test-key",
|
|
1358
1406
|
baseUrl: null,
|
|
1407
|
+
storageBaseUrl: null,
|
|
1359
1408
|
orgId: null,
|
|
1360
1409
|
defaultProject: null,
|
|
1361
1410
|
projectName: null,
|
|
@@ -1375,6 +1424,7 @@ describe("MCP Server", () => {
|
|
|
1375
1424
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1376
1425
|
apiKey: "test-key",
|
|
1377
1426
|
baseUrl: null,
|
|
1427
|
+
storageBaseUrl: null,
|
|
1378
1428
|
orgId: null,
|
|
1379
1429
|
defaultProject: null,
|
|
1380
1430
|
projectName: null,
|
|
@@ -1394,6 +1444,7 @@ describe("MCP Server", () => {
|
|
|
1394
1444
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1395
1445
|
apiKey: "test-key",
|
|
1396
1446
|
baseUrl: null,
|
|
1447
|
+
storageBaseUrl: null,
|
|
1397
1448
|
orgId: null,
|
|
1398
1449
|
defaultProject: null,
|
|
1399
1450
|
projectName: null,
|
|
@@ -1413,6 +1464,7 @@ describe("MCP Server", () => {
|
|
|
1413
1464
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1414
1465
|
apiKey: "test-key",
|
|
1415
1466
|
baseUrl: null,
|
|
1467
|
+
storageBaseUrl: null,
|
|
1416
1468
|
orgId: null,
|
|
1417
1469
|
defaultProject: null,
|
|
1418
1470
|
projectName: null,
|
|
@@ -1446,6 +1498,7 @@ describe("MCP Server", () => {
|
|
|
1446
1498
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1447
1499
|
apiKey: "test-key",
|
|
1448
1500
|
baseUrl: null,
|
|
1501
|
+
storageBaseUrl: null,
|
|
1449
1502
|
orgId: null,
|
|
1450
1503
|
defaultProject: null,
|
|
1451
1504
|
projectName: null,
|
|
@@ -1478,6 +1531,7 @@ describe("MCP Server", () => {
|
|
|
1478
1531
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1479
1532
|
apiKey: "test-key",
|
|
1480
1533
|
baseUrl: null,
|
|
1534
|
+
storageBaseUrl: null,
|
|
1481
1535
|
orgId: null,
|
|
1482
1536
|
defaultProject: null,
|
|
1483
1537
|
projectName: null,
|
|
@@ -1517,6 +1571,7 @@ describe("MCP Server", () => {
|
|
|
1517
1571
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1518
1572
|
apiKey: "test-key",
|
|
1519
1573
|
baseUrl: null,
|
|
1574
|
+
storageBaseUrl: null,
|
|
1520
1575
|
orgId: null,
|
|
1521
1576
|
defaultProject: null,
|
|
1522
1577
|
projectName: null,
|
|
@@ -1531,11 +1586,414 @@ describe("MCP Server", () => {
|
|
|
1531
1586
|
});
|
|
1532
1587
|
});
|
|
1533
1588
|
|
|
1589
|
+
describe("list_reports tool", () => {
|
|
1590
|
+
test("successfully returns reports list as JSON", async () => {
|
|
1591
|
+
const mockReports = [
|
|
1592
|
+
{ id: 1, org_id: 1, org_name: "TestOrg", project_id: 10, project_name: "prod-db", status: "completed" },
|
|
1593
|
+
];
|
|
1594
|
+
|
|
1595
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1596
|
+
apiKey: "test-key",
|
|
1597
|
+
baseUrl: null,
|
|
1598
|
+
storageBaseUrl: null,
|
|
1599
|
+
orgId: null,
|
|
1600
|
+
defaultProject: null,
|
|
1601
|
+
projectName: null,
|
|
1602
|
+
});
|
|
1603
|
+
|
|
1604
|
+
globalThis.fetch = mock(() =>
|
|
1605
|
+
Promise.resolve(
|
|
1606
|
+
new Response(JSON.stringify(mockReports), {
|
|
1607
|
+
status: 200,
|
|
1608
|
+
headers: { "Content-Type": "application/json" },
|
|
1609
|
+
})
|
|
1610
|
+
)
|
|
1611
|
+
) as unknown as typeof fetch;
|
|
1612
|
+
|
|
1613
|
+
const response = await handleToolCall(createRequest("list_reports"));
|
|
1614
|
+
|
|
1615
|
+
expect(response.isError).toBeUndefined();
|
|
1616
|
+
const parsed = JSON.parse(getResponseText(response));
|
|
1617
|
+
expect(parsed).toHaveLength(1);
|
|
1618
|
+
expect(parsed[0].status).toBe("completed");
|
|
1619
|
+
|
|
1620
|
+
readConfigSpy.mockRestore();
|
|
1621
|
+
});
|
|
1622
|
+
|
|
1623
|
+
test("passes filters to API", async () => {
|
|
1624
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1625
|
+
apiKey: "test-key",
|
|
1626
|
+
baseUrl: null,
|
|
1627
|
+
storageBaseUrl: null,
|
|
1628
|
+
orgId: null,
|
|
1629
|
+
defaultProject: null,
|
|
1630
|
+
projectName: null,
|
|
1631
|
+
});
|
|
1632
|
+
|
|
1633
|
+
let capturedUrl: string | undefined;
|
|
1634
|
+
globalThis.fetch = mock((url: string) => {
|
|
1635
|
+
capturedUrl = url;
|
|
1636
|
+
return Promise.resolve(
|
|
1637
|
+
new Response(JSON.stringify([]), {
|
|
1638
|
+
status: 200,
|
|
1639
|
+
headers: { "Content-Type": "application/json" },
|
|
1640
|
+
})
|
|
1641
|
+
);
|
|
1642
|
+
}) as unknown as typeof fetch;
|
|
1643
|
+
|
|
1644
|
+
await handleToolCall(createRequest("list_reports", {
|
|
1645
|
+
project_id: 5,
|
|
1646
|
+
status: "completed",
|
|
1647
|
+
limit: 10,
|
|
1648
|
+
}));
|
|
1649
|
+
|
|
1650
|
+
expect(capturedUrl).toContain("project_id=eq.5");
|
|
1651
|
+
expect(capturedUrl).toContain("status=eq.completed");
|
|
1652
|
+
expect(capturedUrl).toContain("limit=10");
|
|
1653
|
+
|
|
1654
|
+
readConfigSpy.mockRestore();
|
|
1655
|
+
});
|
|
1656
|
+
|
|
1657
|
+
test("handles API errors gracefully", async () => {
|
|
1658
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1659
|
+
apiKey: "test-key",
|
|
1660
|
+
baseUrl: null,
|
|
1661
|
+
storageBaseUrl: null,
|
|
1662
|
+
orgId: null,
|
|
1663
|
+
defaultProject: null,
|
|
1664
|
+
projectName: null,
|
|
1665
|
+
});
|
|
1666
|
+
|
|
1667
|
+
globalThis.fetch = mock(() =>
|
|
1668
|
+
Promise.resolve(
|
|
1669
|
+
new Response('{"message": "Unauthorized"}', {
|
|
1670
|
+
status: 401,
|
|
1671
|
+
headers: { "Content-Type": "application/json" },
|
|
1672
|
+
})
|
|
1673
|
+
)
|
|
1674
|
+
) as unknown as typeof fetch;
|
|
1675
|
+
|
|
1676
|
+
const response = await handleToolCall(createRequest("list_reports"));
|
|
1677
|
+
|
|
1678
|
+
expect(response.isError).toBe(true);
|
|
1679
|
+
expect(getResponseText(response)).toContain("401");
|
|
1680
|
+
|
|
1681
|
+
readConfigSpy.mockRestore();
|
|
1682
|
+
});
|
|
1683
|
+
|
|
1684
|
+
test("passes before_date to API as created_at filter", async () => {
|
|
1685
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1686
|
+
apiKey: "test-key",
|
|
1687
|
+
baseUrl: null,
|
|
1688
|
+
storageBaseUrl: null,
|
|
1689
|
+
orgId: null,
|
|
1690
|
+
defaultProject: null,
|
|
1691
|
+
projectName: null,
|
|
1692
|
+
});
|
|
1693
|
+
|
|
1694
|
+
let capturedUrl: string | undefined;
|
|
1695
|
+
globalThis.fetch = mock((url: string) => {
|
|
1696
|
+
capturedUrl = url;
|
|
1697
|
+
return Promise.resolve(
|
|
1698
|
+
new Response(JSON.stringify([]), {
|
|
1699
|
+
status: 200,
|
|
1700
|
+
headers: { "Content-Type": "application/json" },
|
|
1701
|
+
})
|
|
1702
|
+
);
|
|
1703
|
+
}) as unknown as typeof fetch;
|
|
1704
|
+
|
|
1705
|
+
await handleToolCall(createRequest("list_reports", {
|
|
1706
|
+
before_date: "2025-01-15",
|
|
1707
|
+
}));
|
|
1708
|
+
|
|
1709
|
+
expect(capturedUrl).toContain("created_at=lt.2025-01-15");
|
|
1710
|
+
|
|
1711
|
+
readConfigSpy.mockRestore();
|
|
1712
|
+
});
|
|
1713
|
+
|
|
1714
|
+
test("fetches all reports when all=true", async () => {
|
|
1715
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1716
|
+
apiKey: "test-key",
|
|
1717
|
+
baseUrl: null,
|
|
1718
|
+
storageBaseUrl: null,
|
|
1719
|
+
orgId: null,
|
|
1720
|
+
defaultProject: null,
|
|
1721
|
+
projectName: null,
|
|
1722
|
+
});
|
|
1723
|
+
|
|
1724
|
+
const mockReports = [
|
|
1725
|
+
{ id: 10, org_id: 1, org_name: "O", project_id: 1, project_name: "P", status: "completed" },
|
|
1726
|
+
];
|
|
1727
|
+
|
|
1728
|
+
globalThis.fetch = mock(() =>
|
|
1729
|
+
Promise.resolve(
|
|
1730
|
+
new Response(JSON.stringify(mockReports), {
|
|
1731
|
+
status: 200,
|
|
1732
|
+
headers: { "Content-Type": "application/json" },
|
|
1733
|
+
})
|
|
1734
|
+
)
|
|
1735
|
+
) as unknown as typeof fetch;
|
|
1736
|
+
|
|
1737
|
+
const response = await handleToolCall(createRequest("list_reports", {
|
|
1738
|
+
all: true,
|
|
1739
|
+
}));
|
|
1740
|
+
|
|
1741
|
+
expect(response.isError).toBeUndefined();
|
|
1742
|
+
const parsed = JSON.parse(getResponseText(response));
|
|
1743
|
+
expect(parsed).toHaveLength(1);
|
|
1744
|
+
expect(parsed[0].id).toBe(10);
|
|
1745
|
+
|
|
1746
|
+
readConfigSpy.mockRestore();
|
|
1747
|
+
});
|
|
1748
|
+
});
|
|
1749
|
+
|
|
1750
|
+
describe("list_report_files tool", () => {
|
|
1751
|
+
test("returns error when neither report_id nor check_id is provided", async () => {
|
|
1752
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1753
|
+
apiKey: "test-key",
|
|
1754
|
+
baseUrl: null,
|
|
1755
|
+
storageBaseUrl: null,
|
|
1756
|
+
orgId: null,
|
|
1757
|
+
defaultProject: null,
|
|
1758
|
+
projectName: null,
|
|
1759
|
+
});
|
|
1760
|
+
|
|
1761
|
+
const response = await handleToolCall(createRequest("list_report_files", {}));
|
|
1762
|
+
|
|
1763
|
+
expect(response.isError).toBe(true);
|
|
1764
|
+
expect(getResponseText(response)).toContain("Either report_id or check_id is required");
|
|
1765
|
+
|
|
1766
|
+
readConfigSpy.mockRestore();
|
|
1767
|
+
});
|
|
1768
|
+
|
|
1769
|
+
test("works with only check_id (no report_id)", async () => {
|
|
1770
|
+
const mockFiles = [
|
|
1771
|
+
{ id: 100, checkup_report_id: 1, filename: "H002.md", check_id: "H002", type: "md" },
|
|
1772
|
+
];
|
|
1773
|
+
|
|
1774
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1775
|
+
apiKey: "test-key",
|
|
1776
|
+
baseUrl: null,
|
|
1777
|
+
storageBaseUrl: null,
|
|
1778
|
+
orgId: null,
|
|
1779
|
+
defaultProject: null,
|
|
1780
|
+
projectName: null,
|
|
1781
|
+
});
|
|
1782
|
+
|
|
1783
|
+
let capturedUrl: string | undefined;
|
|
1784
|
+
globalThis.fetch = mock((url: string) => {
|
|
1785
|
+
capturedUrl = url;
|
|
1786
|
+
return Promise.resolve(
|
|
1787
|
+
new Response(JSON.stringify(mockFiles), {
|
|
1788
|
+
status: 200,
|
|
1789
|
+
headers: { "Content-Type": "application/json" },
|
|
1790
|
+
})
|
|
1791
|
+
);
|
|
1792
|
+
}) as unknown as typeof fetch;
|
|
1793
|
+
|
|
1794
|
+
const response = await handleToolCall(createRequest("list_report_files", {
|
|
1795
|
+
check_id: "H002",
|
|
1796
|
+
}));
|
|
1797
|
+
|
|
1798
|
+
expect(response.isError).toBeUndefined();
|
|
1799
|
+
const parsed = JSON.parse(getResponseText(response));
|
|
1800
|
+
expect(parsed[0].filename).toBe("H002.md");
|
|
1801
|
+
expect(capturedUrl).toContain("check_id=eq.H002");
|
|
1802
|
+
expect(capturedUrl).not.toContain("checkup_report_id");
|
|
1803
|
+
|
|
1804
|
+
readConfigSpy.mockRestore();
|
|
1805
|
+
});
|
|
1806
|
+
|
|
1807
|
+
test("successfully returns report files", async () => {
|
|
1808
|
+
const mockFiles = [
|
|
1809
|
+
{ id: 100, checkup_report_id: 1, filename: "H002.md", check_id: "H002", type: "md" },
|
|
1810
|
+
];
|
|
1811
|
+
|
|
1812
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1813
|
+
apiKey: "test-key",
|
|
1814
|
+
baseUrl: null,
|
|
1815
|
+
storageBaseUrl: null,
|
|
1816
|
+
orgId: null,
|
|
1817
|
+
defaultProject: null,
|
|
1818
|
+
projectName: null,
|
|
1819
|
+
});
|
|
1820
|
+
|
|
1821
|
+
let capturedUrl: string | undefined;
|
|
1822
|
+
globalThis.fetch = mock((url: string) => {
|
|
1823
|
+
capturedUrl = url;
|
|
1824
|
+
return Promise.resolve(
|
|
1825
|
+
new Response(JSON.stringify(mockFiles), {
|
|
1826
|
+
status: 200,
|
|
1827
|
+
headers: { "Content-Type": "application/json" },
|
|
1828
|
+
})
|
|
1829
|
+
);
|
|
1830
|
+
}) as unknown as typeof fetch;
|
|
1831
|
+
|
|
1832
|
+
const response = await handleToolCall(createRequest("list_report_files", {
|
|
1833
|
+
report_id: 1,
|
|
1834
|
+
type: "md",
|
|
1835
|
+
check_id: "H002",
|
|
1836
|
+
}));
|
|
1837
|
+
|
|
1838
|
+
expect(response.isError).toBeUndefined();
|
|
1839
|
+
const parsed = JSON.parse(getResponseText(response));
|
|
1840
|
+
expect(parsed[0].filename).toBe("H002.md");
|
|
1841
|
+
expect(capturedUrl).toContain("checkup_report_id=eq.1");
|
|
1842
|
+
expect(capturedUrl).toContain("type=eq.md");
|
|
1843
|
+
expect(capturedUrl).toContain("check_id=eq.H002");
|
|
1844
|
+
|
|
1845
|
+
readConfigSpy.mockRestore();
|
|
1846
|
+
});
|
|
1847
|
+
});
|
|
1848
|
+
|
|
1849
|
+
describe("get_report_data tool", () => {
|
|
1850
|
+
test("returns error when neither report_id nor check_id is provided", async () => {
|
|
1851
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1852
|
+
apiKey: "test-key",
|
|
1853
|
+
baseUrl: null,
|
|
1854
|
+
storageBaseUrl: null,
|
|
1855
|
+
orgId: null,
|
|
1856
|
+
defaultProject: null,
|
|
1857
|
+
projectName: null,
|
|
1858
|
+
});
|
|
1859
|
+
|
|
1860
|
+
const response = await handleToolCall(createRequest("get_report_data", {}));
|
|
1861
|
+
|
|
1862
|
+
expect(response.isError).toBe(true);
|
|
1863
|
+
expect(getResponseText(response)).toContain("Either report_id or check_id is required");
|
|
1864
|
+
|
|
1865
|
+
readConfigSpy.mockRestore();
|
|
1866
|
+
});
|
|
1867
|
+
|
|
1868
|
+
test("works with only check_id (no report_id)", async () => {
|
|
1869
|
+
const mockData = [
|
|
1870
|
+
{
|
|
1871
|
+
id: 100,
|
|
1872
|
+
checkup_report_id: 1,
|
|
1873
|
+
filename: "H002.md",
|
|
1874
|
+
check_id: "H002",
|
|
1875
|
+
type: "md",
|
|
1876
|
+
data: "# H002\n\nUnused indexes found.",
|
|
1877
|
+
},
|
|
1878
|
+
];
|
|
1879
|
+
|
|
1880
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1881
|
+
apiKey: "test-key",
|
|
1882
|
+
baseUrl: null,
|
|
1883
|
+
storageBaseUrl: null,
|
|
1884
|
+
orgId: null,
|
|
1885
|
+
defaultProject: null,
|
|
1886
|
+
projectName: null,
|
|
1887
|
+
});
|
|
1888
|
+
|
|
1889
|
+
let capturedUrl: string | undefined;
|
|
1890
|
+
globalThis.fetch = mock((url: string) => {
|
|
1891
|
+
capturedUrl = url;
|
|
1892
|
+
return Promise.resolve(
|
|
1893
|
+
new Response(JSON.stringify(mockData), {
|
|
1894
|
+
status: 200,
|
|
1895
|
+
headers: { "Content-Type": "application/json" },
|
|
1896
|
+
})
|
|
1897
|
+
);
|
|
1898
|
+
}) as unknown as typeof fetch;
|
|
1899
|
+
|
|
1900
|
+
const response = await handleToolCall(createRequest("get_report_data", {
|
|
1901
|
+
check_id: "H002",
|
|
1902
|
+
}));
|
|
1903
|
+
|
|
1904
|
+
expect(response.isError).toBeUndefined();
|
|
1905
|
+
const parsed = JSON.parse(getResponseText(response));
|
|
1906
|
+
expect(parsed[0].data).toContain("# H002");
|
|
1907
|
+
expect(capturedUrl).toContain("check_id=eq.H002");
|
|
1908
|
+
expect(capturedUrl).not.toContain("checkup_report_id");
|
|
1909
|
+
|
|
1910
|
+
readConfigSpy.mockRestore();
|
|
1911
|
+
});
|
|
1912
|
+
|
|
1913
|
+
test("successfully returns report data with content", async () => {
|
|
1914
|
+
const mockData = [
|
|
1915
|
+
{
|
|
1916
|
+
id: 100,
|
|
1917
|
+
checkup_report_id: 1,
|
|
1918
|
+
filename: "H002.md",
|
|
1919
|
+
check_id: "H002",
|
|
1920
|
+
type: "md",
|
|
1921
|
+
data: "# H002\n\nUnused indexes found.",
|
|
1922
|
+
},
|
|
1923
|
+
];
|
|
1924
|
+
|
|
1925
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1926
|
+
apiKey: "test-key",
|
|
1927
|
+
baseUrl: null,
|
|
1928
|
+
storageBaseUrl: null,
|
|
1929
|
+
orgId: null,
|
|
1930
|
+
defaultProject: null,
|
|
1931
|
+
projectName: null,
|
|
1932
|
+
});
|
|
1933
|
+
|
|
1934
|
+
globalThis.fetch = mock(() =>
|
|
1935
|
+
Promise.resolve(
|
|
1936
|
+
new Response(JSON.stringify(mockData), {
|
|
1937
|
+
status: 200,
|
|
1938
|
+
headers: { "Content-Type": "application/json" },
|
|
1939
|
+
})
|
|
1940
|
+
)
|
|
1941
|
+
) as unknown as typeof fetch;
|
|
1942
|
+
|
|
1943
|
+
const response = await handleToolCall(createRequest("get_report_data", {
|
|
1944
|
+
report_id: 1,
|
|
1945
|
+
type: "md",
|
|
1946
|
+
check_id: "H002",
|
|
1947
|
+
}));
|
|
1948
|
+
|
|
1949
|
+
expect(response.isError).toBeUndefined();
|
|
1950
|
+
const parsed = JSON.parse(getResponseText(response));
|
|
1951
|
+
expect(parsed[0].data).toContain("# H002");
|
|
1952
|
+
|
|
1953
|
+
readConfigSpy.mockRestore();
|
|
1954
|
+
});
|
|
1955
|
+
|
|
1956
|
+
test("passes filters to API", async () => {
|
|
1957
|
+
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1958
|
+
apiKey: "test-key",
|
|
1959
|
+
baseUrl: null,
|
|
1960
|
+
storageBaseUrl: null,
|
|
1961
|
+
orgId: null,
|
|
1962
|
+
defaultProject: null,
|
|
1963
|
+
projectName: null,
|
|
1964
|
+
});
|
|
1965
|
+
|
|
1966
|
+
let capturedUrl: string | undefined;
|
|
1967
|
+
globalThis.fetch = mock((url: string) => {
|
|
1968
|
+
capturedUrl = url;
|
|
1969
|
+
return Promise.resolve(
|
|
1970
|
+
new Response(JSON.stringify([]), {
|
|
1971
|
+
status: 200,
|
|
1972
|
+
headers: { "Content-Type": "application/json" },
|
|
1973
|
+
})
|
|
1974
|
+
);
|
|
1975
|
+
}) as unknown as typeof fetch;
|
|
1976
|
+
|
|
1977
|
+
await handleToolCall(createRequest("get_report_data", {
|
|
1978
|
+
report_id: 42,
|
|
1979
|
+
type: "json",
|
|
1980
|
+
check_id: "F004",
|
|
1981
|
+
}));
|
|
1982
|
+
|
|
1983
|
+
expect(capturedUrl).toContain("checkup_report_id=eq.42");
|
|
1984
|
+
expect(capturedUrl).toContain("type=eq.json");
|
|
1985
|
+
expect(capturedUrl).toContain("check_id=eq.F004");
|
|
1986
|
+
|
|
1987
|
+
readConfigSpy.mockRestore();
|
|
1988
|
+
});
|
|
1989
|
+
});
|
|
1990
|
+
|
|
1534
1991
|
describe("error propagation", () => {
|
|
1535
1992
|
test("propagates API errors through MCP layer", async () => {
|
|
1536
1993
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1537
1994
|
apiKey: "test-key",
|
|
1538
1995
|
baseUrl: null,
|
|
1996
|
+
storageBaseUrl: null,
|
|
1539
1997
|
orgId: 1,
|
|
1540
1998
|
defaultProject: null,
|
|
1541
1999
|
projectName: null,
|
|
@@ -1564,6 +2022,7 @@ describe("MCP Server", () => {
|
|
|
1564
2022
|
const readConfigSpy = spyOn(config, "readConfig").mockReturnValue({
|
|
1565
2023
|
apiKey: "test-key",
|
|
1566
2024
|
baseUrl: null,
|
|
2025
|
+
storageBaseUrl: null,
|
|
1567
2026
|
orgId: 1,
|
|
1568
2027
|
defaultProject: null,
|
|
1569
2028
|
projectName: null,
|