@topolo/mcp 0.4.6 → 0.4.8
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/dist/dispatch.js +17 -0
- package/dist/index.js +191 -138
- package/package.json +13 -13
package/dist/dispatch.js
CHANGED
|
@@ -91,6 +91,8 @@ var TOOLS = [
|
|
|
91
91
|
effectiveUrl: resolveCatalogServiceUrl(entry, { serviceKey: id }),
|
|
92
92
|
surfaceKind: entry.surfaceKind,
|
|
93
93
|
launchable: entry.launchable,
|
|
94
|
+
apiKeyResource: entry.apiKeyResource,
|
|
95
|
+
apiKeyResources: [...entry.apiKeyResources],
|
|
94
96
|
permissions: [...entry.permissions]
|
|
95
97
|
};
|
|
96
98
|
}).sort((left, right) => left.id.localeCompare(right.id));
|
|
@@ -284,6 +286,14 @@ var TOOLS = [
|
|
|
284
286
|
additionalProperties: { type: "string" },
|
|
285
287
|
description: "Query string parameters as string values."
|
|
286
288
|
},
|
|
289
|
+
resourceType: {
|
|
290
|
+
type: "string",
|
|
291
|
+
description: "Optional workspace resource alias from topolo_list_services apiKeyResources. Aliases are app-defined, e.g. brand, mailbox, venue, merchant, or any other cataloged alias."
|
|
292
|
+
},
|
|
293
|
+
resourceId: {
|
|
294
|
+
type: "string",
|
|
295
|
+
description: "Resource id for resourceType. Required when resourceType is provided."
|
|
296
|
+
},
|
|
287
297
|
confirm: {
|
|
288
298
|
type: "boolean",
|
|
289
299
|
description: "Required for non-GET methods. Explicit human-in-the-loop acknowledgement for writes."
|
|
@@ -310,12 +320,19 @@ var TOOLS = [
|
|
|
310
320
|
const normalisedQuery = query && typeof query === "object" && !Array.isArray(query) ? Object.fromEntries(
|
|
311
321
|
Object.entries(query).map(([k, v]) => [k, String(v)])
|
|
312
322
|
) : void 0;
|
|
323
|
+
const resourceType = typeof args["resourceType"] === "string" ? args["resourceType"].trim() : "";
|
|
324
|
+
const resourceId = typeof args["resourceId"] === "string" ? args["resourceId"].trim() : "";
|
|
325
|
+
if (resourceType && !resourceId || !resourceType && resourceId) {
|
|
326
|
+
throw new Error("resourceType and resourceId must be provided together.");
|
|
327
|
+
}
|
|
328
|
+
const resource = resourceType && resourceId ? { resourceType, resourceId } : void 0;
|
|
313
329
|
return topolo.client.request({
|
|
314
330
|
service: service.trim(),
|
|
315
331
|
method,
|
|
316
332
|
path,
|
|
317
333
|
body: args["body"],
|
|
318
334
|
...normalisedQuery ? { query: normalisedQuery } : {},
|
|
335
|
+
...resource ? { resource } : {},
|
|
319
336
|
confirm: Boolean(args["confirm"])
|
|
320
337
|
});
|
|
321
338
|
}
|
package/dist/index.js
CHANGED
|
@@ -59,54 +59,53 @@ var TopoloHttpError = class extends TopoloSdkError {
|
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
61
|
var SERVICES = {
|
|
62
|
-
agent: "https://agent
|
|
62
|
+
agent: "https://agent.topolo.app",
|
|
63
63
|
auth: "https://auth.topolo.app",
|
|
64
64
|
backup: "https://backup.topolo.app",
|
|
65
65
|
books: "https://books.topolo.app",
|
|
66
66
|
bugfix: "https://bugfix.topolo.app",
|
|
67
|
-
bytes: "https://bytes
|
|
67
|
+
bytes: "https://bytes.topolo.app",
|
|
68
68
|
calendar: "https://calendar.topolo.app",
|
|
69
69
|
capacity: "https://capacity.topolo.app",
|
|
70
70
|
chat: "https://chat.topolo.app",
|
|
71
|
-
commerce: "https://commerce
|
|
71
|
+
commerce: "https://commerce.topolo.app",
|
|
72
72
|
compose: "https://compose.topolo.app",
|
|
73
73
|
consent: "https://consent.topolo.app",
|
|
74
|
-
crm: "https://crm
|
|
74
|
+
crm: "https://crm.topolo.app",
|
|
75
75
|
developers: "https://developers.topolo.app",
|
|
76
76
|
director: "https://director.topolo.app",
|
|
77
|
-
feed: "https://feed
|
|
77
|
+
feed: "https://feed.topolo.app",
|
|
78
78
|
flow: "https://flow.topolo.app",
|
|
79
|
-
forecast: "https://forecast
|
|
79
|
+
forecast: "https://forecast.topolo.app",
|
|
80
80
|
forms: "https://forms.topolo.app",
|
|
81
81
|
home: "https://home.topolo.app",
|
|
82
82
|
insights: "https://insights.topolo.app",
|
|
83
83
|
inventory: "https://inventory.topolo.app",
|
|
84
|
-
learn: "https://learn
|
|
84
|
+
learn: "https://learn.topolo.app",
|
|
85
85
|
localize: "https://localize.topolo.app",
|
|
86
|
-
mail: "https://mail
|
|
87
|
-
mdm: "https://mdm
|
|
86
|
+
mail: "https://mail.topolo.app",
|
|
87
|
+
mdm: "https://mdm.topolo.app",
|
|
88
88
|
messages: "https://messages.topolo.app",
|
|
89
89
|
nexus: "https://nexus-api.topolo.app",
|
|
90
90
|
notify: "https://notify.topolo.app",
|
|
91
91
|
observability_watch: "https://observability-watch.topolo.app",
|
|
92
|
-
one: "https://
|
|
92
|
+
one: "https://www.topolo.app",
|
|
93
93
|
p2p: "https://p2p.topolo.app",
|
|
94
94
|
pay: "https://pay.topolo.app",
|
|
95
95
|
people: "https://people.topolo.app",
|
|
96
|
-
pulse: "https://pulse.topolo.app",
|
|
97
96
|
"quro.api": "https://api.ol0.me",
|
|
98
97
|
"quro.redirect": "https://ol0.me",
|
|
99
|
-
roadmapper: "https://roadmapper
|
|
98
|
+
roadmapper: "https://roadmapper.topolo.app",
|
|
100
99
|
sign: "https://sign.topolo.app",
|
|
101
|
-
social_studio: "https://studio
|
|
102
|
-
socialize: "https://socialize
|
|
100
|
+
social_studio: "https://studio.topolo.app",
|
|
101
|
+
socialize: "https://socialize.topolo.app",
|
|
103
102
|
spaces: "https://spaces.topolo.app",
|
|
104
103
|
status: "https://status.topolo.app",
|
|
105
104
|
success: "https://success.topolo.app",
|
|
106
105
|
support: "https://support.topolo.app",
|
|
107
106
|
survey: "https://survey.topolo.app",
|
|
108
107
|
voice: "https://voice.topolo.app",
|
|
109
|
-
web: "https://web
|
|
108
|
+
web: "https://web.topolo.app"
|
|
110
109
|
};
|
|
111
110
|
var APPLICATIONS = {
|
|
112
111
|
"admin": {
|
|
@@ -155,17 +154,15 @@ var APPLICATIONS = {
|
|
|
155
154
|
"agent.topolo.app"
|
|
156
155
|
],
|
|
157
156
|
"routes": [],
|
|
158
|
-
"serviceId":
|
|
157
|
+
"serviceId": "agent"
|
|
159
158
|
},
|
|
160
159
|
{
|
|
161
160
|
"name": "topolo-agent-api",
|
|
162
161
|
"kind": "worker",
|
|
163
|
-
"apiUrl":
|
|
164
|
-
"domains": [
|
|
165
|
-
"agent-api.topolo.app"
|
|
166
|
-
],
|
|
162
|
+
"apiUrl": null,
|
|
163
|
+
"domains": [],
|
|
167
164
|
"routes": [],
|
|
168
|
-
"serviceId":
|
|
165
|
+
"serviceId": null
|
|
169
166
|
}
|
|
170
167
|
]
|
|
171
168
|
},
|
|
@@ -285,17 +282,15 @@ var APPLICATIONS = {
|
|
|
285
282
|
"bytes.topolo.app"
|
|
286
283
|
],
|
|
287
284
|
"routes": [],
|
|
288
|
-
"serviceId":
|
|
285
|
+
"serviceId": "bytes"
|
|
289
286
|
},
|
|
290
287
|
{
|
|
291
288
|
"name": "topolo-bytes-api",
|
|
292
289
|
"kind": "worker",
|
|
293
|
-
"apiUrl":
|
|
294
|
-
"domains": [
|
|
295
|
-
"bytes-api.topolo.app"
|
|
296
|
-
],
|
|
290
|
+
"apiUrl": null,
|
|
291
|
+
"domains": [],
|
|
297
292
|
"routes": [],
|
|
298
|
-
"serviceId":
|
|
293
|
+
"serviceId": null
|
|
299
294
|
}
|
|
300
295
|
]
|
|
301
296
|
},
|
|
@@ -394,12 +389,10 @@ var APPLICATIONS = {
|
|
|
394
389
|
{
|
|
395
390
|
"name": "topolo-commerce-api",
|
|
396
391
|
"kind": "worker",
|
|
397
|
-
"apiUrl":
|
|
398
|
-
"domains": [
|
|
399
|
-
"commerce-api.topolo.app"
|
|
400
|
-
],
|
|
392
|
+
"apiUrl": null,
|
|
393
|
+
"domains": [],
|
|
401
394
|
"routes": [],
|
|
402
|
-
"serviceId":
|
|
395
|
+
"serviceId": null
|
|
403
396
|
},
|
|
404
397
|
{
|
|
405
398
|
"name": "topolo-commerce-guest-web",
|
|
@@ -419,7 +412,7 @@ var APPLICATIONS = {
|
|
|
419
412
|
"commerce.topolo.app"
|
|
420
413
|
],
|
|
421
414
|
"routes": [],
|
|
422
|
-
"serviceId":
|
|
415
|
+
"serviceId": "commerce"
|
|
423
416
|
},
|
|
424
417
|
{
|
|
425
418
|
"name": "topolo-commerce-station-web",
|
|
@@ -506,12 +499,10 @@ var APPLICATIONS = {
|
|
|
506
499
|
{
|
|
507
500
|
"name": "topolo-crm-api",
|
|
508
501
|
"kind": "worker",
|
|
509
|
-
"apiUrl":
|
|
510
|
-
"domains": [
|
|
511
|
-
"crm-api.topolo.app"
|
|
512
|
-
],
|
|
502
|
+
"apiUrl": null,
|
|
503
|
+
"domains": [],
|
|
513
504
|
"routes": [],
|
|
514
|
-
"serviceId":
|
|
505
|
+
"serviceId": null
|
|
515
506
|
},
|
|
516
507
|
{
|
|
517
508
|
"name": "topolo-crm-app",
|
|
@@ -521,7 +512,7 @@ var APPLICATIONS = {
|
|
|
521
512
|
"crm.topolo.app"
|
|
522
513
|
],
|
|
523
514
|
"routes": [],
|
|
524
|
-
"serviceId":
|
|
515
|
+
"serviceId": "crm"
|
|
525
516
|
}
|
|
526
517
|
]
|
|
527
518
|
},
|
|
@@ -644,12 +635,10 @@ var APPLICATIONS = {
|
|
|
644
635
|
{
|
|
645
636
|
"name": "topolo-feed-api",
|
|
646
637
|
"kind": "worker",
|
|
647
|
-
"apiUrl":
|
|
648
|
-
"domains": [
|
|
649
|
-
"feed-api.topolo.app"
|
|
650
|
-
],
|
|
638
|
+
"apiUrl": null,
|
|
639
|
+
"domains": [],
|
|
651
640
|
"routes": [],
|
|
652
|
-
"serviceId":
|
|
641
|
+
"serviceId": null
|
|
653
642
|
},
|
|
654
643
|
{
|
|
655
644
|
"name": "topolo-feed-web",
|
|
@@ -659,7 +648,7 @@ var APPLICATIONS = {
|
|
|
659
648
|
"feed.topolo.app"
|
|
660
649
|
],
|
|
661
650
|
"routes": [],
|
|
662
|
-
"serviceId":
|
|
651
|
+
"serviceId": "feed"
|
|
663
652
|
}
|
|
664
653
|
]
|
|
665
654
|
},
|
|
@@ -711,17 +700,15 @@ var APPLICATIONS = {
|
|
|
711
700
|
"forecast.topolo.app"
|
|
712
701
|
],
|
|
713
702
|
"routes": [],
|
|
714
|
-
"serviceId":
|
|
703
|
+
"serviceId": "forecast"
|
|
715
704
|
},
|
|
716
705
|
{
|
|
717
706
|
"name": "topolo-forecast-api",
|
|
718
707
|
"kind": "worker",
|
|
719
|
-
"apiUrl":
|
|
720
|
-
"domains": [
|
|
721
|
-
"forecast-api.topolo.app"
|
|
722
|
-
],
|
|
708
|
+
"apiUrl": null,
|
|
709
|
+
"domains": [],
|
|
723
710
|
"routes": [],
|
|
724
|
-
"serviceId":
|
|
711
|
+
"serviceId": null
|
|
725
712
|
}
|
|
726
713
|
]
|
|
727
714
|
},
|
|
@@ -863,17 +850,15 @@ var APPLICATIONS = {
|
|
|
863
850
|
"learn.topolo.app"
|
|
864
851
|
],
|
|
865
852
|
"routes": [],
|
|
866
|
-
"serviceId":
|
|
853
|
+
"serviceId": "learn"
|
|
867
854
|
},
|
|
868
855
|
{
|
|
869
856
|
"name": "topolo-learn-api",
|
|
870
857
|
"kind": "worker",
|
|
871
|
-
"apiUrl":
|
|
872
|
-
"domains": [
|
|
873
|
-
"learn-api.topolo.app"
|
|
874
|
-
],
|
|
858
|
+
"apiUrl": null,
|
|
859
|
+
"domains": [],
|
|
875
860
|
"routes": [],
|
|
876
|
-
"serviceId":
|
|
861
|
+
"serviceId": null
|
|
877
862
|
}
|
|
878
863
|
]
|
|
879
864
|
},
|
|
@@ -919,17 +904,15 @@ var APPLICATIONS = {
|
|
|
919
904
|
"mail.topolo.app"
|
|
920
905
|
],
|
|
921
906
|
"routes": [],
|
|
922
|
-
"serviceId":
|
|
907
|
+
"serviceId": "mail"
|
|
923
908
|
},
|
|
924
909
|
{
|
|
925
910
|
"name": "topolo-mail-api",
|
|
926
911
|
"kind": "worker",
|
|
927
|
-
"apiUrl":
|
|
928
|
-
"domains": [
|
|
929
|
-
"mail-api.topolo.app"
|
|
930
|
-
],
|
|
912
|
+
"apiUrl": null,
|
|
913
|
+
"domains": [],
|
|
931
914
|
"routes": [],
|
|
932
|
-
"serviceId":
|
|
915
|
+
"serviceId": null
|
|
933
916
|
}
|
|
934
917
|
]
|
|
935
918
|
},
|
|
@@ -946,12 +929,10 @@ var APPLICATIONS = {
|
|
|
946
929
|
{
|
|
947
930
|
"name": "topolo-mdm-api",
|
|
948
931
|
"kind": "worker",
|
|
949
|
-
"apiUrl":
|
|
950
|
-
"domains": [
|
|
951
|
-
"mdm-api.topolo.app"
|
|
952
|
-
],
|
|
932
|
+
"apiUrl": null,
|
|
933
|
+
"domains": [],
|
|
953
934
|
"routes": [],
|
|
954
|
-
"serviceId":
|
|
935
|
+
"serviceId": null
|
|
955
936
|
},
|
|
956
937
|
{
|
|
957
938
|
"name": "topolo-mdm-console",
|
|
@@ -961,7 +942,7 @@ var APPLICATIONS = {
|
|
|
961
942
|
"mdm.topolo.app"
|
|
962
943
|
],
|
|
963
944
|
"routes": [],
|
|
964
|
-
"serviceId":
|
|
945
|
+
"serviceId": "mdm"
|
|
965
946
|
}
|
|
966
947
|
]
|
|
967
948
|
},
|
|
@@ -1094,20 +1075,23 @@ var APPLICATIONS = {
|
|
|
1094
1075
|
{
|
|
1095
1076
|
"name": "topolo-one",
|
|
1096
1077
|
"kind": "worker",
|
|
1097
|
-
"apiUrl":
|
|
1098
|
-
"domains": [
|
|
1099
|
-
|
|
1078
|
+
"apiUrl": "https://one.topolo.app",
|
|
1079
|
+
"domains": [
|
|
1080
|
+
"one.topolo.app"
|
|
1081
|
+
],
|
|
1082
|
+
"routes": [
|
|
1083
|
+
"one.topolo.app/*"
|
|
1084
|
+
],
|
|
1100
1085
|
"serviceId": null
|
|
1101
1086
|
},
|
|
1102
1087
|
{
|
|
1103
1088
|
"name": "topolo-one-api",
|
|
1104
1089
|
"kind": "worker",
|
|
1105
|
-
"apiUrl": "https://
|
|
1090
|
+
"apiUrl": "https://www.topolo.app",
|
|
1106
1091
|
"domains": [
|
|
1107
|
-
"
|
|
1092
|
+
"www.topolo.app"
|
|
1108
1093
|
],
|
|
1109
1094
|
"routes": [
|
|
1110
|
-
"one.topolo.app/*",
|
|
1111
1095
|
"www.topolo.app/*"
|
|
1112
1096
|
],
|
|
1113
1097
|
"serviceId": "one"
|
|
@@ -1217,36 +1201,6 @@ var APPLICATIONS = {
|
|
|
1217
1201
|
}
|
|
1218
1202
|
]
|
|
1219
1203
|
},
|
|
1220
|
-
"pulse": {
|
|
1221
|
-
"id": "pulse",
|
|
1222
|
-
"appDir": "TopoloPulse",
|
|
1223
|
-
"name": "topolo-pulse",
|
|
1224
|
-
"packageName": "topolo-pulse",
|
|
1225
|
-
"productionUrl": "https://pulse.topolo.app",
|
|
1226
|
-
"services": [
|
|
1227
|
-
"pulse"
|
|
1228
|
-
],
|
|
1229
|
-
"deployTargets": [
|
|
1230
|
-
{
|
|
1231
|
-
"name": "topolo-pulse",
|
|
1232
|
-
"kind": "worker",
|
|
1233
|
-
"apiUrl": "https://pulse.topolo.app",
|
|
1234
|
-
"domains": [
|
|
1235
|
-
"pulse.topolo.app"
|
|
1236
|
-
],
|
|
1237
|
-
"routes": [],
|
|
1238
|
-
"serviceId": "pulse"
|
|
1239
|
-
},
|
|
1240
|
-
{
|
|
1241
|
-
"name": "topolo-pulse-api",
|
|
1242
|
-
"kind": "worker",
|
|
1243
|
-
"apiUrl": null,
|
|
1244
|
-
"domains": [],
|
|
1245
|
-
"routes": [],
|
|
1246
|
-
"serviceId": null
|
|
1247
|
-
}
|
|
1248
|
-
]
|
|
1249
|
-
},
|
|
1250
1204
|
"quro": {
|
|
1251
1205
|
"id": "quro",
|
|
1252
1206
|
"appDir": "TopoloQuro",
|
|
@@ -1312,17 +1266,15 @@ var APPLICATIONS = {
|
|
|
1312
1266
|
"roadmapper.topolo.app"
|
|
1313
1267
|
],
|
|
1314
1268
|
"routes": [],
|
|
1315
|
-
"serviceId":
|
|
1269
|
+
"serviceId": "roadmapper"
|
|
1316
1270
|
},
|
|
1317
1271
|
{
|
|
1318
1272
|
"name": "topolo-roadmapper-api",
|
|
1319
1273
|
"kind": "worker",
|
|
1320
|
-
"apiUrl":
|
|
1321
|
-
"domains": [
|
|
1322
|
-
"roadmapper-api.topolo.app"
|
|
1323
|
-
],
|
|
1274
|
+
"apiUrl": null,
|
|
1275
|
+
"domains": [],
|
|
1324
1276
|
"routes": [],
|
|
1325
|
-
"serviceId":
|
|
1277
|
+
"serviceId": null
|
|
1326
1278
|
}
|
|
1327
1279
|
]
|
|
1328
1280
|
},
|
|
@@ -1374,17 +1326,15 @@ var APPLICATIONS = {
|
|
|
1374
1326
|
"studio.topolo.app"
|
|
1375
1327
|
],
|
|
1376
1328
|
"routes": [],
|
|
1377
|
-
"serviceId":
|
|
1329
|
+
"serviceId": "social_studio"
|
|
1378
1330
|
},
|
|
1379
1331
|
{
|
|
1380
1332
|
"name": "topolo-social-studio-api",
|
|
1381
1333
|
"kind": "worker",
|
|
1382
|
-
"apiUrl":
|
|
1383
|
-
"domains": [
|
|
1384
|
-
"studio-api.topolo.app"
|
|
1385
|
-
],
|
|
1334
|
+
"apiUrl": null,
|
|
1335
|
+
"domains": [],
|
|
1386
1336
|
"routes": [],
|
|
1387
|
-
"serviceId":
|
|
1337
|
+
"serviceId": null
|
|
1388
1338
|
},
|
|
1389
1339
|
{
|
|
1390
1340
|
"name": "topolo-social-studio-queue",
|
|
@@ -1414,17 +1364,15 @@ var APPLICATIONS = {
|
|
|
1414
1364
|
"socialize.topolo.app"
|
|
1415
1365
|
],
|
|
1416
1366
|
"routes": [],
|
|
1417
|
-
"serviceId":
|
|
1367
|
+
"serviceId": "socialize"
|
|
1418
1368
|
},
|
|
1419
1369
|
{
|
|
1420
1370
|
"name": "topolo-socialize-api",
|
|
1421
1371
|
"kind": "worker",
|
|
1422
|
-
"apiUrl":
|
|
1423
|
-
"domains": [
|
|
1424
|
-
"socialize-api.topolo.app"
|
|
1425
|
-
],
|
|
1372
|
+
"apiUrl": null,
|
|
1373
|
+
"domains": [],
|
|
1426
1374
|
"routes": [],
|
|
1427
|
-
"serviceId":
|
|
1375
|
+
"serviceId": null
|
|
1428
1376
|
},
|
|
1429
1377
|
{
|
|
1430
1378
|
"name": "topolo-socialize-scheduler",
|
|
@@ -1625,12 +1573,10 @@ var APPLICATIONS = {
|
|
|
1625
1573
|
{
|
|
1626
1574
|
"name": "topolo-web-api",
|
|
1627
1575
|
"kind": "worker",
|
|
1628
|
-
"apiUrl":
|
|
1629
|
-
"domains": [
|
|
1630
|
-
"web-api.topolo.app"
|
|
1631
|
-
],
|
|
1576
|
+
"apiUrl": null,
|
|
1577
|
+
"domains": [],
|
|
1632
1578
|
"routes": [],
|
|
1633
|
-
"serviceId":
|
|
1579
|
+
"serviceId": null
|
|
1634
1580
|
},
|
|
1635
1581
|
{
|
|
1636
1582
|
"name": "topolo-web-runtime",
|
|
@@ -1653,12 +1599,12 @@ var APPLICATIONS = {
|
|
|
1653
1599
|
"web.topolo.app"
|
|
1654
1600
|
],
|
|
1655
1601
|
"routes": [],
|
|
1656
|
-
"serviceId":
|
|
1602
|
+
"serviceId": "web"
|
|
1657
1603
|
}
|
|
1658
1604
|
]
|
|
1659
1605
|
}
|
|
1660
1606
|
};
|
|
1661
|
-
var APPLICATION_REQUIREMENTS_VERSION = "2026-
|
|
1607
|
+
var APPLICATION_REQUIREMENTS_VERSION = "2026-06-07.1";
|
|
1662
1608
|
var APPLICATION_REQUIREMENTS = [
|
|
1663
1609
|
{
|
|
1664
1610
|
id: "platform-metadata",
|
|
@@ -1714,16 +1660,20 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1714
1660
|
summary: "Browser applications should feel like one platform and should not create isolated navigation or account surfaces.",
|
|
1715
1661
|
appliesTo: ["browser"],
|
|
1716
1662
|
evidence: [
|
|
1717
|
-
"@topolo/
|
|
1718
|
-
"
|
|
1719
|
-
"Account menu and sign-out behavior use TopoloAppShell or TopoloAccountMenu",
|
|
1663
|
+
"@topolo-io/app-shell is used for the platform shell where the app has authenticated UI",
|
|
1664
|
+
"@topolo-io/app-launcher keeps the shared launcher/app switcher reachable from authenticated app chrome",
|
|
1665
|
+
"Account menu and sign-out behavior use TopoloAppShell or the ui-kit TopoloAccountMenu primitive",
|
|
1666
|
+
"Repeated app body surfaces use shared TopoloAppLayout primitives instead of local stat cards, empty states, or status badges",
|
|
1667
|
+
"Local preview supports deterministic visual QA fixtures for overview, list, detail, settings, and empty/loading states",
|
|
1720
1668
|
"Authenticated app body content stays inside the viewport on mobile and desktop widths"
|
|
1721
1669
|
],
|
|
1722
1670
|
implementation: [
|
|
1723
|
-
"Use TopoloAppShell for authenticated app layouts",
|
|
1724
|
-
"Use TopoloAccountMenu when a partial-shell surface still needs account chrome",
|
|
1671
|
+
"Use @topolo-io/app-shell TopoloAppShell for authenticated app layouts",
|
|
1672
|
+
"Use the @topolo-io/ui-kit TopoloAccountMenu primitive when a partial-shell surface still needs account chrome",
|
|
1725
1673
|
"Pass app-specific account actions as additive menu items instead of forking dropdowns",
|
|
1726
1674
|
"Use shared design tokens and platform UI primitives before creating local equivalents",
|
|
1675
|
+
"Use TopoloAppMetricCard, TopoloAppEmptyState, TopoloAppStatusBadge, TopoloAppGrid, and TopoloAppSection for repeated app body patterns",
|
|
1676
|
+
"Keep visual QA fixtures available through visualQa=1 or __devpreview=1 so screenshot checks do not depend on live API state",
|
|
1727
1677
|
"Keep mobile and desktop shell behavior aligned with the platform UI kit",
|
|
1728
1678
|
"Constrain app-owned workspace wrappers with min-width: 0, width: auto, and viewport-aware max-width so shell padding cannot create page-level horizontal overflow"
|
|
1729
1679
|
]
|
|
@@ -1802,11 +1752,13 @@ var APPLICATION_REQUIREMENTS = [
|
|
|
1802
1752
|
evidence: [
|
|
1803
1753
|
"The app-owned API exposes GET /api/widget",
|
|
1804
1754
|
"The endpoint returns TopoloWidgetApiResponse from @topolo/sdk",
|
|
1755
|
+
"Every returned widget includes snapshot.summary with app-owned operational prose",
|
|
1805
1756
|
"The endpoint derives organization/user context from the app auth boundary"
|
|
1806
1757
|
],
|
|
1807
1758
|
implementation: [
|
|
1808
1759
|
"Import createTopoloWidgetResponse from @topolo/sdk in the app backend",
|
|
1809
1760
|
"Return native app metrics or action widgets instead of generic launch-card fallbacks",
|
|
1761
|
+
"Populate snapshot.summary in the producing app for every widget instead of synthesizing summaries in TopoloOne",
|
|
1810
1762
|
"Add a route-level test that validates the response with validateTopoloWidgetResponse"
|
|
1811
1763
|
]
|
|
1812
1764
|
},
|
|
@@ -2099,6 +2051,8 @@ function firstString(...values) {
|
|
|
2099
2051
|
var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
2100
2052
|
var TOPOLO_ACTION_ID_HEADER = "X-Topolo-Action-Id";
|
|
2101
2053
|
var TOPOLO_ACTION_NAME_HEADER = "X-Topolo-Action-Name";
|
|
2054
|
+
var TOPOLO_RESOURCE_TYPE_HEADER = "X-Topolo-Resource-Type";
|
|
2055
|
+
var TOPOLO_RESOURCE_ID_HEADER = "X-Topolo-Resource-ID";
|
|
2102
2056
|
var POSITIVE_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
2103
2057
|
var NEGATIVE_CACHE_TTL_MS = 60 * 1e3;
|
|
2104
2058
|
var CATALOG_CACHE_TTL_MS = 60 * 1e3;
|
|
@@ -2177,6 +2131,18 @@ var TopoloClient = class _TopoloClient {
|
|
|
2177
2131
|
if (opts.headers) {
|
|
2178
2132
|
for (const [k, v] of Object.entries(opts.headers)) headers.set(k, v);
|
|
2179
2133
|
}
|
|
2134
|
+
if (opts.resource) {
|
|
2135
|
+
const resourceType = opts.resource.resourceType.trim();
|
|
2136
|
+
const resourceId = opts.resource.resourceId.trim();
|
|
2137
|
+
if (!resourceType || !resourceId) {
|
|
2138
|
+
throw new TopoloSdkError(
|
|
2139
|
+
"invalid_resource_context",
|
|
2140
|
+
"Both resource.resourceType and resource.resourceId are required when resource context is provided."
|
|
2141
|
+
);
|
|
2142
|
+
}
|
|
2143
|
+
headers.set(TOPOLO_RESOURCE_TYPE_HEADER, resourceType);
|
|
2144
|
+
headers.set(TOPOLO_RESOURCE_ID_HEADER, resourceId);
|
|
2145
|
+
}
|
|
2180
2146
|
const controller = new AbortController();
|
|
2181
2147
|
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
2182
2148
|
const signal = opts.signal ? mergeSignals(opts.signal, controller.signal) : controller.signal;
|
|
@@ -2359,6 +2325,11 @@ var TopoloClient = class _TopoloClient {
|
|
|
2359
2325
|
const serviceId = typeof s.service_id === "string" ? s.service_id : typeof s.id === "string" ? s.id : null;
|
|
2360
2326
|
if (!serviceId) continue;
|
|
2361
2327
|
const permissions = Array.isArray(s.granted_permissions) ? s.granted_permissions.filter((permission) => typeof permission === "string" && permission.trim().length > 0) : [];
|
|
2328
|
+
const catalogApiKeyResources = normalizeApiKeyResourceMetadataList(
|
|
2329
|
+
s.api_key_resources ?? s.apiKeyResources
|
|
2330
|
+
);
|
|
2331
|
+
const apiKeyResource = normalizeApiKeyResourceMetadata(s.api_key_resource ?? s.apiKeyResource) ?? catalogApiKeyResources[0] ?? null;
|
|
2332
|
+
const apiKeyResources = catalogApiKeyResources.length > 0 ? catalogApiKeyResources : apiKeyResource ? [apiKeyResource] : [];
|
|
2362
2333
|
entries.push({
|
|
2363
2334
|
serviceId,
|
|
2364
2335
|
slug: typeof s.app_slug === "string" ? s.app_slug : null,
|
|
@@ -2369,7 +2340,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2369
2340
|
status: typeof s.status === "string" ? s.status : null,
|
|
2370
2341
|
surfaceKind: typeof s.surface_kind === "string" ? s.surface_kind : null,
|
|
2371
2342
|
launchable: s.launchable === true,
|
|
2372
|
-
permissions
|
|
2343
|
+
permissions,
|
|
2344
|
+
apiKeyResource,
|
|
2345
|
+
apiKeyResources
|
|
2373
2346
|
});
|
|
2374
2347
|
}
|
|
2375
2348
|
this.serviceCatalogCache = {
|
|
@@ -2455,7 +2428,9 @@ var TopoloClient = class _TopoloClient {
|
|
|
2455
2428
|
status: "bundled",
|
|
2456
2429
|
surfaceKind: "application",
|
|
2457
2430
|
launchable: Boolean(app.productionUrl),
|
|
2458
|
-
permissions: []
|
|
2431
|
+
permissions: [],
|
|
2432
|
+
apiKeyResource: null,
|
|
2433
|
+
apiKeyResources: []
|
|
2459
2434
|
}));
|
|
2460
2435
|
}
|
|
2461
2436
|
/**
|
|
@@ -2504,6 +2479,46 @@ function resolveConfiguredServiceId(slug, serviceIds) {
|
|
|
2504
2479
|
}
|
|
2505
2480
|
return null;
|
|
2506
2481
|
}
|
|
2482
|
+
function normalizeApiKeyResourceMetadata(input) {
|
|
2483
|
+
if (!isRecord(input)) return null;
|
|
2484
|
+
const resourceType = readString(input.resourceType ?? input.resource_type);
|
|
2485
|
+
const label = readString(input.label);
|
|
2486
|
+
const emptyLabel = readString(input.emptyLabel ?? input.empty_label);
|
|
2487
|
+
const resourceConcept = readString(input.resourceConcept ?? input.resource_concept);
|
|
2488
|
+
const canonicalResourceType = readString(input.canonicalResourceType ?? input.canonical_resource_type);
|
|
2489
|
+
const defaultEntitlement = readString(input.defaultEntitlement ?? input.default_entitlement);
|
|
2490
|
+
const exceptionPolicy = readString(input.exceptionPolicy ?? input.exception_policy);
|
|
2491
|
+
if (!resourceType || !label || !emptyLabel || resourceConcept !== "workspace" || canonicalResourceType !== "workspace" || defaultEntitlement !== "enterprise" || exceptionPolicy !== "app_or_organization") {
|
|
2492
|
+
return null;
|
|
2493
|
+
}
|
|
2494
|
+
return {
|
|
2495
|
+
resourceType,
|
|
2496
|
+
label,
|
|
2497
|
+
emptyLabel,
|
|
2498
|
+
resourceConcept,
|
|
2499
|
+
canonicalResourceType,
|
|
2500
|
+
defaultEntitlement,
|
|
2501
|
+
exceptionPolicy
|
|
2502
|
+
};
|
|
2503
|
+
}
|
|
2504
|
+
function normalizeApiKeyResourceMetadataList(input) {
|
|
2505
|
+
if (!Array.isArray(input)) return [];
|
|
2506
|
+
const resources = [];
|
|
2507
|
+
const seenTypes = /* @__PURE__ */ new Set();
|
|
2508
|
+
for (const item of input) {
|
|
2509
|
+
const resource = normalizeApiKeyResourceMetadata(item);
|
|
2510
|
+
if (!resource || seenTypes.has(resource.resourceType)) continue;
|
|
2511
|
+
seenTypes.add(resource.resourceType);
|
|
2512
|
+
resources.push(resource);
|
|
2513
|
+
}
|
|
2514
|
+
return resources;
|
|
2515
|
+
}
|
|
2516
|
+
function readString(value) {
|
|
2517
|
+
return typeof value === "string" ? value.trim() : "";
|
|
2518
|
+
}
|
|
2519
|
+
function isRecord(value) {
|
|
2520
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2521
|
+
}
|
|
2507
2522
|
function resolveConfiguredServiceUrl(slug, serviceUrls) {
|
|
2508
2523
|
for (const serviceKey of serviceKeyCandidates2(slug)) {
|
|
2509
2524
|
const configured = serviceUrls?.[serviceKey];
|
|
@@ -2838,6 +2853,8 @@ var TOOLS = [
|
|
|
2838
2853
|
effectiveUrl: resolveCatalogServiceUrl(entry, { serviceKey: id }),
|
|
2839
2854
|
surfaceKind: entry.surfaceKind,
|
|
2840
2855
|
launchable: entry.launchable,
|
|
2856
|
+
apiKeyResource: entry.apiKeyResource,
|
|
2857
|
+
apiKeyResources: [...entry.apiKeyResources],
|
|
2841
2858
|
permissions: [...entry.permissions]
|
|
2842
2859
|
};
|
|
2843
2860
|
}).sort((left, right) => left.id.localeCompare(right.id));
|
|
@@ -3031,6 +3048,14 @@ var TOOLS = [
|
|
|
3031
3048
|
additionalProperties: { type: "string" },
|
|
3032
3049
|
description: "Query string parameters as string values."
|
|
3033
3050
|
},
|
|
3051
|
+
resourceType: {
|
|
3052
|
+
type: "string",
|
|
3053
|
+
description: "Optional workspace resource alias from topolo_list_services apiKeyResources. Aliases are app-defined, e.g. brand, mailbox, venue, merchant, or any other cataloged alias."
|
|
3054
|
+
},
|
|
3055
|
+
resourceId: {
|
|
3056
|
+
type: "string",
|
|
3057
|
+
description: "Resource id for resourceType. Required when resourceType is provided."
|
|
3058
|
+
},
|
|
3034
3059
|
confirm: {
|
|
3035
3060
|
type: "boolean",
|
|
3036
3061
|
description: "Required for non-GET methods. Explicit human-in-the-loop acknowledgement for writes."
|
|
@@ -3057,12 +3082,19 @@ var TOOLS = [
|
|
|
3057
3082
|
const normalisedQuery = query && typeof query === "object" && !Array.isArray(query) ? Object.fromEntries(
|
|
3058
3083
|
Object.entries(query).map(([k, v]) => [k, String(v)])
|
|
3059
3084
|
) : void 0;
|
|
3085
|
+
const resourceType = typeof args["resourceType"] === "string" ? args["resourceType"].trim() : "";
|
|
3086
|
+
const resourceId = typeof args["resourceId"] === "string" ? args["resourceId"].trim() : "";
|
|
3087
|
+
if (resourceType && !resourceId || !resourceType && resourceId) {
|
|
3088
|
+
throw new Error("resourceType and resourceId must be provided together.");
|
|
3089
|
+
}
|
|
3090
|
+
const resource = resourceType && resourceId ? { resourceType, resourceId } : void 0;
|
|
3060
3091
|
return topolo.client.request({
|
|
3061
3092
|
service: service.trim(),
|
|
3062
3093
|
method,
|
|
3063
3094
|
path,
|
|
3064
3095
|
body: args["body"],
|
|
3065
3096
|
...normalisedQuery ? { query: normalisedQuery } : {},
|
|
3097
|
+
...resource ? { resource } : {},
|
|
3066
3098
|
confirm: Boolean(args["confirm"])
|
|
3067
3099
|
});
|
|
3068
3100
|
}
|
|
@@ -3184,7 +3216,28 @@ function formatKnownValues(values, label) {
|
|
|
3184
3216
|
}
|
|
3185
3217
|
|
|
3186
3218
|
// src/version.ts
|
|
3187
|
-
|
|
3219
|
+
import { readFileSync } from "fs";
|
|
3220
|
+
import { dirname, join } from "path";
|
|
3221
|
+
import { fileURLToPath } from "url";
|
|
3222
|
+
function readMcpVersion() {
|
|
3223
|
+
try {
|
|
3224
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
3225
|
+
const candidates = [
|
|
3226
|
+
join(here, "package.json"),
|
|
3227
|
+
join(here, "..", "package.json")
|
|
3228
|
+
];
|
|
3229
|
+
for (const path of candidates) {
|
|
3230
|
+
try {
|
|
3231
|
+
const pkg = JSON.parse(readFileSync(path, "utf8"));
|
|
3232
|
+
if (typeof pkg.version === "string" && pkg.version) return pkg.version;
|
|
3233
|
+
} catch {
|
|
3234
|
+
}
|
|
3235
|
+
}
|
|
3236
|
+
} catch {
|
|
3237
|
+
}
|
|
3238
|
+
return "0.0.0";
|
|
3239
|
+
}
|
|
3240
|
+
var MCP_VERSION = readMcpVersion();
|
|
3188
3241
|
|
|
3189
3242
|
// src/server.ts
|
|
3190
3243
|
function buildServer(topolo, scopes, tools = TOOLS) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topolo/mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.8",
|
|
4
4
|
"description": "Model Context Protocol server for the Topolo platform. Exposes scope-gated tools that third-party agents (Claude, Codex, etc.) can call natively.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,27 +15,27 @@
|
|
|
15
15
|
"files": [
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
|
-
"scripts": {
|
|
19
|
-
"build": "tsup",
|
|
20
|
-
"dev": "tsup --watch",
|
|
21
|
-
"typecheck": "tsc --noEmit",
|
|
22
|
-
"start": "node dist/index.js",
|
|
23
|
-
"test": "vitest run",
|
|
24
|
-
"test:watch": "vitest",
|
|
25
|
-
"coverage": "vitest run --coverage"
|
|
26
|
-
},
|
|
27
18
|
"dependencies": {
|
|
28
19
|
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
29
20
|
},
|
|
30
21
|
"devDependencies": {
|
|
31
|
-
"@topolo/sdk": "workspace:*",
|
|
32
22
|
"@types/node": "^20.12.0",
|
|
33
23
|
"@vitest/coverage-v8": "^2.1.0",
|
|
34
24
|
"tsup": "^8.0.0",
|
|
35
25
|
"typescript": "^5.4.0",
|
|
36
|
-
"vitest": "^2.1.0"
|
|
26
|
+
"vitest": "^2.1.0",
|
|
27
|
+
"@topolo/sdk": "0.4.8"
|
|
37
28
|
},
|
|
38
29
|
"engines": {
|
|
39
30
|
"node": ">=20"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup",
|
|
34
|
+
"dev": "tsup --watch",
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"start": "node dist/index.js",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"test:watch": "vitest",
|
|
39
|
+
"coverage": "vitest run --coverage"
|
|
40
40
|
}
|
|
41
|
-
}
|
|
41
|
+
}
|