@usewhisper/mcp-server 2.1.0 → 2.3.0

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/server.js +269 -45
  2. package/package.json +1 -1
package/dist/server.js CHANGED
@@ -524,9 +524,71 @@ var WhisperContext = class _WhisperContext {
524
524
  this.projectRefToId.set(p.slug, p.id);
525
525
  this.projectRefToId.set(p.name, p.id);
526
526
  }
527
+ if (this.defaultProject) {
528
+ const hasDefaultProject = this.projectCache.some(
529
+ (project) => project.id === this.defaultProject || project.slug === this.defaultProject || project.name === this.defaultProject
530
+ );
531
+ if (!hasDefaultProject) {
532
+ const resolvedDefault = await this.fetchResolvedProject(this.defaultProject);
533
+ if (resolvedDefault) {
534
+ this.projectCache = [...this.projectCache, resolvedDefault];
535
+ this.projectRefToId.set(resolvedDefault.id, resolvedDefault.id);
536
+ this.projectRefToId.set(resolvedDefault.slug, resolvedDefault.id);
537
+ this.projectRefToId.set(resolvedDefault.name, resolvedDefault.id);
538
+ }
539
+ }
540
+ }
527
541
  this.projectCacheExpiresAt = Date.now() + PROJECT_CACHE_TTL_MS;
528
542
  return this.projectCache;
529
543
  }
