@hebbianvault/mcp 0.2.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/LICENSE +178 -0
- package/README.md +122 -0
- package/dist/assets/lockup.txt +6 -0
- package/dist/banner.d.ts +27 -0
- package/dist/banner.d.ts.map +1 -0
- package/dist/banner.js +91 -0
- package/dist/banner.js.map +1 -0
- package/dist/client.d.ts +47 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +135 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +36 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +86 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +120 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/ask.d.ts +21 -0
- package/dist/tools/ask.d.ts.map +1 -0
- package/dist/tools/ask.js +53 -0
- package/dist/tools/ask.js.map +1 -0
- package/dist/tools/capture.d.ts +22 -0
- package/dist/tools/capture.d.ts.map +1 -0
- package/dist/tools/capture.js +85 -0
- package/dist/tools/capture.js.map +1 -0
- package/dist/tools/graph_helpers.d.ts +56 -0
- package/dist/tools/graph_helpers.d.ts.map +1 -0
- package/dist/tools/graph_helpers.js +82 -0
- package/dist/tools/graph_helpers.js.map +1 -0
- package/dist/tools/index.d.ts +14 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +14 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/provenance.d.ts +20 -0
- package/dist/tools/provenance.d.ts.map +1 -0
- package/dist/tools/provenance.js +64 -0
- package/dist/tools/provenance.js.map +1 -0
- package/dist/tools/read_node.d.ts +16 -0
- package/dist/tools/read_node.d.ts.map +1 -0
- package/dist/tools/read_node.js +44 -0
- package/dist/tools/read_node.js.map +1 -0
- package/dist/tools/recent_activity.d.ts +18 -0
- package/dist/tools/recent_activity.d.ts.map +1 -0
- package/dist/tools/recent_activity.js +60 -0
- package/dist/tools/recent_activity.js.map +1 -0
- package/dist/tools/salience.d.ts +17 -0
- package/dist/tools/salience.d.ts.map +1 -0
- package/dist/tools/salience.js +45 -0
- package/dist/tools/salience.js.map +1 -0
- package/dist/tools/search.d.ts +22 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +73 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/traverse.d.ts +21 -0
- package/dist/tools/traverse.d.ts.map +1 -0
- package/dist/tools/traverse.js +117 -0
- package/dist/tools/traverse.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/provenance.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_provenance
|
|
5
|
+
* Retrieve the provenance trail for a node — where its knowledge came from.
|
|
6
|
+
*
|
|
7
|
+
* The node's provenance travels with it in the workspace graph
|
|
8
|
+
* (GET /vault/graph). This tool reads the node and returns its provenance
|
|
9
|
+
* plus identifying metadata. Access is enforced server-side, so a node is
|
|
10
|
+
* only returned when the caller's token may see it.
|
|
11
|
+
*/
|
|
12
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
13
|
+
import type { HebbianClient } from "../client.js";
|
|
14
|
+
export declare const HEBBIAN_PROVENANCE: Tool;
|
|
15
|
+
interface ProvenanceArgs {
|
|
16
|
+
uuid: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function handleProvenance(client: HebbianClient, args: ProvenanceArgs): Promise<string>;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../src/tools/provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAIlD,eAAO,MAAM,kBAAkB,EAAE,IAoBhC,CAAC;AAEF,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,MAAM,CAAC,CA2CjB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/provenance.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_provenance
|
|
5
|
+
* Retrieve the provenance trail for a node — where its knowledge came from.
|
|
6
|
+
*
|
|
7
|
+
* The node's provenance travels with it in the workspace graph
|
|
8
|
+
* (GET /vault/graph). This tool reads the node and returns its provenance
|
|
9
|
+
* plus identifying metadata. Access is enforced server-side, so a node is
|
|
10
|
+
* only returned when the caller's token may see it.
|
|
11
|
+
*/
|
|
12
|
+
import { HebbianApiError } from "../client.js";
|
|
13
|
+
import { fetchGraph } from "./graph_helpers.js";
|
|
14
|
+
export const HEBBIAN_PROVENANCE = {
|
|
15
|
+
name: "hebbian_provenance",
|
|
16
|
+
description: "Retrieve the provenance trail for a workspace node — where the knowledge came " +
|
|
17
|
+
"from. Use this to verify a source, trace an insight back to where it " +
|
|
18
|
+
"originated, or understand how a node was formed. Returns nothing if the node " +
|
|
19
|
+
"is outside your token's scope.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: "object",
|
|
22
|
+
properties: {
|
|
23
|
+
uuid: {
|
|
24
|
+
type: "string",
|
|
25
|
+
description: "UUID of the node whose provenance to retrieve. " +
|
|
26
|
+
"Obtain from hebbian_search or hebbian_traverse.",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
required: ["uuid"],
|
|
30
|
+
additionalProperties: false,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
export async function handleProvenance(client, args) {
|
|
34
|
+
const { uuid } = args;
|
|
35
|
+
if (!uuid || typeof uuid !== "string" || uuid.trim().length === 0) {
|
|
36
|
+
throw new Error("uuid is required and must be a non-empty string");
|
|
37
|
+
}
|
|
38
|
+
const target = uuid.trim();
|
|
39
|
+
try {
|
|
40
|
+
const nodes = await fetchGraph(client);
|
|
41
|
+
const node = nodes.find((n) => n.uuid === target);
|
|
42
|
+
if (!node) {
|
|
43
|
+
return JSON.stringify({
|
|
44
|
+
uuid: target,
|
|
45
|
+
message: "Node not found in the visible workspace graph. It may not exist or " +
|
|
46
|
+
"may be outside your token's scope.",
|
|
47
|
+
provenance: null,
|
|
48
|
+
}, null, 2);
|
|
49
|
+
}
|
|
50
|
+
return JSON.stringify({
|
|
51
|
+
uuid: node.uuid,
|
|
52
|
+
title: node.title ?? null,
|
|
53
|
+
domain: node.domain ?? null,
|
|
54
|
+
provenance: node.provenance ?? null,
|
|
55
|
+
}, null, 2);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
if (err instanceof HebbianApiError) {
|
|
59
|
+
throw new Error(err.toToolError());
|
|
60
|
+
}
|
|
61
|
+
throw err;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../src/tools/provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,CAAC,MAAM,kBAAkB,GAAS;IACtC,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EACT,gFAAgF;QAChF,uEAAuE;QACvE,+EAA+E;QAC/E,gCAAgC;IAClC,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,iDAAiD;oBACjD,iDAAiD;aACpD;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAMF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAqB,EACrB,IAAoB;IAEpB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAEtB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAE3B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QAElD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,IAAI,CAAC,SAAS,CACnB;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EACL,qEAAqE;oBACrE,oCAAoC;gBACtC,UAAU,EAAE,IAAI;aACjB,EACD,IAAI,EACJ,CAAC,CACF,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CACnB;YACE,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;YACzB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI;YAC3B,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;SACpC,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/read_node.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_read_node
|
|
5
|
+
* Fetches a single node by UUID — body, frontmatter, and connected edges.
|
|
6
|
+
* Maps to: GET /nodes/:uuid
|
|
7
|
+
*/
|
|
8
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
9
|
+
import type { HebbianClient } from "../client.js";
|
|
10
|
+
export declare const HEBBIAN_READ_NODE: Tool;
|
|
11
|
+
interface ReadNodeArgs {
|
|
12
|
+
uuid: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function handleReadNode(client: HebbianClient, args: ReadNodeArgs): Promise<string>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=read_node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read_node.d.ts","sourceRoot":"","sources":["../../src/tools/read_node.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,eAAO,MAAM,iBAAiB,EAAE,IAoB/B,CAAC;AAEF,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,MAAM,CAAC,CAkBjB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/read_node.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_read_node
|
|
5
|
+
* Fetches a single node by UUID — body, frontmatter, and connected edges.
|
|
6
|
+
* Maps to: GET /nodes/:uuid
|
|
7
|
+
*/
|
|
8
|
+
import { HebbianApiError } from "../client.js";
|
|
9
|
+
export const HEBBIAN_READ_NODE = {
|
|
10
|
+
name: "hebbian_read_node",
|
|
11
|
+
description: "Retrieve a single Hebbian workspace node by its UUID. Returns the node body, " +
|
|
12
|
+
"frontmatter (domain, archetype, actor, title, summary), and the edges that " +
|
|
13
|
+
"connect it to other nodes. Use this when you have a specific node ID from a " +
|
|
14
|
+
"previous search or traversal and want to read its full content.",
|
|
15
|
+
inputSchema: {
|
|
16
|
+
type: "object",
|
|
17
|
+
properties: {
|
|
18
|
+
uuid: {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "The UUID of the node to retrieve (e.g. '550e8400-e29b-41d4-a716-446655440000'). " +
|
|
21
|
+
"Obtain from hebbian_search, hebbian_traverse, or hebbian_recent_activity.",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
required: ["uuid"],
|
|
25
|
+
additionalProperties: false,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
export async function handleReadNode(client, args) {
|
|
29
|
+
const { uuid } = args;
|
|
30
|
+
if (!uuid || typeof uuid !== "string" || uuid.trim().length === 0) {
|
|
31
|
+
throw new Error("uuid is required and must be a non-empty string");
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const node = await client.get(`/nodes/${encodeURIComponent(uuid.trim())}`);
|
|
35
|
+
return JSON.stringify(node, null, 2);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (err instanceof HebbianApiError) {
|
|
39
|
+
throw new Error(err.toToolError());
|
|
40
|
+
}
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=read_node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read_node.js","sourceRoot":"","sources":["../../src/tools/read_node.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,MAAM,iBAAiB,GAAS;IACrC,IAAI,EAAE,mBAAmB;IACzB,WAAW,EACT,+EAA+E;QAC/E,6EAA6E;QAC7E,8EAA8E;QAC9E,iEAAiE;IACnE,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,kFAAkF;oBAClF,2EAA2E;aAC9E;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAMF,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAqB,EACrB,IAAkB;IAElB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAEtB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAC3B,UAAU,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAC5C,CAAC;QACF,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/recent_activity.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_recent_activity
|
|
5
|
+
* Retrieve the recent activity timeline for the workspace — new notes,
|
|
6
|
+
* intakes, and other audited events.
|
|
7
|
+
* Maps to: GET /vault/activity
|
|
8
|
+
*/
|
|
9
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
10
|
+
import type { HebbianClient } from "../client.js";
|
|
11
|
+
export declare const HEBBIAN_RECENT_ACTIVITY: Tool;
|
|
12
|
+
interface RecentActivityArgs {
|
|
13
|
+
since?: string;
|
|
14
|
+
limit?: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function handleRecentActivity(client: HebbianClient, args: RecentActivityArgs): Promise<string>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=recent_activity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recent_activity.d.ts","sourceRoot":"","sources":["../../src/tools/recent_activity.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,eAAO,MAAM,uBAAuB,EAAE,IA4BrC,CAAC;AAEF,UAAU,kBAAkB;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,MAAM,CAAC,CAyBjB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/recent_activity.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_recent_activity
|
|
5
|
+
* Retrieve the recent activity timeline for the workspace — new notes,
|
|
6
|
+
* intakes, and other audited events.
|
|
7
|
+
* Maps to: GET /vault/activity
|
|
8
|
+
*/
|
|
9
|
+
import { HebbianApiError } from "../client.js";
|
|
10
|
+
export const HEBBIAN_RECENT_ACTIVITY = {
|
|
11
|
+
name: "hebbian_recent_activity",
|
|
12
|
+
description: "Retrieve recent activity in your Hebbian workspace — which notes were " +
|
|
13
|
+
"created or updated and other audited events. Use this to catch up on what " +
|
|
14
|
+
"the workspace has learned since your last session, or to find recently-" +
|
|
15
|
+
"created nodes. Returns a reverse-chronological activity timeline. " +
|
|
16
|
+
"The 'since' param accepts an ISO 8601 datetime.",
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
since: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "ISO 8601 datetime to retrieve activity from (e.g. '2026-05-14T09:00:00Z'). " +
|
|
23
|
+
"Omit to get the most recent activity.",
|
|
24
|
+
},
|
|
25
|
+
limit: {
|
|
26
|
+
type: "number",
|
|
27
|
+
description: "Maximum number of activity items to return. Default: 20. Max: 100.",
|
|
28
|
+
minimum: 1,
|
|
29
|
+
maximum: 100,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
required: [],
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
export async function handleRecentActivity(client, args) {
|
|
37
|
+
const { since, limit = 20 } = args;
|
|
38
|
+
const query = {
|
|
39
|
+
limit: Math.min(Math.max(1, limit), 100),
|
|
40
|
+
};
|
|
41
|
+
if (since) {
|
|
42
|
+
// Validate ISO 8601 format — basic check
|
|
43
|
+
const parsed = Date.parse(since);
|
|
44
|
+
if (isNaN(parsed)) {
|
|
45
|
+
throw new Error(`'since' must be a valid ISO 8601 datetime, got: "${since}"`);
|
|
46
|
+
}
|
|
47
|
+
query["since"] = since;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
const result = await client.get("/vault/activity", query);
|
|
51
|
+
return JSON.stringify(result, null, 2);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
if (err instanceof HebbianApiError) {
|
|
55
|
+
throw new Error(err.toToolError());
|
|
56
|
+
}
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=recent_activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recent_activity.js","sourceRoot":"","sources":["../../src/tools/recent_activity.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,MAAM,uBAAuB,GAAS;IAC3C,IAAI,EAAE,yBAAyB;IAC/B,WAAW,EACT,wEAAwE;QACxE,4EAA4E;QAC5E,yEAAyE;QACzE,oEAAoE;QACpE,iDAAiD;IACnD,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,6EAA6E;oBAC7E,uCAAuC;aAC1C;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,oEAAoE;gBACtE,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,GAAG;aACb;SACF;QACD,QAAQ,EAAE,EAAE;QACZ,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAOF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAqB,EACrB,IAAwB;IAExB,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;IAEnC,MAAM,KAAK,GAA0D;QACnE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC;KACzC,CAAC;IAEF,IAAI,KAAK,EAAE,CAAC;QACV,yCAAyC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,oDAAoD,KAAK,GAAG,CAAC,CAAC;QAChF,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/salience.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_salience
|
|
5
|
+
* Return the recent activity/salience history for a node — how often and how
|
|
6
|
+
* recently it has been surfacing in the workspace.
|
|
7
|
+
* Maps to: GET /metrics/nodes/:uuid/activation-history
|
|
8
|
+
*/
|
|
9
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
10
|
+
import type { HebbianClient } from "../client.js";
|
|
11
|
+
export declare const HEBBIAN_SALIENCE: Tool;
|
|
12
|
+
interface SalienceArgs {
|
|
13
|
+
uuid: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function handleSalience(client: HebbianClient, args: SalienceArgs): Promise<string>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=salience.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"salience.d.ts","sourceRoot":"","sources":["../../src/tools/salience.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,eAAO,MAAM,gBAAgB,EAAE,IAoB9B,CAAC;AAEF,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,MAAM,CAAC,CAkBjB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/salience.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_salience
|
|
5
|
+
* Return the recent activity/salience history for a node — how often and how
|
|
6
|
+
* recently it has been surfacing in the workspace.
|
|
7
|
+
* Maps to: GET /metrics/nodes/:uuid/activation-history
|
|
8
|
+
*/
|
|
9
|
+
import { HebbianApiError } from "../client.js";
|
|
10
|
+
export const HEBBIAN_SALIENCE = {
|
|
11
|
+
name: "hebbian_salience",
|
|
12
|
+
description: "Retrieve the salience history for a workspace node — a timeline of how often " +
|
|
13
|
+
"and how recently it has been surfacing. Use this to gauge whether a node is " +
|
|
14
|
+
"currently active and relevant, or fading from daily use. Returns an empty " +
|
|
15
|
+
"history when a node has no recorded activity yet.",
|
|
16
|
+
inputSchema: {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
uuid: {
|
|
20
|
+
type: "string",
|
|
21
|
+
description: "UUID of the node whose salience history to retrieve. " +
|
|
22
|
+
"Obtain from hebbian_search or hebbian_traverse.",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
required: ["uuid"],
|
|
26
|
+
additionalProperties: false,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
export async function handleSalience(client, args) {
|
|
30
|
+
const { uuid } = args;
|
|
31
|
+
if (!uuid || typeof uuid !== "string" || uuid.trim().length === 0) {
|
|
32
|
+
throw new Error("uuid is required and must be a non-empty string");
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const result = await client.get(`/metrics/nodes/${encodeURIComponent(uuid.trim())}/activation-history`);
|
|
36
|
+
return JSON.stringify(result, null, 2);
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
if (err instanceof HebbianApiError) {
|
|
40
|
+
throw new Error(err.toToolError());
|
|
41
|
+
}
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=salience.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"salience.js","sourceRoot":"","sources":["../../src/tools/salience.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT,+EAA+E;QAC/E,8EAA8E;QAC9E,4EAA4E;QAC5E,mDAAmD;IACrD,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,uDAAuD;oBACvD,iDAAiD;aACpD;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAMF,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAqB,EACrB,IAAkB;IAElB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAEtB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAC7B,kBAAkB,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,qBAAqB,CACvE,CAAC;QACF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/search.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_search
|
|
5
|
+
* Search the workspace for nodes matching a query.
|
|
6
|
+
*
|
|
7
|
+
* The Hebbian API exposes the workspace as a scoped graph (GET /vault/graph),
|
|
8
|
+
* already filtered to what the caller's token may see. This tool ranks that
|
|
9
|
+
* graph against the query and returns the best matches. The graph is the
|
|
10
|
+
* authoritative source; ranking is a thin presentation layer.
|
|
11
|
+
*/
|
|
12
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
13
|
+
import type { HebbianClient } from "../client.js";
|
|
14
|
+
export declare const HEBBIAN_SEARCH: Tool;
|
|
15
|
+
interface SearchArgs {
|
|
16
|
+
q: string;
|
|
17
|
+
domain?: string;
|
|
18
|
+
limit?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function handleSearch(client: HebbianClient, args: SearchArgs): Promise<string>;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAUlD,eAAO,MAAM,cAAc,EAAE,IAgC5B,CAAC;AAEF,UAAU,UAAU;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,MAAM,CAAC,CAoCjB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/search.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_search
|
|
5
|
+
* Search the workspace for nodes matching a query.
|
|
6
|
+
*
|
|
7
|
+
* The Hebbian API exposes the workspace as a scoped graph (GET /vault/graph),
|
|
8
|
+
* already filtered to what the caller's token may see. This tool ranks that
|
|
9
|
+
* graph against the query and returns the best matches. The graph is the
|
|
10
|
+
* authoritative source; ranking is a thin presentation layer.
|
|
11
|
+
*/
|
|
12
|
+
import { HebbianApiError } from "../client.js";
|
|
13
|
+
import { fetchGraph, queryTerms, scoreNode, summarise, } from "./graph_helpers.js";
|
|
14
|
+
export const HEBBIAN_SEARCH = {
|
|
15
|
+
name: "hebbian_search",
|
|
16
|
+
description: "Search your Hebbian workspace for nodes matching a query. Returns a ranked " +
|
|
17
|
+
"list of matching nodes with their UUID, title, domain, archetype, tags, and " +
|
|
18
|
+
"a snippet. Use this as the starting point for exploring the workspace when " +
|
|
19
|
+
"you have a topic or question. The 'domain' param filters by knowledge area " +
|
|
20
|
+
"(e.g. 'Company', 'Compass'). Results only ever include what your token is " +
|
|
21
|
+
"allowed to see — access is enforced server-side.",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
q: {
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "Search query — natural language or keywords. Required.",
|
|
28
|
+
},
|
|
29
|
+
domain: {
|
|
30
|
+
type: "string",
|
|
31
|
+
description: "Optional filter by knowledge domain (e.g. 'Company', 'CRM', 'Compass', " +
|
|
32
|
+
"'Axis', 'Mirror', 'Finance', 'Oracle'). Omit to search all domains.",
|
|
33
|
+
},
|
|
34
|
+
limit: {
|
|
35
|
+
type: "number",
|
|
36
|
+
description: "Maximum number of results to return. Default: 10. Max: 50.",
|
|
37
|
+
minimum: 1,
|
|
38
|
+
maximum: 50,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
required: ["q"],
|
|
42
|
+
additionalProperties: false,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
export async function handleSearch(client, args) {
|
|
46
|
+
const { q, domain, limit = 10 } = args;
|
|
47
|
+
if (!q || typeof q !== "string" || q.trim().length === 0) {
|
|
48
|
+
throw new Error("q is required and must be a non-empty string");
|
|
49
|
+
}
|
|
50
|
+
const cap = Math.min(Math.max(1, limit), 50);
|
|
51
|
+
const terms = queryTerms(q);
|
|
52
|
+
try {
|
|
53
|
+
let nodes = await fetchGraph(client);
|
|
54
|
+
if (domain) {
|
|
55
|
+
const d = domain.toLowerCase();
|
|
56
|
+
nodes = nodes.filter((n) => (n.domain ?? "").toLowerCase() === d);
|
|
57
|
+
}
|
|
58
|
+
const ranked = nodes
|
|
59
|
+
.map((n) => ({ n, score: scoreNode(n, terms) }))
|
|
60
|
+
.filter((x) => x.score > 0)
|
|
61
|
+
.sort((a, b) => b.score - a.score)
|
|
62
|
+
.slice(0, cap)
|
|
63
|
+
.map((x) => summarise(x.n));
|
|
64
|
+
return JSON.stringify({ query: q.trim(), domain: domain ?? null, count: ranked.length, results: ranked }, null, 2);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (err instanceof HebbianApiError) {
|
|
68
|
+
throw new Error(err.toToolError());
|
|
69
|
+
}
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/traverse.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_traverse
|
|
5
|
+
* Walk the workspace graph outward from a starting node up to N hops.
|
|
6
|
+
*
|
|
7
|
+
* Built over the scoped workspace graph (GET /vault/graph), where each node
|
|
8
|
+
* carries its inline edges. We do a breadth-first walk from the start node;
|
|
9
|
+
* only nodes the caller's token may see are present in the graph, so traversal
|
|
10
|
+
* never crosses an access boundary.
|
|
11
|
+
*/
|
|
12
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
13
|
+
import type { HebbianClient } from "../client.js";
|
|
14
|
+
export declare const HEBBIAN_TRAVERSE: Tool;
|
|
15
|
+
interface TraverseArgs {
|
|
16
|
+
start_uuid: string;
|
|
17
|
+
max_hops?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function handleTraverse(client: HebbianClient, args: TraverseArgs): Promise<string>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=traverse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traverse.d.ts","sourceRoot":"","sources":["../../src/tools/traverse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAOlD,eAAO,MAAM,gBAAgB,EAAE,IA4B9B,CAAC;AAEF,UAAU,YAAY;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AASD,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,MAAM,CAAC,CAuFjB"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/traverse.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_traverse
|
|
5
|
+
* Walk the workspace graph outward from a starting node up to N hops.
|
|
6
|
+
*
|
|
7
|
+
* Built over the scoped workspace graph (GET /vault/graph), where each node
|
|
8
|
+
* carries its inline edges. We do a breadth-first walk from the start node;
|
|
9
|
+
* only nodes the caller's token may see are present in the graph, so traversal
|
|
10
|
+
* never crosses an access boundary.
|
|
11
|
+
*/
|
|
12
|
+
import { HebbianApiError } from "../client.js";
|
|
13
|
+
import { fetchGraph, normaliseEdge, summarise } from "./graph_helpers.js";
|
|
14
|
+
const MAX_HOPS = 5;
|
|
15
|
+
const DEFAULT_HOPS = 2;
|
|
16
|
+
export const HEBBIAN_TRAVERSE = {
|
|
17
|
+
name: "hebbian_traverse",
|
|
18
|
+
description: "Walk your Hebbian workspace graph from a starting node, returning connected " +
|
|
19
|
+
"nodes up to N hops away plus the edges between them. Use this to explore the " +
|
|
20
|
+
"context around a node — e.g. notes related to a project, or signals connected " +
|
|
21
|
+
"to a person. Only nodes your token may see are returned.",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
start_uuid: {
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "UUID of the starting node. Obtain from hebbian_search or " +
|
|
28
|
+
"hebbian_recent_activity.",
|
|
29
|
+
},
|
|
30
|
+
max_hops: {
|
|
31
|
+
type: "number",
|
|
32
|
+
description: `Maximum number of hops to traverse. Default: ${DEFAULT_HOPS}. Max: ${MAX_HOPS}. ` +
|
|
33
|
+
"Higher values return more context but may include loosely-related nodes.",
|
|
34
|
+
minimum: 1,
|
|
35
|
+
maximum: MAX_HOPS,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
required: ["start_uuid"],
|
|
39
|
+
additionalProperties: false,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
export async function handleTraverse(client, args) {
|
|
43
|
+
const { start_uuid, max_hops = DEFAULT_HOPS } = args;
|
|
44
|
+
if (!start_uuid || typeof start_uuid !== "string" || start_uuid.trim().length === 0) {
|
|
45
|
+
throw new Error("start_uuid is required and must be a non-empty string");
|
|
46
|
+
}
|
|
47
|
+
const hops = Math.min(Math.max(1, max_hops), MAX_HOPS);
|
|
48
|
+
const start = start_uuid.trim();
|
|
49
|
+
try {
|
|
50
|
+
const nodes = await fetchGraph(client);
|
|
51
|
+
const byUuid = new Map();
|
|
52
|
+
for (const n of nodes)
|
|
53
|
+
byUuid.set(n.uuid, n);
|
|
54
|
+
if (!byUuid.has(start)) {
|
|
55
|
+
return JSON.stringify({
|
|
56
|
+
start_uuid: start,
|
|
57
|
+
message: "Start node not found in the visible workspace graph. It may not exist " +
|
|
58
|
+
"or may be outside your token's scope.",
|
|
59
|
+
nodes: [],
|
|
60
|
+
edges: [],
|
|
61
|
+
}, null, 2);
|
|
62
|
+
}
|
|
63
|
+
// BFS over inline edges.
|
|
64
|
+
const visited = new Set([start]);
|
|
65
|
+
const collectedEdges = [];
|
|
66
|
+
const edgeSeen = new Set();
|
|
67
|
+
let frontier = [start];
|
|
68
|
+
for (let hop = 0; hop < hops; hop++) {
|
|
69
|
+
const next = [];
|
|
70
|
+
for (const uuid of frontier) {
|
|
71
|
+
const node = byUuid.get(uuid);
|
|
72
|
+
if (!node || !Array.isArray(node.edges))
|
|
73
|
+
continue;
|
|
74
|
+
for (const e of node.edges) {
|
|
75
|
+
const { source: src, target: tgt, relation, weight } = normaliseEdge(e, uuid);
|
|
76
|
+
const neighbour = src === uuid ? tgt : src;
|
|
77
|
+
const key = `${src}->${tgt}:${relation ?? ""}`;
|
|
78
|
+
if (!edgeSeen.has(key)) {
|
|
79
|
+
edgeSeen.add(key);
|
|
80
|
+
collectedEdges.push({
|
|
81
|
+
source_uuid: src,
|
|
82
|
+
target_uuid: tgt,
|
|
83
|
+
relation_type: relation,
|
|
84
|
+
weight,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
if (neighbour && !visited.has(neighbour) && byUuid.has(neighbour)) {
|
|
88
|
+
visited.add(neighbour);
|
|
89
|
+
next.push(neighbour);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
frontier = next;
|
|
94
|
+
if (frontier.length === 0)
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
const resultNodes = [...visited]
|
|
98
|
+
.map((u) => byUuid.get(u))
|
|
99
|
+
.filter((n) => Boolean(n))
|
|
100
|
+
.map(summarise);
|
|
101
|
+
return JSON.stringify({
|
|
102
|
+
start_uuid: start,
|
|
103
|
+
max_hops: hops,
|
|
104
|
+
node_count: resultNodes.length,
|
|
105
|
+
edge_count: collectedEdges.length,
|
|
106
|
+
nodes: resultNodes,
|
|
107
|
+
edges: collectedEdges,
|
|
108
|
+
}, null, 2);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
if (err instanceof HebbianApiError) {
|
|
112
|
+
throw new Error(err.toToolError());
|
|
113
|
+
}
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=traverse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traverse.js","sourceRoot":"","sources":["../../src/tools/traverse.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hebbianvault/mcp",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Customer-installable MCP server for the Hebbian tenant brain. One package, scope-by-token (Employee or Company). Install in Claude Code, Claude Desktop, Cursor, Cowork, or any MCP-compatible agent.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"hebbian-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"LICENSE",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc && node -e \"const{mkdirSync,cpSync}=require('fs');mkdirSync('dist/assets',{recursive:true});cpSync('src/assets/lockup.txt','dist/assets/lockup.txt')\"",
|
|
23
|
+
"dev": "tsc --watch",
|
|
24
|
+
"test": "node --experimental-vm-modules node_modules/.bin/jest --config=jest.config.cjs tests/",
|
|
25
|
+
"prepublishOnly": "npm run build && npm test",
|
|
26
|
+
"start": "node dist/index.js",
|
|
27
|
+
"postinstall": "node scripts/postinstall.mjs || true"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"mcp",
|
|
31
|
+
"hebbian",
|
|
32
|
+
"knowledge-graph",
|
|
33
|
+
"ai-tools",
|
|
34
|
+
"model-context-protocol"
|
|
35
|
+
],
|
|
36
|
+
"author": "Hebbian",
|
|
37
|
+
"license": "Apache-2.0",
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public",
|
|
40
|
+
"registry": "https://registry.npmjs.org/"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=20.0.0"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/jest": "^29.5.14",
|
|
50
|
+
"@types/node": "^22.0.0",
|
|
51
|
+
"jest": "^29.7.0",
|
|
52
|
+
"ts-jest": "^29.4.9",
|
|
53
|
+
"typescript": "^5.6.3"
|
|
54
|
+
}
|
|
55
|
+
}
|