@melandlabs/memory-store 0.2.7 → 0.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.
package/dist/mcp.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { M as MemoryStoreConfig } from './config-Ll6ktm4D.js';
2
+ import { M as MemoryStoreConfig } from './config-2Q092MUz.js';
3
3
 
4
4
  /**
5
5
  * @melandlabs/memory-store/mcp — MCP server entry.
package/dist/mcp.js CHANGED
@@ -240,7 +240,7 @@ __export(raw_message_store_exports, {
240
240
  getRawMessageStorageBackend: () => getRawMessageStorageBackend,
241
241
  isRawMessageStorageAvailable: () => isRawMessageStorageAvailable
242
242
  });
243
- function resolveBackend(env) {
243
+ function resolveBackend(_env) {
244
244
  const explicit = process.env.OPENCONTEXT_MEMORY_STORE_BACKEND?.trim().toLowerCase();
245
245
  if (explicit === "postgres") return "postgres";
246
246
  return "sqlite";
@@ -373,6 +373,12 @@ function mergeUnifiedMemorySearchResults(results, limit, options = {}) {
373
373
  function normalizeUnifiedMemoryMergeStrategy(value) {
374
374
  return value === "rrf" ? "rrf" : "similarity";
375
375
  }
376
+ function normalizeUnifiedMemoryReasoningStrategy(value, defaultStrategy = "none") {
377
+ if (value === "rewrite" || value === "iterative") {
378
+ return value;
379
+ }
380
+ return defaultStrategy;
381
+ }
376
382
  var DEFAULT_RRF_K = 60;
377
383
  function mergeUnifiedMemorySearchResultsRrf(lists, limit, k = DEFAULT_RRF_K) {
378
384
  if (!Array.isArray(lists) || lists.length === 0) {
@@ -395,7 +401,13 @@ function mergeUnifiedMemorySearchResultsRrf(lists, limit, k = DEFAULT_RRF_K) {
395
401
  }
396
402
  }
397
403
  }
398
- const ranked = order.map((key) => scores.get(key)).sort((a, b) => {
404
+ const ranked = order.map((key) => {
405
+ const entry = scores.get(key);
406
+ if (!entry) {
407
+ throw new Error(`Invariant violation: missing RRF score for key "${key}"`);
408
+ }
409
+ return entry;
410
+ }).sort((a, b) => {
399
411
  if (b.rrf !== a.rrf) {
400
412
  return b.rrf - a.rrf;
401
413
  }
@@ -440,14 +452,222 @@ function isRawMemorySemanticResult(result) {
440
452
  function deriveLexicalKeywords(query) {
441
453
  return query.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((token) => token.length >= 2).slice(0, 16);
442
454
  }
455
+ function parseDateBoundary(value, role) {
456
+ const trimmed = value.trim();
457
+ if (!trimmed) {
458
+ return void 0;
459
+ }
460
+ const dateOnlyMatch = trimmed.match(/^(\d{4})-(\d{2})-(\d{2})$/);
461
+ if (dateOnlyMatch) {
462
+ const year = Number.parseInt(dateOnlyMatch[1], 10);
463
+ const month = Number.parseInt(dateOnlyMatch[2], 10) - 1;
464
+ const day = Number.parseInt(dateOnlyMatch[3], 10);
465
+ if (role === "from") {
466
+ return Date.UTC(year, month, day);
467
+ }
468
+ return Date.UTC(year, month, day + 1) - 1;
469
+ }
470
+ const parsed = Date.parse(trimmed);
471
+ if (Number.isNaN(parsed)) {
472
+ return void 0;
473
+ }
474
+ return parsed;
475
+ }
476
+ function getCandidateTimestamp(metadata) {
477
+ for (const key of ["timestamp", "createdAt", "time"]) {
478
+ const value = metadata[key];
479
+ if (typeof value === "number") {
480
+ return value;
481
+ }
482
+ if (typeof value === "string") {
483
+ const parsed = Date.parse(value);
484
+ if (!Number.isNaN(parsed)) {
485
+ return parsed;
486
+ }
487
+ }
488
+ }
489
+ return void 0;
490
+ }
491
+ function filterByDateRange(items, dateFrom, dateTo) {
492
+ if (!dateFrom && !dateTo) {
493
+ return items;
494
+ }
495
+ const fromMs = dateFrom ? parseDateBoundary(dateFrom, "from") : void 0;
496
+ const toMs = dateTo ? parseDateBoundary(dateTo, "to") : void 0;
497
+ if (fromMs === void 0 && toMs === void 0) {
498
+ return items;
499
+ }
500
+ return items.filter((item) => {
501
+ const ts = getCandidateTimestamp(item.metadata);
502
+ if (ts === void 0) {
503
+ return true;
504
+ }
505
+ if (fromMs !== void 0 && ts < fromMs) {
506
+ return false;
507
+ }
508
+ if (toMs !== void 0 && ts > toMs) {
509
+ return false;
510
+ }
511
+ return true;
512
+ });
513
+ }
514
+ async function embedQueryVariant(embedQuery, input, query) {
515
+ return embedQuery({
516
+ userId: input.userId,
517
+ query,
518
+ authToken: input.authToken
519
+ });
520
+ }
521
+ async function runSemanticSearchForEmbedding(deps, input, queryEmbedding, limit, threshold, logger) {
522
+ const filters = input.botIds && input.botIds.length > 0 ? input.botIds.map((botId) => ({ botId })) : [{}];
523
+ let semantic = [];
524
+ if (isRawMessageChromaEnabled()) {
525
+ try {
526
+ semantic = (await Promise.all(
527
+ filters.map((filter) => {
528
+ const botId = "botId" in filter ? filter.botId : void 0;
529
+ return searchRawMessagesWithChroma({
530
+ userId: input.userId,
531
+ queryEmbedding,
532
+ limit,
533
+ threshold,
534
+ botId
535
+ });
536
+ })
537
+ )).flat().map(toMemoryResult);
538
+ logger.log?.("[memory-store] Raw message semantic search completed", {
539
+ backend: "chroma",
540
+ dimensions: queryEmbedding.length,
541
+ count: semantic.length
542
+ });
543
+ } catch (error) {
544
+ logger.warn?.(
545
+ "[memory-store] Chroma raw message search failed; falling back to database search:",
546
+ error
547
+ );
548
+ }
549
+ } else if (typeof deps.searchRawMessagesAnn === "function") {
550
+ const searchRawMessagesAnn = deps.searchRawMessagesAnn;
551
+ semantic = (await Promise.all(
552
+ filters.map(
553
+ (filter) => searchRawMessagesAnn({
554
+ userId: input.userId,
555
+ queryEmbedding,
556
+ limit,
557
+ threshold,
558
+ botId: "botId" in filter ? filter.botId : void 0
559
+ })
560
+ )
561
+ )).flat().filter(isRawMemorySemanticResult).map(toMemoryResult);
562
+ }
563
+ if (semantic.length === 0) {
564
+ try {
565
+ const { getRawMessageManager: getRawMessageManager2 } = await Promise.resolve().then(() => (init_raw_message_store(), raw_message_store_exports));
566
+ const manager2 = await getRawMessageManager2();
567
+ if (typeof manager2.searchMessagesSemantically === "function") {
568
+ const results = await manager2.searchMessagesSemantically({
569
+ userId: input.userId,
570
+ queryEmbedding,
571
+ limit,
572
+ threshold
573
+ });
574
+ semantic = results.map((r) => ({
575
+ type: "memory",
576
+ id: r.id,
577
+ content: r.content,
578
+ similarity: r.similarity,
579
+ metadata: r.metadata ?? {}
580
+ }));
581
+ }
582
+ } catch (error) {
583
+ logger.warn?.("[memory-store] SQLite semantic search failed:", error);
584
+ }
585
+ }
586
+ return semantic;
587
+ }
588
+ function mergeByMaxScore(lists) {
589
+ const best = /* @__PURE__ */ new Map();
590
+ for (const list of lists) {
591
+ for (const hit of list) {
592
+ const existing = best.get(hit.id);
593
+ if (!existing || hit.similarity > existing.similarity) {
594
+ best.set(hit.id, hit);
595
+ }
596
+ }
597
+ }
598
+ return Array.from(best.values()).sort((a, b) => b.similarity - a.similarity);
599
+ }
600
+ function toIterativeRecallCandidate(hit) {
601
+ return {
602
+ id: hit.id,
603
+ content: hit.content,
604
+ similarity: hit.similarity,
605
+ metadata: hit.metadata
606
+ };
607
+ }
608
+ async function runLexicalSearchForKeywords(deps, input, keywords, limit, logger) {
609
+ if (keywords.length === 0) {
610
+ return [];
611
+ }
612
+ if (typeof deps.searchRawMessagesLexical === "function") {
613
+ try {
614
+ const filters = input.botIds && input.botIds.length > 0 ? input.botIds : [void 0];
615
+ const searchRawMessagesLexical = deps.searchRawMessagesLexical;
616
+ return (await Promise.all(
617
+ filters.map(
618
+ (botId) => searchRawMessagesLexical({
619
+ userId: input.userId,
620
+ keywords,
621
+ limit: Math.ceil(limit / filters.length),
622
+ botId
623
+ })
624
+ )
625
+ )).flat().filter(isRawMemorySemanticResult).map((hit) => ({
626
+ ...toMemoryResult(hit),
627
+ metadata: { ...hit.metadata, scoring: "bm25" }
628
+ }));
629
+ } catch (error) {
630
+ logger.warn?.("[memory-store] lexical memory search failed:", error);
631
+ }
632
+ }
633
+ try {
634
+ const { lexicalSearchRawMessages: lexicalSearchRawMessages2 } = await Promise.resolve().then(() => (init_sqlite_raw_message_store(), sqlite_raw_message_store_exports));
635
+ const filters = input.botIds && input.botIds.length > 0 ? input.botIds : [void 0];
636
+ return (await Promise.all(
637
+ filters.map(
638
+ (botId) => lexicalSearchRawMessages2({
639
+ userId: input.userId,
640
+ keywords,
641
+ limit: Math.ceil(limit / filters.length),
642
+ botId
643
+ })
644
+ )
645
+ )).flat().filter(Boolean).map(
646
+ (r) => toMemoryResult(
647
+ r
648
+ )
649
+ );
650
+ } catch (error) {
651
+ logger.warn?.("[memory-store] SQLite lexical search failed:", error);
652
+ }
653
+ return [];
654
+ }
443
655
  function createUnifiedSearch(deps = {}) {
444
656
  const logger = deps.logger ?? console;
657
+ function resolveReasoningStrategy(input) {
658
+ const requested = normalizeUnifiedMemoryReasoningStrategy(input.reasoningStrategy);
659
+ if (requested !== "none") {
660
+ return requested;
661
+ }
662
+ return normalizeUnifiedMemoryReasoningStrategy(deps.reasoning?.defaultStrategy, "none");
663
+ }
445
664
  async function searchUnifiedMemory(input) {
446
665
  const query = input.query.trim();
447
666
  const sources = normalizeUnifiedMemorySearchSources(input.sources);
448
667
  const limit = clampUnifiedMemorySearchLimit(input.limit);
449
668
  const threshold = clampUnifiedMemorySearchThreshold(input.threshold);
450
669
  const mergeStrategy = normalizeUnifiedMemoryMergeStrategy(input.mergeStrategy);
670
+ const reasoningStrategy = resolveReasoningStrategy(input);
451
671
  const warnings = [];
452
672
  if (!query) {
453
673
  return {
@@ -459,10 +679,21 @@ function createUnifiedSearch(deps = {}) {
459
679
  };
460
680
  }
461
681
  let memorySubs;
682
+ const reasoningInfo = { strategy: reasoningStrategy };
683
+ if (input.dateFrom || input.dateTo) {
684
+ reasoningInfo.dateRange = { from: input.dateFrom, to: input.dateTo };
685
+ }
462
686
  if (sources.includes("memory")) {
463
687
  if (isRawMessageStorageAvailable()) {
464
688
  try {
465
- memorySubs = await runMemorySource(input, limit, threshold, warnings);
689
+ memorySubs = await runMemorySource(
690
+ input,
691
+ limit,
692
+ threshold,
693
+ warnings,
694
+ reasoningStrategy,
695
+ reasoningInfo
696
+ );
466
697
  } catch (error) {
467
698
  logger.warn?.("[memory-store] memory source failed:", error);
468
699
  warnings.push({
@@ -541,121 +772,155 @@ function createUnifiedSearch(deps = {}) {
541
772
  limit,
542
773
  strategy: mergeStrategy
543
774
  });
544
- return {
775
+ const output = {
545
776
  query: input.query,
546
777
  sources,
547
778
  results: merged,
548
779
  count: merged.length,
549
780
  warnings
550
781
  };
782
+ if (reasoningInfo && (reasoningInfo.strategy !== "none" || reasoningInfo.dateRange !== void 0)) {
783
+ output.reasoning = reasoningInfo;
784
+ }
785
+ return output;
551
786
  }
552
- async function runMemorySource(input, limit, threshold, warnings) {
787
+ async function runMemorySource(input, limit, threshold, warnings, reasoningStrategy = "none", reasoningInfo) {
788
+ if (reasoningStrategy === "iterative" && !deps.reasoning?.iterativePlanner) {
789
+ warnings.push({
790
+ source: "memory",
791
+ code: "memory_iterative_planner_not_configured",
792
+ message: "Iterative reasoning requested but no iterativePlanner is configured; falling back to default search."
793
+ });
794
+ if (reasoningInfo) reasoningInfo.degraded = true;
795
+ }
796
+ if (reasoningStrategy === "rewrite" && !deps.reasoning?.queryRewriter) {
797
+ warnings.push({
798
+ source: "memory",
799
+ code: "memory_query_rewrite_not_configured",
800
+ message: "Rewrite reasoning requested but no queryRewriter is configured; falling back to default search."
801
+ });
802
+ if (reasoningInfo) reasoningInfo.degraded = true;
803
+ }
804
+ if (reasoningStrategy === "iterative" && deps.reasoning?.iterativePlanner) {
805
+ const planner = deps.reasoning.iterativePlanner;
806
+ const result = await planner.plan({
807
+ query: input.query,
808
+ dateFrom: input.dateFrom,
809
+ dateTo: input.dateTo,
810
+ executor: {
811
+ search: async (request) => {
812
+ const keywords2 = request.keywords.length > 0 ? request.keywords : deriveLexicalKeywords(input.query);
813
+ const lexicalHits = await runLexicalSearchForKeywords(deps, input, keywords2, limit, logger);
814
+ let semanticHits = [];
815
+ if (typeof deps.embedQuery === "function") {
816
+ try {
817
+ const semanticQuery = keywords2.join(" ");
818
+ const queryEmbedding = await embedQueryVariant(deps.embedQuery, input, semanticQuery);
819
+ semanticHits = await runSemanticSearchForEmbedding(
820
+ deps,
821
+ input,
822
+ queryEmbedding,
823
+ limit,
824
+ threshold,
825
+ logger
826
+ );
827
+ } catch (error) {
828
+ logger.warn?.(
829
+ "[memory-store] Iterative semantic search failed; using lexical results only:",
830
+ error
831
+ );
832
+ }
833
+ }
834
+ const candidates = filterByDateRange(
835
+ mergeByMaxScore([
836
+ lexicalHits.map(toIterativeRecallCandidate),
837
+ semanticHits.map(toIterativeRecallCandidate)
838
+ ]),
839
+ request.dateFrom,
840
+ request.dateTo
841
+ );
842
+ return { candidates };
843
+ }
844
+ }
845
+ });
846
+ if (reasoningInfo) {
847
+ reasoningInfo.iterations = result.stats.iterations;
848
+ reasoningInfo.evidenceCount = result.evidence.length;
849
+ if (planner.lastDegraded?.()) {
850
+ reasoningInfo.degraded = true;
851
+ }
852
+ }
853
+ const semantic2 = result.evidence.map((candidate) => ({
854
+ type: "memory",
855
+ id: candidate.id,
856
+ content: candidate.content,
857
+ similarity: candidate.similarity,
858
+ metadata: { ...candidate.metadata, reasoning: "iterative" }
859
+ }));
860
+ return { semantic: semantic2, lexical: [] };
861
+ }
553
862
  if (typeof deps.embedQuery !== "function") {
554
863
  warnings.push({
555
864
  source: "memory",
556
865
  code: "memory_lexical_search_fallback",
557
866
  message: "Semantic search not configured, using keyword search as fallback"
558
867
  });
559
- const { lexicalSearchRawMessages: lexicalSearchRawMessages2 } = await Promise.resolve().then(() => (init_sqlite_raw_message_store(), sqlite_raw_message_store_exports));
560
- const keywords = deriveLexicalKeywords(input.query);
561
- let lexical2 = [];
562
- if (keywords.length > 0) {
563
- try {
564
- const filters2 = input.botIds && input.botIds.length > 0 ? input.botIds : [void 0];
565
- const results = await Promise.all(
566
- filters2.map(
567
- (botId) => lexicalSearchRawMessages2({
568
- userId: input.userId,
569
- keywords,
570
- limit: Math.ceil(limit / filters2.length),
571
- botId
572
- })
573
- )
574
- );
575
- lexical2 = results.flat().filter(Boolean).map(toMemoryResult);
576
- } catch (error) {
577
- logger.warn?.("[memory-store] Default lexical search failed:", error);
578
- }
579
- }
868
+ const keywords2 = deriveLexicalKeywords(input.query);
869
+ const lexical2 = filterByDateRange(
870
+ await runLexicalSearchForKeywords(deps, input, keywords2, limit, logger),
871
+ input.dateFrom,
872
+ input.dateTo
873
+ );
580
874
  return { semantic: [], lexical: lexical2 };
581
875
  }
582
- const queryEmbedding = await deps.embedQuery({
583
- userId: input.userId,
584
- query: input.query,
585
- authToken: input.authToken
586
- });
587
- const filters = input.botIds && input.botIds.length > 0 ? input.botIds.map((botId) => ({ botId })) : [{}];
588
876
  let semantic = [];
589
- if (isRawMessageChromaEnabled()) {
877
+ const embedQuery = deps.embedQuery;
878
+ if (reasoningStrategy === "rewrite" && deps.reasoning?.queryRewriter) {
590
879
  try {
591
- semantic = (await Promise.all(
592
- filters.map((filter) => {
593
- const botId = "botId" in filter ? filter.botId : void 0;
594
- return searchRawMessagesWithChroma({
595
- userId: input.userId,
596
- queryEmbedding,
597
- limit,
598
- threshold,
599
- botId
600
- });
601
- })
602
- )).flat().map(toMemoryResult);
603
- logger.log?.("[memory-store] Raw message semantic search completed", {
604
- backend: "chroma",
605
- dimensions: queryEmbedding.length,
606
- count: semantic.length
880
+ const variants = await deps.reasoning.queryRewriter.rewrite({
881
+ query: input.query,
882
+ userId: input.userId,
883
+ authToken: input.authToken
607
884
  });
608
- } catch (error) {
609
- logger.warn?.(
610
- "[memory-store] Chroma raw message search failed; falling back to database search:",
611
- error
885
+ if (reasoningInfo) {
886
+ reasoningInfo.rewrittenQueries = variants;
887
+ if (deps.reasoning.queryRewriter.lastDegraded?.()) {
888
+ reasoningInfo.degraded = true;
889
+ }
890
+ }
891
+ const embeddings = await Promise.all(
892
+ variants.map((variant) => embedQueryVariant(embedQuery, input, variant))
612
893
  );
894
+ const lists = await Promise.all(
895
+ embeddings.map(
896
+ (embedding) => runSemanticSearchForEmbedding(deps, input, embedding, limit, threshold, logger)
897
+ )
898
+ );
899
+ semantic = mergeByMaxScore(lists);
900
+ } catch (error) {
901
+ logger.warn?.("[memory-store] Query rewriting failed; falling back to original query:", error);
902
+ warnings.push({
903
+ source: "memory",
904
+ code: "memory_query_rewrite_failed",
905
+ message: `Query rewriting failed: ${error.message ?? "Unknown error"}. Using original query.`
906
+ });
907
+ if (reasoningInfo) reasoningInfo.degraded = true;
613
908
  }
614
- } else if (typeof deps.searchRawMessagesAnn === "function") {
615
- semantic = (await Promise.all(
616
- filters.map(
617
- (filter) => deps.searchRawMessagesAnn({
618
- userId: input.userId,
619
- queryEmbedding,
620
- limit,
621
- threshold,
622
- botId: "botId" in filter ? filter.botId : void 0
623
- })
624
- )
625
- )).flat().filter(isRawMemorySemanticResult).map(toMemoryResult);
626
909
  }
627
910
  if (semantic.length === 0) {
628
- try {
629
- const { getRawMessageManager: getRawMessageManager2 } = await Promise.resolve().then(() => (init_raw_message_store(), raw_message_store_exports));
630
- const manager2 = await getRawMessageManager2();
631
- if (typeof manager2.searchMessagesSemantically === "function") {
632
- const results = await manager2.searchMessagesSemantically({
633
- userId: input.userId,
634
- queryEmbedding,
635
- limit,
636
- threshold
637
- });
638
- semantic = results.map((r) => ({
639
- type: "memory",
640
- id: r.id,
641
- content: r.content,
642
- similarity: r.similarity,
643
- metadata: r.metadata ?? {}
644
- }));
645
- }
646
- } catch (error) {
647
- logger.warn?.("[memory-store] SQLite semantic search failed:", error);
648
- }
911
+ const queryEmbedding = await embedQueryVariant(embedQuery, input, input.query);
912
+ semantic = await runSemanticSearchForEmbedding(deps, input, queryEmbedding, limit, threshold, logger);
649
913
  }
650
914
  let lexical = [];
651
- if (typeof deps.searchRawMessagesLexical === "function") {
652
- const keywords = deriveLexicalKeywords(input.query);
653
- if (keywords.length > 0) {
915
+ const keywords = deriveLexicalKeywords(input.query);
916
+ if (keywords.length > 0) {
917
+ if (typeof deps.searchRawMessagesLexical === "function") {
654
918
  try {
655
919
  const lexFilters = input.botIds && input.botIds.length > 0 ? input.botIds : [void 0];
920
+ const searchRawMessagesLexical = deps.searchRawMessagesLexical;
656
921
  lexical = (await Promise.all(
657
922
  lexFilters.map(
658
- (botId) => deps.searchRawMessagesLexical({
923
+ (botId) => searchRawMessagesLexical({
659
924
  userId: input.userId,
660
925
  keywords,
661
926
  limit,
@@ -674,20 +939,24 @@ function createUnifiedSearch(deps = {}) {
674
939
  message: error.message ?? "memory_lexical_search_failed"
675
940
  });
676
941
  }
942
+ } else if (input.mergeStrategy === "rrf") {
943
+ warnings.push({
944
+ source: "memory",
945
+ code: "memory_lexical_search_not_configured",
946
+ message: "RRF merge requested but lexical search is not configured; falling back to semantic-only RRF."
947
+ });
677
948
  }
678
- } else if (input.mergeStrategy === "rrf") {
679
- warnings.push({
680
- source: "memory",
681
- code: "memory_lexical_search_not_configured",
682
- message: "RRF merge requested but lexical search is not configured; falling back to semantic-only RRF."
683
- });
684
949
  }
685
- return { semantic, lexical };
950
+ return {
951
+ semantic: filterByDateRange(semantic, input.dateFrom, input.dateTo),
952
+ lexical: filterByDateRange(lexical, input.dateFrom, input.dateTo)
953
+ };
686
954
  }
687
955
  async function searchRawMemorySemantically(input) {
688
956
  const limit = clampUnifiedMemorySearchLimit(input.limit);
689
957
  const threshold = clampUnifiedMemorySearchThreshold(input.threshold);
690
- const sub = await runMemorySource(input, limit, threshold, []);
958
+ const reasoningStrategy = resolveReasoningStrategy(input);
959
+ const sub = await runMemorySource(input, limit, threshold, [], reasoningStrategy);
691
960
  return mergeAcrossSources({
692
961
  memorySubs: sub,
693
962
  insightHits: [],
@@ -814,6 +1083,7 @@ async function startMcpServer(options = {}) {
814
1083
  {
815
1084
  title: "Search Unified Memory",
816
1085
  description: "Semantic search across raw messages (always), and optionally insights and uploaded knowledge.",
1086
+ // biome-ignore lint/suspicious/noExplicitAny: MCP SDK expects Zod schema type
817
1087
  inputSchema: searchSchema
818
1088
  },
819
1089
  async (args) => {
@@ -829,6 +1099,7 @@ async function startMcpServer(options = {}) {
829
1099
  {
830
1100
  title: "Write Raw Message",
831
1101
  description: "Persist a single raw message to the user's memory store.",
1102
+ // biome-ignore lint/suspicious/noExplicitAny: MCP SDK expects Zod schema type
832
1103
  inputSchema: writeSchema
833
1104
  },
834
1105
  async (args) => {
@@ -868,6 +1139,7 @@ async function startMcpServer(options = {}) {
868
1139
  {
869
1140
  title: "Get Raw Message",
870
1141
  description: "Fetch a single raw message by its message id.",
1142
+ // biome-ignore lint/suspicious/noExplicitAny: MCP SDK expects Zod schema type
871
1143
  inputSchema: getSchema
872
1144
  },
873
1145
  async (args) => {