544
+ async fetchResolvedProject(projectRef) {
545
+ if (!projectRef) return null;
546
+ try {
547
+ const response = await this.request(`/v1/projects/resolve?project=${encodeURIComponent(projectRef)}`, { method: "GET" });
548
+ return response?.resolved || null;
549
+ } catch (error) {
550
+ if (error instanceof WhisperError && error.code === "PROJECT_NOT_FOUND") {
551
+ return null;
552
+ }
553
+ throw error;
554
+ }
555
+ }
556
+ async resolveProject(projectRef) {
557
+ const resolvedRef = this.getRequiredProject(projectRef);
558
+ const cachedProjects = await this.refreshProjectCache(false);
559
+ const cachedProject = cachedProjects.find(
560
+ (project) => project.id === resolvedRef || project.slug === resolvedRef || project.name === resolvedRef
561
+ );
562
+ if (cachedProject) {
563
+ return cachedProject;
564
+ }
565
+ const resolvedProject = await this.fetchResolvedProject(resolvedRef);
566
+ if (resolvedProject) {
567
+ this.projectRefToId.set(resolvedProject.id, resolvedProject.id);
568
+ this.projectRefToId.set(resolvedProject.slug, resolvedProject.id);
569
+ this.projectRefToId.set(resolvedProject.name, resolvedProject.id);
570
+ this.projectCache = [
571
+ ...this.projectCache.filter((project) => project.id !== resolvedProject.id),
572
+ resolvedProject
573
+ ];
574
+ this.projectCacheExpiresAt = Date.now() + PROJECT_CACHE_TTL_MS;
575
+ return resolvedProject;
576
+ }
577
+ if (isLikelyProjectId(resolvedRef)) {
578
+ return {
579
+ id: resolvedRef,
580
+ orgId: "",
581
+ name: resolvedRef,
582
+ slug: resolvedRef,
583
+ createdAt: (/* @__PURE__ */ new Date(0)).toISOString(),
584
+ updatedAt: (/* @__PURE__ */ new Date(0)).toISOString()
585
+ };
586
+ }
587
+ throw new WhisperError({
588
+ code: "PROJECT_NOT_FOUND",
589
+ message: `Project '${resolvedRef}' not found`
590
+ });
591
+ }
530
592
  async resolveProjectId(projectRef) {
531
593
  if (this.projectRefToId.has(projectRef)) {
532
594
  return this.projectRefToId.get(projectRef);
@@ -547,6 +609,18 @@ var WhisperContext = class _WhisperContext {
547
609
  if (isLikelyProjectId(projectRef)) {
548
610
  return projectRef;
549
611
  }
612
+ const resolvedProject = await this.fetchResolvedProject(projectRef);
613
+ if (resolvedProject) {
614
+ this.projectRefToId.set(resolvedProject.id, resolvedProject.id);
615
+ this.projectRefToId.set(resolvedProject.slug, resolvedProject.id);
616
+ this.projectRefToId.set(resolvedProject.name, resolvedProject.id);
617
+ this.projectCache = [
618
+ ...this.projectCache.filter((project) => project.id !== resolvedProject.id),
619
+ resolvedProject
620
+ ];
621
+ this.projectCacheExpiresAt = Date.now() + PROJECT_CACHE_TTL_MS;
622
+ return resolvedProject.id;
623
+ }
550
624
  throw new WhisperError({
551
625
  code: "PROJECT_NOT_FOUND",
552
626
  message: `Project '${projectRef}' not found`
@@ -602,6 +676,26 @@ var WhisperContext = class _WhisperContext {
602
676
  message: `Project '${projectRef}' not found`
603
677
  });
604
678
  }
679
+ shouldRetryWithResolvedProjectId(error) {
680
+ return error instanceof WhisperError && error.status === 404 && !this.isEndpointNotFoundError(error);
681
+ }
682
+ async withProjectPathFallback(projectRef, execute) {
683
+ try {
684
+ return await execute(projectRef);
685
+ } catch (error) {
686
+ if (!this.shouldRetryWithResolvedProjectId(error)) {
687
+ throw error;
688
+ }
689
+ }
690
+ const resolvedProjectId = await this.resolveProjectId(projectRef);
691
+ if (resolvedProjectId === projectRef) {
692
+ throw new WhisperError({
693
+ code: "PROJECT_NOT_FOUND",
694
+ message: `Project '${projectRef}' not found`
695
+ });
696
+ }
697
+ return execute(resolvedProjectId);
698
+ }
605
699
  classifyError(status, message) {
606
700
  if (status === 401 || /api key|unauthorized|forbidden/i.test(message)) {
607
701
  return { code: "INVALID_API_KEY", retryable: false };
@@ -717,29 +811,42 @@ var WhisperContext = class _WhisperContext {
717
811
  return projects;
718
812
  }
719
813
  async getProject(id) {
720
- const projectId = await this.resolveProjectId(id);
721
- return this.request(`/v1/projects/${projectId}`);
814
+ return this.withProjectPathFallback(
815
+ this.getRequiredProject(id),
816
+ (projectPathRef) => this.request(`/v1/projects/${encodeURIComponent(projectPathRef)}`)
817
+ );
818
+ }
819
+ async listSources(project) {
820
+ const projectRef = this.getRequiredProject(project);
821
+ return this.withProjectRefFallback(
822
+ projectRef,
823
+ (resolvedProject) => this.request(`/v1/sources?project=${encodeURIComponent(resolvedProject)}`, { method: "GET" })
824
+ );
722
825
  }
723
826
  async deleteProject(id) {
724
827
  const projectId = await this.resolveProjectId(id);
725
828
  return this.request(`/v1/projects/${projectId}`, { method: "DELETE" });
726
829
  }
727
830
  async addSource(projectId, params) {
728
- const resolvedProjectId = await this.resolveProjectId(projectId);
729
- return this.request(`/v1/projects/${resolvedProjectId}/sources`, {
730
- method: "POST",
731
- body: JSON.stringify(params)
732
- });
831
+ return this.withProjectPathFallback(
832
+ this.getRequiredProject(projectId),
833
+ (projectPathRef) => this.request(`/v1/projects/${encodeURIComponent(projectPathRef)}/sources`, {
834
+ method: "POST",
835
+ body: JSON.stringify(params)
836
+ })
837
+ );
733
838
  }
734
839
  async syncSource(sourceId) {
735
840
  return this.request(`/v1/sources/${sourceId}/sync`, { method: "POST" });
736
841
  }
737
842
  async addSourceByType(projectId, params) {
738
- const resolvedProjectId = await this.resolveProjectId(projectId);
739
- return this.request(`/v1/projects/${resolvedProjectId}/add_source`, {
740
- method: "POST",
741
- body: JSON.stringify(params)
742
- });
843
+ return this.withProjectPathFallback(
844
+ this.getRequiredProject(projectId),
845
+ (projectPathRef) => this.request(`/v1/projects/${encodeURIComponent(projectPathRef)}/add_source`, {
846
+ method: "POST",
847
+ body: JSON.stringify(params)
848
+ })
849
+ );
743
850
  }
744
851
  async getSourceStatus(sourceId) {
745
852
  return this.request(`/v1/sources/${sourceId}/status`, { method: "GET" });
@@ -801,14 +908,16 @@ var WhisperContext = class _WhisperContext {
801
908
  };
802
909
  }
803
910
  async ingest(projectId, documents) {
804
- const resolvedProjectId = await this.resolveProjectId(projectId);
805
- return this.request(`/v1/projects/${resolvedProjectId}/ingest`, {
806
- method: "POST",
807
- body: JSON.stringify({ documents })
808
- });
911
+ return this.withProjectPathFallback(
912
+ this.getRequiredProject(projectId),
913
+ (projectPathRef) => this.request(`/v1/projects/${encodeURIComponent(projectPathRef)}/ingest`, {
914
+ method: "POST",
915
+ body: JSON.stringify({ documents })
916
+ })
917
+ );
809
918
  }
810
919
  async addContext(params) {
811
- const projectId = await this.resolveProjectId(this.getRequiredProject(params.project));
920
+ const projectId = (await this.resolveProject(this.getRequiredProject(params.project))).id;
812
921
  return this.ingest(projectId, [
813
922
  {
814
923
  title: params.title || "Context",
@@ -860,7 +969,7 @@ var WhisperContext = class _WhisperContext {
860
969
  importance: params.importance,
861
970
  metadata: params.metadata,
862
971
  async: params.async,
863
- write_mode: params.write_mode
972
+ write_mode: params.write_mode || (params.async === true ? "async" : "sync")
864
973
  })
865
974
  });
866
975
  const mode = direct?.mode === "async" ? "async" : direct?.mode === "sync" ? "sync" : void 0;
@@ -879,7 +988,8 @@ var WhisperContext = class _WhisperContext {
879
988
  ...direct?.status_url ? { status_url: direct.status_url } : {},
880
989
  ...direct?.accepted_at ? { accepted_at: direct.accepted_at } : {},
881
990
  ...direct?.visibility_sla_ms ? { visibility_sla_ms: direct.visibility_sla_ms } : {},
882
- ...direct?.pending_visibility !== void 0 ? { pending_visibility: Boolean(direct.pending_visibility) } : {}
991
+ ...direct?.pending_visibility !== void 0 ? { pending_visibility: Boolean(direct.pending_visibility) } : {},
992
+ ...direct?.semantic_status ? { semantic_status: direct.semantic_status } : {}
883
993
  };
884
994
  }
885
995
  if (direct?.success === true) {
@@ -892,7 +1002,8 @@ var WhisperContext = class _WhisperContext {
892
1002
  ...direct?.status_url ? { status_url: direct.status_url } : {},
893
1003
  ...direct?.accepted_at ? { accepted_at: direct.accepted_at } : {},
894
1004
  ...direct?.visibility_sla_ms ? { visibility_sla_ms: direct.visibility_sla_ms } : {},
895
- ...direct?.pending_visibility !== void 0 ? { pending_visibility: Boolean(direct.pending_visibility) } : {}
1005
+ ...direct?.pending_visibility !== void 0 ? { pending_visibility: Boolean(direct.pending_visibility) } : {},
1006
+ ...direct?.semantic_status ? { semantic_status: direct.semantic_status } : {}
896
1007
  };
897
1008
  }
898
1009
  } catch (error) {
@@ -927,7 +1038,8 @@ var WhisperContext = class _WhisperContext {
927
1038
  path: "legacy",
928
1039
  fallback_used: true,
929
1040
  mode: "sync",
930
- memory_id: id
1041
+ memory_id: id,
1042
+ semantic_status: "ready"
931
1043
  };
932
1044
  });
933
1045
  }
@@ -1215,28 +1327,37 @@ var WhisperContext = class _WhisperContext {
1215
1327
  });
1216
1328
  }
