backpack-ontology 0.2.0 → 0.2.2
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/README.md +78 -139
- package/dist/auth/oauth.d.ts +32 -0
- package/dist/auth/oauth.d.ts.map +1 -0
- package/dist/auth/oauth.js +208 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/bin/backpack-app.d.ts +3 -0
- package/dist/bin/backpack-app.d.ts.map +1 -0
- package/dist/bin/backpack-app.js +37 -0
- package/dist/bin/backpack-app.js.map +1 -0
- package/dist/bin/backpack-sync.d.ts +3 -0
- package/dist/bin/backpack-sync.d.ts.map +1 -0
- package/dist/bin/backpack-sync.js +148 -0
- package/dist/bin/backpack-sync.js.map +1 -0
- package/dist/bin/backpack.js +4 -4
- package/dist/bin/backpack.js.map +1 -1
- package/dist/bin/init.js +12 -79
- package/dist/bin/init.js.map +1 -1
- package/dist/core/hooks.d.ts +6 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +68 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +24 -4
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +29 -7
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/bulk-tools.js +1 -1
- package/dist/mcp/tools/bulk-tools.js.map +1 -1
- package/dist/mcp/tools/edge-tools.js +3 -3
- package/dist/mcp/tools/edge-tools.js.map +1 -1
- package/dist/mcp/tools/node-tools.js +7 -7
- package/dist/mcp/tools/node-tools.js.map +1 -1
- package/dist/mcp/tools/ontology-tools.js +5 -5
- package/dist/mcp/tools/ontology-tools.js.map +1 -1
- package/dist/storage/backpack-app-backend.d.ts +22 -0
- package/dist/storage/backpack-app-backend.d.ts.map +1 -0
- package/dist/storage/backpack-app-backend.js +80 -0
- package/dist/storage/backpack-app-backend.js.map +1 -0
- package/hooks/hooks.json +2 -2
- package/package.json +3 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import * as crypto from "node:crypto";
|
|
3
|
+
import * as fs from "node:fs/promises";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { JsonFileBackend } from "../storage/json-file-backend.js";
|
|
6
|
+
import { BackpackAppBackend } from "../storage/backpack-app-backend.js";
|
|
7
|
+
import { OAuthClient } from "../auth/oauth.js";
|
|
8
|
+
import { loadConfig } from "../core/config.js";
|
|
9
|
+
const DEFAULTS = {
|
|
10
|
+
url: "https://app.backpackontology.com",
|
|
11
|
+
clientId: "YOUR_ENTRA_CLIENT_ID_HERE",
|
|
12
|
+
issuerUrl: "https://YOUR_TENANT.ciamlogin.com/YOUR_TENANT_ID/v2.0",
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Try to read backpack-app config from .mcp.json in the current directory
|
|
16
|
+
* or parent directories. This lets sync reuse the same auth as the MCP server.
|
|
17
|
+
*/
|
|
18
|
+
async function discoverMcpConfig() {
|
|
19
|
+
let dir = process.cwd();
|
|
20
|
+
for (let i = 0; i < 10; i++) {
|
|
21
|
+
const mcpPath = path.join(dir, ".mcp.json");
|
|
22
|
+
try {
|
|
23
|
+
const raw = await fs.readFile(mcpPath, "utf-8");
|
|
24
|
+
const config = JSON.parse(raw);
|
|
25
|
+
// Look for any backpack-app server config
|
|
26
|
+
for (const [name, server] of Object.entries(config.mcpServers ?? {})) {
|
|
27
|
+
if (name.startsWith("backpack-app") && server.env) {
|
|
28
|
+
// Apply TLS override if configured (for local dev with self-signed certs)
|
|
29
|
+
if (server.env.NODE_TLS_REJECT_UNAUTHORIZED) {
|
|
30
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED =
|
|
31
|
+
server.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
url: server.env.BACKPACK_APP_URL,
|
|
35
|
+
clientId: server.env.BACKPACK_APP_CLIENT_ID,
|
|
36
|
+
issuerUrl: server.env.BACKPACK_APP_ISSUER_URL,
|
|
37
|
+
token: server.env.BACKPACK_APP_TOKEN,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// No .mcp.json here, try parent
|
|
44
|
+
}
|
|
45
|
+
const parent = path.dirname(dir);
|
|
46
|
+
if (parent === dir)
|
|
47
|
+
break;
|
|
48
|
+
dir = parent;
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
async function main() {
|
|
53
|
+
// Auto-discover config from .mcp.json if no env vars are set
|
|
54
|
+
const discovered = await discoverMcpConfig();
|
|
55
|
+
const apiUrl = process.env.BACKPACK_APP_URL ||
|
|
56
|
+
discovered?.url ||
|
|
57
|
+
DEFAULTS.url;
|
|
58
|
+
const clientId = process.env.BACKPACK_APP_CLIENT_ID ||
|
|
59
|
+
discovered?.clientId ||
|
|
60
|
+
DEFAULTS.clientId;
|
|
61
|
+
const issuerUrl = process.env.BACKPACK_APP_ISSUER_URL ||
|
|
62
|
+
discovered?.issuerUrl ||
|
|
63
|
+
DEFAULTS.issuerUrl;
|
|
64
|
+
const staticToken = process.env.BACKPACK_APP_TOKEN ||
|
|
65
|
+
discovered?.token;
|
|
66
|
+
console.log("");
|
|
67
|
+
console.log(" Backpack Sync — upload local ontologies to Backpack App");
|
|
68
|
+
console.log(` Target: ${apiUrl}`);
|
|
69
|
+
console.log("");
|
|
70
|
+
// Set up local backend
|
|
71
|
+
const config = await loadConfig();
|
|
72
|
+
const local = new JsonFileBackend(config.dataDir);
|
|
73
|
+
await local.initialize();
|
|
74
|
+
// Set up remote backend
|
|
75
|
+
let remote;
|
|
76
|
+
if (staticToken) {
|
|
77
|
+
remote = new BackpackAppBackend(apiUrl, staticToken);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const cacheKey = crypto
|
|
81
|
+
.createHash("sha256")
|
|
82
|
+
.update(apiUrl)
|
|
83
|
+
.digest("hex")
|
|
84
|
+
.slice(0, 12);
|
|
85
|
+
const oauth = new OAuthClient(clientId, issuerUrl, cacheKey);
|
|
86
|
+
remote = new BackpackAppBackend(apiUrl, () => oauth.getAccessToken());
|
|
87
|
+
}
|
|
88
|
+
// List local ontologies
|
|
89
|
+
const localOntologies = await local.listOntologies();
|
|
90
|
+
if (localOntologies.length === 0) {
|
|
91
|
+
console.log(" No local ontologies found. Nothing to sync.");
|
|
92
|
+
console.log("");
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
console.log(` Found ${localOntologies.length} local ontology(s):`);
|
|
96
|
+
for (const o of localOntologies) {
|
|
97
|
+
console.log(` - ${o.name} (${o.nodeCount} nodes, ${o.edgeCount} edges)`);
|
|
98
|
+
}
|
|
99
|
+
console.log("");
|
|
100
|
+
// Check which already exist remotely
|
|
101
|
+
let remoteNames;
|
|
102
|
+
try {
|
|
103
|
+
const remoteOntologies = await remote.listOntologies();
|
|
104
|
+
remoteNames = new Set(remoteOntologies.map((o) => o.name));
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
console.error(` Failed to connect to Backpack App at ${apiUrl}:`, err.message);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
let created = 0;
|
|
111
|
+
let updated = 0;
|
|
112
|
+
let skipped = 0;
|
|
113
|
+
for (const summary of localOntologies) {
|
|
114
|
+
const data = await local.loadOntology(summary.name);
|
|
115
|
+
const exists = remoteNames.has(summary.name);
|
|
116
|
+
if (exists) {
|
|
117
|
+
await remote.saveOntology(summary.name, data);
|
|
118
|
+
updated++;
|
|
119
|
+
console.log(` Updated: ${summary.name}`);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
try {
|
|
123
|
+
await remote.createOntology(summary.name, data.metadata.description);
|
|
124
|
+
await remote.saveOntology(summary.name, data);
|
|
125
|
+
created++;
|
|
126
|
+
console.log(` Created: ${summary.name}`);
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
console.error(` Failed: ${summary.name} — ${err.message}`);
|
|
130
|
+
skipped++;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
console.log("");
|
|
135
|
+
console.log(` Done. ${created} created, ${updated} updated, ${skipped} failed.`);
|
|
136
|
+
if (created + updated > 0) {
|
|
137
|
+
console.log("");
|
|
138
|
+
console.log(" Your ontologies are now in Backpack App.");
|
|
139
|
+
console.log(" To switch to cloud mode, update your .mcp.json to use backpack-app");
|
|
140
|
+
console.log(" instead of backpack.");
|
|
141
|
+
}
|
|
142
|
+
console.log("");
|
|
143
|
+
}
|
|
144
|
+
main().catch((error) => {
|
|
145
|
+
console.error("Error:", error.message ?? error);
|
|
146
|
+
process.exit(1);
|
|
147
|
+
});
|
|
148
|
+
//# sourceMappingURL=backpack-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backpack-sync.js","sourceRoot":"","sources":["../../src/bin/backpack-sync.ts"],"names":[],"mappings":"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"}
|
package/dist/bin/backpack.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
import { createMcpServer } from "../mcp/server.js";
|
|
4
|
-
import { JsonFileBackend } from "../storage/json-file-backend.js";
|
|
5
4
|
import { loadConfig } from "../core/config.js";
|
|
5
|
+
import { ensureHooksInstalled } from "../core/hooks.js";
|
|
6
6
|
import { shutdown as shutdownTelemetry } from "../core/telemetry.js";
|
|
7
7
|
async function main() {
|
|
8
8
|
const config = await loadConfig();
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
const server = await createMcpServer(
|
|
9
|
+
// Install hooks on first run (silent, non-blocking)
|
|
10
|
+
ensureHooksInstalled().catch(() => { });
|
|
11
|
+
const server = await createMcpServer({ mode: "local", dataDir: config.dataDir });
|
|
12
12
|
const transport = new StdioServerTransport();
|
|
13
13
|
await server.connect(transport);
|
|
14
14
|
// Log to stderr because stdout is reserved for the MCP protocol
|
package/dist/bin/backpack.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backpack.js","sourceRoot":"","sources":["../../src/bin/backpack.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"backpack.js","sourceRoot":"","sources":["../../src/bin/backpack.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAErE,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAElC,oDAAoD;IACpD,oBAAoB,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAEvC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACjF,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,gEAAgE;IAChE,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;AACxD,CAAC;AAED,kDAAkD;AAClD,KAAK,UAAU,gBAAgB;IAC7B,MAAM,iBAAiB,EAAE,CAAC;IAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AACvC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;AAExC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/bin/init.js
CHANGED
|
@@ -1,88 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
2
|
+
import { ensureHooksInstalled } from "../core/hooks.js";
|
|
3
|
+
/**
|
|
4
|
+
* `backpack-init` — manually install Backpack hooks.
|
|
5
|
+
*
|
|
6
|
+
* Note: Hooks are now installed automatically when the MCP server starts.
|
|
7
|
+
* This command exists for users who want to explicitly reinstall or verify.
|
|
8
|
+
*/
|
|
10
9
|
async function main() {
|
|
11
|
-
|
|
12
|
-
const claudeDir = path.join(projectDir, ".claude");
|
|
13
|
-
const settingsPath = path.join(claudeDir, "settings.json");
|
|
14
|
-
// Load the hooks configuration shipped with backpack-ontology
|
|
15
|
-
const thisFile = fileURLToPath(import.meta.url);
|
|
16
|
-
const packageRoot = path.resolve(path.dirname(thisFile), "..", "..");
|
|
17
|
-
const hooksJsonPath = path.join(packageRoot, "hooks", "hooks.json");
|
|
18
|
-
let hooksConfig;
|
|
19
|
-
try {
|
|
20
|
-
const raw = await fs.readFile(hooksJsonPath, "utf-8");
|
|
21
|
-
hooksConfig = JSON.parse(raw);
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
console.error("Error: could not read hooks configuration from backpack-ontology package.");
|
|
25
|
-
console.error(`Expected at: ${hooksJsonPath}`);
|
|
26
|
-
process.exit(1);
|
|
27
|
-
}
|
|
28
|
-
// Ensure .claude directory exists
|
|
29
|
-
await fs.mkdir(claudeDir, { recursive: true });
|
|
30
|
-
// Read existing settings or start fresh
|
|
31
|
-
let settings = {};
|
|
32
|
-
try {
|
|
33
|
-
const raw = await fs.readFile(settingsPath, "utf-8");
|
|
34
|
-
settings = JSON.parse(raw);
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
// File doesn't exist or isn't valid JSON — start fresh
|
|
38
|
-
}
|
|
39
|
-
// Merge hooks — backpack hooks are added alongside any existing hooks
|
|
40
|
-
if (!settings.hooks) {
|
|
41
|
-
settings.hooks = {};
|
|
42
|
-
}
|
|
43
|
-
const existingHooks = settings.hooks;
|
|
44
|
-
const newHooks = (hooksConfig.hooks ?? {});
|
|
45
|
-
let alreadyConfigured = false;
|
|
46
|
-
for (const [event, rules] of Object.entries(newHooks)) {
|
|
47
|
-
if (!existingHooks[event]) {
|
|
48
|
-
existingHooks[event] = rules;
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
const existing = existingHooks[event];
|
|
52
|
-
if (Array.isArray(existing) && hasBackpackRule(existing)) {
|
|
53
|
-
// Backpack hooks already present for this event — skip to avoid duplicates
|
|
54
|
-
alreadyConfigured = true;
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
// Append backpack hook rules to existing event rules
|
|
58
|
-
if (Array.isArray(existing) && Array.isArray(rules)) {
|
|
59
|
-
existingHooks[event] = [...existing, ...rules];
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
existingHooks[event] = rules;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (alreadyConfigured) {
|
|
67
|
-
console.log("");
|
|
68
|
-
console.log(" Backpack hooks are already configured in: " + settingsPath);
|
|
69
|
-
console.log(" No changes made. To reconfigure, remove the existing backpack hooks first.");
|
|
70
|
-
console.log("");
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
settings.hooks = existingHooks;
|
|
74
|
-
// Write settings
|
|
75
|
-
await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
76
|
-
console.log("");
|
|
77
|
-
console.log(" Backpack hooks configured successfully!");
|
|
10
|
+
await ensureHooksInstalled();
|
|
78
11
|
console.log("");
|
|
79
|
-
console.log("
|
|
12
|
+
console.log(" Backpack hooks are installed.");
|
|
80
13
|
console.log("");
|
|
81
14
|
console.log(" What's enabled:");
|
|
82
15
|
console.log(" - Auto-capture: a background agent reviews your Claude conversations");
|
|
83
|
-
console.log(" and
|
|
84
|
-
console.log(" - Viewer suggestions: after
|
|
85
|
-
console.log(" visualize your knowledge graph
|
|
16
|
+
console.log(" and saves meaningful knowledge to your backpack.");
|
|
17
|
+
console.log(" - Viewer suggestions: after updates, you'll be reminded to");
|
|
18
|
+
console.log(" visualize your knowledge graph.");
|
|
86
19
|
console.log("");
|
|
87
20
|
console.log(" To disable, remove the backpack hooks from .claude/settings.json");
|
|
88
21
|
console.log("");
|
package/dist/bin/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/bin/init.ts"],"names":[],"mappings":";AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/bin/init.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD;;;;;GAKG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,oBAAoB,EAAE,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;IACxF,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;IACtE,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;IAClF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-install Backpack hooks into .claude/settings.json if not already present.
|
|
3
|
+
* Runs silently on MCP server startup — users opt out by removing the hooks.
|
|
4
|
+
*/
|
|
5
|
+
export declare function ensureHooksInstalled(): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/core/hooks.ts"],"names":[],"mappings":"AA+BA;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAoE1D"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
/** Check if a hook rule array already contains a backpack-originated rule. */
|
|
5
|
+
function hasBackpackRule(rules) {
|
|
6
|
+
return rules.some((r) => r.hooks?.some((h) => (h.prompt && h.prompt.includes("Backpack")) ||
|
|
7
|
+
(h.command && h.command.includes("backpack"))) ?? false);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Auto-install Backpack hooks into .claude/settings.json if not already present.
|
|
11
|
+
* Runs silently on MCP server startup — users opt out by removing the hooks.
|
|
12
|
+
*/
|
|
13
|
+
export async function ensureHooksInstalled() {
|
|
14
|
+
const projectDir = process.cwd();
|
|
15
|
+
const claudeDir = path.join(projectDir, ".claude");
|
|
16
|
+
const settingsPath = path.join(claudeDir, "settings.json");
|
|
17
|
+
// Locate hooks.json shipped with the package
|
|
18
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
19
|
+
const packageRoot = path.resolve(path.dirname(thisFile), "..", "..");
|
|
20
|
+
const hooksJsonPath = path.join(packageRoot, "hooks", "hooks.json");
|
|
21
|
+
let hooksConfig;
|
|
22
|
+
try {
|
|
23
|
+
const raw = await fs.readFile(hooksJsonPath, "utf-8");
|
|
24
|
+
hooksConfig = JSON.parse(raw);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return; // Can't read hooks config — skip silently
|
|
28
|
+
}
|
|
29
|
+
await fs.mkdir(claudeDir, { recursive: true });
|
|
30
|
+
let settings = {};
|
|
31
|
+
try {
|
|
32
|
+
const raw = await fs.readFile(settingsPath, "utf-8");
|
|
33
|
+
settings = JSON.parse(raw);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// File doesn't exist or isn't valid JSON — start fresh
|
|
37
|
+
}
|
|
38
|
+
if (!settings.hooks) {
|
|
39
|
+
settings.hooks = {};
|
|
40
|
+
}
|
|
41
|
+
const existingHooks = settings.hooks;
|
|
42
|
+
const newHooks = (hooksConfig.hooks ?? {});
|
|
43
|
+
let changed = false;
|
|
44
|
+
for (const [event, rules] of Object.entries(newHooks)) {
|
|
45
|
+
if (!existingHooks[event]) {
|
|
46
|
+
existingHooks[event] = rules;
|
|
47
|
+
changed = true;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const existing = existingHooks[event];
|
|
51
|
+
if (Array.isArray(existing) &&
|
|
52
|
+
hasBackpackRule(existing)) {
|
|
53
|
+
continue; // Already installed
|
|
54
|
+
}
|
|
55
|
+
if (Array.isArray(existing) && Array.isArray(rules)) {
|
|
56
|
+
existingHooks[event] = [...existing, ...rules];
|
|
57
|
+
changed = true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!changed)
|
|
62
|
+
return;
|
|
63
|
+
settings.hooks = existingHooks;
|
|
64
|
+
await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
65
|
+
console.error("Backpack hooks enabled (auto-capture + viewer suggestions). " +
|
|
66
|
+
"To disable, remove backpack hooks from .claude/settings.json");
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/core/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,8 +3,9 @@ export { Graph } from "./core/graph.js";
|
|
|
3
3
|
export { configDir, dataDir, configFile } from "./core/paths.js";
|
|
4
4
|
export { loadConfig } from "./core/config.js";
|
|
5
5
|
export type { BackpackConfig } from "./core/config.js";
|
|
6
|
-
export type { Node, Edge, OntologyData, OntologyMetadata, OntologySummary, NodeSummary, EdgeSummary, NodeTypeInfo, EdgeTypeInfo, ListNodesResult, GetNodeResult, NeighborResult, NeighborEntry,
|
|
6
|
+
export type { Node, Edge, OntologyData, OntologyMetadata, OntologySummary, NodeSummary, EdgeSummary, NodeTypeInfo, EdgeTypeInfo, ListNodesResult, GetNodeResult, NeighborResult, NeighborEntry, } from "./core/types.js";
|
|
7
7
|
export { JsonFileBackend } from "./storage/json-file-backend.js";
|
|
8
8
|
export { initTelemetry, trackEvent, shutdown as shutdownTelemetry } from "./core/telemetry.js";
|
|
9
9
|
export { createMcpServer } from "./mcp/server.js";
|
|
10
|
+
export type { BackpackServerConfig, BackpackLocalConfig, BackpackAppConfig } from "./mcp/server.js";
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EACV,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,aAAa,EACb,cAAc,EACd,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EACV,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGjE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAG/F,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO;AACP,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO;AACP,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAkB9C,mBAAmB;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEjE,YAAY;AACZ,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE/F,qBAAqB;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
|
|
2
|
+
/** Configuration for local file-based storage. */
|
|
3
|
+
export interface BackpackLocalConfig {
|
|
4
|
+
mode: "local";
|
|
5
|
+
dataDir?: string;
|
|
6
|
+
}
|
|
7
|
+
/** Configuration for Backpack App with a static token. */
|
|
8
|
+
export interface BackpackAppTokenConfig {
|
|
9
|
+
mode: "app";
|
|
10
|
+
url: string;
|
|
11
|
+
token: string;
|
|
12
|
+
}
|
|
13
|
+
/** Configuration for Backpack App with OAuth2/OIDC SSO. */
|
|
14
|
+
export interface BackpackAppOAuthConfig {
|
|
15
|
+
mode: "app";
|
|
16
|
+
url: string;
|
|
17
|
+
clientId: string;
|
|
18
|
+
issuerUrl: string;
|
|
19
|
+
}
|
|
20
|
+
export type BackpackAppConfig = BackpackAppTokenConfig | BackpackAppOAuthConfig;
|
|
21
|
+
export type BackpackServerConfig = BackpackLocalConfig | BackpackAppConfig;
|
|
3
22
|
/**
|
|
4
23
|
* Create and configure the MCP server.
|
|
5
24
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
25
|
+
* Supports two modes:
|
|
26
|
+
* - "local" (default): JSON files on disk
|
|
27
|
+
* - "app": Backpack App cloud API (via static token or OAuth2 SSO)
|
|
8
28
|
*/
|
|
9
|
-
export declare function createMcpServer(
|
|
29
|
+
export declare function createMcpServer(config?: BackpackServerConfig): Promise<McpServer>;
|
|
10
30
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE,kDAAkD;AAClD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,0DAA0D;AAC1D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,2DAA2D;AAC3D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,GAAG,sBAAsB,CAAC;AAChF,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAE3E;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,MAAM,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,SAAS,CAAC,CAmDpB"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import * as crypto from "node:crypto";
|
|
1
2
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
3
|
import { Backpack } from "../core/backpack.js";
|
|
3
4
|
import { JsonFileBackend } from "../storage/json-file-backend.js";
|
|
5
|
+
import { BackpackAppBackend } from "../storage/backpack-app-backend.js";
|
|
6
|
+
import { OAuthClient } from "../auth/oauth.js";
|
|
4
7
|
import { initTelemetry } from "../core/telemetry.js";
|
|
5
8
|
import { registerOntologyTools } from "./tools/ontology-tools.js";
|
|
6
9
|
import { registerNodeTools } from "./tools/node-tools.js";
|
|
@@ -9,25 +12,44 @@ import { registerBulkTools } from "./tools/bulk-tools.js";
|
|
|
9
12
|
/**
|
|
10
13
|
* Create and configure the MCP server.
|
|
11
14
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
15
|
+
* Supports two modes:
|
|
16
|
+
* - "local" (default): JSON files on disk
|
|
17
|
+
* - "app": Backpack App cloud API (via static token or OAuth2 SSO)
|
|
14
18
|
*/
|
|
15
|
-
export async function createMcpServer(
|
|
16
|
-
|
|
19
|
+
export async function createMcpServer(config) {
|
|
20
|
+
let backend;
|
|
21
|
+
if (!config || config.mode === "local") {
|
|
22
|
+
backend = new JsonFileBackend(config?.dataDir);
|
|
23
|
+
}
|
|
24
|
+
else if ("token" in config) {
|
|
25
|
+
backend = new BackpackAppBackend(config.url, config.token);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// OAuth2 SSO — opens browser on first run, caches tokens
|
|
29
|
+
const cacheKey = crypto
|
|
30
|
+
.createHash("sha256")
|
|
31
|
+
.update(config.url)
|
|
32
|
+
.digest("hex")
|
|
33
|
+
.slice(0, 12);
|
|
34
|
+
const oauth = new OAuthClient(config.clientId, config.issuerUrl, cacheKey);
|
|
35
|
+
backend = new BackpackAppBackend(config.url, () => oauth.getAccessToken());
|
|
36
|
+
}
|
|
17
37
|
const backpack = new Backpack(backend);
|
|
18
38
|
await backpack.initialize();
|
|
19
39
|
// Initialize telemetry (non-blocking, fails silently)
|
|
20
40
|
try {
|
|
21
41
|
await initTelemetry(backpack);
|
|
22
42
|
}
|
|
23
|
-
catch {
|
|
43
|
+
catch {
|
|
44
|
+
/* noop */
|
|
45
|
+
}
|
|
24
46
|
const server = new McpServer({
|
|
25
47
|
name: "backpack",
|
|
26
48
|
version: "0.2.0",
|
|
27
49
|
}, {
|
|
28
|
-
instructions: `Backpack is
|
|
50
|
+
instructions: `Backpack is the user's persistent knowledge base that carries what matters across conversations. Think of it as a single backpack the user carries everywhere — inside it are ontologies, each one a knowledge graph about a different topic (clients, processes, architecture, etc.).
|
|
29
51
|
|
|
30
|
-
|
|
52
|
+
There is one backpack. Inside it are ontologies. Each ontology contains nodes (things) connected by edges (relationships). Use backpack_list to see what's in the backpack, and backpack_describe to understand an ontology's structure before adding to it. Create a new ontology when the topic is distinct from existing ones.
|
|
31
53
|
|
|
32
54
|
After updating an ontology, let the user know they can visualize their knowledge graph by running: npx backpack-viewer (opens http://localhost:5173)
|
|
33
55
|
|
package/dist/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AA0B1D;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAA6B;IAE7B,IAAI,OAAuB,CAAC;IAE5B,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACvC,OAAO,GAAG,IAAI,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;SAAM,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;QAC7B,OAAO,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC;SAAM,CAAC;QACN,yDAAyD;QACzD,MAAM,QAAQ,GAAG,MAAM;aACpB,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;aAClB,MAAM,CAAC,KAAK,CAAC;aACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChB,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC3E,OAAO,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC;IAE5B,sDAAsD;IACtD,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,UAAU;IACZ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE;;;;;;oLAMgK;KAC/K,CACF,CAAC;IAEF,2BAA2B;IAC3B,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACxC,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACpC,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACpC,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAEpC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { trackEvent } from "../../core/telemetry.js";
|
|
|
3
3
|
export function registerBulkTools(server, backpack) {
|
|
4
4
|
server.registerTool("backpack_import_nodes", {
|
|
5
5
|
title: "Import Nodes",
|
|
6
|
-
description: "
|
|
6
|
+
description: "Add multiple items to an ontology in the backpack at once. Each item needs a type and properties.",
|
|
7
7
|
inputSchema: {
|
|
8
8
|
ontology: z.string().describe("Name of the ontology"),
|
|
9
9
|
nodes: z
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulk-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/bulk-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,QAAkB;IAElB,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"bulk-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/bulk-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,QAAkB;IAElB,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EACT,mGAAmG;QACrG,WAAW,EAAE;YACX,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YACrD,KAAK,EAAE,CAAC;iBACL,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;gBACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;gBACtC,UAAU,EAAE,CAAC;qBACV,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;qBAC/B,QAAQ,CAAC,8BAA8B,CAAC;aAC5C,CAAC,CACH;iBACA,QAAQ,CAAC,0BAA0B,CAAC;SACxC;KACF,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,WAAW,CACvC,QAAQ,EACR,KAGE,CACH,CAAC;YACF,UAAU,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC,CAAC;YAC3D,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,YAAY,MAAM,CAAC,KAAK,mBAAmB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;qBAC9E;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,GAAa,CAAC,OAAO,EAAE,EAAE;iBACpE;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { trackEvent } from "../../core/telemetry.js";
|
|
|
3
3
|
export function registerEdgeTools(server, backpack) {
|
|
4
4
|
server.registerTool("backpack_add_edge", {
|
|
5
5
|
title: "Add Edge",
|
|
6
|
-
description: "Create a relationship
|
|
6
|
+
description: "Create a relationship between two items in an ontology. The type is freeform (e.g. 'WORKS_WITH', 'REPORTS_TO', 'DEPENDS_ON').",
|
|
7
7
|
inputSchema: {
|
|
8
8
|
ontology: z.string().describe("Name of the ontology"),
|
|
9
9
|
type: z
|
|
@@ -37,7 +37,7 @@ export function registerEdgeTools(server, backpack) {
|
|
|
37
37
|
});
|
|
38
38
|
server.registerTool("backpack_remove_edge", {
|
|
39
39
|
title: "Remove Edge",
|
|
40
|
-
description: "Remove a relationship
|
|
40
|
+
description: "Remove a relationship between two items in an ontology.",
|
|
41
41
|
annotations: { destructiveHint: true },
|
|
42
42
|
inputSchema: {
|
|
43
43
|
ontology: z.string().describe("Name of the ontology"),
|
|
@@ -64,7 +64,7 @@ export function registerEdgeTools(server, backpack) {
|
|
|
64
64
|
});
|
|
65
65
|
server.registerTool("backpack_get_neighbors", {
|
|
66
66
|
title: "Get Neighbors",
|
|
67
|
-
description: "
|
|
67
|
+
description: "Explore connections from an item in an ontology. Returns related items with their relationships. Use depth > 1 to follow the chain further (max 3).",
|
|
68
68
|
annotations: { readOnlyHint: true },
|
|
69
69
|
inputSchema: {
|
|
70
70
|
ontology: z.string().describe("Name of the ontology"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edge-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/edge-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,QAAkB;IAElB,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,UAAU;QACjB,WAAW,EACT,+
|
|
1
|
+
{"version":3,"file":"edge-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/edge-tools.ts"],"names":[],"mappings":"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"}
|