@abraca/mcp 1.1.2 → 1.3.4
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/abracadabra-mcp.cjs +37 -11
- package/dist/abracadabra-mcp.cjs.map +1 -1
- package/dist/abracadabra-mcp.esm.js +37 -11
- package/dist/abracadabra-mcp.esm.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/server.ts +16 -0
- package/src/tools/tree.ts +24 -12
|
@@ -19448,6 +19448,7 @@ var AbracadabraMCPServer = class {
|
|
|
19448
19448
|
this._statusClearTimer = null;
|
|
19449
19449
|
this._typingInterval = null;
|
|
19450
19450
|
this._lastChatChannel = null;
|
|
19451
|
+
this._signFn = null;
|
|
19451
19452
|
this.config = config;
|
|
19452
19453
|
this.client = new AbracadabraClient({
|
|
19453
19454
|
url: config.url,
|
|
@@ -19483,6 +19484,7 @@ var AbracadabraMCPServer = class {
|
|
|
19483
19484
|
const keypair = await loadOrCreateKeypair(this.config.keyFile);
|
|
19484
19485
|
this._userId = keypair.publicKeyB64;
|
|
19485
19486
|
const signFn = (challenge) => Promise.resolve(signChallenge(challenge, keypair.privateKey));
|
|
19487
|
+
this._signFn = signFn;
|
|
19486
19488
|
try {
|
|
19487
19489
|
await this.client.loginWithKey(keypair.publicKeyB64, signFn);
|
|
19488
19490
|
} catch (err) {
|
|
@@ -19543,6 +19545,11 @@ var AbracadabraMCPServer = class {
|
|
|
19543
19545
|
this._rootDocId = docId;
|
|
19544
19546
|
return existing;
|
|
19545
19547
|
}
|
|
19548
|
+
if (!this.client.isTokenValid() && this._signFn && this._userId) {
|
|
19549
|
+
console.error("[abracadabra-mcp] JWT expired, re-authenticating...");
|
|
19550
|
+
await this.client.loginWithKey(this._userId, this._signFn);
|
|
19551
|
+
console.error("[abracadabra-mcp] Re-authenticated successfully");
|
|
19552
|
+
}
|
|
19546
19553
|
const doc = new Y.Doc({ guid: docId });
|
|
19547
19554
|
const provider = new AbracadabraProvider({
|
|
19548
19555
|
name: docId,
|
|
@@ -19607,6 +19614,11 @@ var AbracadabraMCPServer = class {
|
|
|
19607
19614
|
}
|
|
19608
19615
|
const activeProvider = this._activeConnection?.provider;
|
|
19609
19616
|
if (!activeProvider) throw new Error("Not connected. Call connect() first.");
|
|
19617
|
+
if (!this.client.isTokenValid() && this._signFn && this._userId) {
|
|
19618
|
+
console.error("[abracadabra-mcp] JWT expired, re-authenticating...");
|
|
19619
|
+
await this.client.loginWithKey(this._userId, this._signFn);
|
|
19620
|
+
console.error("[abracadabra-mcp] Re-authenticated successfully");
|
|
19621
|
+
}
|
|
19610
19622
|
const childProvider = await activeProvider.loadChild(docId);
|
|
19611
19623
|
await waitForSync(childProvider);
|
|
19612
19624
|
childProvider.awareness.setLocalStateField("user", {
|
|
@@ -19879,6 +19891,9 @@ function docToSpaceMeta(doc) {
|
|
|
19879
19891
|
//#endregion
|
|
19880
19892
|
//#region packages/mcp/src/tools/tree.ts
|
|
19881
19893
|
/**
|
|
19894
|
+
* Document tree tools — operate on the root Y.Doc's "doc-tree" Y.Map.
|
|
19895
|
+
*/
|
|
19896
|
+
/**
|
|
19882
19897
|
* Normalize a document ID so the hub/root doc ID is treated as the tree root (null).
|
|
19883
19898
|
* This lets callers pass the hub doc_id from list_spaces as parentId/rootId
|
|
19884
19899
|
* and get the expected root-level results instead of an empty set.
|
|
@@ -19887,9 +19902,15 @@ function normalizeRootId(id, server) {
|
|
|
19887
19902
|
if (id == null) return null;
|
|
19888
19903
|
return id === server.rootDocId ? null : id;
|
|
19889
19904
|
}
|
|
19905
|
+
/** Safely read a tree map value, converting Y.Map to plain object if needed. */
|
|
19906
|
+
function toPlain(val) {
|
|
19907
|
+
return val instanceof Y.Map ? val.toJSON() : val;
|
|
19908
|
+
}
|
|
19890
19909
|
function readEntries$1(treeMap) {
|
|
19891
19910
|
const entries = [];
|
|
19892
|
-
treeMap.forEach((
|
|
19911
|
+
treeMap.forEach((raw, id) => {
|
|
19912
|
+
const value = toPlain(raw);
|
|
19913
|
+
if (typeof value !== "object" || value === null) return;
|
|
19893
19914
|
entries.push({
|
|
19894
19915
|
id,
|
|
19895
19916
|
label: value.label || "Untitled",
|
|
@@ -20092,14 +20113,15 @@ function registerTreeTools(mcp, server) {
|
|
|
20092
20113
|
text: "Not connected"
|
|
20093
20114
|
}] };
|
|
20094
20115
|
}
|
|
20095
|
-
const
|
|
20096
|
-
if (!
|
|
20116
|
+
const raw = treeMap.get(id);
|
|
20117
|
+
if (!raw) {
|
|
20097
20118
|
server.setActiveToolCall(null);
|
|
20098
20119
|
return { content: [{
|
|
20099
20120
|
type: "text",
|
|
20100
20121
|
text: `Document ${id} not found`
|
|
20101
20122
|
}] };
|
|
20102
20123
|
}
|
|
20124
|
+
const entry = toPlain(raw);
|
|
20103
20125
|
treeMap.set(id, {
|
|
20104
20126
|
...entry,
|
|
20105
20127
|
label,
|
|
@@ -20129,14 +20151,15 @@ function registerTreeTools(mcp, server) {
|
|
|
20129
20151
|
text: "Not connected"
|
|
20130
20152
|
}] };
|
|
20131
20153
|
}
|
|
20132
|
-
const
|
|
20133
|
-
if (!
|
|
20154
|
+
const raw = treeMap.get(id);
|
|
20155
|
+
if (!raw) {
|
|
20134
20156
|
server.setActiveToolCall(null);
|
|
20135
20157
|
return { content: [{
|
|
20136
20158
|
type: "text",
|
|
20137
20159
|
text: `Document ${id} not found`
|
|
20138
20160
|
}] };
|
|
20139
20161
|
}
|
|
20162
|
+
const entry = toPlain(raw);
|
|
20140
20163
|
treeMap.set(id, {
|
|
20141
20164
|
...entry,
|
|
20142
20165
|
parentId: normalizeRootId(newParentId, server),
|
|
@@ -20169,8 +20192,9 @@ function registerTreeTools(mcp, server) {
|
|
|
20169
20192
|
const now = Date.now();
|
|
20170
20193
|
rootDoc.transact(() => {
|
|
20171
20194
|
for (const nid of toDelete) {
|
|
20172
|
-
const
|
|
20173
|
-
if (!
|
|
20195
|
+
const raw = treeMap.get(nid);
|
|
20196
|
+
if (!raw) continue;
|
|
20197
|
+
const entry = toPlain(raw);
|
|
20174
20198
|
trashMap.set(nid, {
|
|
20175
20199
|
label: entry.label || "Untitled",
|
|
20176
20200
|
parentId: entry.parentId ?? null,
|
|
@@ -20205,14 +20229,15 @@ function registerTreeTools(mcp, server) {
|
|
|
20205
20229
|
text: "Not connected"
|
|
20206
20230
|
}] };
|
|
20207
20231
|
}
|
|
20208
|
-
const
|
|
20209
|
-
if (!
|
|
20232
|
+
const raw = treeMap.get(id);
|
|
20233
|
+
if (!raw) {
|
|
20210
20234
|
server.setActiveToolCall(null);
|
|
20211
20235
|
return { content: [{
|
|
20212
20236
|
type: "text",
|
|
20213
20237
|
text: `Document ${id} not found`
|
|
20214
20238
|
}] };
|
|
20215
20239
|
}
|
|
20240
|
+
const entry = toPlain(raw);
|
|
20216
20241
|
treeMap.set(id, {
|
|
20217
20242
|
...entry,
|
|
20218
20243
|
type,
|
|
@@ -20253,11 +20278,12 @@ function registerTreeTools(mcp, server) {
|
|
|
20253
20278
|
type: "text",
|
|
20254
20279
|
text: "Not connected"
|
|
20255
20280
|
}] };
|
|
20256
|
-
const
|
|
20257
|
-
if (!
|
|
20281
|
+
const raw = treeMap.get(id);
|
|
20282
|
+
if (!raw) return { content: [{
|
|
20258
20283
|
type: "text",
|
|
20259
20284
|
text: `Document ${id} not found`
|
|
20260
20285
|
}] };
|
|
20286
|
+
const entry = toPlain(raw);
|
|
20261
20287
|
const newId = crypto.randomUUID();
|
|
20262
20288
|
treeMap.set(newId, {
|
|
20263
20289
|
...entry,
|