@topolo/mcp 0.9.8 → 0.9.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/dist/dispatch.js CHANGED
@@ -73,6 +73,20 @@ function optionalResourceContext(args) {
73
73
  }
74
74
  return { resourceType, resourceId };
75
75
  }
76
+ function coerceObjectParam(value, name) {
77
+ let candidate = value;
78
+ if (typeof candidate === "string" && candidate.trim().startsWith("{")) {
79
+ try {
80
+ candidate = JSON.parse(candidate);
81
+ } catch {
82
+ }
83
+ }
84
+ if (candidate === void 0) return {};
85
+ if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) {
86
+ throw new TopoloMcpPublicError(`${name} must be an object.`);
87
+ }
88
+ return candidate;
89
+ }
76
90
  var TOOLS = [
77
91
  {
78
92
  name: "topolo_whoami",
@@ -223,14 +237,11 @@ var TOOLS = [
223
237
  handler: async (topolo, args) => {
224
238
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
225
239
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
226
- const input = args["input"];
227
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
228
- throw new TopoloMcpPublicError("input must be an object.");
229
- }
240
+ const input = coerceObjectParam(args["input"], "input");
230
241
  const resource = optionalResourceContext(args);
231
242
  return topolo.client.readAction(
232
243
  actionId,
233
- input ?? {},
244
+ input,
234
245
  resource ? { resource } : {}
235
246
  );
236
247
  }
@@ -256,14 +267,11 @@ var TOOLS = [
256
267
  handler: async (topolo, args) => {
257
268
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
258
269
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
259
- const input = args["input"];
260
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
261
- throw new TopoloMcpPublicError("input must be an object.");
262
- }
270
+ const input = coerceObjectParam(args["input"], "input");
263
271
  const resource = optionalResourceContext(args);
264
272
  return topolo.client.callAction(
265
273
  actionId,
266
- input ?? {},
274
+ input,
267
275
  {
268
276
  confirm: args["confirm"] === true,
269
277
  ...resource ? { resource } : {}
@@ -302,23 +310,17 @@ var TOOLS = [
302
310
  if (!isCanonicalBase64(contentBase64)) throw new TopoloMcpPublicError("contentBase64 must be canonical base64.");
303
311
  if (!contentType) throw new TopoloMcpPublicError("contentType is required.");
304
312
  if (!fileName) throw new TopoloMcpPublicError("fileName is required.");
305
- const input = args["input"];
306
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
307
- throw new TopoloMcpPublicError("input must be an object.");
308
- }
309
- const completionInput = args["completionInput"];
310
- if (completionInput !== void 0 && (!completionInput || typeof completionInput !== "object" || Array.isArray(completionInput))) {
311
- throw new TopoloMcpPublicError("completionInput must be an object.");
312
- }
313
+ const input = coerceObjectParam(args["input"], "input");
314
+ const completionInput = coerceObjectParam(args["completionInput"], "completionInput");
313
315
  const resource = optionalResourceContext(args);
314
316
  return topolo.client.uploadActionBase64(
315
317
  actionId,
316
318
  contentBase64,
317
- input ?? {},
319
+ input,
318
320
  {
319
321
  fileName,
320
322
  contentType,
321
- completionInput: completionInput ?? {},
323
+ completionInput,
322
324
  confirm: args["confirm"] === true,
323
325
  ...resource ? { resource } : {}
324
326
  }
@@ -343,11 +345,8 @@ var TOOLS = [
343
345
  handler: async (topolo, args) => {
344
346
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
345
347
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
346
- const input = args["input"];
347
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
348
- throw new TopoloMcpPublicError("input must be an object.");
349
- }
350
- return topolo.client.validateActionInput(actionId, input ?? {});
348
+ const input = coerceObjectParam(args["input"], "input");
349
+ return topolo.client.validateActionInput(actionId, input);
351
350
  }
352
351
  },
353
352
  {
@@ -371,14 +370,11 @@ var TOOLS = [
371
370
  handler: async (topolo, args) => {
372
371
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
373
372
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
374
- const input = args["input"];
375
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
376
- throw new TopoloMcpPublicError("input must be an object.");
377
- }
373
+ const input = coerceObjectParam(args["input"], "input");
378
374
  const resource = optionalResourceContext(args);
379
375
  return topolo.client.planAction(
380
376
  actionId,
381
- input ?? {},
377
+ input,
382
378
  {
383
379
  confirm: args["confirm"] === true,
384
380
  ...resource ? { resource } : {}
@@ -412,7 +408,7 @@ var TOOLS = [
412
408
  {
413
409
  name: "topolo_discover_capabilities",
414
410
  title: "Discover one Topolo application capability contract",
415
- description: "Discovers capability and schema actions published by one application. Use the actionService value returned by topolo_search_applications as service.",
411
+ description: "Lists every action published by one application \u2014 its full capability contract, straight from the registry-canonical catalog. Use the actionService value returned by topolo_search_applications as service. Follow page.nextCursor via topolo_search_actions when the contract exceeds one page.",
416
412
  requiredScopes: [],
417
413
  destructive: false,
418
414
  inputSchema: {
@@ -424,7 +420,7 @@ var TOOLS = [
424
420
  handler: async (topolo, args) => {
425
421
  const service = typeof args["service"] === "string" ? args["service"].trim() : "";
426
422
  if (!service) throw new TopoloMcpPublicError("service is required.");
427
- return topolo.client.searchActions({ service, query: "capabilities", limit: 100 });
423
+ return topolo.client.searchActions({ service, limit: 100 });
428
424
  }
429
425
  },
430
426
  {
@@ -616,11 +612,21 @@ var TOOLS = [
616
612
  Object.entries(query).map(([k, v]) => [k, String(v)])
617
613
  ) : void 0;
618
614
  const resource = optionalResourceContext(args);
615
+ let body = args["body"];
616
+ if (typeof body === "string") {
617
+ const candidate = body.trim();
618
+ if (candidate.startsWith("{") || candidate.startsWith("[")) {
619
+ try {
620
+ body = JSON.parse(candidate);
621
+ } catch {
622
+ }
623
+ }
624
+ }
619
625
  return topolo.client.request({
620
626
  service: service.trim(),
621
627
  method,
622
628
  path,
623
- body: args["body"],
629
+ body,
624
630
  ...normalisedQuery ? { query: normalisedQuery } : {},
625
631
  ...resource ? { resource } : {},
626
632
  confirm: Boolean(args["confirm"])
package/dist/http.js CHANGED
@@ -15887,6 +15887,20 @@ function optionalResourceContext(args) {
15887
15887
  }
15888
15888
  return { resourceType, resourceId };
15889
15889
  }
15890
+ function coerceObjectParam(value, name) {
15891
+ let candidate = value;
15892
+ if (typeof candidate === "string" && candidate.trim().startsWith("{")) {
15893
+ try {
15894
+ candidate = JSON.parse(candidate);
15895
+ } catch {
15896
+ }
15897
+ }
15898
+ if (candidate === void 0) return {};
15899
+ if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) {
15900
+ throw new TopoloMcpPublicError(`${name} must be an object.`);
15901
+ }
15902
+ return candidate;
15903
+ }
15890
15904
  var TOOLS = [
15891
15905
  {
15892
15906
  name: "topolo_whoami",
@@ -16037,14 +16051,11 @@ var TOOLS = [
16037
16051
  handler: async (topolo, args) => {
16038
16052
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
16039
16053
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
16040
- const input = args["input"];
16041
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
16042
- throw new TopoloMcpPublicError("input must be an object.");
16043
- }
16054
+ const input = coerceObjectParam(args["input"], "input");
16044
16055
  const resource = optionalResourceContext(args);
16045
16056
  return topolo.client.readAction(
16046
16057
  actionId,
16047
- input ?? {},
16058
+ input,
16048
16059
  resource ? { resource } : {}
16049
16060
  );
16050
16061
  }
@@ -16070,14 +16081,11 @@ var TOOLS = [
16070
16081
  handler: async (topolo, args) => {
16071
16082
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
16072
16083
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
16073
- const input = args["input"];
16074
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
16075
- throw new TopoloMcpPublicError("input must be an object.");
16076
- }
16084
+ const input = coerceObjectParam(args["input"], "input");
16077
16085
  const resource = optionalResourceContext(args);
16078
16086
  return topolo.client.callAction(
16079
16087
  actionId,
16080
- input ?? {},
16088
+ input,
16081
16089
  {
16082
16090
  confirm: args["confirm"] === true,
16083
16091
  ...resource ? { resource } : {}
@@ -16116,23 +16124,17 @@ var TOOLS = [
16116
16124
  if (!isCanonicalBase64(contentBase64)) throw new TopoloMcpPublicError("contentBase64 must be canonical base64.");
16117
16125
  if (!contentType) throw new TopoloMcpPublicError("contentType is required.");
16118
16126
  if (!fileName) throw new TopoloMcpPublicError("fileName is required.");
16119
- const input = args["input"];
16120
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
16121
- throw new TopoloMcpPublicError("input must be an object.");
16122
- }
16123
- const completionInput = args["completionInput"];
16124
- if (completionInput !== void 0 && (!completionInput || typeof completionInput !== "object" || Array.isArray(completionInput))) {
16125
- throw new TopoloMcpPublicError("completionInput must be an object.");
16126
- }
16127
+ const input = coerceObjectParam(args["input"], "input");
16128
+ const completionInput = coerceObjectParam(args["completionInput"], "completionInput");
16127
16129
  const resource = optionalResourceContext(args);
16128
16130
  return topolo.client.uploadActionBase64(
16129
16131
  actionId,
16130
16132
  contentBase64,
16131
- input ?? {},
16133
+ input,
16132
16134
  {
16133
16135
  fileName,
16134
16136
  contentType,
16135
- completionInput: completionInput ?? {},
16137
+ completionInput,
16136
16138
  confirm: args["confirm"] === true,
16137
16139
  ...resource ? { resource } : {}
16138
16140
  }
@@ -16157,11 +16159,8 @@ var TOOLS = [
16157
16159
  handler: async (topolo, args) => {
16158
16160
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
16159
16161
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
16160
- const input = args["input"];
16161
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
16162
- throw new TopoloMcpPublicError("input must be an object.");
16163
- }
16164
- return topolo.client.validateActionInput(actionId, input ?? {});
16162
+ const input = coerceObjectParam(args["input"], "input");
16163
+ return topolo.client.validateActionInput(actionId, input);
16165
16164
  }
16166
16165
  },
16167
16166
  {
@@ -16185,14 +16184,11 @@ var TOOLS = [
16185
16184
  handler: async (topolo, args) => {
16186
16185
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
16187
16186
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
16188
- const input = args["input"];
16189
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
16190
- throw new TopoloMcpPublicError("input must be an object.");
16191
- }
16187
+ const input = coerceObjectParam(args["input"], "input");
16192
16188
  const resource = optionalResourceContext(args);
16193
16189
  return topolo.client.planAction(
16194
16190
  actionId,
16195
- input ?? {},
16191
+ input,
16196
16192
  {
16197
16193
  confirm: args["confirm"] === true,
16198
16194
  ...resource ? { resource } : {}
@@ -16226,7 +16222,7 @@ var TOOLS = [
16226
16222
  {
16227
16223
  name: "topolo_discover_capabilities",
16228
16224
  title: "Discover one Topolo application capability contract",
16229
- description: "Discovers capability and schema actions published by one application. Use the actionService value returned by topolo_search_applications as service.",
16225
+ description: "Lists every action published by one application \u2014 its full capability contract, straight from the registry-canonical catalog. Use the actionService value returned by topolo_search_applications as service. Follow page.nextCursor via topolo_search_actions when the contract exceeds one page.",
16230
16226
  requiredScopes: [],
16231
16227
  destructive: false,
16232
16228
  inputSchema: {
@@ -16238,7 +16234,7 @@ var TOOLS = [
16238
16234
  handler: async (topolo, args) => {
16239
16235
  const service = typeof args["service"] === "string" ? args["service"].trim() : "";
16240
16236
  if (!service) throw new TopoloMcpPublicError("service is required.");
16241
- return topolo.client.searchActions({ service, query: "capabilities", limit: 100 });
16237
+ return topolo.client.searchActions({ service, limit: 100 });
16242
16238
  }
16243
16239
  },
16244
16240
  {
@@ -16430,11 +16426,21 @@ var TOOLS = [
16430
16426
  Object.entries(query).map(([k, v]) => [k, String(v)])
16431
16427
  ) : void 0;
16432
16428
  const resource = optionalResourceContext(args);
16429
+ let body = args["body"];
16430
+ if (typeof body === "string") {
16431
+ const candidate = body.trim();
16432
+ if (candidate.startsWith("{") || candidate.startsWith("[")) {
16433
+ try {
16434
+ body = JSON.parse(candidate);
16435
+ } catch {
16436
+ }
16437
+ }
16438
+ }
16433
16439
  return topolo.client.request({
16434
16440
  service: service.trim(),
16435
16441
  method,
16436
16442
  path,
16437
- body: args["body"],
16443
+ body,
16438
16444
  ...normalisedQuery ? { query: normalisedQuery } : {},
16439
16445
  ...resource ? { resource } : {},
16440
16446
  confirm: Boolean(args["confirm"])
package/dist/index.js CHANGED
@@ -107,6 +107,7 @@ var APP_API_URLS = {
107
107
  agent: "https://agent.topolo.app",
108
108
  auth: "https://auth.topolo.app",
109
109
  backup: "https://backup.topolo.app",
110
+ blog: "https://blog.topolo.app",
110
111
  books: "https://books.topolo.app",
111
112
  brand: "https://brand.topolo.app",
112
113
  bugfix: "https://bugfix.topolo.app",
@@ -119,6 +120,7 @@ var APP_API_URLS = {
119
120
  compose: "https://compose.topolo.app",
120
121
  consent: "https://consent.topolo.app",
121
122
  crm: "https://crm.topolo.app",
123
+ design: "https://design.topolo.app",
122
124
  developers: "https://developers.topolo.app",
123
125
  director: "https://director.topolo.app",
124
126
  feed: "https://feed.topolo.app",
@@ -202,7 +204,9 @@ var APPLICATIONS = {
202
204
  "domains": [
203
205
  "agent.topolo.app"
204
206
  ],
205
- "routes": [],
207
+ "routes": [
208
+ "agent.topolo.app"
209
+ ],
206
210
  "appId": "agent"
207
211
  },
208
212
  {
@@ -263,6 +267,38 @@ var APPLICATIONS = {
263
267
  }
264
268
  ]
265
269
  },
270
+ "blog": {
271
+ "id": "blog",
272
+ "appDir": "TopoloBlog",
273
+ "name": "topolo-blog",
274
+ "packageName": "topolo-blog",
275
+ "productionUrl": "https://blog.topolo.app",
276
+ "services": [
277
+ "blog"
278
+ ],
279
+ "deployTargets": [
280
+ {
281
+ "name": "topolo-blog",
282
+ "kind": "worker",
283
+ "apiUrl": "https://blog.topolo.app",
284
+ "domains": [
285
+ "blog.topolo.app"
286
+ ],
287
+ "routes": [
288
+ "blog.topolo.app"
289
+ ],
290
+ "appId": "blog"
291
+ },
292
+ {
293
+ "name": "topolo-blog-api",
294
+ "kind": "worker",
295
+ "apiUrl": null,
296
+ "domains": [],
297
+ "routes": [],
298
+ "appId": null
299
+ }
300
+ ]
301
+ },
266
302
  "books": {
267
303
  "id": "books",
268
304
  "appDir": "TopoloBooks",
@@ -280,7 +316,9 @@ var APPLICATIONS = {
280
316
  "domains": [
281
317
  "books.topolo.app"
282
318
  ],
283
- "routes": [],
319
+ "routes": [
320
+ "books.topolo.app"
321
+ ],
284
322
  "appId": "books"
285
323
  },
286
324
  {
@@ -430,7 +468,9 @@ var APPLICATIONS = {
430
468
  "domains": [
431
469
  "campaigns.topolo.app"
432
470
  ],
433
- "routes": [],
471
+ "routes": [
472
+ "campaigns.topolo.app"
473
+ ],
434
474
  "appId": "campaigns"
435
475
  },
436
476
  {
@@ -572,7 +612,9 @@ var APPLICATIONS = {
572
612
  "domains": [
573
613
  "compose.topolo.app"
574
614
  ],
575
- "routes": [],
615
+ "routes": [
616
+ "compose.topolo.app"
617
+ ],
576
618
  "appId": "compose"
577
619
  },
578
620
  {
@@ -602,7 +644,9 @@ var APPLICATIONS = {
602
644
  "domains": [
603
645
  "consent.topolo.app"
604
646
  ],
605
- "routes": [],
647
+ "routes": [
648
+ "consent.topolo.app"
649
+ ],
606
650
  "appId": "consent"
607
651
  },
608
652
  {
@@ -640,11 +684,45 @@ var APPLICATIONS = {
640
684
  "domains": [
641
685
  "crm.topolo.app"
642
686
  ],
643
- "routes": [],
687
+ "routes": [
688
+ "crm.topolo.app"
689
+ ],
644
690
  "appId": "crm"
645
691
  }
646
692
  ]
647
693
  },
694
+ "design": {
695
+ "id": "design",
696
+ "appDir": "TopoloDesign",
697
+ "name": "topolo-design",
698
+ "packageName": "@topolo-io/design",
699
+ "productionUrl": "https://design.topolo.app",
700
+ "services": [
701
+ "design"
702
+ ],
703
+ "deployTargets": [
704
+ {
705
+ "name": "topolo-design",
706
+ "kind": "worker",
707
+ "apiUrl": "https://design.topolo.app",
708
+ "domains": [
709
+ "design.topolo.app"
710
+ ],
711
+ "routes": [
712
+ "design.topolo.app"
713
+ ],
714
+ "appId": "design"
715
+ },
716
+ {
717
+ "name": "topolo-design-api",
718
+ "kind": "worker",
719
+ "apiUrl": null,
720
+ "domains": [],
721
+ "routes": [],
722
+ "appId": null
723
+ }
724
+ ]
725
+ },
648
726
  "developers": {
649
727
  "id": "developers",
650
728
  "appDir": "TopoloDevelopers",
@@ -670,7 +748,9 @@ var APPLICATIONS = {
670
748
  "domains": [
671
749
  "developers.topolo.app"
672
750
  ],
673
- "routes": [],
751
+ "routes": [
752
+ "developers.topolo.app"
753
+ ],
674
754
  "appId": "developers"
675
755
  },
676
756
  {
@@ -700,7 +780,9 @@ var APPLICATIONS = {
700
780
  "domains": [
701
781
  "director.topolo.app"
702
782
  ],
703
- "routes": [],
783
+ "routes": [
784
+ "director.topolo.app"
785
+ ],
704
786
  "appId": "director"
705
787
  },
706
788
  {
@@ -808,7 +890,9 @@ var APPLICATIONS = {
808
890
  "domains": [
809
891
  "flow.topolo.app"
810
892
  ],
811
- "routes": [],
893
+ "routes": [
894
+ "flow.topolo.app"
895
+ ],
812
896
  "appId": "flow"
813
897
  },
814
898
  {
@@ -838,7 +922,9 @@ var APPLICATIONS = {
838
922
  "domains": [
839
923
  "forecast.topolo.app"
840
924
  ],
841
- "routes": [],
925
+ "routes": [
926
+ "forecast.topolo.app"
927
+ ],
842
928
  "appId": "forecast"
843
929
  },
844
930
  {
@@ -932,7 +1018,9 @@ var APPLICATIONS = {
932
1018
  "domains": [
933
1019
  "insights.topolo.app"
934
1020
  ],
935
- "routes": [],
1021
+ "routes": [
1022
+ "insights.topolo.app"
1023
+ ],
936
1024
  "appId": "insights"
937
1025
  },
938
1026
  {
@@ -962,7 +1050,9 @@ var APPLICATIONS = {
962
1050
  "domains": [
963
1051
  "inventory.topolo.app"
964
1052
  ],
965
- "routes": [],
1053
+ "routes": [
1054
+ "inventory.topolo.app"
1055
+ ],
966
1056
  "appId": "inventory"
967
1057
  },
968
1058
  {
@@ -1316,7 +1406,9 @@ var APPLICATIONS = {
1316
1406
  "domains": [
1317
1407
  "pay.topolo.app"
1318
1408
  ],
1319
- "routes": [],
1409
+ "routes": [
1410
+ "pay.topolo.app"
1411
+ ],
1320
1412
  "appId": "pay"
1321
1413
  },
1322
1414
  {
@@ -1346,7 +1438,9 @@ var APPLICATIONS = {
1346
1438
  "domains": [
1347
1439
  "people.topolo.app"
1348
1440
  ],
1349
- "routes": [],
1441
+ "routes": [
1442
+ "people.topolo.app"
1443
+ ],
1350
1444
  "appId": "people"
1351
1445
  },
1352
1446
  {
@@ -1425,7 +1519,9 @@ var APPLICATIONS = {
1425
1519
  "domains": [
1426
1520
  "roadmapper.topolo.app"
1427
1521
  ],
1428
- "routes": [],
1522
+ "routes": [
1523
+ "roadmapper.topolo.app"
1524
+ ],
1429
1525
  "appId": "roadmapper"
1430
1526
  },
1431
1527
  {
@@ -1455,7 +1551,9 @@ var APPLICATIONS = {
1455
1551
  "domains": [
1456
1552
  "sign.topolo.app"
1457
1553
  ],
1458
- "routes": [],
1554
+ "routes": [
1555
+ "sign.topolo.app"
1556
+ ],
1459
1557
  "appId": "sign"
1460
1558
  },
1461
1559
  {
@@ -1569,7 +1667,9 @@ var APPLICATIONS = {
1569
1667
  "domains": [
1570
1668
  "spaces.topolo.app"
1571
1669
  ],
1572
- "routes": [],
1670
+ "routes": [
1671
+ "spaces.topolo.app"
1672
+ ],
1573
1673
  "appId": "spaces"
1574
1674
  },
1575
1675
  {
@@ -3629,10 +3729,19 @@ function mapActionInput(action, input) {
3629
3729
  delete remaining[key];
3630
3730
  return encodeURIComponent(String(value));
3631
3731
  });
3632
- const explicitQuery = plainObject(remaining.query);
3633
- delete remaining.query;
3634
- const explicitBody = Object.prototype.hasOwnProperty.call(remaining, "body") ? remaining.body : void 0;
3635
- delete remaining.body;
3732
+ const schemaProperties = plainObject(plainObject(action.inputSchema).properties);
3733
+ const schemaOwnsQuery = Object.prototype.hasOwnProperty.call(schemaProperties, "query");
3734
+ const schemaOwnsBody = Object.prototype.hasOwnProperty.call(schemaProperties, "body");
3735
+ let explicitQuery = {};
3736
+ if (!schemaOwnsQuery) {
3737
+ explicitQuery = plainObject(remaining.query);
3738
+ delete remaining.query;
3739
+ }
3740
+ let explicitBody;
3741
+ if (!schemaOwnsBody) {
3742
+ explicitBody = Object.prototype.hasOwnProperty.call(remaining, "body") ? remaining.body : void 0;
3743
+ delete remaining.body;
3744
+ }
3636
3745
  if (action.method === "GET") {
3637
3746
  return {
3638
3747
  path,
@@ -3829,6 +3938,7 @@ var APP_API_URLS2 = {
3829
3938
  agent: "https://agent.topolo.app",
3830
3939
  auth: "https://auth.topolo.app",
3831
3940
  backup: "https://backup.topolo.app",
3941
+ blog: "https://blog.topolo.app",
3832
3942
  books: "https://books.topolo.app",
3833
3943
  brand: "https://brand.topolo.app",
3834
3944
  bugfix: "https://bugfix.topolo.app",
@@ -3841,6 +3951,7 @@ var APP_API_URLS2 = {
3841
3951
  compose: "https://compose.topolo.app",
3842
3952
  consent: "https://consent.topolo.app",
3843
3953
  crm: "https://crm.topolo.app",
3954
+ design: "https://design.topolo.app",
3844
3955
  developers: "https://developers.topolo.app",
3845
3956
  director: "https://director.topolo.app",
3846
3957
  feed: "https://feed.topolo.app",
@@ -4252,6 +4363,20 @@ function optionalResourceContext(args) {
4252
4363
  }
4253
4364
  return { resourceType, resourceId };
4254
4365
  }
4366
+ function coerceObjectParam(value, name) {
4367
+ let candidate = value;
4368
+ if (typeof candidate === "string" && candidate.trim().startsWith("{")) {
4369
+ try {
4370
+ candidate = JSON.parse(candidate);
4371
+ } catch {
4372
+ }
4373
+ }
4374
+ if (candidate === void 0) return {};
4375
+ if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) {
4376
+ throw new TopoloMcpPublicError(`${name} must be an object.`);
4377
+ }
4378
+ return candidate;
4379
+ }
4255
4380
  var TOOLS = [
4256
4381
  {
4257
4382
  name: "topolo_whoami",
@@ -4402,14 +4527,11 @@ var TOOLS = [
4402
4527
  handler: async (topolo, args) => {
4403
4528
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
4404
4529
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
4405
- const input = args["input"];
4406
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
4407
- throw new TopoloMcpPublicError("input must be an object.");
4408
- }
4530
+ const input = coerceObjectParam(args["input"], "input");
4409
4531
  const resource = optionalResourceContext(args);
4410
4532
  return topolo.client.readAction(
4411
4533
  actionId,
4412
- input ?? {},
4534
+ input,
4413
4535
  resource ? { resource } : {}
4414
4536
  );
4415
4537
  }
@@ -4435,14 +4557,11 @@ var TOOLS = [
4435
4557
  handler: async (topolo, args) => {
4436
4558
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
4437
4559
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
4438
- const input = args["input"];
4439
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
4440
- throw new TopoloMcpPublicError("input must be an object.");
4441
- }
4560
+ const input = coerceObjectParam(args["input"], "input");
4442
4561
  const resource = optionalResourceContext(args);
4443
4562
  return topolo.client.callAction(
4444
4563
  actionId,
4445
- input ?? {},
4564
+ input,
4446
4565
  {
4447
4566
  confirm: args["confirm"] === true,
4448
4567
  ...resource ? { resource } : {}
@@ -4481,23 +4600,17 @@ var TOOLS = [
4481
4600
  if (!isCanonicalBase642(contentBase64)) throw new TopoloMcpPublicError("contentBase64 must be canonical base64.");
4482
4601
  if (!contentType) throw new TopoloMcpPublicError("contentType is required.");
4483
4602
  if (!fileName) throw new TopoloMcpPublicError("fileName is required.");
4484
- const input = args["input"];
4485
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
4486
- throw new TopoloMcpPublicError("input must be an object.");
4487
- }
4488
- const completionInput = args["completionInput"];
4489
- if (completionInput !== void 0 && (!completionInput || typeof completionInput !== "object" || Array.isArray(completionInput))) {
4490
- throw new TopoloMcpPublicError("completionInput must be an object.");
4491
- }
4603
+ const input = coerceObjectParam(args["input"], "input");
4604
+ const completionInput = coerceObjectParam(args["completionInput"], "completionInput");
4492
4605
  const resource = optionalResourceContext(args);
4493
4606
  return topolo.client.uploadActionBase64(
4494
4607
  actionId,
4495
4608
  contentBase64,
4496
- input ?? {},
4609
+ input,
4497
4610
  {
4498
4611
  fileName,
4499
4612
  contentType,
4500
- completionInput: completionInput ?? {},
4613
+ completionInput,
4501
4614
  confirm: args["confirm"] === true,
4502
4615
  ...resource ? { resource } : {}
4503
4616
  }
@@ -4522,11 +4635,8 @@ var TOOLS = [
4522
4635
  handler: async (topolo, args) => {
4523
4636
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
4524
4637
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
4525
- const input = args["input"];
4526
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
4527
- throw new TopoloMcpPublicError("input must be an object.");
4528
- }
4529
- return topolo.client.validateActionInput(actionId, input ?? {});
4638
+ const input = coerceObjectParam(args["input"], "input");
4639
+ return topolo.client.validateActionInput(actionId, input);
4530
4640
  }
4531
4641
  },
4532
4642
  {
@@ -4550,14 +4660,11 @@ var TOOLS = [
4550
4660
  handler: async (topolo, args) => {
4551
4661
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
4552
4662
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
4553
- const input = args["input"];
4554
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
4555
- throw new TopoloMcpPublicError("input must be an object.");
4556
- }
4663
+ const input = coerceObjectParam(args["input"], "input");
4557
4664
  const resource = optionalResourceContext(args);
4558
4665
  return topolo.client.planAction(
4559
4666
  actionId,
4560
- input ?? {},
4667
+ input,
4561
4668
  {
4562
4669
  confirm: args["confirm"] === true,
4563
4670
  ...resource ? { resource } : {}
@@ -4591,7 +4698,7 @@ var TOOLS = [
4591
4698
  {
4592
4699
  name: "topolo_discover_capabilities",
4593
4700
  title: "Discover one Topolo application capability contract",
4594
- description: "Discovers capability and schema actions published by one application. Use the actionService value returned by topolo_search_applications as service.",
4701
+ description: "Lists every action published by one application \u2014 its full capability contract, straight from the registry-canonical catalog. Use the actionService value returned by topolo_search_applications as service. Follow page.nextCursor via topolo_search_actions when the contract exceeds one page.",
4595
4702
  requiredScopes: [],
4596
4703
  destructive: false,
4597
4704
  inputSchema: {
@@ -4603,7 +4710,7 @@ var TOOLS = [
4603
4710
  handler: async (topolo, args) => {
4604
4711
  const service = typeof args["service"] === "string" ? args["service"].trim() : "";
4605
4712
  if (!service) throw new TopoloMcpPublicError("service is required.");
4606
- return topolo.client.searchActions({ service, query: "capabilities", limit: 100 });
4713
+ return topolo.client.searchActions({ service, limit: 100 });
4607
4714
  }
4608
4715
  },
4609
4716
  {
@@ -4795,11 +4902,21 @@ var TOOLS = [
4795
4902
  Object.entries(query).map(([k, v]) => [k, String(v)])
4796
4903
  ) : void 0;
4797
4904
  const resource = optionalResourceContext(args);
4905
+ let body = args["body"];
4906
+ if (typeof body === "string") {
4907
+ const candidate = body.trim();
4908
+ if (candidate.startsWith("{") || candidate.startsWith("[")) {
4909
+ try {
4910
+ body = JSON.parse(candidate);
4911
+ } catch {
4912
+ }
4913
+ }
4914
+ }
4798
4915
  return topolo.client.request({
4799
4916
  service: service.trim(),
4800
4917
  method,
4801
4918
  path,
4802
- body: args["body"],
4919
+ body,
4803
4920
  ...normalisedQuery ? { query: normalisedQuery } : {},
4804
4921
  ...resource ? { resource } : {},
4805
4922
  confirm: Boolean(args["confirm"])
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@topolo/mcp",
3
- "version": "0.9.8",
3
+ "version": "0.9.10",
4
+ "topoloPublishedVersion": "0.9.10",
4
5
  "description": "Model Context Protocol server for the Topolo platform. Exposes scope-gated tools that third-party agents (Claude, Codex, etc.) can call natively.",
5
6
  "type": "module",
6
7
  "bin": {
@@ -36,7 +37,7 @@
36
37
  "@modelcontextprotocol/sdk": "^1.0.0"
37
38
  },
38
39
  "peerDependencies": {
39
- "@topolo/sdk": "^0.9.8"
40
+ "@topolo/sdk": "^0.9.9"
40
41
  },
41
42
  "devDependencies": {
42
43
  "@topolo/sdk": "file:../topolo-sdk",