@topolo/mcp 0.11.7 → 0.11.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +30 -4
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -724,7 +724,7 @@ function prepareTopoloActionUploadInput(contractValue, content, input, options)
724
724
  if (bytes.byteLength > contract.maxBytes) {
725
725
  throw new TopoloSdkError("upload_too_large", `Upload content exceeds the ${contract.maxBytes}-byte action limit.`);
726
726
  }
727
- return mapUploadInput(contract, bytesToBase64(bytes), input, options);
727
+ return mapUploadInput(contract, encodeTopoloActionBase64(bytes), input, options);
728
728
  }
729
729
  function prepareTopoloActionBase64UploadInput(contractValue, contentBase64, input, options) {
730
730
  const contract = parseTopoloActionUploadContract(contractValue);
@@ -860,7 +860,7 @@ function requiredField(value, name) {
860
860
  function matchesContentType(contentType, accepted) {
861
861
  return accepted.some((candidate) => candidate === "*/*" || candidate === contentType || candidate.endsWith("/*") && contentType.startsWith(candidate.slice(0, -1)));
862
862
  }
863
- function bytesToBase64(bytes) {
863
+ function encodeTopoloActionBase64(bytes) {
864
864
  let binary = "";
865
865
  const chunkSize = 32768;
866
866
  for (let offset = 0; offset < bytes.length; offset += chunkSize) {
@@ -1037,7 +1037,20 @@ var TopoloClient = class _TopoloClient {
1037
1037
  throw err;
1038
1038
  }
1039
1039
  const contentType = res.headers.get("Content-Type") ?? "";
1040
- const parsed = contentType.includes("application/json") ? await res.json().catch(() => null) : await res.text().catch(() => null);
1040
+ const normalizedContentType = contentType.split(";", 1)[0]?.trim().toLowerCase() ?? "";
1041
+ let parsed;
1042
+ if (normalizedContentType === "application/json" || normalizedContentType.endsWith("+json")) {
1043
+ parsed = await res.json().catch(() => null);
1044
+ } else if (!res.ok || !normalizedContentType || normalizedContentType.startsWith("text/")) {
1045
+ parsed = await res.text().catch(() => null);
1046
+ } else {
1047
+ const bytes = new Uint8Array(await res.arrayBuffer());
1048
+ parsed = {
1049
+ contentType: normalizedContentType,
1050
+ contentLength: bytes.byteLength,
1051
+ contentBase64: encodeTopoloActionBase64(bytes)
1052
+ };
1053
+ }
1041
1054
  if (!res.ok) {
1042
1055
  const durationMs = Date.now() - startedAt;
1043
1056
  const message = describeError(parsed, `HTTP ${res.status}`);
@@ -1588,7 +1601,7 @@ var TopoloClient = class _TopoloClient {
1588
1601
  }
1589
1602
  const mapped = mapActionInput(entry, input);
1590
1603
  const service = entry.appSlug || entry.appId;
1591
- return this.request({
1604
+ const result = await this.request({
1592
1605
  service,
1593
1606
  ...entry.apiBaseUrl ? { baseUrl: entry.apiBaseUrl } : {},
1594
1607
  method: entry.method,
@@ -1602,6 +1615,7 @@ var TopoloClient = class _TopoloClient {
1602
1615
  },
1603
1616
  confirm: options.confirm === true || entry.readOnly && !entry.destructive && !entry.requiresConfirmation
1604
1617
  });
1618
+ return redactActionResult(result);
1605
1619
  }
1606
1620
  /**
1607
1621
  * Introspect the current credential. Returns the caller's resolved identity,
@@ -1725,6 +1739,18 @@ function readOptionalString(value) {
1725
1739
  function isRecord3(value) {
1726
1740
  return typeof value === "object" && value !== null && !Array.isArray(value);
1727
1741
  }
1742
+ function redactActionResult(value) {
1743
+ if (Array.isArray(value)) return value.map(redactActionResult);
1744
+ if (!isRecord3(value)) return value;
1745
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [
1746
+ key,
1747
+ isSensitiveActionResultKey(key) ? "[REDACTED]" : redactActionResult(item)
1748
+ ]));
1749
+ }
1750
+ function isSensitiveActionResultKey(key) {
1751
+ const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
1752
+ return ["authorization", "cookie", "setcookie", "proxyauthorization", "capability"].includes(normalized) || /(token|secret|password|privatekey|apikey)$/.test(normalized);
1753
+ }
1728
1754
  function resolveConfiguredServiceUrl(slug, serviceUrls) {
1729
1755
  for (const serviceKey of serviceKeyCandidates2(slug)) {
1730
1756
  const configured = serviceUrls?.[serviceKey];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@topolo/mcp",
3
- "version": "0.11.7",
4
- "topoloPublishedVersion": "0.11.7",
3
+ "version": "0.11.9",
4
+ "topoloPublishedVersion": "0.11.9",
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
  "license": "UNLICENSED",
7
7
  "author": "Topolo",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@modelcontextprotocol/sdk": "^1.0.0",
38
- "@topolo/sdk": "0.11.7"
38
+ "@topolo/sdk": "0.11.9"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/node": "^20.12.0",