@tinycloud/mcp 0.8.0-beta.6 → 0.8.0-beta.7

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/index.cjs CHANGED
@@ -522,7 +522,7 @@ function outcomeCode(result) {
522
522
  // package.json
523
523
  var package_default = {
524
524
  name: "@tinycloud/mcp",
525
- version: "0.8.0-beta.6",
525
+ version: "0.8.0-beta.7",
526
526
  description: "TinyCloud delegated operations MCP server",
527
527
  keywords: [
528
528
  "tinycloud",
@@ -895,9 +895,9 @@ var RemoteTenantStore = class {
895
895
  }
896
896
  async connectStatus(subject, ownerDids = []) {
897
897
  const tenant = await this.#ensureTenant(subject);
898
- if (await this.#hasValidSession(tenant, ownerDids, true)) {
899
- return { connected: true, sessionDid: tenant.sessionDid };
900
- }
898
+ const state = await this.#sessionState(tenant, ownerDids, true);
899
+ if (state === "valid") return { connected: true, sessionDid: tenant.sessionDid };
900
+ if (state === "unknown") return { connected: false, sessionDid: tenant.sessionDid };
901
901
  const pending = await this.#createPending(subject, ownerDids, "bootstrap", BOOTSTRAP_PERMISSIONS);
902
902
  return {
903
903
  connected: false,
@@ -1237,7 +1237,10 @@ var RemoteTenantStore = class {
1237
1237
  return initializing;
1238
1238
  }
1239
1239
  async #hasValidSession(tenant, ownerDids, fresh = false) {
1240
- if (this.#renewalRequired.has(tenant.stateRoot)) return false;
1240
+ return await this.#sessionState(tenant, ownerDids, fresh) !== "invalid";
1241
+ }
1242
+ async #sessionState(tenant, ownerDids, fresh = false) {
1243
+ if (this.#renewalRequired.has(tenant.stateRoot)) return "invalid";
1241
1244
  const key = JSON.stringify([tenant.stateRoot, ownerDids.map(normalizeDid), fresh]);
1242
1245
  const current = this.#sessionChecks.get(key);
1243
1246
  if (current) return current;
@@ -1254,9 +1257,9 @@ var RemoteTenantStore = class {
1254
1257
  } catch (error) {
1255
1258
  if (!(error instanceof SyntaxError)) throw error;
1256
1259
  await this.#clearAuthority(tenant);
1257
- return false;
1260
+ return "invalid";
1258
1261
  }
1259
- if (raw === null) return false;
1262
+ if (raw === null) return "invalid";
1260
1263
  const node = new import_node_sdk2.TinyCloudNode({ host: this.#config.nodeHost });
1261
1264
  try {
1262
1265
  await node.restoreSession(raw);
@@ -1265,11 +1268,11 @@ var RemoteTenantStore = class {
1265
1268
  const signedExpiry = typeof header === "string" ? (0, import_node_sdk2.signedCompactUcanExpiry)(header) : void 0;
1266
1269
  const siweExpiry = typeof raw.siwe === "string" ? /^Expiration Time: ([^\r\n]+)\r?$/m.exec(raw.siwe)?.[1] : void 0;
1267
1270
  const expiry = signedExpiry ?? (siweExpiry === void 0 ? void 0 : new Date(siweExpiry));
1268
- if (expiry !== void 0 && expiry.getTime() <= Date.now()) return false;
1271
+ if (expiry !== void 0 && expiry.getTime() <= Date.now()) return "invalid";
1269
1272
  await this.#clearAuthority(tenant);
1270
- return false;
1273
+ return "invalid";
1271
1274
  }
1272
- if (!samePrincipal(node.sessionDid, tenant.sessionDid) || !ownerDids.some((did) => samePrincipal(node.did, did))) return false;
1275
+ if (!samePrincipal(node.sessionDid, tenant.sessionDid) || !ownerDids.some((did) => samePrincipal(node.did, did))) return "invalid";
1273
1276
  const additional = await readJson(this.#additionalPath(tenant.stateRoot));
1274
1277
  const cids = [raw.delegationCid];
1275
1278
  if (additional !== null) {
@@ -1284,7 +1287,7 @@ var RemoteTenantStore = class {
1284
1287
  }
1285
1288
  const fingerprint = cids.join("\n");
1286
1289
  const cached = this.#activeSessions.get(tenant.stateRoot);
1287
- if (!fresh && cached?.cids === fingerprint && cached.until > Date.now()) return true;
1290
+ if (!fresh && cached?.cids === fingerprint && cached.until > Date.now()) return "valid";
1288
1291
  let timer;
1289
1292
  const timeout = new Promise((resolve) => {
1290
1293
  timer = setTimeout(() => resolve(void 0), 2e3);
@@ -1297,13 +1300,14 @@ var RemoteTenantStore = class {
1297
1300
  const refusal = probe !== void 0 && !probe.ok ? (0, import_mcp_authority.nodeRevocationOf)(probe.error) : void 0;
1298
1301
  if (refusal !== void 0 && (refusal.revokedCid === raw.delegationCid || refusal.reason === "delegation_ancestor_revoked" && refusal.ancestorCid === raw.delegationCid)) {
1299
1302
  await this.#clearAuthority(tenant);
1300
- return false;
1303
+ return "invalid";
1301
1304
  }
1302
- if (this.#renewalRequired.has(tenant.stateRoot)) return false;
1305
+ if (this.#renewalRequired.has(tenant.stateRoot)) return "invalid";
1303
1306
  if (probe?.ok) {
1304
1307
  this.#activeSessions.set(tenant.stateRoot, { cids: fingerprint, until: Date.now() + 3e4 });
1308
+ return "valid";
1305
1309
  }
1306
- return true;
1310
+ return "unknown";
1307
1311
  }
1308
1312
  async #clearAuthority(tenant) {
1309
1313
  const current = this.#clearing.get(tenant.stateRoot);
@@ -1815,19 +1819,26 @@ function registerConnectTool(server, validator, store, identity, surface) {
1815
1819
  async () => {
1816
1820
  const startedAt = performance.now();
1817
1821
  let code = "INTERNAL_ERROR";
1822
+ let text;
1818
1823
  try {
1819
1824
  const status = await store.connectStatus(identity.subject, identity.ownerDids);
1820
- code = status.connected ? "ok" : "authority_required";
1825
+ if (status.connected) {
1826
+ code = "ok";
1827
+ text = "TinyCloud is connected.";
1828
+ } else if (status.approvalUrl === void 0) {
1829
+ code = "unavailable";
1830
+ text = "TinyCloud is unavailable. Call this tool again shortly.";
1831
+ } else {
1832
+ code = "authority_required";
1833
+ text = `TinyCloud approval is required. Open ${status.approvalUrl}, then call this tool again. This link expires at ${status.expiresAt}.`;
1834
+ }
1821
1835
  const visibleStatus = surface === "hosted" ? status : {
1822
1836
  connected: status.connected,
1823
1837
  ...status.approvalUrl === void 0 ? {} : { approvalUrl: status.approvalUrl },
1824
1838
  ...status.expiresAt === void 0 ? {} : { expiresAt: status.expiresAt }
1825
1839
  };
1826
1840
  return {
1827
- content: [{
1828
- type: "text",
1829
- text: status.connected ? "TinyCloud is connected." : `TinyCloud approval is required. Open ${status.approvalUrl}, then call this tool again. This link expires at ${status.expiresAt}.`
1830
- }],
1841
+ content: [{ type: "text", text }],
1831
1842
  structuredContent: visibleStatus
1832
1843
  };
1833
1844
  } finally {