@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":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAQD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,IAAI,aAAa,CAgC1C"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/config.ts
|
|
3
|
+
*
|
|
4
|
+
* Configuration loading for @hebbianvault/mcp.
|
|
5
|
+
*
|
|
6
|
+
* Auth: bearer token from HEBBIAN_API_TOKEN env var (preferred) or
|
|
7
|
+
* HEBBIAN_TOKEN (alternative) or config-file JSON path.
|
|
8
|
+
* URL: HEBBIAN_API_URL env var (default: the Hebbian SaaS API). Enterprise
|
|
9
|
+
* self-host customers override this to point at their own VM.
|
|
10
|
+
* Tenant: HEBBIAN_TENANT (optional) — only needed when your account belongs to
|
|
11
|
+
* more than one Hebbian workspace, to disambiguate which one to act in.
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
14
|
+
import { resolve } from "node:path";
|
|
15
|
+
// Hebbian SaaS API. Enterprise/self-host customers override with HEBBIAN_API_URL.
|
|
16
|
+
const DEFAULT_API_URL = "https://api.hebbianvault.com";
|
|
17
|
+
/**
|
|
18
|
+
* Load configuration from environment variables and optional config file.
|
|
19
|
+
*
|
|
20
|
+
* Priority (highest first):
|
|
21
|
+
* 1. HEBBIAN_API_TOKEN / HEBBIAN_TOKEN env vars
|
|
22
|
+
* 2. HEBBIAN_CONFIG_PATH — path to a JSON config file
|
|
23
|
+
* 3. ~/.config/hebbian/mcp-tenant.json
|
|
24
|
+
*
|
|
25
|
+
* Throws if no token can be resolved — the MCP server cannot start without auth.
|
|
26
|
+
*/
|
|
27
|
+
export function loadConfig() {
|
|
28
|
+
// ── API URL ────────────────────────────────────────────────────────────────
|
|
29
|
+
const apiUrl = process.env.HEBBIAN_API_URL ?? DEFAULT_API_URL;
|
|
30
|
+
// ── Tenant (optional) ────────────────────────────────────────────────────────
|
|
31
|
+
const envTenant = process.env.HEBBIAN_TENANT?.trim() || undefined;
|
|
32
|
+
// ── Token (env first) ──────────────────────────────────────────────────────
|
|
33
|
+
const envToken = process.env.HEBBIAN_API_TOKEN ?? process.env.HEBBIAN_TOKEN;
|
|
34
|
+
if (envToken && envToken.length > 0) {
|
|
35
|
+
return { apiUrl, token: envToken, tenant: envTenant };
|
|
36
|
+
}
|
|
37
|
+
// ── Token (config file) ────────────────────────────────────────────────────
|
|
38
|
+
const configPath = resolveConfigPath();
|
|
39
|
+
if (configPath) {
|
|
40
|
+
const file = readConfigFile(configPath);
|
|
41
|
+
if (file.token && file.token.length > 0) {
|
|
42
|
+
return {
|
|
43
|
+
apiUrl: file.api_url ?? apiUrl,
|
|
44
|
+
token: file.token,
|
|
45
|
+
tenant: envTenant ?? file.tenant,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
throw new Error("Hebbian MCP: No API token found. " +
|
|
50
|
+
"Set HEBBIAN_API_TOKEN env var or HEBBIAN_TOKEN env var, " +
|
|
51
|
+
"or write your token to ~/.config/hebbian/mcp-tenant.json as { \"token\": \"...\" }. " +
|
|
52
|
+
"Generate a token from the AI Tools tab in your Hebbian integrations page.");
|
|
53
|
+
}
|
|
54
|
+
/** Resolve config file path — explicit env var or default location. */
|
|
55
|
+
function resolveConfigPath() {
|
|
56
|
+
const explicit = process.env.HEBBIAN_CONFIG_PATH;
|
|
57
|
+
if (explicit) {
|
|
58
|
+
const abs = resolve(explicit);
|
|
59
|
+
if (existsSync(abs))
|
|
60
|
+
return abs;
|
|
61
|
+
// Warn but don't throw — fall back to env token check result above
|
|
62
|
+
process.stderr.write(`[hebbian-mcp] Warning: HEBBIAN_CONFIG_PATH set to "${explicit}" but file not found.\n`);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
66
|
+
if (!homeDir)
|
|
67
|
+
return null;
|
|
68
|
+
const defaultPath = resolve(homeDir, ".config", "hebbian", "mcp-tenant.json");
|
|
69
|
+
return existsSync(defaultPath) ? defaultPath : null;
|
|
70
|
+
}
|
|
71
|
+
/** Read and parse a JSON config file; tolerates missing fields. */
|
|
72
|
+
function readConfigFile(path) {
|
|
73
|
+
try {
|
|
74
|
+
const raw = readFileSync(path, "utf-8");
|
|
75
|
+
const parsed = JSON.parse(raw);
|
|
76
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
77
|
+
throw new Error("Config file must be a JSON object");
|
|
78
|
+
}
|
|
79
|
+
return parsed;
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
process.stderr.write(`[hebbian-mcp] Warning: Could not read config file at "${path}": ${String(err)}\n`);
|
|
83
|
+
return {};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @hebbianvault/mcp — Customer-installable MCP server for the Hebbian tenant brain.
|
|
4
|
+
*
|
|
5
|
+
* One package, scope-by-token (Employee or Company). Install in Claude Code,
|
|
6
|
+
* Claude Desktop, Cursor, Cowork, or any MCP-compatible agent. Configure with a
|
|
7
|
+
* token issued from your Hebbian integrations page (AI Tools tab).
|
|
8
|
+
*
|
|
9
|
+
* Auth: set HEBBIAN_API_TOKEN (or HEBBIAN_TOKEN) env var, or write a config
|
|
10
|
+
* file at ~/.config/hebbian/mcp-tenant.json with { "token": "hbn_..." }.
|
|
11
|
+
*
|
|
12
|
+
* 8 tools:
|
|
13
|
+
* hebbian_read_node — fetch a node by UUID
|
|
14
|
+
* hebbian_search — search the workspace for matching nodes
|
|
15
|
+
* hebbian_ask — synthesis Q&A returned with source quotes
|
|
16
|
+
* hebbian_capture — write a note into the workspace
|
|
17
|
+
* hebbian_traverse — walk the graph from a starting node
|
|
18
|
+
* hebbian_provenance — source trail for a node
|
|
19
|
+
* hebbian_salience — salience/activity history for a node
|
|
20
|
+
* hebbian_recent_activity — recent workspace activity timeline
|
|
21
|
+
*
|
|
22
|
+
* All access control is enforced server-side by the API. What a token can
|
|
23
|
+
* read and write is determined by its scope; this package is a thin client.
|
|
24
|
+
*/
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;GAsBG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @hebbianvault/mcp — Customer-installable MCP server for the Hebbian tenant brain.
|
|
4
|
+
*
|
|
5
|
+
* One package, scope-by-token (Employee or Company). Install in Claude Code,
|
|
6
|
+
* Claude Desktop, Cursor, Cowork, or any MCP-compatible agent. Configure with a
|
|
7
|
+
* token issued from your Hebbian integrations page (AI Tools tab).
|
|
8
|
+
*
|
|
9
|
+
* Auth: set HEBBIAN_API_TOKEN (or HEBBIAN_TOKEN) env var, or write a config
|
|
10
|
+
* file at ~/.config/hebbian/mcp-tenant.json with { "token": "hbn_..." }.
|
|
11
|
+
*
|
|
12
|
+
* 8 tools:
|
|
13
|
+
* hebbian_read_node — fetch a node by UUID
|
|
14
|
+
* hebbian_search — search the workspace for matching nodes
|
|
15
|
+
* hebbian_ask — synthesis Q&A returned with source quotes
|
|
16
|
+
* hebbian_capture — write a note into the workspace
|
|
17
|
+
* hebbian_traverse — walk the graph from a starting node
|
|
18
|
+
* hebbian_provenance — source trail for a node
|
|
19
|
+
* hebbian_salience — salience/activity history for a node
|
|
20
|
+
* hebbian_recent_activity — recent workspace activity timeline
|
|
21
|
+
*
|
|
22
|
+
* All access control is enforced server-side by the API. What a token can
|
|
23
|
+
* read and write is determined by its scope; this package is a thin client.
|
|
24
|
+
*/
|
|
25
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
26
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
27
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
28
|
+
import { loadConfig } from "./config.js";
|
|
29
|
+
import { HebbianClient } from "./client.js";
|
|
30
|
+
import { printBanner } from "./banner.js";
|
|
31
|
+
import { HEBBIAN_READ_NODE, handleReadNode, HEBBIAN_SEARCH, handleSearch, HEBBIAN_ASK, handleAsk, HEBBIAN_CAPTURE, handleCapture, HEBBIAN_TRAVERSE, handleTraverse, HEBBIAN_PROVENANCE, handleProvenance, HEBBIAN_SALIENCE, handleSalience, HEBBIAN_RECENT_ACTIVITY, handleRecentActivity, } from "./tools/index.js";
|
|
32
|
+
// ── Constants ──────────────────────────────────────────────────────────────────
|
|
33
|
+
const SERVER_NAME = "@hebbianvault/mcp";
|
|
34
|
+
const SERVER_VERSION = "0.2.0";
|
|
35
|
+
// ── All registered tools ───────────────────────────────────────────────────────
|
|
36
|
+
const TOOLS = [
|
|
37
|
+
HEBBIAN_READ_NODE,
|
|
38
|
+
HEBBIAN_SEARCH,
|
|
39
|
+
HEBBIAN_ASK,
|
|
40
|
+
HEBBIAN_CAPTURE,
|
|
41
|
+
HEBBIAN_TRAVERSE,
|
|
42
|
+
HEBBIAN_PROVENANCE,
|
|
43
|
+
HEBBIAN_SALIENCE,
|
|
44
|
+
HEBBIAN_RECENT_ACTIVITY,
|
|
45
|
+
];
|
|
46
|
+
// ── Boot ───────────────────────────────────────────────────────────────────────
|
|
47
|
+
async function main() {
|
|
48
|
+
// Print brand banner to STDERR before transport connects.
|
|
49
|
+
// STDERR only — stdout is the JSON-RPC wire; any write there corrupts the protocol.
|
|
50
|
+
printBanner();
|
|
51
|
+
// Load config early — throw clearly if no token
|
|
52
|
+
const config = loadConfig();
|
|
53
|
+
const client = new HebbianClient(config.apiUrl, config.token, config.tenant);
|
|
54
|
+
const server = new Server({ name: SERVER_NAME, version: SERVER_VERSION }, { capabilities: { tools: {} } });
|
|
55
|
+
// ── list_tools ─────────────────────────────────────────────────────────────
|
|
56
|
+
server.setRequestHandler(ListToolsRequestSchema, () => ({
|
|
57
|
+
tools: [...TOOLS],
|
|
58
|
+
}));
|
|
59
|
+
// ── call_tool ──────────────────────────────────────────────────────────────
|
|
60
|
+
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
61
|
+
const { name, arguments: rawArgs } = req.params;
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
+
const args = (rawArgs ?? {});
|
|
64
|
+
try {
|
|
65
|
+
let result;
|
|
66
|
+
switch (name) {
|
|
67
|
+
case "hebbian_read_node":
|
|
68
|
+
result = await handleReadNode(client, args);
|
|
69
|
+
break;
|
|
70
|
+
case "hebbian_search":
|
|
71
|
+
result = await handleSearch(client, args);
|
|
72
|
+
break;
|
|
73
|
+
case "hebbian_ask":
|
|
74
|
+
result = await handleAsk(client, args);
|
|
75
|
+
break;
|
|
76
|
+
case "hebbian_capture":
|
|
77
|
+
result = await handleCapture(client, args);
|
|
78
|
+
break;
|
|
79
|
+
case "hebbian_traverse":
|
|
80
|
+
result = await handleTraverse(client, args);
|
|
81
|
+
break;
|
|
82
|
+
case "hebbian_provenance":
|
|
83
|
+
result = await handleProvenance(client, args);
|
|
84
|
+
break;
|
|
85
|
+
case "hebbian_salience":
|
|
86
|
+
result = await handleSalience(client, args);
|
|
87
|
+
break;
|
|
88
|
+
case "hebbian_recent_activity":
|
|
89
|
+
result = await handleRecentActivity(client, args);
|
|
90
|
+
break;
|
|
91
|
+
default:
|
|
92
|
+
return {
|
|
93
|
+
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
|
94
|
+
isError: true,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
content: [{ type: "text", text: result }],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
103
|
+
return {
|
|
104
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
105
|
+
isError: true,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
// ── Transport ──────────────────────────────────────────────────────────────
|
|
110
|
+
const transport = new StdioServerTransport();
|
|
111
|
+
await server.connect(transport);
|
|
112
|
+
// Log to stderr only (stdout is the MCP wire)
|
|
113
|
+
process.stderr.write(`[hebbian-mcp] ${SERVER_NAME}@${SERVER_VERSION} started. ` +
|
|
114
|
+
`API: ${config.apiUrl}\n`);
|
|
115
|
+
}
|
|
116
|
+
main().catch((err) => {
|
|
117
|
+
process.stderr.write(`[hebbian-mcp] Fatal startup error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
118
|
+
process.exit(1);
|
|
119
|
+
});
|
|
120
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/ask.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_ask
|
|
5
|
+
* Synthesis Q&A grounded in the workspace, returned with source quotes.
|
|
6
|
+
* Maps to: POST /ask (request body: { query })
|
|
7
|
+
*
|
|
8
|
+
* The API response includes `answer`, `sources[]` (each with a `quote`,
|
|
9
|
+
* `title`, `domain`, `node_uuid`), and a `scope_receipt` describing which
|
|
10
|
+
* part of the workspace was searched — what you can see is enforced
|
|
11
|
+
* server-side by your token's scope.
|
|
12
|
+
*/
|
|
13
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
14
|
+
import type { HebbianClient } from "../client.js";
|
|
15
|
+
export declare const HEBBIAN_ASK: Tool;
|
|
16
|
+
interface AskArgs {
|
|
17
|
+
question: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function handleAsk(client: HebbianClient, args: AskArgs): Promise<string>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=ask.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/tools/ask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,eAAO,MAAM,WAAW,EAAE,IAuBzB,CAAC;AAEF,UAAU,OAAO;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/ask.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_ask
|
|
5
|
+
* Synthesis Q&A grounded in the workspace, returned with source quotes.
|
|
6
|
+
* Maps to: POST /ask (request body: { query })
|
|
7
|
+
*
|
|
8
|
+
* The API response includes `answer`, `sources[]` (each with a `quote`,
|
|
9
|
+
* `title`, `domain`, `node_uuid`), and a `scope_receipt` describing which
|
|
10
|
+
* part of the workspace was searched — what you can see is enforced
|
|
11
|
+
* server-side by your token's scope.
|
|
12
|
+
*/
|
|
13
|
+
import { HebbianApiError } from "../client.js";
|
|
14
|
+
export const HEBBIAN_ASK = {
|
|
15
|
+
name: "hebbian_ask",
|
|
16
|
+
description: "Ask a synthesis question grounded in your Hebbian workspace. Returns an " +
|
|
17
|
+
"answer backed by source quotes (each citing the node it came from) plus a " +
|
|
18
|
+
"scope receipt showing what the answer was drawn from. Use this when you " +
|
|
19
|
+
"need synthesised insight — not just a list of nodes. What the answer can " +
|
|
20
|
+
"draw on is determined by your token's scope and enforced server-side. " +
|
|
21
|
+
"Note: each call consumes your workspace's AI-action budget (metered in billing).",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
question: {
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "Natural language question to ask your Hebbian workspace. " +
|
|
28
|
+
"Be specific — the answer is grounded in source quotes, " +
|
|
29
|
+
"so precise questions yield more accurate citations.",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
required: ["question"],
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
export async function handleAsk(client, args) {
|
|
37
|
+
const { question } = args;
|
|
38
|
+
if (!question || typeof question !== "string" || question.trim().length === 0) {
|
|
39
|
+
throw new Error("question is required and must be a non-empty string");
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
// API contract: the request field is `query`.
|
|
43
|
+
const result = await client.post("/ask", { query: question.trim() });
|
|
44
|
+
return JSON.stringify(result, null, 2);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
if (err instanceof HebbianApiError) {
|
|
48
|
+
throw new Error(err.toToolError());
|
|
49
|
+
}
|
|
50
|
+
throw err;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=ask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../src/tools/ask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,MAAM,WAAW,GAAS;IAC/B,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,0EAA0E;QAC1E,4EAA4E;QAC5E,0EAA0E;QAC1E,2EAA2E;QAC3E,wEAAwE;QACxE,kFAAkF;IACpF,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,2DAA2D;oBAC3D,yDAAyD;oBACzD,qDAAqD;aACxD;SACF;QACD,QAAQ,EAAE,CAAC,UAAU,CAAC;QACtB,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAMF,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAqB,EACrB,IAAa;IAEb,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAE1B,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,CAAC;QACH,8CAA8C;QAC9C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACrE,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/capture.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_capture
|
|
5
|
+
* Writes a note into the workspace. Confidential-by-default: captures are
|
|
6
|
+
* private to you unless you explicitly contribute them to the company pool.
|
|
7
|
+
* Maps to: POST /capture
|
|
8
|
+
* body: { title, body, domain?, tags?, owner_kind? }
|
|
9
|
+
*/
|
|
10
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
11
|
+
import type { HebbianClient } from "../client.js";
|
|
12
|
+
export declare const HEBBIAN_CAPTURE: Tool;
|
|
13
|
+
interface CaptureArgs {
|
|
14
|
+
title: string;
|
|
15
|
+
text: string;
|
|
16
|
+
domain?: string;
|
|
17
|
+
tags?: string[];
|
|
18
|
+
scope?: "private" | "company";
|
|
19
|
+
}
|
|
20
|
+
export declare function handleCapture(client: HebbianClient, args: CaptureArgs): Promise<string>;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/tools/capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,eAAO,MAAM,eAAe,EAAE,IA6C7B,CAAC;AAEF,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CAC/B;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,MAAM,CAAC,CA8BjB"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/capture.ts
|
|
3
|
+
*
|
|
4
|
+
* Tool: hebbian_capture
|
|
5
|
+
* Writes a note into the workspace. Confidential-by-default: captures are
|
|
6
|
+
* private to you unless you explicitly contribute them to the company pool.
|
|
7
|
+
* Maps to: POST /capture
|
|
8
|
+
* body: { title, body, domain?, tags?, owner_kind? }
|
|
9
|
+
*/
|
|
10
|
+
import { HebbianApiError } from "../client.js";
|
|
11
|
+
export const HEBBIAN_CAPTURE = {
|
|
12
|
+
name: "hebbian_capture",
|
|
13
|
+
description: "Capture a note into your Hebbian workspace directly from your AI session. " +
|
|
14
|
+
"Captures are confidential-by-default — private to you unless you set " +
|
|
15
|
+
"scope='company' to contribute the note to the shared company workspace. " +
|
|
16
|
+
"Returns the created node UUID. Captured notes appear in the activity " +
|
|
17
|
+
"timeline. Note: writes are subject to your token's permissions, enforced " +
|
|
18
|
+
"server-side.",
|
|
19
|
+
inputSchema: {
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {
|
|
22
|
+
title: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description: "Short title for the note. Required.",
|
|
25
|
+
},
|
|
26
|
+
text: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description: "Body of the note (Markdown). A raw thought, meeting note, decision, " +
|
|
29
|
+
"code snippet with context, or any knowledge worth preserving.",
|
|
30
|
+
},
|
|
31
|
+
domain: {
|
|
32
|
+
type: "string",
|
|
33
|
+
description: "Optional knowledge domain hint (e.g. 'Company', 'CRM', 'Compass', " +
|
|
34
|
+
"'Axis', 'Mirror'). Omit to let the workspace classify it.",
|
|
35
|
+
},
|
|
36
|
+
tags: {
|
|
37
|
+
type: "array",
|
|
38
|
+
items: { type: "string" },
|
|
39
|
+
description: "Optional free-form tags.",
|
|
40
|
+
},
|
|
41
|
+
scope: {
|
|
42
|
+
type: "string",
|
|
43
|
+
enum: ["private", "company"],
|
|
44
|
+
description: "Where this note lives. 'private' (default) keeps it visible only to " +
|
|
45
|
+
"you; 'company' contributes it to the shared company workspace. " +
|
|
46
|
+
"Company-scope writes require the appropriate permission on your token.",
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
required: ["title", "text"],
|
|
50
|
+
additionalProperties: false,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
export async function handleCapture(client, args) {
|
|
54
|
+
const { title, text, domain, tags, scope } = args;
|
|
55
|
+
if (!title || typeof title !== "string" || title.trim().length === 0) {
|
|
56
|
+
throw new Error("title is required and must be a non-empty string");
|
|
57
|
+
}
|
|
58
|
+
if (!text || typeof text !== "string" || text.trim().length === 0) {
|
|
59
|
+
throw new Error("text is required and must be a non-empty string");
|
|
60
|
+
}
|
|
61
|
+
// API contract: { title, body, domain?, tags?, owner_kind? }.
|
|
62
|
+
// owner_kind defaults to employee-private at the API; we only send 'company'
|
|
63
|
+
// when the caller explicitly opts in.
|
|
64
|
+
const body = {
|
|
65
|
+
title: title.trim(),
|
|
66
|
+
body: text.trim(),
|
|
67
|
+
};
|
|
68
|
+
if (domain)
|
|
69
|
+
body["domain"] = domain;
|
|
70
|
+
if (tags && tags.length > 0)
|
|
71
|
+
body["tags"] = tags;
|
|
72
|
+
if (scope === "company")
|
|
73
|
+
body["owner_kind"] = "company";
|
|
74
|
+
try {
|
|
75
|
+
const result = await client.post("/capture", body);
|
|
76
|
+
return JSON.stringify(result, null, 2);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
if (err instanceof HebbianApiError) {
|
|
80
|
+
throw new Error(err.toToolError());
|
|
81
|
+
}
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/tools/capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACT,4EAA4E;QAC5E,uEAAuE;QACvE,0EAA0E;QAC1E,uEAAuE;QACvE,2EAA2E;QAC3E,cAAc;IAChB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,qCAAqC;aACnD;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,sEAAsE;oBACtE,+DAA+D;aAClE;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,oEAAoE;oBACpE,2DAA2D;aAC9D;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,WAAW,EAAE,0BAA0B;aACxC;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;gBAC5B,WAAW,EACT,sEAAsE;oBACtE,iEAAiE;oBACjE,wEAAwE;aAC3E;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;QAC3B,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAUF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAqB,EACrB,IAAiB;IAEjB,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IAElD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,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,8DAA8D;IAC9D,6EAA6E;IAC7E,sCAAsC;IACtC,MAAM,IAAI,GAA4B;QACpC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;QACnB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;KAClB,CAAC;IACF,IAAI,MAAM;QAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;IACpC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACjD,IAAI,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;IAExD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACnD,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,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/graph_helpers.ts
|
|
3
|
+
*
|
|
4
|
+
* Shared helpers for tools that operate over the workspace graph.
|
|
5
|
+
*
|
|
6
|
+
* The Hebbian API exposes the workspace as a single scoped graph
|
|
7
|
+
* (GET /vault/graph) where every node carries its title, summary, domain,
|
|
8
|
+
* archetype, tags, inline edges, and provenance. Several MCP tools
|
|
9
|
+
* (search, traverse, provenance) are presentation-layer views over that
|
|
10
|
+
* graph: the API returns the data, this module shapes it for the agent.
|
|
11
|
+
* Access control is enforced server-side — the graph only ever contains
|
|
12
|
+
* what the caller's token is allowed to see.
|
|
13
|
+
*/
|
|
14
|
+
import type { HebbianClient } from "../client.js";
|
|
15
|
+
export interface GraphEdge {
|
|
16
|
+
to?: string;
|
|
17
|
+
source_uuid?: string;
|
|
18
|
+
target_uuid?: string;
|
|
19
|
+
direction?: "in" | "out";
|
|
20
|
+
relation_type?: string;
|
|
21
|
+
weight?: number;
|
|
22
|
+
[k: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Normalise an edge owned by `ownerUuid` into (source, target, relation, weight).
|
|
26
|
+
* Handles both the /vault/graph `{ to }` shape and the /nodes/:uuid
|
|
27
|
+
* `{ source_uuid, target_uuid }` shape.
|
|
28
|
+
*/
|
|
29
|
+
export declare function normaliseEdge(e: GraphEdge, ownerUuid: string): {
|
|
30
|
+
source: string;
|
|
31
|
+
target: string;
|
|
32
|
+
relation?: string;
|
|
33
|
+
weight?: number;
|
|
34
|
+
};
|
|
35
|
+
export interface GraphNode {
|
|
36
|
+
uuid: string;
|
|
37
|
+
title?: string;
|
|
38
|
+
summary?: string;
|
|
39
|
+
detail?: string;
|
|
40
|
+
domain?: string;
|
|
41
|
+
archetype?: string;
|
|
42
|
+
actor?: string;
|
|
43
|
+
tags?: string[];
|
|
44
|
+
edges?: GraphEdge[];
|
|
45
|
+
provenance?: unknown;
|
|
46
|
+
[k: string]: unknown;
|
|
47
|
+
}
|
|
48
|
+
/** Fetch the full scoped workspace graph for the current token. */
|
|
49
|
+
export declare function fetchGraph(client: HebbianClient): Promise<GraphNode[]>;
|
|
50
|
+
/** Score a node against query terms. Returns 0 when no term matches. */
|
|
51
|
+
export declare function scoreNode(n: GraphNode, terms: string[]): number;
|
|
52
|
+
/** Split a query string into lower-cased terms. */
|
|
53
|
+
export declare function queryTerms(q: string): string[];
|
|
54
|
+
/** A compact node summary for search/traverse result lists. */
|
|
55
|
+
export declare function summarise(n: GraphNode): Record<string, unknown>;
|
|
56
|
+
//# sourceMappingURL=graph_helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph_helpers.d.ts","sourceRoot":"","sources":["../../src/tools/graph_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,SAAS;IAIxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,CAAC,EAAE,SAAS,EACZ,SAAS,EAAE,MAAM,GAChB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAQxE;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAOD,mEAAmE;AACnE,wBAAsB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAG5E;AAeD,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAW/D;AAED,mDAAmD;AACnD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAM9C;AAED,+DAA+D;AAC/D,wBAAgB,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAU/D"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/graph_helpers.ts
|
|
3
|
+
*
|
|
4
|
+
* Shared helpers for tools that operate over the workspace graph.
|
|
5
|
+
*
|
|
6
|
+
* The Hebbian API exposes the workspace as a single scoped graph
|
|
7
|
+
* (GET /vault/graph) where every node carries its title, summary, domain,
|
|
8
|
+
* archetype, tags, inline edges, and provenance. Several MCP tools
|
|
9
|
+
* (search, traverse, provenance) are presentation-layer views over that
|
|
10
|
+
* graph: the API returns the data, this module shapes it for the agent.
|
|
11
|
+
* Access control is enforced server-side — the graph only ever contains
|
|
12
|
+
* what the caller's token is allowed to see.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Normalise an edge owned by `ownerUuid` into (source, target, relation, weight).
|
|
16
|
+
* Handles both the /vault/graph `{ to }` shape and the /nodes/:uuid
|
|
17
|
+
* `{ source_uuid, target_uuid }` shape.
|
|
18
|
+
*/
|
|
19
|
+
export function normaliseEdge(e, ownerUuid) {
|
|
20
|
+
if (typeof e.to === "string") {
|
|
21
|
+
// Adjacency form: owner -> to (direction not exposed; treat owner as source).
|
|
22
|
+
return { source: ownerUuid, target: e.to, relation: e.relation_type, weight: e.weight };
|
|
23
|
+
}
|
|
24
|
+
const src = e.source_uuid ?? ownerUuid;
|
|
25
|
+
const tgt = e.target_uuid ?? ownerUuid;
|
|
26
|
+
return { source: src, target: tgt, relation: e.relation_type, weight: e.weight };
|
|
27
|
+
}
|
|
28
|
+
/** Fetch the full scoped workspace graph for the current token. */
|
|
29
|
+
export async function fetchGraph(client) {
|
|
30
|
+
const resp = (await client.get("/vault/graph"));
|
|
31
|
+
return Array.isArray(resp.nodes) ? resp.nodes : [];
|
|
32
|
+
}
|
|
33
|
+
/** Lower-cased haystack of a node's searchable text fields. */
|
|
34
|
+
function nodeHaystack(n) {
|
|
35
|
+
const parts = [
|
|
36
|
+
n.title,
|
|
37
|
+
n.summary,
|
|
38
|
+
n.detail,
|
|
39
|
+
n.domain,
|
|
40
|
+
n.archetype,
|
|
41
|
+
...(Array.isArray(n.tags) ? n.tags : []),
|
|
42
|
+
];
|
|
43
|
+
return parts.filter(Boolean).join(" \n ").toLowerCase();
|
|
44
|
+
}
|
|
45
|
+
/** Score a node against query terms. Returns 0 when no term matches. */
|
|
46
|
+
export function scoreNode(n, terms) {
|
|
47
|
+
if (terms.length === 0)
|
|
48
|
+
return 0;
|
|
49
|
+
const hay = nodeHaystack(n);
|
|
50
|
+
const title = (n.title ?? "").toLowerCase();
|
|
51
|
+
let score = 0;
|
|
52
|
+
for (const t of terms) {
|
|
53
|
+
if (!t)
|
|
54
|
+
continue;
|
|
55
|
+
if (title.includes(t))
|
|
56
|
+
score += 3; // title hits weigh more
|
|
57
|
+
else if (hay.includes(t))
|
|
58
|
+
score += 1;
|
|
59
|
+
}
|
|
60
|
+
return score;
|
|
61
|
+
}
|
|
62
|
+
/** Split a query string into lower-cased terms. */
|
|
63
|
+
export function queryTerms(q) {
|
|
64
|
+
return q
|
|
65
|
+
.toLowerCase()
|
|
66
|
+
.split(/\s+/)
|
|
67
|
+
.map((t) => t.trim())
|
|
68
|
+
.filter((t) => t.length > 0);
|
|
69
|
+
}
|
|
70
|
+
/** A compact node summary for search/traverse result lists. */
|
|
71
|
+
export function summarise(n) {
|
|
72
|
+
const snippet = (n.summary ?? n.detail ?? "").toString().slice(0, 280);
|
|
73
|
+
return {
|
|
74
|
+
uuid: n.uuid,
|
|
75
|
+
title: n.title ?? null,
|
|
76
|
+
domain: n.domain ?? null,
|
|
77
|
+
archetype: n.archetype ?? null,
|
|
78
|
+
tags: n.tags ?? [],
|
|
79
|
+
snippet,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=graph_helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph_helpers.js","sourceRoot":"","sources":["../../src/tools/graph_helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/index.ts
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all 8 tool definitions for @hebbianvault/mcp.
|
|
5
|
+
*/
|
|
6
|
+
export { HEBBIAN_READ_NODE, handleReadNode } from "./read_node.js";
|
|
7
|
+
export { HEBBIAN_SEARCH, handleSearch } from "./search.js";
|
|
8
|
+
export { HEBBIAN_ASK, handleAsk } from "./ask.js";
|
|
9
|
+
export { HEBBIAN_CAPTURE, handleCapture } from "./capture.js";
|
|
10
|
+
export { HEBBIAN_TRAVERSE, handleTraverse } from "./traverse.js";
|
|
11
|
+
export { HEBBIAN_PROVENANCE, handleProvenance } from "./provenance.js";
|
|
12
|
+
export { HEBBIAN_SALIENCE, handleSalience } from "./salience.js";
|
|
13
|
+
export { HEBBIAN_RECENT_ACTIVITY, handleRecentActivity } from "./recent_activity.js";
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","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,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tools/index.ts
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all 8 tool definitions for @hebbianvault/mcp.
|
|
5
|
+
*/
|
|
6
|
+
export { HEBBIAN_READ_NODE, handleReadNode } from "./read_node.js";
|
|
7
|
+
export { HEBBIAN_SEARCH, handleSearch } from "./search.js";
|
|
8
|
+
export { HEBBIAN_ASK, handleAsk } from "./ask.js";
|
|
9
|
+
export { HEBBIAN_CAPTURE, handleCapture } from "./capture.js";
|
|
10
|
+
export { HEBBIAN_TRAVERSE, handleTraverse } from "./traverse.js";
|
|
11
|
+
export { HEBBIAN_PROVENANCE, handleProvenance } from "./provenance.js";
|
|
12
|
+
export { HEBBIAN_SALIENCE, handleSalience } from "./salience.js";
|
|
13
|
+
export { HEBBIAN_RECENT_ACTIVITY, handleRecentActivity } from "./recent_activity.js";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|