1217
1329
  async createSharedContext(params) {
1218
- const project = await this.resolveProjectId(this.getRequiredProject(params.project));
1219
- return this.request("/v1/context/share", {
1220
- method: "POST",
1221
- body: JSON.stringify({ ...params, project })
1222
- });
1330
+ const projectRef = this.getRequiredProject(params.project);
1331
+ return this.withProjectRefFallback(
1332
+ projectRef,
1333
+ (project) => this.request("/v1/context/share", {
1334
+ method: "POST",
1335
+ body: JSON.stringify({ ...params, project })
1336
+ })
1337
+ );
1223
1338
  }
1224
1339
  async loadSharedContext(shareId) {
1225
1340
  return this.request(`/v1/context/shared/${shareId}`);
1226
1341
  }
1227
1342
  async resumeFromSharedContext(params) {
1228
- const project = await this.resolveProjectId(this.getRequiredProject(params.project));
1229
- return this.request("/v1/context/resume", {
1230
- method: "POST",
1231
- body: JSON.stringify({ ...params, project })
1232
- });
1343
+ const projectRef = this.getRequiredProject(params.project);
1344
+ return this.withProjectRefFallback(
1345
+ projectRef,
1346
+ (project) => this.request("/v1/context/resume", {
1347
+ method: "POST",
1348
+ body: JSON.stringify({ ...params, project })
1349
+ })
1350
+ );
1233
1351
  }
