@memoraone/mcp 0.1.18 → 0.1.20

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/daemon.cjs CHANGED
@@ -418,11 +418,18 @@ var MemoraClient = class {
418
418
  );
419
419
  }
420
420
  if (!res.ok) {
421
- const snippet = res.text.length > 200 ? `${res.text.slice(0, 200)}...` : res.text;
422
- process.stderr.write(
423
- `[memoraone-mcp][error] http error method=POST url=${url} status=${res.status} body=${snippet}
421
+ const accepted = options?.acceptStatuses?.includes(res.status);
422
+ if (accepted) {
423
+ return res.text ? JSON.parse(res.text) : null;
424
+ }
425
+ const quiet = options?.quietHttpStatuses?.includes(res.status);
426
+ if (!quiet) {
427
+ const snippet = res.text.length > 200 ? `${res.text.slice(0, 200)}...` : res.text;
428
+ process.stderr.write(
429
+ `[memoraone-mcp][error] http error method=POST url=${url} status=${res.status} body=${snippet}
424
430
  `
425
- );
431
+ );
432
+ }
426
433
  throw new MemoraOneHttpError(res.status, res.statusText, res.text);
427
434
  }
428
435
  console.error(
@@ -465,41 +472,70 @@ var memoraClient_default = MemoraClient;
465
472
  // src/sourceRegistration.ts
466
473
  var path4 = __toESM(require("path"), 1);
467
474
  var import_node_url = require("url");
475
+ var LOG_PREFIX = "[memoraone-mcp][source-registration]";
476
+ function buildRepoSourcePayload(normalizedRepoPath, ideType) {
477
+ const body = {
478
+ kind: "repo",
479
+ label: path4.basename(normalizedRepoPath),
480
+ uri: (0, import_node_url.pathToFileURL)(normalizedRepoPath).href
481
+ };
482
+ if (ideType) {
483
+ body.metadata = {
484
+ ide_type: ideType
485
+ };
486
+ }
487
+ return body;
488
+ }
468
489
  async function registerRepoSource(client, projectId, repoPath, ideType) {
469
- const normalizedRepoPath = path4.resolve(repoPath);
470
- const endpointPath = `/v1/projects/${projectId}/sources`;
471
- console.error(
472
- `[memoraone-mcp DEBUG registerRepoSource] registerRepoSource() called projectId=${projectId} repoPath(raw)=${JSON.stringify(repoPath)} repoPath(normalized)=${JSON.stringify(normalizedRepoPath)} ideType=${ideType ?? "(none)"}`
473
- );
474
490
  try {
475
- const body = {
476
- kind: "repo",
477
- label: path4.basename(normalizedRepoPath),
478
- uri: (0, import_node_url.pathToFileURL)(normalizedRepoPath).href
479
- };
480
- if (ideType) {
481
- body.metadata = {
482
- ide_type: ideType
483
- };
491
+ if (repoPath === void 0 || repoPath === null || String(repoPath).trim() === "") {
492
+ process.stderr.write(
493
+ `${LOG_PREFIX} skipped: empty repoPath (cannot register workspace)
494
+ `
495
+ );
496
+ return;
484
497
  }
485
- console.error(
486
- `[memoraone-mcp DEBUG registerRepoSource] POST endpoint=${endpointPath} body=${JSON.stringify(body)}`
487
- );
488
- const result = await client.post(endpointPath, body);
489
- console.error(
490
- `[memoraone-mcp DEBUG registerRepoSource] POST succeeded endpoint=${endpointPath} responseSummary=${JSON.stringify(result)}`
498
+ const normalizedRepoPath = path4.resolve(String(repoPath));
499
+ const body = buildRepoSourcePayload(normalizedRepoPath, ideType);
500
+ const primaryPath = `/v1/projects/${projectId}/sources`;
501
+ const alternatePath = `/v1/projects/${projectId}/sources/register`;
502
+ process.stderr.write(
503
+ `${LOG_PREFIX} registering projectId=${projectId} path=${normalizedRepoPath} ideType=${ideType ?? "(none)"}
504
+ `
491
505
  );
506
+ try {
507
+ await client.post(primaryPath, body, {
508
+ acceptStatuses: [409],
509
+ log: false,
510
+ quietHttpStatuses: [404, 405, 501]
511
+ });
512
+ process.stderr.write(`${LOG_PREFIX} ok: POST ${primaryPath}
513
+ `);
514
+ return;
515
+ } catch (err) {
516
+ if (err instanceof MemoraOneHttpError && (err.status === 404 || err.status === 405 || err.status === 501)) {
517
+ process.stderr.write(
518
+ `${LOG_PREFIX} primary route returned ${err.status}; retrying POST ${alternatePath}
519
+ `
520
+ );
521
+ await client.post(alternatePath, body, { acceptStatuses: [409], log: false });
522
+ process.stderr.write(`${LOG_PREFIX} ok: POST ${alternatePath}
523
+ `);
524
+ return;
525
+ }
526
+ throw err;
527
+ }
492
528
  } catch (err) {
493
- console.error(
494
- `[memoraone-mcp DEBUG registerRepoSource] POST threw endpoint=${endpointPath} message=${String(err?.message ?? err)}`
495
- );
529
+ const msg = String(err?.message ?? err);
530
+ process.stderr.write(`${LOG_PREFIX} failed: ${msg}
531
+ `);
496
532
  if (err instanceof MemoraOneHttpError) {
497
533
  const bodyStr = typeof err.body === "string" ? err.body : JSON.stringify(err.body ?? null);
498
- console.error(
499
- `[memoraone-mcp DEBUG registerRepoSource] MemoraOneHttpError status=${err.status} body=${bodyStr}`
534
+ process.stderr.write(
535
+ `${LOG_PREFIX} http status=${err.status} body=${bodyStr.length > 500 ? bodyStr.slice(0, 500) + "..." : bodyStr}
536
+ `
500
537
  );
501
538
  }
502
- console.warn("[memoraone-mcp] registerRepoSource failed:", err);
503
539
  }
504
540
  }
505
541
 
@@ -515,80 +551,106 @@ var postEventShape = {
515
551
  metadata: import_v42.z.record(import_v42.z.string(), import_v42.z.any()).optional()
516
552
  };
517
553
 
518
- // src/tools/askWithMemory.ts
554
+ // src/tools/createFact.ts
519
555
  var import_v43 = require("zod/v4");
556
+ var createFactShape = {
557
+ content: import_v43.z.string().min(1).describe("Explicit fact text to persist for the current project"),
558
+ metadata: import_v43.z.record(import_v43.z.string(), import_v43.z.any()).optional()
559
+ };
560
+
561
+ // src/tools/addPersonalContext.ts
562
+ var import_v44 = require("zod/v4");
563
+ var addPersonalContextShape = {
564
+ content: import_v44.z.string().min(1).describe("Text to store (note, preference, or similar)"),
565
+ category: import_v44.z.string().optional().describe("Optional category label"),
566
+ tags: import_v44.z.array(import_v44.z.string()).optional().describe("Optional tags"),
567
+ scope_type: import_v44.z.enum(["general", "project"]).optional(),
568
+ scope_id: import_v44.z.string().optional()
569
+ };
570
+
571
+ // src/tools/getPersonalContext.ts
572
+ var import_v45 = require("zod/v4");
573
+ var getPersonalContextShape = {
574
+ query: import_v45.z.string().optional().describe("Search query; sent as q when set"),
575
+ scope_type: import_v45.z.enum(["general", "project"]).optional(),
576
+ scope_id: import_v45.z.string().optional(),
577
+ limit: import_v45.z.number().int().positive().optional().describe("Max items to return")
578
+ };
579
+
580
+ // src/tools/askWithMemory.ts
581
+ var import_v46 = require("zod/v4");
520
582
  var askWithMemoryShape = {
521
- question: import_v43.z.string().min(1),
522
- code_context: import_v43.z.object({
523
- file_path: import_v43.z.string().optional(),
524
- selected_text: import_v43.z.string().optional(),
525
- language: import_v43.z.string().optional()
583
+ question: import_v46.z.string().min(1),
584
+ code_context: import_v46.z.object({
585
+ file_path: import_v46.z.string().optional(),
586
+ selected_text: import_v46.z.string().optional(),
587
+ language: import_v46.z.string().optional()
526
588
  }).optional()
527
589
  };
528
590
 
529
591
  // src/tools/logIntent.ts
530
- var import_v44 = require("zod/v4");
592
+ var import_v47 = require("zod/v4");
531
593
  var logIntentShape = {
532
- intent: import_v44.z.enum(["task", "decision"]),
533
- message: import_v44.z.string().min(1),
534
- context: import_v44.z.record(import_v44.z.string(), import_v44.z.any()).optional(),
535
- intent_source: import_v44.z.string().optional().default("cursor_chat"),
536
- run_id: import_v44.z.string().min(1).optional()
594
+ intent: import_v47.z.enum(["task", "decision"]),
595
+ message: import_v47.z.string().min(1),
596
+ context: import_v47.z.record(import_v47.z.string(), import_v47.z.any()).optional(),
597
+ intent_source: import_v47.z.string().optional().default("cursor_chat"),
598
+ run_id: import_v47.z.string().min(1).optional()
537
599
  };
538
600
 
539
601
  // src/tools/logChangeSummary.ts
540
- var import_v45 = require("zod/v4");
602
+ var import_v48 = require("zod/v4");
541
603
  var logChangeSummaryShape = {
542
- summary: import_v45.z.string().min(1),
543
- scope: import_v45.z.string().min(1).optional(),
544
- files: import_v45.z.array(import_v45.z.string().min(1)).optional(),
545
- stats: import_v45.z.object({
546
- files: import_v45.z.number().int().nonnegative().optional(),
547
- add: import_v45.z.number().int().nonnegative().optional(),
548
- del: import_v45.z.number().int().nonnegative().optional()
604
+ summary: import_v48.z.string().min(1),
605
+ scope: import_v48.z.string().min(1).optional(),
606
+ files: import_v48.z.array(import_v48.z.string().min(1)).optional(),
607
+ stats: import_v48.z.object({
608
+ files: import_v48.z.number().int().nonnegative().optional(),
609
+ add: import_v48.z.number().int().nonnegative().optional(),
610
+ del: import_v48.z.number().int().nonnegative().optional()
549
611
  }).optional(),
550
- commit: import_v45.z.string().min(1).optional(),
551
- run_id: import_v45.z.string().min(1).optional()
612
+ commit: import_v48.z.string().min(1).optional(),
613
+ run_id: import_v48.z.string().min(1).optional()
552
614
  };
553
615
 
554
616
  // src/tools/logToolResult.ts
555
- var import_v46 = require("zod/v4");
617
+ var import_v49 = require("zod/v4");
556
618
  var logToolResultShape = {
557
- tool: import_v46.z.string().min(1),
558
- status: import_v46.z.enum(["ok", "error", "partial"]),
559
- summary: import_v46.z.string().min(1),
560
- run_id: import_v46.z.string().min(1).optional(),
561
- duration_ms: import_v46.z.number().int().nonnegative().optional(),
562
- error_code: import_v46.z.string().min(1).optional(),
563
- error_message: import_v46.z.string().min(1).optional(),
564
- error_kind: import_v46.z.enum(["infra", "logic", "auth", "rate_limit", "validation", "unknown"]).optional(),
565
- stats: import_v46.z.record(import_v46.z.string(), import_v46.z.any()).optional()
619
+ tool: import_v49.z.string().min(1),
620
+ status: import_v49.z.enum(["ok", "error", "partial"]),
621
+ summary: import_v49.z.string().min(1),
622
+ run_id: import_v49.z.string().min(1).optional(),
623
+ duration_ms: import_v49.z.number().int().nonnegative().optional(),
624
+ error_code: import_v49.z.string().min(1).optional(),
625
+ error_message: import_v49.z.string().min(1).optional(),
626
+ error_kind: import_v49.z.enum(["infra", "logic", "auth", "rate_limit", "validation", "unknown"]).optional(),
627
+ stats: import_v49.z.record(import_v49.z.string(), import_v49.z.any()).optional()
566
628
  };
567
629
 
568
630
  // src/tools/logCommand.ts
569
- var import_v47 = require("zod/v4");
631
+ var import_v410 = require("zod/v4");
570
632
  var logCommandShape = {
571
- cmd: import_v47.z.string().min(1),
572
- summary: import_v47.z.string().min(1),
573
- cwd: import_v47.z.string().min(1).optional(),
574
- exit_code: import_v47.z.number().int().optional(),
575
- duration_ms: import_v47.z.number().int().nonnegative().optional(),
576
- run_id: import_v47.z.string().min(1).optional(),
577
- stats: import_v47.z.record(import_v47.z.string(), import_v47.z.any()).optional()
633
+ cmd: import_v410.z.string().min(1),
634
+ summary: import_v410.z.string().min(1),
635
+ cwd: import_v410.z.string().min(1).optional(),
636
+ exit_code: import_v410.z.number().int().optional(),
637
+ duration_ms: import_v410.z.number().int().nonnegative().optional(),
638
+ run_id: import_v410.z.string().min(1).optional(),
639
+ stats: import_v410.z.record(import_v410.z.string(), import_v410.z.any()).optional()
578
640
  };
579
641
 
580
642
  // src/tools/listProjects.ts
581
643
  var listProjectsShape = {};
582
644
 
583
645
  // src/tools/setProject.ts
584
- var import_v48 = require("zod/v4");
646
+ var import_v411 = require("zod/v4");
585
647
  var setProjectShape = {
586
- projectKey: import_v48.z.string().min(1).optional(),
587
- projectId: import_v48.z.string().min(1).optional()
648
+ projectKey: import_v411.z.string().min(1).optional(),
649
+ projectId: import_v411.z.string().min(1).optional()
588
650
  };
589
651
 
590
652
  // src/tools/handlers/postEvent.ts
591
- var import_v49 = require("zod/v4");
653
+ var import_v412 = require("zod/v4");
592
654
  var crypto3 = __toESM(require("crypto"), 1);
593
655
 
594
656
  // src/runContext.ts
@@ -650,14 +712,14 @@ function generateRunId() {
650
712
  }
651
713
 
652
714
  // src/tools/handlers/postEvent.ts
653
- var postEventInputSchema = import_v49.z.object({
654
- kind: import_v49.z.string().min(1),
655
- actor: import_v49.z.object({
656
- identifier: import_v49.z.string().min(1),
657
- id: import_v49.z.string().min(1).optional()
715
+ var postEventInputSchema = import_v412.z.object({
716
+ kind: import_v412.z.string().min(1),
717
+ actor: import_v412.z.object({
718
+ identifier: import_v412.z.string().min(1),
719
+ id: import_v412.z.string().min(1).optional()
658
720
  }),
659
- content: import_v49.z.record(import_v49.z.string(), import_v49.z.any()),
660
- metadata: import_v49.z.record(import_v49.z.string(), import_v49.z.any()).optional()
721
+ content: import_v412.z.record(import_v412.z.string(), import_v412.z.any()),
722
+ metadata: import_v412.z.record(import_v412.z.string(), import_v412.z.any()).optional()
661
723
  });
662
724
  async function handlePostEvent(client, args) {
663
725
  const nonce = crypto3.randomBytes(8).toString("hex");
@@ -699,14 +761,144 @@ async function handlePostEvent(client, args) {
699
761
  return { ok: true, forwarded: true };
700
762
  }
701
763
 
764
+ // src/tools/handlers/createFact.ts
765
+ var import_v413 = require("zod/v4");
766
+ var createFactInputSchema = import_v413.z.object({
767
+ content: import_v413.z.string().min(1),
768
+ metadata: import_v413.z.record(import_v413.z.string(), import_v413.z.any()).optional()
769
+ });
770
+ async function handleCreateFact(client, args) {
771
+ const parsed2 = createFactInputSchema.parse(args ?? {});
772
+ const projectKey = getCurrentProjectId();
773
+ if (!projectKey) {
774
+ throw new Error("No project selected. Use memora_list_projects and memora_set_project to select a project.");
775
+ }
776
+ const content = parsed2.content.trim();
777
+ if (!content) {
778
+ throw new Error("content cannot be empty after trimming");
779
+ }
780
+ const { tags: userTagsRaw, ...userMetaRest } = parsed2.metadata ?? {};
781
+ const userTags = Array.isArray(userTagsRaw) ? userTagsRaw.filter((t) => typeof t === "string") : [];
782
+ const tags = ["explicit_fact", ...userTags.filter((t) => t !== "explicit_fact")];
783
+ const body = {
784
+ projectKey,
785
+ content,
786
+ metadata: {
787
+ ...userMetaRest,
788
+ source: "memoraone-mcp",
789
+ purpose: "explicit_fact",
790
+ schema: "v1",
791
+ tool: "memora_create_fact",
792
+ agent_identifier: config2.agentName,
793
+ tags
794
+ }
795
+ };
796
+ try {
797
+ const result = await client.post("/facts", body);
798
+ return { ok: true, result };
799
+ } catch (err) {
800
+ if (err instanceof MemoraOneHttpError) {
801
+ const bodyText = typeof err.body === "string" ? err.body : JSON.stringify(err.body ?? "");
802
+ throw new Error(
803
+ `memora_create_fact failed: ${err.status} ${err.message} ${bodyText}`.trim()
804
+ );
805
+ }
806
+ throw err;
807
+ }
808
+ }
809
+
810
+ // src/tools/handlers/addPersonalContext.ts
811
+ var import_v414 = require("zod/v4");
812
+ var addPersonalContextInputSchema = import_v414.z.object({
813
+ content: import_v414.z.string().min(1),
814
+ category: import_v414.z.string().optional(),
815
+ tags: import_v414.z.array(import_v414.z.string()).optional(),
816
+ scope_type: import_v414.z.enum(["general", "project"]).optional(),
817
+ scope_id: import_v414.z.string().optional()
818
+ });
819
+ async function handleAddPersonalContext(client, args) {
820
+ const parsed2 = addPersonalContextInputSchema.parse(args ?? {});
821
+ const content = parsed2.content.trim();
822
+ if (!content) {
823
+ throw new Error("content cannot be empty after trimming");
824
+ }
825
+ const body = { content };
826
+ if (parsed2.category !== void 0 && parsed2.category.trim() !== "") {
827
+ body.category = parsed2.category.trim();
828
+ }
829
+ if (parsed2.tags !== void 0 && parsed2.tags.length > 0) {
830
+ body.tags = parsed2.tags;
831
+ }
832
+ if (parsed2.scope_type !== void 0) {
833
+ body.scope_type = parsed2.scope_type;
834
+ }
835
+ if (parsed2.scope_id !== void 0 && parsed2.scope_id.trim() !== "") {
836
+ body.scope_id = parsed2.scope_id.trim();
837
+ }
838
+ try {
839
+ const result = await client.post("/v1/personal-context", body);
840
+ return { ok: true, result };
841
+ } catch (err) {
842
+ if (err instanceof MemoraOneHttpError) {
843
+ const bodyText = typeof err.body === "string" ? err.body : JSON.stringify(err.body ?? "");
844
+ throw new Error(
845
+ `memora_add_personal_context failed: ${err.status} ${err.message} ${bodyText}`.trim()
846
+ );
847
+ }
848
+ throw err;
849
+ }
850
+ }
851
+
852
+ // src/tools/handlers/getPersonalContext.ts
853
+ var import_v415 = require("zod/v4");
854
+ var getPersonalContextInputSchema = import_v415.z.object({
855
+ query: import_v415.z.string().optional(),
856
+ scope_type: import_v415.z.enum(["general", "project"]).optional(),
857
+ scope_id: import_v415.z.string().optional(),
858
+ limit: import_v415.z.number().int().positive().optional()
859
+ });
860
+ function buildPersonalContextPath(parsed2) {
861
+ const params = new URLSearchParams();
862
+ if (parsed2.query !== void 0 && parsed2.query.trim() !== "") {
863
+ params.set("q", parsed2.query.trim());
864
+ }
865
+ if (parsed2.scope_type !== void 0) {
866
+ params.set("scope_type", parsed2.scope_type);
867
+ }
868
+ if (parsed2.scope_id !== void 0 && parsed2.scope_id.trim() !== "") {
869
+ params.set("scope_id", parsed2.scope_id.trim());
870
+ }
871
+ if (parsed2.limit !== void 0) {
872
+ params.set("limit", String(parsed2.limit));
873
+ }
874
+ const qs = params.toString();
875
+ return qs ? `/v1/personal-context?${qs}` : "/v1/personal-context";
876
+ }
877
+ async function handleGetPersonalContext(client, args) {
878
+ const parsed2 = getPersonalContextInputSchema.parse(args ?? {});
879
+ const path8 = buildPersonalContextPath(parsed2);
880
+ try {
881
+ const result = await client.get(path8);
882
+ return { ok: true, result };
883
+ } catch (err) {
884
+ if (err instanceof MemoraOneHttpError) {
885
+ const bodyText = typeof err.body === "string" ? err.body : JSON.stringify(err.body ?? "");
886
+ throw new Error(
887
+ `memora_get_personal_context failed: ${err.status} ${err.message} ${bodyText}`.trim()
888
+ );
889
+ }
890
+ throw err;
891
+ }
892
+ }
893
+
702
894
  // src/tools/handlers/askWithMemory.ts
703
- var import_v410 = require("zod/v4");
704
- var askWithMemoryInputSchema = import_v410.z.object({
705
- question: import_v410.z.string().min(1),
706
- code_context: import_v410.z.object({
707
- file_path: import_v410.z.string().optional(),
708
- selected_text: import_v410.z.string().optional(),
709
- language: import_v410.z.string().optional()
895
+ var import_v416 = require("zod/v4");
896
+ var askWithMemoryInputSchema = import_v416.z.object({
897
+ question: import_v416.z.string().min(1),
898
+ code_context: import_v416.z.object({
899
+ file_path: import_v416.z.string().optional(),
900
+ selected_text: import_v416.z.string().optional(),
901
+ language: import_v416.z.string().optional()
710
902
  }).optional()
711
903
  });
712
904
  function isAskWithMemoryResponse(value) {
@@ -739,13 +931,13 @@ async function handleAskWithMemory(client, args) {
739
931
  }
740
932
 
741
933
  // src/tools/handlers/logIntent.ts
742
- var import_v411 = require("zod/v4");
743
- var logIntentInputSchema = import_v411.z.object({
744
- intent: import_v411.z.enum(["task", "decision"]),
745
- message: import_v411.z.string().min(1),
746
- context: import_v411.z.record(import_v411.z.string(), import_v411.z.any()).optional(),
747
- intent_source: import_v411.z.string().optional().default("cursor_chat"),
748
- run_id: import_v411.z.string().min(1).optional()
934
+ var import_v417 = require("zod/v4");
935
+ var logIntentInputSchema = import_v417.z.object({
936
+ intent: import_v417.z.enum(["task", "decision"]),
937
+ message: import_v417.z.string().min(1),
938
+ context: import_v417.z.record(import_v417.z.string(), import_v417.z.any()).optional(),
939
+ intent_source: import_v417.z.string().optional().default("cursor_chat"),
940
+ run_id: import_v417.z.string().min(1).optional()
749
941
  });
750
942
  async function handleLogIntent(client, args) {
751
943
  const parsed2 = logIntentInputSchema.parse(args ?? {});
@@ -785,18 +977,18 @@ async function handleLogIntent(client, args) {
785
977
  }
786
978
 
787
979
  // src/tools/handlers/logChangeSummary.ts
788
- var import_v412 = require("zod/v4");
789
- var logChangeSummaryInputSchema = import_v412.z.object({
790
- summary: import_v412.z.string().min(1),
791
- scope: import_v412.z.string().min(1).optional(),
792
- files: import_v412.z.array(import_v412.z.string().min(1)).optional(),
793
- stats: import_v412.z.object({
794
- files: import_v412.z.number().int().nonnegative().optional(),
795
- add: import_v412.z.number().int().nonnegative().optional(),
796
- del: import_v412.z.number().int().nonnegative().optional()
980
+ var import_v418 = require("zod/v4");
981
+ var logChangeSummaryInputSchema = import_v418.z.object({
982
+ summary: import_v418.z.string().min(1),
983
+ scope: import_v418.z.string().min(1).optional(),
984
+ files: import_v418.z.array(import_v418.z.string().min(1)).optional(),
985
+ stats: import_v418.z.object({
986
+ files: import_v418.z.number().int().nonnegative().optional(),
987
+ add: import_v418.z.number().int().nonnegative().optional(),
988
+ del: import_v418.z.number().int().nonnegative().optional()
797
989
  }).optional(),
798
- commit: import_v412.z.string().min(1).optional(),
799
- run_id: import_v412.z.string().min(1).optional()
990
+ commit: import_v418.z.string().min(1).optional(),
991
+ run_id: import_v418.z.string().min(1).optional()
800
992
  });
801
993
  async function handleLogChangeSummary(client, args) {
802
994
  const parsed2 = logChangeSummaryInputSchema.parse(args ?? {});
@@ -829,17 +1021,17 @@ async function handleLogChangeSummary(client, args) {
829
1021
  }
830
1022
 
831
1023
  // src/tools/handlers/logToolResult.ts
832
- var import_v413 = require("zod/v4");
833
- var logToolResultInputSchema = import_v413.z.object({
834
- tool: import_v413.z.string().min(1),
835
- status: import_v413.z.enum(["ok", "error", "partial"]),
836
- summary: import_v413.z.string().min(1),
837
- run_id: import_v413.z.string().min(1).optional(),
838
- duration_ms: import_v413.z.number().int().nonnegative().optional(),
839
- error_code: import_v413.z.string().min(1).optional(),
840
- error_message: import_v413.z.string().min(1).optional(),
841
- error_kind: import_v413.z.enum(["infra", "logic", "auth", "rate_limit", "validation", "unknown"]).optional(),
842
- stats: import_v413.z.record(import_v413.z.string(), import_v413.z.any()).optional()
1024
+ var import_v419 = require("zod/v4");
1025
+ var logToolResultInputSchema = import_v419.z.object({
1026
+ tool: import_v419.z.string().min(1),
1027
+ status: import_v419.z.enum(["ok", "error", "partial"]),
1028
+ summary: import_v419.z.string().min(1),
1029
+ run_id: import_v419.z.string().min(1).optional(),
1030
+ duration_ms: import_v419.z.number().int().nonnegative().optional(),
1031
+ error_code: import_v419.z.string().min(1).optional(),
1032
+ error_message: import_v419.z.string().min(1).optional(),
1033
+ error_kind: import_v419.z.enum(["infra", "logic", "auth", "rate_limit", "validation", "unknown"]).optional(),
1034
+ stats: import_v419.z.record(import_v419.z.string(), import_v419.z.any()).optional()
843
1035
  });
844
1036
  async function handleLogToolResult(client, args) {
845
1037
  const parsed2 = logToolResultInputSchema.parse(args ?? {});
@@ -875,15 +1067,15 @@ async function handleLogToolResult(client, args) {
875
1067
  }
876
1068
 
877
1069
  // src/tools/handlers/logCommand.ts
878
- var import_v414 = require("zod/v4");
879
- var logCommandInputSchema = import_v414.z.object({
880
- cmd: import_v414.z.string().min(1),
881
- summary: import_v414.z.string().min(1),
882
- cwd: import_v414.z.string().min(1).optional(),
883
- exit_code: import_v414.z.number().int().optional(),
884
- duration_ms: import_v414.z.number().int().nonnegative().optional(),
885
- run_id: import_v414.z.string().min(1).optional(),
886
- stats: import_v414.z.record(import_v414.z.string(), import_v414.z.any()).optional()
1070
+ var import_v420 = require("zod/v4");
1071
+ var logCommandInputSchema = import_v420.z.object({
1072
+ cmd: import_v420.z.string().min(1),
1073
+ summary: import_v420.z.string().min(1),
1074
+ cwd: import_v420.z.string().min(1).optional(),
1075
+ exit_code: import_v420.z.number().int().optional(),
1076
+ duration_ms: import_v420.z.number().int().nonnegative().optional(),
1077
+ run_id: import_v420.z.string().min(1).optional(),
1078
+ stats: import_v420.z.record(import_v420.z.string(), import_v420.z.any()).optional()
887
1079
  });
888
1080
  async function handleLogCommand(client, args) {
889
1081
  const parsed2 = logCommandInputSchema.parse(args ?? {});
@@ -923,7 +1115,7 @@ async function handleListProjects(client) {
923
1115
  }
924
1116
 
925
1117
  // src/tools/handlers/setProject.ts
926
- var import_v415 = require("zod/v4");
1118
+ var import_v421 = require("zod/v4");
927
1119
 
928
1120
  // src/repoFingerprint.ts
929
1121
  var fs4 = __toESM(require("fs"), 1);
@@ -1083,6 +1275,7 @@ async function acquireWorkspaceMapLock() {
1083
1275
  const maxRetries = 10;
1084
1276
  const retryDelayMs = 50;
1085
1277
  const maxLockAgeMs = 5e3;
1278
+ await ensureWorkspaceDir();
1086
1279
  let lockAcquired = false;
1087
1280
  let retries = 0;
1088
1281
  while (!lockAcquired && retries < maxRetries) {
@@ -1251,9 +1444,9 @@ async function setProjectIdForFingerprint(args) {
1251
1444
  }
1252
1445
 
1253
1446
  // src/tools/handlers/setProject.ts
1254
- var setProjectInputSchema = import_v415.z.object({
1255
- projectKey: import_v415.z.string().min(1).optional(),
1256
- projectId: import_v415.z.string().min(1).optional()
1447
+ var setProjectInputSchema = import_v421.z.object({
1448
+ projectKey: import_v421.z.string().min(1).optional(),
1449
+ projectId: import_v421.z.string().min(1).optional()
1257
1450
  });
1258
1451
  async function handleSetProject(args) {
1259
1452
  const parsed2 = setProjectInputSchema.parse(args ?? {});
@@ -1521,6 +1714,45 @@ async function main(opts = {}) {
1521
1714
  })
1522
1715
  );
1523
1716
  registeredToolNames.push("memora_post_event");
1717
+ server.tool(
1718
+ "memora_create_fact",
1719
+ "Create an explicit project-scoped fact (POST /facts)",
1720
+ createFactShape,
1721
+ async (args) => runWithSessionContext(sessionContext, async () => {
1722
+ if (!runtime.client || !runtime.projectId) return notInitializedResult;
1723
+ const result = await handleCreateFact(runtime.client, args);
1724
+ return {
1725
+ content: [{ type: "text", text: JSON.stringify(result) }]
1726
+ };
1727
+ })
1728
+ );
1729
+ registeredToolNames.push("memora_create_fact");
1730
+ server.tool(
1731
+ "memora_add_personal_context",
1732
+ "Store notes or preferences for this workspace (POST /v1/personal-context)",
1733
+ addPersonalContextShape,
1734
+ async (args) => runWithSessionContext(sessionContext, async () => {
1735
+ if (!runtime.client || !runtime.projectId) return notInitializedResult;
1736
+ const result = await handleAddPersonalContext(runtime.client, args);
1737
+ return {
1738
+ content: [{ type: "text", text: JSON.stringify(result) }]
1739
+ };
1740
+ })
1741
+ );
1742
+ registeredToolNames.push("memora_add_personal_context");
1743
+ server.tool(
1744
+ "memora_get_personal_context",
1745
+ "Search stored notes or preferences for this workspace (GET /v1/personal-context)",
1746
+ getPersonalContextShape,
1747
+ async (args) => runWithSessionContext(sessionContext, async () => {
1748
+ if (!runtime.client || !runtime.projectId) return notInitializedResult;
1749
+ const result = await handleGetPersonalContext(runtime.client, args);
1750
+ return {
1751
+ content: [{ type: "text", text: JSON.stringify(result) }]
1752
+ };
1753
+ })
1754
+ );
1755
+ registeredToolNames.push("memora_get_personal_context");
1524
1756
  server.tool(
1525
1757
  "memora_list_projects",
1526
1758
  "List projects available to the current API key",
@@ -1552,7 +1784,7 @@ async function main(opts = {}) {
1552
1784
  runtime,
1553
1785
  sessionContext,
1554
1786
  "memora_ask_with_memory",
1555
- "Ask MemoraOne with project memory context",
1787
+ "Answer using saved workspace knowledge and timeline. In user-visible replies, state facts directly; do not attribute answers to tools, storage, retrieval, or memory-style framing unless the user asks how you know.",
1556
1788
  askWithMemoryShape,
1557
1789
  async (args) => {
1558
1790
  const result = await handleAskWithMemory(runtime.client, args);
@@ -1699,10 +1931,16 @@ async function main(opts = {}) {
1699
1931
  runtime.apiKeyFingerprint = fingerprintApiKey(apiKeyToUse);
1700
1932
  runtime.client = new memoraClient_default(config2, projectId, apiKeyToUse);
1701
1933
  workspaceRoot = binding.workspaceRoot;
1702
- console.error(
1703
- `[memoraone-mcp DEBUG registerRepoSource] pre-register bindingSource=${binding.bindingSource} workspaceRoot=${JSON.stringify(binding.workspaceRoot)} m1Path=${JSON.stringify(binding.m1Path)} ideType=${runtime.ideType ?? "(none)"}`
1934
+ process.stderr.write(
1935
+ `[memoraone-mcp] registering workspace source bindingSource=${binding.bindingSource} workspaceRoot=${workspaceRoot ?? "(unset)"} m1Path=${binding.m1Path}
1936
+ `
1937
+ );
1938
+ await registerRepoSource(
1939
+ runtime.client,
1940
+ runtime.projectId,
1941
+ binding.workspaceRoot,
1942
+ runtime.ideType
1704
1943
  );
1705
- await registerRepoSource(runtime.client, runtime.projectId, workspaceRoot, runtime.ideType);
1706
1944
  if (debugAuth) {
1707
1945
  console.error("[memoraone-mcp][auth] repo root:", binding.workspaceRoot);
1708
1946
  console.error("[memoraone-mcp][auth] project_id:", projectId);