@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/index.cjs CHANGED
@@ -226,11 +226,18 @@ var MemoraClient = class {
226
226
  );
227
227
  }
228
228
  if (!res.ok) {
229
- const snippet = res.text.length > 200 ? `${res.text.slice(0, 200)}...` : res.text;
230
- process.stderr.write(
231
- `[memoraone-mcp][error] http error method=POST url=${url} status=${res.status} body=${snippet}
229
+ const accepted = options?.acceptStatuses?.includes(res.status);
230
+ if (accepted) {
231
+ return res.text ? JSON.parse(res.text) : null;
232
+ }
233
+ const quiet = options?.quietHttpStatuses?.includes(res.status);
234
+ if (!quiet) {
235
+ const snippet = res.text.length > 200 ? `${res.text.slice(0, 200)}...` : res.text;
236
+ process.stderr.write(
237
+ `[memoraone-mcp][error] http error method=POST url=${url} status=${res.status} body=${snippet}
232
238
  `
233
- );
239
+ );
240
+ }
234
241
  throw new MemoraOneHttpError(res.status, res.statusText, res.text);
235
242
  }
236
243
  console.error(
@@ -405,41 +412,70 @@ async function resolveAuthoritativeBinding(workspaceRoot) {
405
412
  // src/sourceRegistration.ts
406
413
  var path3 = __toESM(require("path"), 1);
407
414
  var import_node_url = require("url");
415
+ var LOG_PREFIX = "[memoraone-mcp][source-registration]";
416
+ function buildRepoSourcePayload(normalizedRepoPath, ideType) {
417
+ const body = {
418
+ kind: "repo",
419
+ label: path3.basename(normalizedRepoPath),
420
+ uri: (0, import_node_url.pathToFileURL)(normalizedRepoPath).href
421
+ };
422
+ if (ideType) {
423
+ body.metadata = {
424
+ ide_type: ideType
425
+ };
426
+ }
427
+ return body;
428
+ }
408
429
  async function registerRepoSource(client, projectId, repoPath, ideType) {
409
- const normalizedRepoPath = path3.resolve(repoPath);
410
- const endpointPath = `/v1/projects/${projectId}/sources`;
411
- console.error(
412
- `[memoraone-mcp DEBUG registerRepoSource] registerRepoSource() called projectId=${projectId} repoPath(raw)=${JSON.stringify(repoPath)} repoPath(normalized)=${JSON.stringify(normalizedRepoPath)} ideType=${ideType ?? "(none)"}`
413
- );
414
430
  try {
415
- const body = {
416
- kind: "repo",
417
- label: path3.basename(normalizedRepoPath),
418
- uri: (0, import_node_url.pathToFileURL)(normalizedRepoPath).href
419
- };
420
- if (ideType) {
421
- body.metadata = {
422
- ide_type: ideType
423
- };
431
+ if (repoPath === void 0 || repoPath === null || String(repoPath).trim() === "") {
432
+ process.stderr.write(
433
+ `${LOG_PREFIX} skipped: empty repoPath (cannot register workspace)
434
+ `
435
+ );
436
+ return;
424
437
  }
425
- console.error(
426
- `[memoraone-mcp DEBUG registerRepoSource] POST endpoint=${endpointPath} body=${JSON.stringify(body)}`
427
- );
428
- const result = await client.post(endpointPath, body);
429
- console.error(
430
- `[memoraone-mcp DEBUG registerRepoSource] POST succeeded endpoint=${endpointPath} responseSummary=${JSON.stringify(result)}`
438
+ const normalizedRepoPath = path3.resolve(String(repoPath));
439
+ const body = buildRepoSourcePayload(normalizedRepoPath, ideType);
440
+ const primaryPath = `/v1/projects/${projectId}/sources`;
441
+ const alternatePath = `/v1/projects/${projectId}/sources/register`;
442
+ process.stderr.write(
443
+ `${LOG_PREFIX} registering projectId=${projectId} path=${normalizedRepoPath} ideType=${ideType ?? "(none)"}
444
+ `
431
445
  );
446
+ try {
447
+ await client.post(primaryPath, body, {
448
+ acceptStatuses: [409],
449
+ log: false,
450
+ quietHttpStatuses: [404, 405, 501]
451
+ });
452
+ process.stderr.write(`${LOG_PREFIX} ok: POST ${primaryPath}
453
+ `);
454
+ return;
455
+ } catch (err) {
456
+ if (err instanceof MemoraOneHttpError && (err.status === 404 || err.status === 405 || err.status === 501)) {
457
+ process.stderr.write(
458
+ `${LOG_PREFIX} primary route returned ${err.status}; retrying POST ${alternatePath}
459
+ `
460
+ );
461
+ await client.post(alternatePath, body, { acceptStatuses: [409], log: false });
462
+ process.stderr.write(`${LOG_PREFIX} ok: POST ${alternatePath}
463
+ `);
464
+ return;
465
+ }
466
+ throw err;
467
+ }
432
468
  } catch (err) {
433
- console.error(
434
- `[memoraone-mcp DEBUG registerRepoSource] POST threw endpoint=${endpointPath} message=${String(err?.message ?? err)}`
435
- );
469
+ const msg = String(err?.message ?? err);
470
+ process.stderr.write(`${LOG_PREFIX} failed: ${msg}
471
+ `);
436
472
  if (err instanceof MemoraOneHttpError) {
437
473
  const bodyStr = typeof err.body === "string" ? err.body : JSON.stringify(err.body ?? null);
438
- console.error(
439
- `[memoraone-mcp DEBUG registerRepoSource] MemoraOneHttpError status=${err.status} body=${bodyStr}`
474
+ process.stderr.write(
475
+ `${LOG_PREFIX} http status=${err.status} body=${bodyStr.length > 500 ? bodyStr.slice(0, 500) + "..." : bodyStr}
476
+ `
440
477
  );
441
478
  }
442
- console.warn("[memoraone-mcp] registerRepoSource failed:", err);
443
479
  }
444
480
  }
445
481
 
@@ -455,80 +491,106 @@ var postEventShape = {
455
491
  metadata: import_v42.z.record(import_v42.z.string(), import_v42.z.any()).optional()
456
492
  };
457
493
 
458
- // src/tools/askWithMemory.ts
494
+ // src/tools/createFact.ts
459
495
  var import_v43 = require("zod/v4");
496
+ var createFactShape = {
497
+ content: import_v43.z.string().min(1).describe("Explicit fact text to persist for the current project"),
498
+ metadata: import_v43.z.record(import_v43.z.string(), import_v43.z.any()).optional()
499
+ };
500
+
501
+ // src/tools/addPersonalContext.ts
502
+ var import_v44 = require("zod/v4");
503
+ var addPersonalContextShape = {
504
+ content: import_v44.z.string().min(1).describe("Text to store (note, preference, or similar)"),
505
+ category: import_v44.z.string().optional().describe("Optional category label"),
506
+ tags: import_v44.z.array(import_v44.z.string()).optional().describe("Optional tags"),
507
+ scope_type: import_v44.z.enum(["general", "project"]).optional(),
508
+ scope_id: import_v44.z.string().optional()
509
+ };
510
+
511
+ // src/tools/getPersonalContext.ts
512
+ var import_v45 = require("zod/v4");
513
+ var getPersonalContextShape = {
514
+ query: import_v45.z.string().optional().describe("Search query; sent as q when set"),
515
+ scope_type: import_v45.z.enum(["general", "project"]).optional(),
516
+ scope_id: import_v45.z.string().optional(),
517
+ limit: import_v45.z.number().int().positive().optional().describe("Max items to return")
518
+ };
519
+
520
+ // src/tools/askWithMemory.ts
521
+ var import_v46 = require("zod/v4");
460
522
  var askWithMemoryShape = {
461
- question: import_v43.z.string().min(1),
462
- code_context: import_v43.z.object({
463
- file_path: import_v43.z.string().optional(),
464
- selected_text: import_v43.z.string().optional(),
465
- language: import_v43.z.string().optional()
523
+ question: import_v46.z.string().min(1),
524
+ code_context: import_v46.z.object({
525
+ file_path: import_v46.z.string().optional(),
526
+ selected_text: import_v46.z.string().optional(),
527
+ language: import_v46.z.string().optional()
466
528
  }).optional()
467
529
  };
468
530
 
469
531
  // src/tools/logIntent.ts
470
- var import_v44 = require("zod/v4");
532
+ var import_v47 = require("zod/v4");
471
533
  var logIntentShape = {
472
- intent: import_v44.z.enum(["task", "decision"]),
473
- message: import_v44.z.string().min(1),
474
- context: import_v44.z.record(import_v44.z.string(), import_v44.z.any()).optional(),
475
- intent_source: import_v44.z.string().optional().default("cursor_chat"),
476
- run_id: import_v44.z.string().min(1).optional()
534
+ intent: import_v47.z.enum(["task", "decision"]),
535
+ message: import_v47.z.string().min(1),
536
+ context: import_v47.z.record(import_v47.z.string(), import_v47.z.any()).optional(),
537
+ intent_source: import_v47.z.string().optional().default("cursor_chat"),
538
+ run_id: import_v47.z.string().min(1).optional()
477
539
  };
478
540
 
479
541
  // src/tools/logChangeSummary.ts
480
- var import_v45 = require("zod/v4");
542
+ var import_v48 = require("zod/v4");
481
543
  var logChangeSummaryShape = {
482
- summary: import_v45.z.string().min(1),
483
- scope: import_v45.z.string().min(1).optional(),
484
- files: import_v45.z.array(import_v45.z.string().min(1)).optional(),
485
- stats: import_v45.z.object({
486
- files: import_v45.z.number().int().nonnegative().optional(),
487
- add: import_v45.z.number().int().nonnegative().optional(),
488
- del: import_v45.z.number().int().nonnegative().optional()
544
+ summary: import_v48.z.string().min(1),
545
+ scope: import_v48.z.string().min(1).optional(),
546
+ files: import_v48.z.array(import_v48.z.string().min(1)).optional(),
547
+ stats: import_v48.z.object({
548
+ files: import_v48.z.number().int().nonnegative().optional(),
549
+ add: import_v48.z.number().int().nonnegative().optional(),
550
+ del: import_v48.z.number().int().nonnegative().optional()
489
551
  }).optional(),
490
- commit: import_v45.z.string().min(1).optional(),
491
- run_id: import_v45.z.string().min(1).optional()
552
+ commit: import_v48.z.string().min(1).optional(),
553
+ run_id: import_v48.z.string().min(1).optional()
492
554
  };
493
555
 
494
556
  // src/tools/logToolResult.ts
495
- var import_v46 = require("zod/v4");
557
+ var import_v49 = require("zod/v4");
496
558
  var logToolResultShape = {
497
- tool: import_v46.z.string().min(1),
498
- status: import_v46.z.enum(["ok", "error", "partial"]),
499
- summary: import_v46.z.string().min(1),
500
- run_id: import_v46.z.string().min(1).optional(),
501
- duration_ms: import_v46.z.number().int().nonnegative().optional(),
502
- error_code: import_v46.z.string().min(1).optional(),
503
- error_message: import_v46.z.string().min(1).optional(),
504
- error_kind: import_v46.z.enum(["infra", "logic", "auth", "rate_limit", "validation", "unknown"]).optional(),
505
- stats: import_v46.z.record(import_v46.z.string(), import_v46.z.any()).optional()
559
+ tool: import_v49.z.string().min(1),
560
+ status: import_v49.z.enum(["ok", "error", "partial"]),
561
+ summary: import_v49.z.string().min(1),
562
+ run_id: import_v49.z.string().min(1).optional(),
563
+ duration_ms: import_v49.z.number().int().nonnegative().optional(),
564
+ error_code: import_v49.z.string().min(1).optional(),
565
+ error_message: import_v49.z.string().min(1).optional(),
566
+ error_kind: import_v49.z.enum(["infra", "logic", "auth", "rate_limit", "validation", "unknown"]).optional(),
567
+ stats: import_v49.z.record(import_v49.z.string(), import_v49.z.any()).optional()
506
568
  };
507
569
 
508
570
  // src/tools/logCommand.ts
509
- var import_v47 = require("zod/v4");
571
+ var import_v410 = require("zod/v4");
510
572
  var logCommandShape = {
511
- cmd: import_v47.z.string().min(1),
512
- summary: import_v47.z.string().min(1),
513
- cwd: import_v47.z.string().min(1).optional(),
514
- exit_code: import_v47.z.number().int().optional(),
515
- duration_ms: import_v47.z.number().int().nonnegative().optional(),
516
- run_id: import_v47.z.string().min(1).optional(),
517
- stats: import_v47.z.record(import_v47.z.string(), import_v47.z.any()).optional()
573
+ cmd: import_v410.z.string().min(1),
574
+ summary: import_v410.z.string().min(1),
575
+ cwd: import_v410.z.string().min(1).optional(),
576
+ exit_code: import_v410.z.number().int().optional(),
577
+ duration_ms: import_v410.z.number().int().nonnegative().optional(),
578
+ run_id: import_v410.z.string().min(1).optional(),
579
+ stats: import_v410.z.record(import_v410.z.string(), import_v410.z.any()).optional()
518
580
  };
519
581
 
520
582
  // src/tools/listProjects.ts
521
583
  var listProjectsShape = {};
522
584
 
523
585
  // src/tools/setProject.ts
524
- var import_v48 = require("zod/v4");
586
+ var import_v411 = require("zod/v4");
525
587
  var setProjectShape = {
526
- projectKey: import_v48.z.string().min(1).optional(),
527
- projectId: import_v48.z.string().min(1).optional()
588
+ projectKey: import_v411.z.string().min(1).optional(),
589
+ projectId: import_v411.z.string().min(1).optional()
528
590
  };
529
591
 
530
592
  // src/tools/handlers/postEvent.ts
531
- var import_v49 = require("zod/v4");
593
+ var import_v412 = require("zod/v4");
532
594
  var crypto3 = __toESM(require("crypto"), 1);
533
595
 
534
596
  // src/runContext.ts
@@ -590,14 +652,14 @@ function generateRunId() {
590
652
  }
591
653
 
592
654
  // src/tools/handlers/postEvent.ts
593
- var postEventInputSchema = import_v49.z.object({
594
- kind: import_v49.z.string().min(1),
595
- actor: import_v49.z.object({
596
- identifier: import_v49.z.string().min(1),
597
- id: import_v49.z.string().min(1).optional()
655
+ var postEventInputSchema = import_v412.z.object({
656
+ kind: import_v412.z.string().min(1),
657
+ actor: import_v412.z.object({
658
+ identifier: import_v412.z.string().min(1),
659
+ id: import_v412.z.string().min(1).optional()
598
660
  }),
599
- content: import_v49.z.record(import_v49.z.string(), import_v49.z.any()),
600
- metadata: import_v49.z.record(import_v49.z.string(), import_v49.z.any()).optional()
661
+ content: import_v412.z.record(import_v412.z.string(), import_v412.z.any()),
662
+ metadata: import_v412.z.record(import_v412.z.string(), import_v412.z.any()).optional()
601
663
  });
602
664
  async function handlePostEvent(client, args) {
603
665
  const nonce = crypto3.randomBytes(8).toString("hex");
@@ -639,14 +701,144 @@ async function handlePostEvent(client, args) {
639
701
  return { ok: true, forwarded: true };
640
702
  }
641
703
 
704
+ // src/tools/handlers/createFact.ts
705
+ var import_v413 = require("zod/v4");
706
+ var createFactInputSchema = import_v413.z.object({
707
+ content: import_v413.z.string().min(1),
708
+ metadata: import_v413.z.record(import_v413.z.string(), import_v413.z.any()).optional()
709
+ });
710
+ async function handleCreateFact(client, args) {
711
+ const parsed2 = createFactInputSchema.parse(args ?? {});
712
+ const projectKey = getCurrentProjectId();
713
+ if (!projectKey) {
714
+ throw new Error("No project selected. Use memora_list_projects and memora_set_project to select a project.");
715
+ }
716
+ const content = parsed2.content.trim();
717
+ if (!content) {
718
+ throw new Error("content cannot be empty after trimming");
719
+ }
720
+ const { tags: userTagsRaw, ...userMetaRest } = parsed2.metadata ?? {};
721
+ const userTags = Array.isArray(userTagsRaw) ? userTagsRaw.filter((t) => typeof t === "string") : [];
722
+ const tags = ["explicit_fact", ...userTags.filter((t) => t !== "explicit_fact")];
723
+ const body = {
724
+ projectKey,
725
+ content,
726
+ metadata: {
727
+ ...userMetaRest,
728
+ source: "memoraone-mcp",
729
+ purpose: "explicit_fact",
730
+ schema: "v1",
731
+ tool: "memora_create_fact",
732
+ agent_identifier: config2.agentName,
733
+ tags
734
+ }
735
+ };
736
+ try {
737
+ const result = await client.post("/facts", body);
738
+ return { ok: true, result };
739
+ } catch (err) {
740
+ if (err instanceof MemoraOneHttpError) {
741
+ const bodyText = typeof err.body === "string" ? err.body : JSON.stringify(err.body ?? "");
742
+ throw new Error(
743
+ `memora_create_fact failed: ${err.status} ${err.message} ${bodyText}`.trim()
744
+ );
745
+ }
746
+ throw err;
747
+ }
748
+ }
749
+
750
+ // src/tools/handlers/addPersonalContext.ts
751
+ var import_v414 = require("zod/v4");
752
+ var addPersonalContextInputSchema = import_v414.z.object({
753
+ content: import_v414.z.string().min(1),
754
+ category: import_v414.z.string().optional(),
755
+ tags: import_v414.z.array(import_v414.z.string()).optional(),
756
+ scope_type: import_v414.z.enum(["general", "project"]).optional(),
757
+ scope_id: import_v414.z.string().optional()
758
+ });
759
+ async function handleAddPersonalContext(client, args) {
760
+ const parsed2 = addPersonalContextInputSchema.parse(args ?? {});
761
+ const content = parsed2.content.trim();
762
+ if (!content) {
763
+ throw new Error("content cannot be empty after trimming");
764
+ }
765
+ const body = { content };
766
+ if (parsed2.category !== void 0 && parsed2.category.trim() !== "") {
767
+ body.category = parsed2.category.trim();
768
+ }
769
+ if (parsed2.tags !== void 0 && parsed2.tags.length > 0) {
770
+ body.tags = parsed2.tags;
771
+ }
772
+ if (parsed2.scope_type !== void 0) {
773
+ body.scope_type = parsed2.scope_type;
774
+ }
775
+ if (parsed2.scope_id !== void 0 && parsed2.scope_id.trim() !== "") {
776
+ body.scope_id = parsed2.scope_id.trim();
777
+ }
778
+ try {
779
+ const result = await client.post("/v1/personal-context", body);
780
+ return { ok: true, result };
781
+ } catch (err) {
782
+ if (err instanceof MemoraOneHttpError) {
783
+ const bodyText = typeof err.body === "string" ? err.body : JSON.stringify(err.body ?? "");
784
+ throw new Error(
785
+ `memora_add_personal_context failed: ${err.status} ${err.message} ${bodyText}`.trim()
786
+ );
787
+ }
788
+ throw err;
789
+ }
790
+ }
791
+
792
+ // src/tools/handlers/getPersonalContext.ts
793
+ var import_v415 = require("zod/v4");
794
+ var getPersonalContextInputSchema = import_v415.z.object({
795
+ query: import_v415.z.string().optional(),
796
+ scope_type: import_v415.z.enum(["general", "project"]).optional(),
797
+ scope_id: import_v415.z.string().optional(),
798
+ limit: import_v415.z.number().int().positive().optional()
799
+ });
800
+ function buildPersonalContextPath(parsed2) {
801
+ const params = new URLSearchParams();
802
+ if (parsed2.query !== void 0 && parsed2.query.trim() !== "") {
803
+ params.set("q", parsed2.query.trim());
804
+ }
805
+ if (parsed2.scope_type !== void 0) {
806
+ params.set("scope_type", parsed2.scope_type);
807
+ }
808
+ if (parsed2.scope_id !== void 0 && parsed2.scope_id.trim() !== "") {
809
+ params.set("scope_id", parsed2.scope_id.trim());
810
+ }
811
+ if (parsed2.limit !== void 0) {
812
+ params.set("limit", String(parsed2.limit));
813
+ }
814
+ const qs = params.toString();
815
+ return qs ? `/v1/personal-context?${qs}` : "/v1/personal-context";
816
+ }
817
+ async function handleGetPersonalContext(client, args) {
818
+ const parsed2 = getPersonalContextInputSchema.parse(args ?? {});
819
+ const path7 = buildPersonalContextPath(parsed2);
820
+ try {
821
+ const result = await client.get(path7);
822
+ return { ok: true, result };
823
+ } catch (err) {
824
+ if (err instanceof MemoraOneHttpError) {
825
+ const bodyText = typeof err.body === "string" ? err.body : JSON.stringify(err.body ?? "");
826
+ throw new Error(
827
+ `memora_get_personal_context failed: ${err.status} ${err.message} ${bodyText}`.trim()
828
+ );
829
+ }
830
+ throw err;
831
+ }
832
+ }
833
+
642
834
  // src/tools/handlers/askWithMemory.ts
643
- var import_v410 = require("zod/v4");
644
- var askWithMemoryInputSchema = import_v410.z.object({
645
- question: import_v410.z.string().min(1),
646
- code_context: import_v410.z.object({
647
- file_path: import_v410.z.string().optional(),
648
- selected_text: import_v410.z.string().optional(),
649
- language: import_v410.z.string().optional()
835
+ var import_v416 = require("zod/v4");
836
+ var askWithMemoryInputSchema = import_v416.z.object({
837
+ question: import_v416.z.string().min(1),
838
+ code_context: import_v416.z.object({
839
+ file_path: import_v416.z.string().optional(),
840
+ selected_text: import_v416.z.string().optional(),
841
+ language: import_v416.z.string().optional()
650
842
  }).optional()
651
843
  });
652
844
  function isAskWithMemoryResponse(value) {
@@ -679,13 +871,13 @@ async function handleAskWithMemory(client, args) {
679
871
  }
680
872
 
681
873
  // src/tools/handlers/logIntent.ts
682
- var import_v411 = require("zod/v4");
683
- var logIntentInputSchema = import_v411.z.object({
684
- intent: import_v411.z.enum(["task", "decision"]),
685
- message: import_v411.z.string().min(1),
686
- context: import_v411.z.record(import_v411.z.string(), import_v411.z.any()).optional(),
687
- intent_source: import_v411.z.string().optional().default("cursor_chat"),
688
- run_id: import_v411.z.string().min(1).optional()
874
+ var import_v417 = require("zod/v4");
875
+ var logIntentInputSchema = import_v417.z.object({
876
+ intent: import_v417.z.enum(["task", "decision"]),
877
+ message: import_v417.z.string().min(1),
878
+ context: import_v417.z.record(import_v417.z.string(), import_v417.z.any()).optional(),
879
+ intent_source: import_v417.z.string().optional().default("cursor_chat"),
880
+ run_id: import_v417.z.string().min(1).optional()
689
881
  });
690
882
  async function handleLogIntent(client, args) {
691
883
  const parsed2 = logIntentInputSchema.parse(args ?? {});
@@ -725,18 +917,18 @@ async function handleLogIntent(client, args) {
725
917
  }
726
918
 
727
919
  // src/tools/handlers/logChangeSummary.ts
728
- var import_v412 = require("zod/v4");
729
- var logChangeSummaryInputSchema = import_v412.z.object({
730
- summary: import_v412.z.string().min(1),
731
- scope: import_v412.z.string().min(1).optional(),
732
- files: import_v412.z.array(import_v412.z.string().min(1)).optional(),
733
- stats: import_v412.z.object({
734
- files: import_v412.z.number().int().nonnegative().optional(),
735
- add: import_v412.z.number().int().nonnegative().optional(),
736
- del: import_v412.z.number().int().nonnegative().optional()
920
+ var import_v418 = require("zod/v4");
921
+ var logChangeSummaryInputSchema = import_v418.z.object({
922
+ summary: import_v418.z.string().min(1),
923
+ scope: import_v418.z.string().min(1).optional(),
924
+ files: import_v418.z.array(import_v418.z.string().min(1)).optional(),
925
+ stats: import_v418.z.object({
926
+ files: import_v418.z.number().int().nonnegative().optional(),
927
+ add: import_v418.z.number().int().nonnegative().optional(),
928
+ del: import_v418.z.number().int().nonnegative().optional()
737
929
  }).optional(),
738
- commit: import_v412.z.string().min(1).optional(),
739
- run_id: import_v412.z.string().min(1).optional()
930
+ commit: import_v418.z.string().min(1).optional(),
931
+ run_id: import_v418.z.string().min(1).optional()
740
932
  });
741
933
  async function handleLogChangeSummary(client, args) {
742
934
  const parsed2 = logChangeSummaryInputSchema.parse(args ?? {});
@@ -769,17 +961,17 @@ async function handleLogChangeSummary(client, args) {
769
961
  }
770
962
 
771
963
  // src/tools/handlers/logToolResult.ts
772
- var import_v413 = require("zod/v4");
773
- var logToolResultInputSchema = import_v413.z.object({
774
- tool: import_v413.z.string().min(1),
775
- status: import_v413.z.enum(["ok", "error", "partial"]),
776
- summary: import_v413.z.string().min(1),
777
- run_id: import_v413.z.string().min(1).optional(),
778
- duration_ms: import_v413.z.number().int().nonnegative().optional(),
779
- error_code: import_v413.z.string().min(1).optional(),
780
- error_message: import_v413.z.string().min(1).optional(),
781
- error_kind: import_v413.z.enum(["infra", "logic", "auth", "rate_limit", "validation", "unknown"]).optional(),
782
- stats: import_v413.z.record(import_v413.z.string(), import_v413.z.any()).optional()
964
+ var import_v419 = require("zod/v4");
965
+ var logToolResultInputSchema = import_v419.z.object({
966
+ tool: import_v419.z.string().min(1),
967
+ status: import_v419.z.enum(["ok", "error", "partial"]),
968
+ summary: import_v419.z.string().min(1),
969
+ run_id: import_v419.z.string().min(1).optional(),
970
+ duration_ms: import_v419.z.number().int().nonnegative().optional(),
971
+ error_code: import_v419.z.string().min(1).optional(),
972
+ error_message: import_v419.z.string().min(1).optional(),
973
+ error_kind: import_v419.z.enum(["infra", "logic", "auth", "rate_limit", "validation", "unknown"]).optional(),
974
+ stats: import_v419.z.record(import_v419.z.string(), import_v419.z.any()).optional()
783
975
  });
784
976
  async function handleLogToolResult(client, args) {
785
977
  const parsed2 = logToolResultInputSchema.parse(args ?? {});
@@ -815,15 +1007,15 @@ async function handleLogToolResult(client, args) {
815
1007
  }
816
1008
 
817
1009
  // src/tools/handlers/logCommand.ts
818
- var import_v414 = require("zod/v4");
819
- var logCommandInputSchema = import_v414.z.object({
820
- cmd: import_v414.z.string().min(1),
821
- summary: import_v414.z.string().min(1),
822
- cwd: import_v414.z.string().min(1).optional(),
823
- exit_code: import_v414.z.number().int().optional(),
824
- duration_ms: import_v414.z.number().int().nonnegative().optional(),
825
- run_id: import_v414.z.string().min(1).optional(),
826
- stats: import_v414.z.record(import_v414.z.string(), import_v414.z.any()).optional()
1010
+ var import_v420 = require("zod/v4");
1011
+ var logCommandInputSchema = import_v420.z.object({
1012
+ cmd: import_v420.z.string().min(1),
1013
+ summary: import_v420.z.string().min(1),
1014
+ cwd: import_v420.z.string().min(1).optional(),
1015
+ exit_code: import_v420.z.number().int().optional(),
1016
+ duration_ms: import_v420.z.number().int().nonnegative().optional(),
1017
+ run_id: import_v420.z.string().min(1).optional(),
1018
+ stats: import_v420.z.record(import_v420.z.string(), import_v420.z.any()).optional()
827
1019
  });
828
1020
  async function handleLogCommand(client, args) {
829
1021
  const parsed2 = logCommandInputSchema.parse(args ?? {});
@@ -863,7 +1055,7 @@ async function handleListProjects(client) {
863
1055
  }
864
1056
 
865
1057
  // src/tools/handlers/setProject.ts
866
- var import_v415 = require("zod/v4");
1058
+ var import_v421 = require("zod/v4");
867
1059
 
868
1060
  // src/repoFingerprint.ts
869
1061
  var fs3 = __toESM(require("fs"), 1);
@@ -1023,6 +1215,7 @@ async function acquireWorkspaceMapLock() {
1023
1215
  const maxRetries = 10;
1024
1216
  const retryDelayMs = 50;
1025
1217
  const maxLockAgeMs = 5e3;
1218
+ await ensureWorkspaceDir();
1026
1219
  let lockAcquired = false;
1027
1220
  let retries = 0;
1028
1221
  while (!lockAcquired && retries < maxRetries) {
@@ -1191,9 +1384,9 @@ async function setProjectIdForFingerprint(args) {
1191
1384
  }
1192
1385
 
1193
1386
  // src/tools/handlers/setProject.ts
1194
- var setProjectInputSchema = import_v415.z.object({
1195
- projectKey: import_v415.z.string().min(1).optional(),
1196
- projectId: import_v415.z.string().min(1).optional()
1387
+ var setProjectInputSchema = import_v421.z.object({
1388
+ projectKey: import_v421.z.string().min(1).optional(),
1389
+ projectId: import_v421.z.string().min(1).optional()
1197
1390
  });
1198
1391
  async function handleSetProject(args) {
1199
1392
  const parsed2 = setProjectInputSchema.parse(args ?? {});
@@ -1461,6 +1654,45 @@ async function main(opts = {}) {
1461
1654
  })
1462
1655
  );
1463
1656
  registeredToolNames.push("memora_post_event");
1657
+ server.tool(
1658
+ "memora_create_fact",
1659
+ "Create an explicit project-scoped fact (POST /facts)",
1660
+ createFactShape,
1661
+ async (args) => runWithSessionContext(sessionContext, async () => {
1662
+ if (!runtime.client || !runtime.projectId) return notInitializedResult;
1663
+ const result = await handleCreateFact(runtime.client, args);
1664
+ return {
1665
+ content: [{ type: "text", text: JSON.stringify(result) }]
1666
+ };
1667
+ })
1668
+ );
1669
+ registeredToolNames.push("memora_create_fact");
1670
+ server.tool(
1671
+ "memora_add_personal_context",
1672
+ "Store notes or preferences for this workspace (POST /v1/personal-context)",
1673
+ addPersonalContextShape,
1674
+ async (args) => runWithSessionContext(sessionContext, async () => {
1675
+ if (!runtime.client || !runtime.projectId) return notInitializedResult;
1676
+ const result = await handleAddPersonalContext(runtime.client, args);
1677
+ return {
1678
+ content: [{ type: "text", text: JSON.stringify(result) }]
1679
+ };
1680
+ })
1681
+ );
1682
+ registeredToolNames.push("memora_add_personal_context");
1683
+ server.tool(
1684
+ "memora_get_personal_context",
1685
+ "Search stored notes or preferences for this workspace (GET /v1/personal-context)",
1686
+ getPersonalContextShape,
1687
+ async (args) => runWithSessionContext(sessionContext, async () => {
1688
+ if (!runtime.client || !runtime.projectId) return notInitializedResult;
1689
+ const result = await handleGetPersonalContext(runtime.client, args);
1690
+ return {
1691
+ content: [{ type: "text", text: JSON.stringify(result) }]
1692
+ };
1693
+ })
1694
+ );
1695
+ registeredToolNames.push("memora_get_personal_context");
1464
1696
  server.tool(
1465
1697
  "memora_list_projects",
1466
1698
  "List projects available to the current API key",
@@ -1492,7 +1724,7 @@ async function main(opts = {}) {
1492
1724
  runtime,
1493
1725
  sessionContext,
1494
1726
  "memora_ask_with_memory",
1495
- "Ask MemoraOne with project memory context",
1727
+ "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.",
1496
1728
  askWithMemoryShape,
1497
1729
  async (args) => {
1498
1730
  const result = await handleAskWithMemory(runtime.client, args);
@@ -1639,10 +1871,16 @@ async function main(opts = {}) {
1639
1871
  runtime.apiKeyFingerprint = fingerprintApiKey(apiKeyToUse);
1640
1872
  runtime.client = new memoraClient_default(config2, projectId, apiKeyToUse);
1641
1873
  workspaceRoot = binding.workspaceRoot;
1642
- console.error(
1643
- `[memoraone-mcp DEBUG registerRepoSource] pre-register bindingSource=${binding.bindingSource} workspaceRoot=${JSON.stringify(binding.workspaceRoot)} m1Path=${JSON.stringify(binding.m1Path)} ideType=${runtime.ideType ?? "(none)"}`
1874
+ process.stderr.write(
1875
+ `[memoraone-mcp] registering workspace source bindingSource=${binding.bindingSource} workspaceRoot=${workspaceRoot ?? "(unset)"} m1Path=${binding.m1Path}
1876
+ `
1877
+ );
1878
+ await registerRepoSource(
1879
+ runtime.client,
1880
+ runtime.projectId,
1881
+ binding.workspaceRoot,
1882
+ runtime.ideType
1644
1883
  );
1645
- await registerRepoSource(runtime.client, runtime.projectId, workspaceRoot, runtime.ideType);
1646
1884
  if (debugAuth) {
1647
1885
  console.error("[memoraone-mcp][auth] repo root:", binding.workspaceRoot);
1648
1886
  console.error("[memoraone-mcp][auth] project_id:", projectId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memoraone/mcp",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {