mcp-ts-template 2.2.4 → 2.2.5
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.js +426 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -125174,9 +125174,25 @@ class StorageService2 {
|
|
|
125174
125174
|
const tenantId = requireTenantId(context);
|
|
125175
125175
|
return this.provider.delete(tenantId, key, context);
|
|
125176
125176
|
}
|
|
125177
|
-
list(prefix, context) {
|
|
125177
|
+
list(prefix, context, options) {
|
|
125178
125178
|
const tenantId = requireTenantId(context);
|
|
125179
|
-
return this.provider.list(tenantId, prefix, context);
|
|
125179
|
+
return this.provider.list(tenantId, prefix, context, options);
|
|
125180
|
+
}
|
|
125181
|
+
getMany(keys, context) {
|
|
125182
|
+
const tenantId = requireTenantId(context);
|
|
125183
|
+
return this.provider.getMany(tenantId, keys, context);
|
|
125184
|
+
}
|
|
125185
|
+
setMany(entries, context, options) {
|
|
125186
|
+
const tenantId = requireTenantId(context);
|
|
125187
|
+
return this.provider.setMany(tenantId, entries, context, options);
|
|
125188
|
+
}
|
|
125189
|
+
deleteMany(keys, context) {
|
|
125190
|
+
const tenantId = requireTenantId(context);
|
|
125191
|
+
return this.provider.deleteMany(tenantId, keys, context);
|
|
125192
|
+
}
|
|
125193
|
+
clear(context) {
|
|
125194
|
+
const tenantId = requireTenantId(context);
|
|
125195
|
+
return this.provider.clear(tenantId, context);
|
|
125180
125196
|
}
|
|
125181
125197
|
}
|
|
125182
125198
|
StorageService2 = __legacyDecorateClassTS([
|
|
@@ -125194,6 +125210,7 @@ var import_tsyringe5 = __toESM(require_cjs3(), 1);
|
|
|
125194
125210
|
import { existsSync, mkdirSync } from "fs";
|
|
125195
125211
|
import { readFile, readdir, rm, writeFile } from "fs/promises";
|
|
125196
125212
|
import path2 from "path";
|
|
125213
|
+
var DEFAULT_LIST_LIMIT = 1000;
|
|
125197
125214
|
var FILE_ENVELOPE_VERSION = 1;
|
|
125198
125215
|
|
|
125199
125216
|
class FileSystemProvider {
|
|
@@ -125321,7 +125338,7 @@ class FileSystemProvider {
|
|
|
125321
125338
|
}
|
|
125322
125339
|
return results;
|
|
125323
125340
|
}
|
|
125324
|
-
async list(tenantId, prefix, context) {
|
|
125341
|
+
async list(tenantId, prefix, context, options) {
|
|
125325
125342
|
return ErrorHandler.tryCatch(async () => {
|
|
125326
125343
|
const tenantPath = this.getTenantPath(tenantId);
|
|
125327
125344
|
const allKeys = await this.listFilesRecursively(tenantPath, tenantPath);
|
|
@@ -125339,16 +125356,93 @@ class FileSystemProvider {
|
|
|
125339
125356
|
continue;
|
|
125340
125357
|
}
|
|
125341
125358
|
}
|
|
125342
|
-
|
|
125359
|
+
validKeys.sort();
|
|
125360
|
+
const limit2 = options?.limit ?? DEFAULT_LIST_LIMIT;
|
|
125361
|
+
let startIndex = 0;
|
|
125362
|
+
if (options?.cursor) {
|
|
125363
|
+
const cursorIndex = validKeys.indexOf(options.cursor);
|
|
125364
|
+
if (cursorIndex !== -1) {
|
|
125365
|
+
startIndex = cursorIndex + 1;
|
|
125366
|
+
}
|
|
125367
|
+
}
|
|
125368
|
+
const paginatedKeys = validKeys.slice(startIndex, startIndex + limit2);
|
|
125369
|
+
const nextCursor = startIndex + limit2 < validKeys.length ? paginatedKeys[paginatedKeys.length - 1] : undefined;
|
|
125370
|
+
return {
|
|
125371
|
+
keys: paginatedKeys,
|
|
125372
|
+
nextCursor
|
|
125373
|
+
};
|
|
125343
125374
|
}, {
|
|
125344
125375
|
operation: "FileSystemProvider.list",
|
|
125345
125376
|
context,
|
|
125346
125377
|
input: { tenantId, prefix }
|
|
125347
125378
|
});
|
|
125348
125379
|
}
|
|
125380
|
+
async getMany(tenantId, keys, context) {
|
|
125381
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125382
|
+
const results = new Map;
|
|
125383
|
+
for (const key of keys) {
|
|
125384
|
+
const value = await this.get(tenantId, key, context);
|
|
125385
|
+
if (value !== null) {
|
|
125386
|
+
results.set(key, value);
|
|
125387
|
+
}
|
|
125388
|
+
}
|
|
125389
|
+
return results;
|
|
125390
|
+
}, {
|
|
125391
|
+
operation: "FileSystemProvider.getMany",
|
|
125392
|
+
context,
|
|
125393
|
+
input: { tenantId, keyCount: keys.length }
|
|
125394
|
+
});
|
|
125395
|
+
}
|
|
125396
|
+
async setMany(tenantId, entries, context, options) {
|
|
125397
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125398
|
+
for (const [key, value] of entries.entries()) {
|
|
125399
|
+
await this.set(tenantId, key, value, context, options);
|
|
125400
|
+
}
|
|
125401
|
+
}, {
|
|
125402
|
+
operation: "FileSystemProvider.setMany",
|
|
125403
|
+
context,
|
|
125404
|
+
input: { tenantId, entryCount: entries.size }
|
|
125405
|
+
});
|
|
125406
|
+
}
|
|
125407
|
+
async deleteMany(tenantId, keys, context) {
|
|
125408
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125409
|
+
let deletedCount = 0;
|
|
125410
|
+
for (const key of keys) {
|
|
125411
|
+
const deleted = await this.delete(tenantId, key, context);
|
|
125412
|
+
if (deleted) {
|
|
125413
|
+
deletedCount++;
|
|
125414
|
+
}
|
|
125415
|
+
}
|
|
125416
|
+
return deletedCount;
|
|
125417
|
+
}, {
|
|
125418
|
+
operation: "FileSystemProvider.deleteMany",
|
|
125419
|
+
context,
|
|
125420
|
+
input: { tenantId, keyCount: keys.length }
|
|
125421
|
+
});
|
|
125422
|
+
}
|
|
125423
|
+
async clear(tenantId, context) {
|
|
125424
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125425
|
+
const tenantPath = this.getTenantPath(tenantId);
|
|
125426
|
+
const allKeys = await this.listFilesRecursively(tenantPath, tenantPath);
|
|
125427
|
+
let deletedCount = 0;
|
|
125428
|
+
for (const key of allKeys) {
|
|
125429
|
+
const deleted = await this.delete(tenantId, key, context);
|
|
125430
|
+
if (deleted) {
|
|
125431
|
+
deletedCount++;
|
|
125432
|
+
}
|
|
125433
|
+
}
|
|
125434
|
+
return deletedCount;
|
|
125435
|
+
}, {
|
|
125436
|
+
operation: "FileSystemProvider.clear",
|
|
125437
|
+
context,
|
|
125438
|
+
input: { tenantId }
|
|
125439
|
+
});
|
|
125440
|
+
}
|
|
125349
125441
|
}
|
|
125350
125442
|
|
|
125351
125443
|
// src/storage/providers/inMemory/inMemoryProvider.ts
|
|
125444
|
+
var DEFAULT_LIST_LIMIT2 = 1000;
|
|
125445
|
+
|
|
125352
125446
|
class InMemoryProvider {
|
|
125353
125447
|
store = new Map;
|
|
125354
125448
|
getTenantStore(tenantId) {
|
|
@@ -125388,21 +125482,71 @@ class InMemoryProvider {
|
|
|
125388
125482
|
const tenantStore = this.getTenantStore(tenantId);
|
|
125389
125483
|
return Promise.resolve(tenantStore.delete(key));
|
|
125390
125484
|
}
|
|
125391
|
-
list(tenantId, prefix, context) {
|
|
125392
|
-
logger.debug(`[InMemoryProvider] Listing keys with prefix: ${prefix} for tenant: ${tenantId}`, context);
|
|
125485
|
+
list(tenantId, prefix, context, options) {
|
|
125486
|
+
logger.debug(`[InMemoryProvider] Listing keys with prefix: ${prefix} for tenant: ${tenantId}`, { ...context, options });
|
|
125393
125487
|
const tenantStore = this.getTenantStore(tenantId);
|
|
125394
125488
|
const now = Date.now();
|
|
125395
|
-
const
|
|
125489
|
+
const allKeys = [];
|
|
125396
125490
|
for (const [key, entry] of tenantStore.entries()) {
|
|
125397
125491
|
if (key.startsWith(prefix)) {
|
|
125398
125492
|
if (entry.expiresAt && now > entry.expiresAt) {
|
|
125399
125493
|
tenantStore.delete(key);
|
|
125400
125494
|
} else {
|
|
125401
|
-
|
|
125495
|
+
allKeys.push(key);
|
|
125402
125496
|
}
|
|
125403
125497
|
}
|
|
125404
125498
|
}
|
|
125405
|
-
|
|
125499
|
+
allKeys.sort();
|
|
125500
|
+
const limit2 = options?.limit ?? DEFAULT_LIST_LIMIT2;
|
|
125501
|
+
let startIndex = 0;
|
|
125502
|
+
if (options?.cursor) {
|
|
125503
|
+
const cursorIndex = allKeys.indexOf(options.cursor);
|
|
125504
|
+
if (cursorIndex !== -1) {
|
|
125505
|
+
startIndex = cursorIndex + 1;
|
|
125506
|
+
}
|
|
125507
|
+
}
|
|
125508
|
+
const paginatedKeys = allKeys.slice(startIndex, startIndex + limit2);
|
|
125509
|
+
const nextCursor = startIndex + limit2 < allKeys.length ? paginatedKeys[paginatedKeys.length - 1] : undefined;
|
|
125510
|
+
return Promise.resolve({
|
|
125511
|
+
keys: paginatedKeys,
|
|
125512
|
+
nextCursor
|
|
125513
|
+
});
|
|
125514
|
+
}
|
|
125515
|
+
async getMany(tenantId, keys, context) {
|
|
125516
|
+
logger.debug(`[InMemoryProvider] Getting ${keys.length} keys for tenant: ${tenantId}`, context);
|
|
125517
|
+
const results = new Map;
|
|
125518
|
+
for (const key of keys) {
|
|
125519
|
+
const value = await this.get(tenantId, key, context);
|
|
125520
|
+
if (value !== null) {
|
|
125521
|
+
results.set(key, value);
|
|
125522
|
+
}
|
|
125523
|
+
}
|
|
125524
|
+
return results;
|
|
125525
|
+
}
|
|
125526
|
+
async setMany(tenantId, entries, context, options) {
|
|
125527
|
+
logger.debug(`[InMemoryProvider] Setting ${entries.size} keys for tenant: ${tenantId}`, context);
|
|
125528
|
+
for (const [key, value] of entries.entries()) {
|
|
125529
|
+
await this.set(tenantId, key, value, context, options);
|
|
125530
|
+
}
|
|
125531
|
+
}
|
|
125532
|
+
async deleteMany(tenantId, keys, context) {
|
|
125533
|
+
logger.debug(`[InMemoryProvider] Deleting ${keys.length} keys for tenant: ${tenantId}`, context);
|
|
125534
|
+
let deletedCount = 0;
|
|
125535
|
+
for (const key of keys) {
|
|
125536
|
+
const deleted = await this.delete(tenantId, key, context);
|
|
125537
|
+
if (deleted) {
|
|
125538
|
+
deletedCount++;
|
|
125539
|
+
}
|
|
125540
|
+
}
|
|
125541
|
+
return deletedCount;
|
|
125542
|
+
}
|
|
125543
|
+
clear(tenantId, context) {
|
|
125544
|
+
logger.debug(`[InMemoryProvider] Clearing all keys for tenant: ${tenantId}`, context);
|
|
125545
|
+
const tenantStore = this.getTenantStore(tenantId);
|
|
125546
|
+
const count = tenantStore.size;
|
|
125547
|
+
tenantStore.clear();
|
|
125548
|
+
logger.info(`[InMemoryProvider] Cleared ${count} keys for tenant: ${tenantId}`, context);
|
|
125549
|
+
return Promise.resolve(count);
|
|
125406
125550
|
}
|
|
125407
125551
|
}
|
|
125408
125552
|
|
|
@@ -125410,6 +125554,7 @@ class InMemoryProvider {
|
|
|
125410
125554
|
var import_tsyringe4 = __toESM(require_cjs3(), 1);
|
|
125411
125555
|
var import_supabase_js = __toESM(require_main6(), 1);
|
|
125412
125556
|
var TABLE_NAME = "kv_store";
|
|
125557
|
+
var DEFAULT_LIST_LIMIT3 = 1000;
|
|
125413
125558
|
|
|
125414
125559
|
class SupabaseProvider {
|
|
125415
125560
|
client;
|
|
@@ -125469,17 +125614,101 @@ class SupabaseProvider {
|
|
|
125469
125614
|
input: { tenantId, key }
|
|
125470
125615
|
});
|
|
125471
125616
|
}
|
|
125472
|
-
async list(tenantId, prefix, context) {
|
|
125617
|
+
async list(tenantId, prefix, context, options) {
|
|
125473
125618
|
return ErrorHandler.tryCatch(async () => {
|
|
125474
125619
|
const now = new Date().toISOString();
|
|
125475
|
-
const
|
|
125620
|
+
const limit2 = options?.limit ?? DEFAULT_LIST_LIMIT3;
|
|
125621
|
+
let query = this.getClient().from(TABLE_NAME).select("key").eq("tenant_id", tenantId).like("key", `${prefix}%`).or(`expires_at.is.null,expires_at.gt.${now}`).order("key", { ascending: true }).limit(limit2 + 1);
|
|
125622
|
+
if (options?.cursor) {
|
|
125623
|
+
query = query.gt("key", options.cursor);
|
|
125624
|
+
}
|
|
125625
|
+
const { data, error: error2 } = await query;
|
|
125476
125626
|
if (error2)
|
|
125477
125627
|
throw error2;
|
|
125478
|
-
|
|
125628
|
+
const keys = data?.map((item) => item.key) ?? [];
|
|
125629
|
+
const hasMore = keys.length > limit2;
|
|
125630
|
+
const resultKeys = hasMore ? keys.slice(0, limit2) : keys;
|
|
125631
|
+
const nextCursor = hasMore ? resultKeys[resultKeys.length - 1] : undefined;
|
|
125632
|
+
return {
|
|
125633
|
+
keys: resultKeys,
|
|
125634
|
+
nextCursor
|
|
125635
|
+
};
|
|
125479
125636
|
}, {
|
|
125480
125637
|
operation: "SupabaseProvider.list",
|
|
125481
125638
|
context,
|
|
125482
|
-
input: { tenantId, prefix }
|
|
125639
|
+
input: { tenantId, prefix, options }
|
|
125640
|
+
});
|
|
125641
|
+
}
|
|
125642
|
+
async getMany(tenantId, keys, context) {
|
|
125643
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125644
|
+
if (keys.length === 0) {
|
|
125645
|
+
return new Map;
|
|
125646
|
+
}
|
|
125647
|
+
const { data, error: error2 } = await this.getClient().from(TABLE_NAME).select("key, value, expires_at").eq("tenant_id", tenantId).in("key", keys);
|
|
125648
|
+
if (error2)
|
|
125649
|
+
throw error2;
|
|
125650
|
+
const results = new Map;
|
|
125651
|
+
for (const row of data ?? []) {
|
|
125652
|
+
if (!row.expires_at || new Date(row.expires_at).getTime() >= Date.now()) {
|
|
125653
|
+
results.set(row.key, row.value);
|
|
125654
|
+
} else {
|
|
125655
|
+
await this.delete(tenantId, row.key, context);
|
|
125656
|
+
}
|
|
125657
|
+
}
|
|
125658
|
+
return results;
|
|
125659
|
+
}, {
|
|
125660
|
+
operation: "SupabaseProvider.getMany",
|
|
125661
|
+
context,
|
|
125662
|
+
input: { tenantId, keyCount: keys.length }
|
|
125663
|
+
});
|
|
125664
|
+
}
|
|
125665
|
+
async setMany(tenantId, entries, context, options) {
|
|
125666
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125667
|
+
if (entries.size === 0) {
|
|
125668
|
+
return;
|
|
125669
|
+
}
|
|
125670
|
+
const expires_at = options?.ttl ? new Date(Date.now() + options.ttl * 1000).toISOString() : null;
|
|
125671
|
+
const rows = Array.from(entries.entries()).map(([key, value]) => ({
|
|
125672
|
+
tenant_id: tenantId,
|
|
125673
|
+
key,
|
|
125674
|
+
value,
|
|
125675
|
+
expires_at
|
|
125676
|
+
}));
|
|
125677
|
+
const { error: error2 } = await this.getClient().from(TABLE_NAME).upsert(rows);
|
|
125678
|
+
if (error2)
|
|
125679
|
+
throw error2;
|
|
125680
|
+
}, {
|
|
125681
|
+
operation: "SupabaseProvider.setMany",
|
|
125682
|
+
context,
|
|
125683
|
+
input: { tenantId, entryCount: entries.size }
|
|
125684
|
+
});
|
|
125685
|
+
}
|
|
125686
|
+
async deleteMany(tenantId, keys, context) {
|
|
125687
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125688
|
+
if (keys.length === 0) {
|
|
125689
|
+
return 0;
|
|
125690
|
+
}
|
|
125691
|
+
const { error: error2, count } = await this.getClient().from(TABLE_NAME).delete({ count: "exact" }).eq("tenant_id", tenantId).in("key", keys);
|
|
125692
|
+
if (error2)
|
|
125693
|
+
throw error2;
|
|
125694
|
+
return count ?? 0;
|
|
125695
|
+
}, {
|
|
125696
|
+
operation: "SupabaseProvider.deleteMany",
|
|
125697
|
+
context,
|
|
125698
|
+
input: { tenantId, keyCount: keys.length }
|
|
125699
|
+
});
|
|
125700
|
+
}
|
|
125701
|
+
async clear(tenantId, context) {
|
|
125702
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125703
|
+
const { error: error2, count } = await this.getClient().from(TABLE_NAME).delete({ count: "exact" }).eq("tenant_id", tenantId);
|
|
125704
|
+
if (error2)
|
|
125705
|
+
throw error2;
|
|
125706
|
+
logger.info(`[SupabaseProvider] Cleared ${count ?? 0} keys for tenant: ${tenantId}`, context);
|
|
125707
|
+
return count ?? 0;
|
|
125708
|
+
}, {
|
|
125709
|
+
operation: "SupabaseProvider.clear",
|
|
125710
|
+
context,
|
|
125711
|
+
input: { tenantId }
|
|
125483
125712
|
});
|
|
125484
125713
|
}
|
|
125485
125714
|
}
|
|
@@ -125493,10 +125722,14 @@ SupabaseProvider = __legacyDecorateClassTS([
|
|
|
125493
125722
|
|
|
125494
125723
|
// src/storage/providers/cloudflare/r2Provider.ts
|
|
125495
125724
|
var R2_ENVELOPE_VERSION = 1;
|
|
125725
|
+
var DEFAULT_LIST_LIMIT4 = 1000;
|
|
125496
125726
|
|
|
125497
125727
|
class R2Provider {
|
|
125498
125728
|
bucket;
|
|
125499
125729
|
constructor(bucket) {
|
|
125730
|
+
if (!bucket) {
|
|
125731
|
+
throw new McpError(-32008 /* ConfigurationError */, "R2Provider requires a valid R2Bucket instance.");
|
|
125732
|
+
}
|
|
125500
125733
|
this.bucket = bucket;
|
|
125501
125734
|
}
|
|
125502
125735
|
getR2Key(tenantId, key) {
|
|
@@ -125581,27 +125814,115 @@ class R2Provider {
|
|
|
125581
125814
|
input: { tenantId, key }
|
|
125582
125815
|
});
|
|
125583
125816
|
}
|
|
125584
|
-
async list(tenantId, prefix, context) {
|
|
125817
|
+
async list(tenantId, prefix, context, options) {
|
|
125585
125818
|
const r2Prefix = this.getR2Key(tenantId, prefix);
|
|
125586
125819
|
return ErrorHandler.tryCatch(async () => {
|
|
125587
|
-
logger.debug(`[R2Provider] Listing keys with prefix: ${r2Prefix}`,
|
|
125588
|
-
|
|
125820
|
+
logger.debug(`[R2Provider] Listing keys with prefix: ${r2Prefix}`, {
|
|
125821
|
+
...context,
|
|
125822
|
+
options
|
|
125823
|
+
});
|
|
125824
|
+
const limit2 = options?.limit ?? DEFAULT_LIST_LIMIT4;
|
|
125825
|
+
const listOptions = {
|
|
125826
|
+
prefix: r2Prefix,
|
|
125827
|
+
limit: limit2 + 1
|
|
125828
|
+
};
|
|
125829
|
+
if (options?.cursor) {
|
|
125830
|
+
listOptions.cursor = options.cursor;
|
|
125831
|
+
}
|
|
125832
|
+
const listed = await this.bucket.list(listOptions);
|
|
125589
125833
|
const tenantPrefix = `${tenantId}:`;
|
|
125590
125834
|
const keys = listed.objects.map((obj) => obj.key.startsWith(tenantPrefix) ? obj.key.substring(tenantPrefix.length) : obj.key);
|
|
125591
|
-
|
|
125592
|
-
|
|
125835
|
+
const hasMore = keys.length > limit2;
|
|
125836
|
+
const resultKeys = hasMore ? keys.slice(0, limit2) : keys;
|
|
125837
|
+
const nextCursor = "cursor" in listed && listed.truncated ? listed.cursor : undefined;
|
|
125838
|
+
logger.debug(`[R2Provider] Found ${resultKeys.length} keys with prefix: ${r2Prefix}`, context);
|
|
125839
|
+
return {
|
|
125840
|
+
keys: resultKeys,
|
|
125841
|
+
nextCursor
|
|
125842
|
+
};
|
|
125593
125843
|
}, {
|
|
125594
125844
|
operation: "R2Provider.list",
|
|
125595
125845
|
context,
|
|
125596
|
-
input: { tenantId, prefix }
|
|
125846
|
+
input: { tenantId, prefix, options }
|
|
125847
|
+
});
|
|
125848
|
+
}
|
|
125849
|
+
async getMany(tenantId, keys, context) {
|
|
125850
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125851
|
+
const results = new Map;
|
|
125852
|
+
for (const key of keys) {
|
|
125853
|
+
const value = await this.get(tenantId, key, context);
|
|
125854
|
+
if (value !== null) {
|
|
125855
|
+
results.set(key, value);
|
|
125856
|
+
}
|
|
125857
|
+
}
|
|
125858
|
+
return results;
|
|
125859
|
+
}, {
|
|
125860
|
+
operation: "R2Provider.getMany",
|
|
125861
|
+
context,
|
|
125862
|
+
input: { tenantId, keyCount: keys.length }
|
|
125863
|
+
});
|
|
125864
|
+
}
|
|
125865
|
+
async setMany(tenantId, entries, context, options) {
|
|
125866
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125867
|
+
const promises = Array.from(entries.entries()).map(([key, value]) => this.set(tenantId, key, value, context, options));
|
|
125868
|
+
await Promise.all(promises);
|
|
125869
|
+
}, {
|
|
125870
|
+
operation: "R2Provider.setMany",
|
|
125871
|
+
context,
|
|
125872
|
+
input: { tenantId, entryCount: entries.size }
|
|
125873
|
+
});
|
|
125874
|
+
}
|
|
125875
|
+
async deleteMany(tenantId, keys, context) {
|
|
125876
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125877
|
+
const promises = keys.map((key) => this.delete(tenantId, key, context));
|
|
125878
|
+
const results = await Promise.all(promises);
|
|
125879
|
+
return results.filter((deleted) => deleted).length;
|
|
125880
|
+
}, {
|
|
125881
|
+
operation: "R2Provider.deleteMany",
|
|
125882
|
+
context,
|
|
125883
|
+
input: { tenantId, keyCount: keys.length }
|
|
125884
|
+
});
|
|
125885
|
+
}
|
|
125886
|
+
async clear(tenantId, context) {
|
|
125887
|
+
return ErrorHandler.tryCatch(async () => {
|
|
125888
|
+
const r2Prefix = `${tenantId}:`;
|
|
125889
|
+
let deletedCount = 0;
|
|
125890
|
+
let cursor;
|
|
125891
|
+
let hasMore = true;
|
|
125892
|
+
while (hasMore) {
|
|
125893
|
+
const listOpts = {
|
|
125894
|
+
prefix: r2Prefix,
|
|
125895
|
+
limit: 1000
|
|
125896
|
+
};
|
|
125897
|
+
if (cursor) {
|
|
125898
|
+
listOpts.cursor = cursor;
|
|
125899
|
+
}
|
|
125900
|
+
const listed = await this.bucket.list(listOpts);
|
|
125901
|
+
const deletePromises = listed.objects.map((obj) => this.bucket.delete(obj.key));
|
|
125902
|
+
await Promise.all(deletePromises);
|
|
125903
|
+
deletedCount += listed.objects.length;
|
|
125904
|
+
hasMore = listed.truncated;
|
|
125905
|
+
cursor = "cursor" in listed ? listed.cursor : undefined;
|
|
125906
|
+
}
|
|
125907
|
+
logger.info(`[R2Provider] Cleared ${deletedCount} keys for tenant: ${tenantId}`, context);
|
|
125908
|
+
return deletedCount;
|
|
125909
|
+
}, {
|
|
125910
|
+
operation: "R2Provider.clear",
|
|
125911
|
+
context,
|
|
125912
|
+
input: { tenantId }
|
|
125597
125913
|
});
|
|
125598
125914
|
}
|
|
125599
125915
|
}
|
|
125600
125916
|
|
|
125601
125917
|
// src/storage/providers/cloudflare/kvProvider.ts
|
|
125918
|
+
var DEFAULT_LIST_LIMIT5 = 1000;
|
|
125919
|
+
|
|
125602
125920
|
class KvProvider {
|
|
125603
125921
|
kv;
|
|
125604
125922
|
constructor(kv) {
|
|
125923
|
+
if (!kv) {
|
|
125924
|
+
throw new McpError(-32008 /* ConfigurationError */, "KvProvider requires a valid KVNamespace instance.");
|
|
125925
|
+
}
|
|
125605
125926
|
this.kv = kv;
|
|
125606
125927
|
}
|
|
125607
125928
|
getKvKey(tenantId, key) {
|
|
@@ -125661,19 +125982,100 @@ class KvProvider {
|
|
|
125661
125982
|
input: { tenantId, key }
|
|
125662
125983
|
});
|
|
125663
125984
|
}
|
|
125664
|
-
async list(tenantId, prefix, context) {
|
|
125985
|
+
async list(tenantId, prefix, context, options) {
|
|
125665
125986
|
const kvPrefix = this.getKvKey(tenantId, prefix);
|
|
125666
125987
|
return ErrorHandler.tryCatch(async () => {
|
|
125667
|
-
logger.debug(`[KvProvider] Listing keys with prefix: ${kvPrefix}`,
|
|
125668
|
-
|
|
125988
|
+
logger.debug(`[KvProvider] Listing keys with prefix: ${kvPrefix}`, {
|
|
125989
|
+
...context,
|
|
125990
|
+
options
|
|
125991
|
+
});
|
|
125992
|
+
const limit2 = options?.limit ?? DEFAULT_LIST_LIMIT5;
|
|
125993
|
+
const listOptions = {
|
|
125994
|
+
prefix: kvPrefix,
|
|
125995
|
+
limit: limit2
|
|
125996
|
+
};
|
|
125997
|
+
if (options?.cursor) {
|
|
125998
|
+
listOptions.cursor = options.cursor;
|
|
125999
|
+
}
|
|
126000
|
+
const listed = await this.kv.list(listOptions);
|
|
125669
126001
|
const tenantPrefix = `${tenantId}:`;
|
|
125670
126002
|
const keys = listed.keys.map((keyInfo) => keyInfo.name.startsWith(tenantPrefix) ? keyInfo.name.substring(tenantPrefix.length) : keyInfo.name);
|
|
126003
|
+
const nextCursor = "cursor" in listed && !listed.list_complete ? listed.cursor : undefined;
|
|
125671
126004
|
logger.debug(`[KvProvider] Found ${keys.length} keys with prefix: ${kvPrefix}`, context);
|
|
125672
|
-
return
|
|
126005
|
+
return {
|
|
126006
|
+
keys,
|
|
126007
|
+
nextCursor
|
|
126008
|
+
};
|
|
125673
126009
|
}, {
|
|
125674
126010
|
operation: "KvProvider.list",
|
|
125675
126011
|
context,
|
|
125676
|
-
input: { tenantId, prefix }
|
|
126012
|
+
input: { tenantId, prefix, options }
|
|
126013
|
+
});
|
|
126014
|
+
}
|
|
126015
|
+
async getMany(tenantId, keys, context) {
|
|
126016
|
+
return ErrorHandler.tryCatch(async () => {
|
|
126017
|
+
const results = new Map;
|
|
126018
|
+
for (const key of keys) {
|
|
126019
|
+
const value = await this.get(tenantId, key, context);
|
|
126020
|
+
if (value !== null) {
|
|
126021
|
+
results.set(key, value);
|
|
126022
|
+
}
|
|
126023
|
+
}
|
|
126024
|
+
return results;
|
|
126025
|
+
}, {
|
|
126026
|
+
operation: "KvProvider.getMany",
|
|
126027
|
+
context,
|
|
126028
|
+
input: { tenantId, keyCount: keys.length }
|
|
126029
|
+
});
|
|
126030
|
+
}
|
|
126031
|
+
async setMany(tenantId, entries, context, options) {
|
|
126032
|
+
return ErrorHandler.tryCatch(async () => {
|
|
126033
|
+
const promises = Array.from(entries.entries()).map(([key, value]) => this.set(tenantId, key, value, context, options));
|
|
126034
|
+
await Promise.all(promises);
|
|
126035
|
+
}, {
|
|
126036
|
+
operation: "KvProvider.setMany",
|
|
126037
|
+
context,
|
|
126038
|
+
input: { tenantId, entryCount: entries.size }
|
|
126039
|
+
});
|
|
126040
|
+
}
|
|
126041
|
+
async deleteMany(tenantId, keys, context) {
|
|
126042
|
+
return ErrorHandler.tryCatch(async () => {
|
|
126043
|
+
const promises = keys.map((key) => this.delete(tenantId, key, context));
|
|
126044
|
+
const results = await Promise.all(promises);
|
|
126045
|
+
return results.filter((deleted) => deleted).length;
|
|
126046
|
+
}, {
|
|
126047
|
+
operation: "KvProvider.deleteMany",
|
|
126048
|
+
context,
|
|
126049
|
+
input: { tenantId, keyCount: keys.length }
|
|
126050
|
+
});
|
|
126051
|
+
}
|
|
126052
|
+
async clear(tenantId, context) {
|
|
126053
|
+
return ErrorHandler.tryCatch(async () => {
|
|
126054
|
+
const kvPrefix = `${tenantId}:`;
|
|
126055
|
+
let deletedCount = 0;
|
|
126056
|
+
let cursor;
|
|
126057
|
+
let listComplete = false;
|
|
126058
|
+
while (!listComplete) {
|
|
126059
|
+
const listOpts = {
|
|
126060
|
+
prefix: kvPrefix,
|
|
126061
|
+
limit: 1000
|
|
126062
|
+
};
|
|
126063
|
+
if (cursor) {
|
|
126064
|
+
listOpts.cursor = cursor;
|
|
126065
|
+
}
|
|
126066
|
+
const listed = await this.kv.list(listOpts);
|
|
126067
|
+
const deletePromises = listed.keys.map((keyInfo) => this.kv.delete(keyInfo.name));
|
|
126068
|
+
await Promise.all(deletePromises);
|
|
126069
|
+
deletedCount += listed.keys.length;
|
|
126070
|
+
listComplete = listed.list_complete;
|
|
126071
|
+
cursor = "cursor" in listed ? listed.cursor : undefined;
|
|
126072
|
+
}
|
|
126073
|
+
logger.info(`[KvProvider] Cleared ${deletedCount} keys for tenant: ${tenantId}`, context);
|
|
126074
|
+
return deletedCount;
|
|
126075
|
+
}, {
|
|
126076
|
+
operation: "KvProvider.clear",
|
|
126077
|
+
context,
|
|
126078
|
+
input: { tenantId }
|
|
125677
126079
|
});
|
|
125678
126080
|
}
|
|
125679
126081
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-ts-template",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.5",
|
|
4
4
|
"mcpName": "io.github.cyanheads/mcp-ts-template",
|
|
5
5
|
"description": "The definitive, production-grade template for building powerful and scalable Model Context Protocol (MCP) servers with TypeScript, featuring built-in observability (OpenTelemetry), declarative tooling, robust error handling, and a modular, DI-driven architecture.",
|
|
6
6
|
"main": "dist/index.js",
|