@topolo/mcp 0.9.9 → 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 } : {}
@@ -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 } : {}
@@ -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
@@ -3729,10 +3729,19 @@ function mapActionInput(action, input) {
3729
3729
  delete remaining[key];
3730
3730
  return encodeURIComponent(String(value));
3731
3731
  });
3732
- const explicitQuery = plainObject(remaining.query);
3733
- delete remaining.query;
3734
- const explicitBody = Object.prototype.hasOwnProperty.call(remaining, "body") ? remaining.body : void 0;
3735
- 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
+ }
3736
3745
  if (action.method === "GET") {
3737
3746
  return {
3738
3747
  path,
@@ -4354,6 +4363,20 @@ function optionalResourceContext(args) {
4354
4363
  }
4355
4364
  return { resourceType, resourceId };
4356
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
+ }
4357
4380
  var TOOLS = [
4358
4381
  {
4359
4382
  name: "topolo_whoami",
@@ -4504,14 +4527,11 @@ var TOOLS = [
4504
4527
  handler: async (topolo, args) => {
4505
4528
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
4506
4529
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
4507
- const input = args["input"];
4508
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
4509
- throw new TopoloMcpPublicError("input must be an object.");
4510
- }
4530
+ const input = coerceObjectParam(args["input"], "input");
4511
4531
  const resource = optionalResourceContext(args);
4512
4532
  return topolo.client.readAction(
4513
4533
  actionId,
4514
- input ?? {},
4534
+ input,
4515
4535
  resource ? { resource } : {}
4516
4536
  );
4517
4537
  }
@@ -4537,14 +4557,11 @@ var TOOLS = [
4537
4557
  handler: async (topolo, args) => {
4538
4558
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
4539
4559
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
4540
- const input = args["input"];
4541
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
4542
- throw new TopoloMcpPublicError("input must be an object.");
4543
- }
4560
+ const input = coerceObjectParam(args["input"], "input");
4544
4561
  const resource = optionalResourceContext(args);
4545
4562
  return topolo.client.callAction(
4546
4563
  actionId,
4547
- input ?? {},
4564
+ input,
4548
4565
  {
4549
4566
  confirm: args["confirm"] === true,
4550
4567
  ...resource ? { resource } : {}
@@ -4583,23 +4600,17 @@ var TOOLS = [
4583
4600
  if (!isCanonicalBase642(contentBase64)) throw new TopoloMcpPublicError("contentBase64 must be canonical base64.");
4584
4601
  if (!contentType) throw new TopoloMcpPublicError("contentType is required.");
4585
4602
  if (!fileName) throw new TopoloMcpPublicError("fileName is required.");
4586
- const input = args["input"];
4587
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
4588
- throw new TopoloMcpPublicError("input must be an object.");
4589
- }
4590
- const completionInput = args["completionInput"];
4591
- if (completionInput !== void 0 && (!completionInput || typeof completionInput !== "object" || Array.isArray(completionInput))) {
4592
- throw new TopoloMcpPublicError("completionInput must be an object.");
4593
- }
4603
+ const input = coerceObjectParam(args["input"], "input");
4604
+ const completionInput = coerceObjectParam(args["completionInput"], "completionInput");
4594
4605
  const resource = optionalResourceContext(args);
4595
4606
  return topolo.client.uploadActionBase64(
4596
4607
  actionId,
4597
4608
  contentBase64,
4598
- input ?? {},
4609
+ input,
4599
4610
  {
4600
4611
  fileName,
4601
4612
  contentType,
4602
- completionInput: completionInput ?? {},
4613
+ completionInput,
4603
4614
  confirm: args["confirm"] === true,
4604
4615
  ...resource ? { resource } : {}
4605
4616
  }
@@ -4624,11 +4635,8 @@ var TOOLS = [
4624
4635
  handler: async (topolo, args) => {
4625
4636
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
4626
4637
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
4627
- const input = args["input"];
4628
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
4629
- throw new TopoloMcpPublicError("input must be an object.");
4630
- }
4631
- return topolo.client.validateActionInput(actionId, input ?? {});
4638
+ const input = coerceObjectParam(args["input"], "input");
4639
+ return topolo.client.validateActionInput(actionId, input);
4632
4640
  }
4633
4641
  },
4634
4642
  {
@@ -4652,14 +4660,11 @@ var TOOLS = [
4652
4660
  handler: async (topolo, args) => {
4653
4661
  const actionId = typeof args["actionId"] === "string" ? args["actionId"].trim() : "";
4654
4662
  if (!actionId) throw new TopoloMcpPublicError("actionId is required.");
4655
- const input = args["input"];
4656
- if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
4657
- throw new TopoloMcpPublicError("input must be an object.");
4658
- }
4663
+ const input = coerceObjectParam(args["input"], "input");
4659
4664
  const resource = optionalResourceContext(args);
4660
4665
  return topolo.client.planAction(
4661
4666
  actionId,
4662
- input ?? {},
4667
+ input,
4663
4668
  {
4664
4669
  confirm: args["confirm"] === true,
4665
4670
  ...resource ? { resource } : {}
@@ -4897,11 +4902,21 @@ var TOOLS = [
4897
4902
  Object.entries(query).map(([k, v]) => [k, String(v)])
4898
4903
  ) : void 0;
4899
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
+ }
4900
4915
  return topolo.client.request({
4901
4916
  service: service.trim(),
4902
4917
  method,
4903
4918
  path,
4904
- body: args["body"],
4919
+ body,
4905
4920
  ...normalisedQuery ? { query: normalisedQuery } : {},
4906
4921
  ...resource ? { resource } : {},
4907
4922
  confirm: Boolean(args["confirm"])
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@topolo/mcp",
3
- "version": "0.9.9",
4
- "topoloPublishedVersion": "0.9.9",
3
+ "version": "0.9.10",
4
+ "topoloPublishedVersion": "0.9.10",
5
5
  "description": "Model Context Protocol server for the Topolo platform. Exposes scope-gated tools that third-party agents (Claude, Codex, etc.) can call natively.",
6
6
  "type": "module",
7
7
  "bin": {
@@ -37,7 +37,7 @@
37
37
  "@modelcontextprotocol/sdk": "^1.0.0"
38
38
  },
39
39
  "peerDependencies": {
40
- "@topolo/sdk": "^0.9.8"
40
+ "@topolo/sdk": "^0.9.9"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@topolo/sdk": "file:../topolo-sdk",