1234
1352
  async consolidateMemories(params) {
1235
- const project = await this.resolveProjectId(this.getRequiredProject(params.project));
1236
- return this.request("/v1/memory/consolidate", {
1237
- method: "POST",
1238
- body: JSON.stringify({ ...params, project })
1239
- });
1353
+ const projectRef = this.getRequiredProject(params.project);
1354
+ return this.withProjectRefFallback(
1355
+ projectRef,
1356
+ (project) => this.request("/v1/memory/consolidate", {
1357
+ method: "POST",
1358
+ body: JSON.stringify({ ...params, project })
1359
+ })
1360
+ );
1240
1361
  }
1241
1362
  async updateImportanceDecay(params) {
1242
1363
  const project = await this.resolveProjectId(this.getRequiredProject(params.project));
@@ -1619,7 +1740,17 @@ function computeChecksum(value) {
1619
1740
  }
1620
1741
  var cachedProjectRef = DEFAULT_PROJECT || void 0;
1621
1742
  async function resolveProjectRef(explicit) {
1622
- if (explicit?.trim()) return explicit.trim();
1743
+ if (explicit?.trim()) {
1744
+ const requestedRef = explicit.trim();
1745
+ try {
1746
+ const resolved = await whisper.resolveProject(requestedRef);
1747
+ cachedProjectRef = resolved.slug || resolved.name || resolved.id;
1748
+ return cachedProjectRef;
1749
+ } catch {
1750
+ cachedProjectRef = requestedRef;
1751
+ return requestedRef;
1752
+ }
1753
+ }
1623
1754
  if (cachedProjectRef) return cachedProjectRef;
1624
1755
  try {
1625
1756
  const { projects } = await whisper.listProjects();
@@ -2516,8 +2647,9 @@ server.tool(
2516
2647
  const memoryId = result?.memory_id || result.id;
2517
2648
  const jobId = result?.job_id;
2518
2649
  const mode = result?.mode;
2650
+ const semanticStatus = result?.semantic_status;
2519
2651
  const typeLabel = memory_type || "factual";
2520
- const text = mode === "async" || jobId ? `Memory queued (job_id: ${jobId || result.id}, type: ${typeLabel}).` : `Memory stored (id: ${memoryId}, type: ${typeLabel}).`;
2652
+ const text = mode === "async" || jobId ? `Memory queued (job_id: ${jobId || result.id}, type: ${typeLabel}).` : `Memory stored (id: ${memoryId}, type: ${typeLabel}${semanticStatus ? `, semantic_status: ${semanticStatus}` : ""}).`;
2521
2653
  return { content: [{ type: "text", text }] };
2522
2654
  } catch (error) {
2523
2655
  return { content: [{ type: "text", text: `Error: ${error.message}` }] };
@@ -2564,7 +2696,19 @@ server.tool(
2564
2696
  async () => {
2565
2697
  try {
2566
2698
  const { projects } = await whisper.listProjects();
2567
- const text = projects.length === 0 ? "No projects found." : projects.map((p) => `- ${p.name} (${p.slug})${p.description ? `: ${p.description}` : ""}`).join("\n");
2699
+ const visibleProjects = [...projects];
2700
+ if (cachedProjectRef) {
2701
+ const hasCachedProject = visibleProjects.some(
2702
+ (project) => project.id === cachedProjectRef || project.slug === cachedProjectRef || project.name === cachedProjectRef
2703
+ );
2704
+ if (!hasCachedProject) {
2705
+ try {
2706
+ visibleProjects.push(await whisper.resolveProject(cachedProjectRef));
2707
+ } catch {
2708
+ }
2709
+ }
2710
+ }
2711
+ const text = visibleProjects.length === 0 ? "No projects found." : visibleProjects.map((p) => `- ${p.name} (${p.slug})${p.description ? `: ${p.description}` : ""}`).join("\n");
2568
2712
  return { content: [{ type: "text", text }] };
2569
2713
  } catch (error) {
2570
2714
  return { content: [{ type: "text", text: `Error: ${error.message}` }] };
@@ -2577,8 +2721,8 @@ server.tool(
2577
2721
  { project: z.string().optional().describe("Project name or slug") },
2578
2722
  async ({ project }) => {
2579
2723
  try {
2580
- const projectData = await whisper.getProject(project || DEFAULT_PROJECT);
2581
- const srcs = projectData.sources || [];
2724
+ const sourceData = await whisper.listSources(project || DEFAULT_PROJECT);
2725
+ const srcs = sourceData.sources || [];
2582
2726
  const text = srcs.length === 0 ? "No sources connected." : srcs.map((s) => `- ${s.name} (${s.connectorType}) \u2014 ${s.status}`).join("\n");
2583
2727
  return { content: [{ type: "text", text }] };
2584
2728
  } catch (error) {
@@ -3130,7 +3274,25 @@ server.tool(
3130
3274
  top_k: 25,
3131
3275
  include_relations: false
3132
3276
  });
3133
- const memoryIds = (search.results || []).map((r) => String(r?.memory?.id || "")).filter(Boolean);
3277
+ const normalizedQuery = String(target.query || "").trim().toLowerCase();
3278
+ const exactMatches = (search.results || []).filter((r) => {
3279
+ const memory = r?.memory || r;
3280
+ const content = String(memory?.content || "").trim().toLowerCase();
3281
+ const memoryId = String(memory?.id || "").trim().toLowerCase();
3282
+ const metadata = memory?.metadata || {};
3283
+ const normalizedContent = String(metadata?.normalized_content || "").trim().toLowerCase();
3284
+ const canonicalContent = String(metadata?.canonical_content || "").trim().toLowerCase();
3285
+ return memoryId === normalizedQuery || content === normalizedQuery || normalizedContent === normalizedQuery || canonicalContent === normalizedQuery;
3286
+ });
3287
+ const memoryIds = exactMatches.map((r) => String(r?.memory?.id || "")).filter(Boolean);
3288
+ if (memoryIds.length === 0) {
3289
+ const payload2 = {
3290
+ status: "completed",
3291
+ affected_ids: affectedIds,
3292
+ warning: "Query did not resolve to an exact memory match. No memories were changed."
3293
+ };
3294
+ return { content: [{ type: "text", text: JSON.stringify(payload2, null, 2) }] };
3295
+ }
3134
3296
  for (const id of memoryIds) {
3135
3297
  await applyToMemory(id);
3136
3298
  }
@@ -3204,6 +3366,7 @@ server.tool(
3204
3366
  const bundleWithoutChecksum = {
3205
3367
  bundle_version: "1.0",
3206
3368
  workspace_id: workspaceId,
3369
+ ...resolvedProject ? { project: resolvedProject } : {},
3207
3370
  exported_at: now,
3208
3371
  contents
3209
3372
  };
@@ -3223,6 +3386,7 @@ server.tool(
3223
3386
  bundle: z.object({
3224
3387
  bundle_version: z.string(),
3225
3388
  workspace_id: z.string(),
3389
+ project: z.string().optional(),
3226
3390
  exported_at: z.string(),
3227
3391
  contents: z.object({
3228
3392
  memories: z.array(z.any()).default([]),
@@ -3246,8 +3410,10 @@ server.tool(
3246
3410
  if (dedupe_strategy === "id") return existing.some((e) => e.id === incoming.id);
3247
3411
  const norm = incoming.content.toLowerCase().trim();
3248
3412
  return existing.some((e) => e.content.toLowerCase().trim() === norm);
3413
+ }, normalizeString2 = function(value) {
3414
+ return String(value || "").trim().toLowerCase();
3249
3415
  };
3250
- var dedupe = dedupe2;
3416
+ var dedupe = dedupe2, normalizeString = normalizeString2;
3251
3417
  const workspaceId = getWorkspaceId(workspace_id || bundle.workspace_id);
3252
3418
  const state = loadState();
3253
3419
  const workspace = getWorkspaceState(state, workspaceId);
@@ -3273,6 +3439,30 @@ server.tool(
3273
3439
  session_summaries: 0,
3274
3440
  documents: 0
3275
3441
  };
3442
+ const resolvedProject = await resolveProjectRef(bundle.project);
3443
+ async function shouldSkipImportedMemory(memory) {
3444
+ if (dedupe_strategy === "none" || !resolvedProject) return false;
3445
+ const exactId = normalizeString2(memory?.id);
3446
+ const exactContent = normalizeString2(memory?.content);
3447
+ if (!exactId && !exactContent) return false;
3448
+ const existing = await whisper.searchMemoriesSOTA({
3449
+ project: resolvedProject,
3450
+ query: exactId || exactContent,
3451
+ top_k: 10,
3452
+ include_relations: false
3453
+ });
3454
+ return (existing.results || []).some((result) => {
3455
+ const candidate = result?.memory || result;
3456
+ const candidateId = normalizeString2(candidate?.id);
3457
+ const candidateContent = normalizeString2(candidate?.content);
3458
+ const candidateMetadata = candidate?.metadata || {};
3459
+ const importedOriginalId = normalizeString2(candidateMetadata?.bundle_original_id);
3460
+ if (dedupe_strategy === "id") {
3461
+ return Boolean(exactId) && (candidateId === exactId || importedOriginalId === exactId);
3462
+ }
3463
+ return Boolean(exactContent) && candidateContent === exactContent;
3464
+ });
3465
+ }
3276
3466
  if (mode === "replace") {
3277
3467
  workspace.entities = [];
3278
3468
  workspace.decisions = [];
@@ -3282,6 +3472,40 @@ server.tool(
3282
3472
  workspace.documents = [];
3283
3473
  workspace.events = [];
3284
3474
  }
3475
+ if (!checksumVerified) {
3476
+ const payload2 = {
3477
+ imported_counts: importedCounts,
3478
+ skipped_counts: skippedCounts,
3479
+ conflicts,
3480
+ checksum_verified: checksumVerified
3481
+ };
3482
+ return { content: [{ type: "text", text: JSON.stringify(payload2, null, 2) }] };
3483
+ }
3484
+ for (const memory of bundle.contents.memories || []) {
3485
+ if (!resolvedProject) {
3486
+ skippedCounts.memories += 1;
3487
+ continue;
3488
+ }
3489
+ if (await shouldSkipImportedMemory(memory)) {
3490
+ skippedCounts.memories += 1;
3491
+ continue;
3492
+ }
3493
+ await whisper.addMemory({
3494
+ project: resolvedProject,
3495
+ content: String(memory?.content || ""),
3496
+ memory_type: String(memory?.type || memory?.memoryType || "factual"),
3497
+ user_id: memory?.user_id || memory?.userId,
3498
+ session_id: memory?.session_id || memory?.sessionId,
3499
+ importance: typeof memory?.importance === "number" ? memory.importance : void 0,
3500
+ metadata: {
3501
+ ...memory?.metadata && typeof memory.metadata === "object" ? memory.metadata : {},
3502
+ bundle_original_id: memory?.id || void 0,
3503
+ imported_from_bundle: true,
3504
+ bundle_exported_at: bundle.exported_at
3505
+ }
3506
+ });
3507
+ importedCounts.memories += 1;
3508
+ }
3285
3509
  const keys = ["entities", "decisions", "failures", "annotations", "session_summaries", "documents"];
3286
3510
  for (const key of keys) {
3287
3511
  const sourceItems = bundle.contents[key];
@@ -3308,7 +3532,7 @@ server.tool(
3308
3532
  const payload = {
3309
3533
  imported_counts: importedCounts,
3310
3534
  skipped_counts: skippedCounts,
3311
- conflicts,
3535
+ conflicts: resolvedProject ? conflicts : [...conflicts, "project_unresolved"],
3312
3536
  checksum_verified: checksumVerified
3313
3537
  };
3314
3538
  return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usewhisper/mcp-server",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "whisperContractVersion": "2026.03.09",
5
5
  "scripts": {
6
6
  "build": "tsup ../src/mcp/server.ts --format esm --out-dir dist",