@memoraone/mcp 0.1.51 → 0.1.53

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/cli.cjs CHANGED
@@ -231,7 +231,7 @@ var require_package = __commonJS({
231
231
  "package.json"(exports2, module2) {
232
232
  module2.exports = {
233
233
  name: "@memoraone/mcp",
234
- version: "0.1.51",
234
+ version: "0.1.53",
235
235
  type: "module",
236
236
  main: "dist/index.cjs",
237
237
  exports: {
@@ -13432,6 +13432,9 @@ var init_bridgeClientRoots = __esm({
13432
13432
  });
13433
13433
 
13434
13434
  // src/pluginStartupBindingWait.ts
13435
+ function isPluginStartupSetupRequired(value) {
13436
+ return typeof value === "object" && value !== null && !Array.isArray(value) && value.status === "setup_required" && !(value instanceof Error);
13437
+ }
13435
13438
  function toPluginStartupSetupRequired(err, gate = {}) {
13436
13439
  if (!shouldWaitForPluginStartupBinding(gate)) {
13437
13440
  return null;
@@ -13812,6 +13815,17 @@ function extractJsonRpcId(line) {
13812
13815
  return void 0;
13813
13816
  }
13814
13817
  }
13818
+ function extractInitializeProtocolVersion(line) {
13819
+ try {
13820
+ const message = JSON.parse(line.trim());
13821
+ const version2 = message.params?.protocolVersion;
13822
+ if (typeof version2 === "string" && version2.trim() !== "") {
13823
+ return version2;
13824
+ }
13825
+ } catch {
13826
+ }
13827
+ return "2024-11-05";
13828
+ }
13815
13829
  function connectWithRetry(socketPath, log, maxRetries, retryDelayMs, connect2) {
13816
13830
  return new Promise((resolve44, reject) => {
13817
13831
  const tryConnect = (attempt) => {
@@ -13946,11 +13960,19 @@ async function runBridgeProxy(options) {
13946
13960
  if (message.method === "initialize") {
13947
13961
  log("resolve binding from initialize request before daemon connect");
13948
13962
  const params = message.params ?? {};
13949
- await router.ensureDaemonForInitialize(params);
13963
+ const sessionKind = await router.ensureDaemonForInitialize(params);
13964
+ if (sessionKind === "setup_required") {
13965
+ router.completeSetupRequiredInitialize(trimmed);
13966
+ continue;
13967
+ }
13950
13968
  await router.forwardInitializeToDaemon(trimmed);
13951
13969
  await router.replayDeferredClientMessages();
13952
13970
  continue;
13953
13971
  }
13972
+ if (router.isSetupRequiredSession()) {
13973
+ router.handleSetupRequiredClientLine(trimmed);
13974
+ continue;
13975
+ }
13954
13976
  if (!router.hasClientInitialize()) {
13955
13977
  const method = typeof message.method === "string" && message.method.trim() !== "" ? message.method : "(unknown)";
13956
13978
  if (message.id !== void 0 && message.id !== null) {
@@ -13973,7 +13995,7 @@ async function runBridgeProxy(options) {
13973
13995
  router.close();
13974
13996
  }
13975
13997
  }
13976
- var net, readline4, import_node_child_process7, defaultLog, JSONRPC_METHOD_NOT_FOUND, BridgeDaemonRouter;
13998
+ var net, readline4, import_node_child_process7, defaultLog, JSONRPC_METHOD_NOT_FOUND, SETUP_REQUIRED_FINISH_SETUP_TOOL, BridgeDaemonRouter;
13977
13999
  var init_bridgeProxy = __esm({
13978
14000
  "src/bridgeProxy.ts"() {
13979
14001
  net = __toESM(require("net"), 1);
@@ -13993,6 +14015,11 @@ var init_bridgeProxy = __esm({
13993
14015
  `);
13994
14016
  };
13995
14017
  JSONRPC_METHOD_NOT_FOUND = -32601;
14018
+ SETUP_REQUIRED_FINISH_SETUP_TOOL = {
14019
+ name: "memora_finish_setup",
14020
+ description: "Start MemoraOne Cursor plugin pairing for this workspace so the user can finish setup. Returns an authorization URL and request metadata; does not open a browser. Use when this plugin-managed session is unbound (setup required).",
14021
+ inputSchema: { type: "object", properties: {} }
14022
+ };
13996
14023
  BridgeDaemonRouter = class {
13997
14024
  constructor(options) {
13998
14025
  this.activeSocket = null;
@@ -14003,6 +14030,8 @@ var init_bridgeProxy = __esm({
14003
14030
  this.pendingDeferredClientLines = [];
14004
14031
  this.handshakeDeferredClientLines = [];
14005
14032
  this.clientInitializeSeen = false;
14033
+ /** Unbound Cursor-plugin session: no daemon by design; handshake is local. */
14034
+ this.setupRequiredSession = false;
14006
14035
  /** Waiters for daemon JSON-RPC responses (keyed by request id). */
14007
14036
  this.pendingDaemonResponseWaiters = /* @__PURE__ */ new Map();
14008
14037
  this.env = options.env ?? process.env;
@@ -14053,6 +14082,9 @@ var init_bridgeProxy = __esm({
14053
14082
  hasClientInitialize() {
14054
14083
  return this.clientInitializeSeen;
14055
14084
  }
14085
+ isSetupRequiredSession() {
14086
+ return this.setupRequiredSession;
14087
+ }
14056
14088
  async ensureDaemonForInitialize(params) {
14057
14089
  logInitializeDebug(
14058
14090
  this.log,
@@ -14111,12 +14143,23 @@ var init_bridgeProxy = __esm({
14111
14143
  ),
14112
14144
  log: this.log
14113
14145
  }) : await resolveBinding();
14146
+ if (isPluginStartupSetupRequired(binding)) {
14147
+ this.setupRequiredSession = true;
14148
+ this.activeBinding = null;
14149
+ this.detachSocketReader();
14150
+ const previousSocket = this.activeSocket;
14151
+ this.activeSocket = null;
14152
+ previousSocket?.destroy();
14153
+ this.log("setup_required: no active binding; initialize will complete locally");
14154
+ return "setup_required";
14155
+ }
14156
+ this.setupRequiredSession = false;
14114
14157
  const environmentLog = binding.environment !== void 0 ? ` environment=${binding.environment}` : "";
14115
14158
  this.log(
14116
14159
  `session binding binding=${binding.repositoryBindingId} project=${binding.projectId} workspace=${binding.workspaceRoot} source=${binding.bindingSource}${environmentLog}`
14117
14160
  );
14118
14161
  if (this.activeBinding && bindingsMatch(this.activeBinding, binding) && this.activeSocket) {
14119
- return;
14162
+ return "connected";
14120
14163
  }
14121
14164
  if (this.activeBinding && !bindingsMatch(this.activeBinding, binding)) {
14122
14165
  this.log(
@@ -14131,11 +14174,71 @@ var init_bridgeProxy = __esm({
14131
14174
  this.activeBinding = binding;
14132
14175
  await this.connectActiveDaemon();
14133
14176
  this.log("bridge connected");
14177
+ return "connected";
14134
14178
  }
14135
14179
  recordClientInitialize(line) {
14136
14180
  this.lastInitializeLine = line;
14137
14181
  this.clientInitializeSeen = true;
14138
14182
  }
14183
+ /**
14184
+ * Finish Setup session: answer initialize on the bridge. Does not connect,
14185
+ * spawn, or forward to a daemon — there is no binding by design.
14186
+ */
14187
+ completeSetupRequiredInitialize(line) {
14188
+ this.recordClientInitialize(line);
14189
+ const initId = extractJsonRpcId(line);
14190
+ if (initId !== void 0) {
14191
+ this.stdout.write(
14192
+ `${JSON.stringify({
14193
+ jsonrpc: "2.0",
14194
+ id: initId,
14195
+ result: {
14196
+ protocolVersion: extractInitializeProtocolVersion(line),
14197
+ capabilities: { tools: { listChanged: true } },
14198
+ serverInfo: { name: "memoraone-mcp", version: "1.0.0" }
14199
+ }
14200
+ })}
14201
+ `
14202
+ );
14203
+ }
14204
+ this.log("setup_required: initialize completed locally");
14205
+ const deferred = this.pendingDeferredClientLines.slice();
14206
+ this.pendingDeferredClientLines = [];
14207
+ this.handshakeDeferredClientLines = deferred.slice();
14208
+ for (const deferredLine of deferred) {
14209
+ this.handleSetupRequiredClientLine(deferredLine);
14210
+ }
14211
+ }
14212
+ /** Local MCP replies for a setup_required session (no daemon socket). */
14213
+ handleSetupRequiredClientLine(line) {
14214
+ let message;
14215
+ try {
14216
+ message = JSON.parse(line.trim());
14217
+ } catch {
14218
+ return;
14219
+ }
14220
+ const method = typeof message.method === "string" ? message.method : "";
14221
+ const id = message.id;
14222
+ if (method === "tools/list" && (typeof id === "string" || typeof id === "number")) {
14223
+ this.stdout.write(
14224
+ `${JSON.stringify({
14225
+ jsonrpc: "2.0",
14226
+ id,
14227
+ result: { tools: [SETUP_REQUIRED_FINISH_SETUP_TOOL] }
14228
+ })}
14229
+ `
14230
+ );
14231
+ return;
14232
+ }
14233
+ if (id === void 0 || id === null) {
14234
+ return;
14235
+ }
14236
+ writePreInitializeJsonRpcError(
14237
+ this.stdout,
14238
+ id,
14239
+ method.trim() !== "" ? method : "(unknown)"
14240
+ );
14241
+ }
14139
14242
  /**
14140
14243
  * Forward initialize to the daemon and wait for its JSON-RPC response before
14141
14244
  * returning. Prevents pipelined tools/call (e.g. Claude Code lazy MCP connect)
@@ -14235,6 +14338,7 @@ var init_bridgeProxy = __esm({
14235
14338
  this.pendingDeferredClientLines = [];
14236
14339
  this.handshakeDeferredClientLines = [];
14237
14340
  this.clientInitializeSeen = false;
14341
+ this.setupRequiredSession = false;
14238
14342
  this.activeBinding = null;
14239
14343
  this.activeIdeType = void 0;
14240
14344
  }
package/dist/index.cjs CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memoraone/mcp",
3
- "version": "0.1.51",
3
+ "version": "0.1.53",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "exports": {
@@ -20,6 +20,15 @@
20
20
  "publishConfig": {
21
21
  "access": "public"
22
22
  },
23
+ "scripts": {
24
+ "build": "tsup && node scripts/writeBinWrapper.cjs",
25
+ "prepublishOnly": "pnpm run build",
26
+ "dev": "tsx src/cli.ts",
27
+ "lint": "eslint .",
28
+ "lint:contracts": "node scripts/lint-contracts.cjs",
29
+ "test": "pnpm run lint:contracts && MEMORAONE_SKIP_CONNECT_HOST_RUNTIME_CLEANUP=1 node --import=tsx --test test/*.test.js",
30
+ "validate:auth": "node --import=tsx --test test/memoraClient.test.js"
31
+ },
23
32
  "dependencies": {
24
33
  "@modelcontextprotocol/sdk": "^1.25.1",
25
34
  "@napi-rs/keyring": "1.3.0",
@@ -32,13 +41,5 @@
32
41
  "tsup": "^8.5.1",
33
42
  "tsx": "^4.21.0",
34
43
  "typescript": "^5.9.2"
35
- },
36
- "scripts": {
37
- "build": "tsup && node scripts/writeBinWrapper.cjs",
38
- "dev": "tsx src/cli.ts",
39
- "lint": "eslint .",
40
- "lint:contracts": "node scripts/lint-contracts.cjs",
41
- "test": "pnpm run lint:contracts && MEMORAONE_SKIP_CONNECT_HOST_RUNTIME_CLEANUP=1 node --import=tsx --test test/*.test.js",
42
- "validate:auth": "node --import=tsx --test test/memoraClient.test.js"
43
44
  }
44
- }
45
+ }