shelbymcp 0.1.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 +21 -0
- package/README.md +335 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +35 -0
- package/dist/config.js.map +1 -0
- package/dist/db/database.d.ts +8 -0
- package/dist/db/database.d.ts.map +1 -0
- package/dist/db/database.js +25 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/edges.d.ts +65 -0
- package/dist/db/edges.d.ts.map +1 -0
- package/dist/db/edges.js +256 -0
- package/dist/db/edges.js.map +1 -0
- package/dist/db/fts.d.ts +25 -0
- package/dist/db/fts.d.ts.map +1 -0
- package/dist/db/fts.js +53 -0
- package/dist/db/fts.js.map +1 -0
- package/dist/db/migrations.d.ts +11 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +95 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/thoughts.d.ts +60 -0
- package/dist/db/thoughts.d.ts.map +1 -0
- package/dist/db/thoughts.js +194 -0
- package/dist/db/thoughts.js.map +1 -0
- package/dist/db/vectors.d.ts +16 -0
- package/dist/db/vectors.d.ts.map +1 -0
- package/dist/db/vectors.js +74 -0
- package/dist/db/vectors.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +8 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +229 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/tools/capture.d.ts +4 -0
- package/dist/tools/capture.d.ts.map +1 -0
- package/dist/tools/capture.js +79 -0
- package/dist/tools/capture.js.map +1 -0
- package/dist/tools/delete.d.ts +4 -0
- package/dist/tools/delete.d.ts.map +1 -0
- package/dist/tools/delete.js +18 -0
- package/dist/tools/delete.js.map +1 -0
- package/dist/tools/get.d.ts +4 -0
- package/dist/tools/get.d.ts.map +1 -0
- package/dist/tools/get.js +19 -0
- package/dist/tools/get.js.map +1 -0
- package/dist/tools/graph.d.ts +5 -0
- package/dist/tools/graph.d.ts.map +1 -0
- package/dist/tools/graph.js +55 -0
- package/dist/tools/graph.js.map +1 -0
- package/dist/tools/helpers.d.ts +12 -0
- package/dist/tools/helpers.d.ts.map +1 -0
- package/dist/tools/helpers.js +21 -0
- package/dist/tools/helpers.js.map +1 -0
- package/dist/tools/list.d.ts +4 -0
- package/dist/tools/list.d.ts.map +1 -0
- package/dist/tools/list.js +18 -0
- package/dist/tools/list.js.map +1 -0
- package/dist/tools/search.d.ts +4 -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/stats.d.ts +4 -0
- package/dist/tools/stats.d.ts.map +1 -0
- package/dist/tools/stats.js +34 -0
- package/dist/tools/stats.js.map +1 -0
- package/dist/tools/update.d.ts +4 -0
- package/dist/tools/update.d.ts.map +1 -0
- package/dist/tools/update.js +59 -0
- package/dist/tools/update.js.map +1 -0
- package/package.json +58 -0
- package/skills/shelby-forage/SKILL.md +85 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { insertThought, getThought } from "../db/thoughts.js";
|
|
2
|
+
import { linkThoughts } from "../db/edges.js";
|
|
3
|
+
import { toolSuccess, toolError } from "./helpers.js";
|
|
4
|
+
function captureSingle(db, args) {
|
|
5
|
+
const id = insertThought(db.db, {
|
|
6
|
+
content: args.content,
|
|
7
|
+
summary: args.summary,
|
|
8
|
+
type: args.type,
|
|
9
|
+
source: args.source,
|
|
10
|
+
project: args.project,
|
|
11
|
+
topics: args.topics,
|
|
12
|
+
people: args.people,
|
|
13
|
+
metadata: args.metadata,
|
|
14
|
+
});
|
|
15
|
+
const linked = [];
|
|
16
|
+
const skipped = [];
|
|
17
|
+
if (args.related_to && Array.isArray(args.related_to)) {
|
|
18
|
+
for (const relatedId of args.related_to) {
|
|
19
|
+
const exists = getThought(db.db, relatedId);
|
|
20
|
+
if (!exists) {
|
|
21
|
+
skipped.push(relatedId);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
linkThoughts(db, {
|
|
26
|
+
source_id: id,
|
|
27
|
+
target_id: relatedId,
|
|
28
|
+
edge_type: "related",
|
|
29
|
+
});
|
|
30
|
+
linked.push(relatedId);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
skipped.push(relatedId);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return { id, linked, skipped };
|
|
38
|
+
}
|
|
39
|
+
export function handleCaptureThought(db, args) {
|
|
40
|
+
const a = args;
|
|
41
|
+
// Bulk capture mode
|
|
42
|
+
if (a.thoughts && Array.isArray(a.thoughts)) {
|
|
43
|
+
if (a.thoughts.length === 0) {
|
|
44
|
+
return toolError("invalid_input", "thoughts array is empty");
|
|
45
|
+
}
|
|
46
|
+
const results = [];
|
|
47
|
+
for (const thought of a.thoughts) {
|
|
48
|
+
if (!thought.content || typeof thought.content !== "string") {
|
|
49
|
+
return toolError("invalid_input", "Each thought in bulk capture must have a content string");
|
|
50
|
+
}
|
|
51
|
+
results.push(captureSingle(db, thought));
|
|
52
|
+
}
|
|
53
|
+
return toolSuccess({
|
|
54
|
+
captured: results.length,
|
|
55
|
+
thoughts: results,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// Single capture mode
|
|
59
|
+
if (!a.content || typeof a.content !== "string") {
|
|
60
|
+
return toolError("invalid_input", "content is required and must be a string. For bulk capture, provide a thoughts array.");
|
|
61
|
+
}
|
|
62
|
+
const result = captureSingle(db, {
|
|
63
|
+
content: a.content,
|
|
64
|
+
summary: a.summary,
|
|
65
|
+
type: a.type,
|
|
66
|
+
source: a.source,
|
|
67
|
+
project: a.project,
|
|
68
|
+
topics: a.topics,
|
|
69
|
+
people: a.people,
|
|
70
|
+
metadata: a.metadata,
|
|
71
|
+
related_to: a.related_to,
|
|
72
|
+
});
|
|
73
|
+
return toolSuccess({
|
|
74
|
+
id: result.id,
|
|
75
|
+
linked: result.linked,
|
|
76
|
+
skipped: result.skipped,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/tools/capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/tools/delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAEvE,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,UAAU,CAqBZ"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { deleteThought, getThought } from "../db/thoughts.js";
|
|
2
|
+
import { toolSuccess, toolError } from "./helpers.js";
|
|
3
|
+
export function handleDeleteThought(db, args) {
|
|
4
|
+
const id = args.id;
|
|
5
|
+
if (!id || typeof id !== "string") {
|
|
6
|
+
return toolError("invalid_input", "id is required and must be a string");
|
|
7
|
+
}
|
|
8
|
+
const exists = getThought(db.db, id);
|
|
9
|
+
if (!exists) {
|
|
10
|
+
return toolError("not_found", `Thought "${id}" not found. Try search_thoughts to find it by content.`);
|
|
11
|
+
}
|
|
12
|
+
const deleted = deleteThought(db.db, id);
|
|
13
|
+
return toolSuccess({
|
|
14
|
+
deleted,
|
|
15
|
+
id,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/tools/delete.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAmB,MAAM,cAAc,CAAC;AAEvE,MAAM,UAAU,mBAAmB,CACjC,EAAmB,EACnB,IAA6B;IAE7B,MAAM,EAAE,GAAG,IAAI,CAAC,EAAwB,CAAC;IAEzC,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC,eAAe,EAAE,qCAAqC,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CACd,WAAW,EACX,YAAY,EAAE,yDAAyD,CACxE,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAEzC,OAAO,WAAW,CAAC;QACjB,OAAO;QACP,EAAE;KACH,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../src/tools/get.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAEvE,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,UAAU,CAkBZ"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { getThought } from "../db/thoughts.js";
|
|
2
|
+
import { toolSuccess, toolError } from "./helpers.js";
|
|
3
|
+
export function handleGetThought(db, args) {
|
|
4
|
+
const id = args.id;
|
|
5
|
+
if (!id || typeof id !== "string") {
|
|
6
|
+
return toolError("invalid_input", "id is required and must be a string");
|
|
7
|
+
}
|
|
8
|
+
const thought = getThought(db.db, id);
|
|
9
|
+
if (!thought) {
|
|
10
|
+
return toolError("not_found", `Thought "${id}" not found`);
|
|
11
|
+
}
|
|
12
|
+
// Strip embedding buffer from response (binary data isn't useful in JSON)
|
|
13
|
+
const { embedding, ...rest } = thought;
|
|
14
|
+
return toolSuccess({
|
|
15
|
+
...rest,
|
|
16
|
+
has_embedding: embedding !== null,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/tools/get.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAmB,MAAM,cAAc,CAAC;AAEvE,MAAM,UAAU,gBAAgB,CAC9B,EAAmB,EACnB,IAA6B;IAE7B,MAAM,EAAE,GAAG,IAAI,CAAC,EAAwB,CAAC;IAEzC,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC,eAAe,EAAE,qCAAqC,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAC,WAAW,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;IAC7D,CAAC;IAED,0EAA0E;IAC1E,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACvC,OAAO,WAAW,CAAC;QACjB,GAAG,IAAI;QACP,aAAa,EAAE,SAAS,KAAK,IAAI;KAClC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ThoughtDatabase } from "../db/database.js";
|
|
2
|
+
import { type ToolResult } from "./helpers.js";
|
|
3
|
+
export declare function handleManageEdges(db: ThoughtDatabase, args: Record<string, unknown>): ToolResult;
|
|
4
|
+
export declare function handleExploreGraph(db: ThoughtDatabase, args: Record<string, unknown>): ToolResult;
|
|
5
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/tools/graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAYvE,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,UAAU,CA6CZ;AAUD,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,UAAU,CAuBZ"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { linkThoughts, unlinkThoughts, VALID_EDGE_TYPES, traverseGraph } from "../db/edges.js";
|
|
2
|
+
import { toolSuccess, toolError } from "./helpers.js";
|
|
3
|
+
export function handleManageEdges(db, args) {
|
|
4
|
+
const a = args;
|
|
5
|
+
if (a.action === "link") {
|
|
6
|
+
try {
|
|
7
|
+
const edgeId = linkThoughts(db, {
|
|
8
|
+
source_id: a.source_id,
|
|
9
|
+
target_id: a.target_id,
|
|
10
|
+
edge_type: a.edge_type,
|
|
11
|
+
metadata: a.metadata,
|
|
12
|
+
});
|
|
13
|
+
return toolSuccess({ edge_id: edgeId, action: "linked" });
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
17
|
+
if (msg.includes("does not exist")) {
|
|
18
|
+
return toolError("not_found", msg);
|
|
19
|
+
}
|
|
20
|
+
if (msg.includes("already exists")) {
|
|
21
|
+
return toolError("duplicate", msg);
|
|
22
|
+
}
|
|
23
|
+
if (msg.includes("Invalid edge type")) {
|
|
24
|
+
return toolError("invalid_input", `Edge type must be one of: ${VALID_EDGE_TYPES.join(", ")}`);
|
|
25
|
+
}
|
|
26
|
+
return toolError("temporary_failure", msg);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (a.action === "unlink") {
|
|
30
|
+
const removed = unlinkThoughts(db, a.source_id, a.target_id, a.edge_type);
|
|
31
|
+
if (!removed) {
|
|
32
|
+
return toolError("not_found", `No edge found: ${a.source_id} -[${a.edge_type}]-> ${a.target_id}`);
|
|
33
|
+
}
|
|
34
|
+
return toolSuccess({ action: "unlinked" });
|
|
35
|
+
}
|
|
36
|
+
return toolError("invalid_input", 'action must be "link" or "unlink"');
|
|
37
|
+
}
|
|
38
|
+
export function handleExploreGraph(db, args) {
|
|
39
|
+
const a = args;
|
|
40
|
+
if (!a.thought_id || typeof a.thought_id !== "string") {
|
|
41
|
+
return toolError("invalid_input", "thought_id is required and must be a string");
|
|
42
|
+
}
|
|
43
|
+
const depth = a.max_depth ?? 1;
|
|
44
|
+
const nodes = traverseGraph(db, a.thought_id, depth, a.edge_types);
|
|
45
|
+
if (nodes.length === 0) {
|
|
46
|
+
return toolError("not_found", `Thought "${a.thought_id}" not found. Try search_thoughts to find it by content.`);
|
|
47
|
+
}
|
|
48
|
+
return toolSuccess({
|
|
49
|
+
root: a.thought_id,
|
|
50
|
+
max_depth: depth,
|
|
51
|
+
node_count: nodes.length,
|
|
52
|
+
nodes,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/tools/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ToolResult {
|
|
2
|
+
[key: string]: unknown;
|
|
3
|
+
content: Array<{
|
|
4
|
+
type: "text";
|
|
5
|
+
text: string;
|
|
6
|
+
}>;
|
|
7
|
+
isError?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function toolSuccess(data: unknown): ToolResult;
|
|
10
|
+
export declare function toolError(category: string, message: string): ToolResult;
|
|
11
|
+
export declare function clampLimit(limit: number | undefined, defaultVal?: number, max?: number): number;
|
|
12
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/tools/helpers.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAIrD;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAUvE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,SAAK,EAAE,GAAG,SAAM,GAAG,MAAM,CAGxF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function toolSuccess(data) {
|
|
2
|
+
return {
|
|
3
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
4
|
+
};
|
|
5
|
+
}
|
|
6
|
+
export function toolError(category, message) {
|
|
7
|
+
return {
|
|
8
|
+
isError: true,
|
|
9
|
+
content: [
|
|
10
|
+
{
|
|
11
|
+
type: "text",
|
|
12
|
+
text: JSON.stringify({ error: category, message }),
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function clampLimit(limit, defaultVal = 20, max = 100) {
|
|
18
|
+
const val = limit ?? defaultVal;
|
|
19
|
+
return Math.max(1, Math.min(val, max));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/tools/helpers.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,WAAW,CAAC,IAAa;IACvC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;KAC1E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,OAAe;IACzD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;aACnD;SACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAyB,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,GAAG,GAAG;IAC9E,MAAM,GAAG,GAAG,KAAK,IAAI,UAAU,CAAC;IAChC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/tools/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAA2B,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAcxE,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,UAAU,CAgBZ"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { listThoughts } from "../db/thoughts.js";
|
|
2
|
+
import { toolSuccess, clampLimit } from "./helpers.js";
|
|
3
|
+
export function handleListThoughts(db, args) {
|
|
4
|
+
const a = args;
|
|
5
|
+
const result = listThoughts(db.db, {
|
|
6
|
+
type: a.type,
|
|
7
|
+
project: a.project,
|
|
8
|
+
topic: a.topic,
|
|
9
|
+
person: a.person,
|
|
10
|
+
source: a.source,
|
|
11
|
+
since: a.since,
|
|
12
|
+
until: a.until,
|
|
13
|
+
limit: clampLimit(a.limit),
|
|
14
|
+
offset: a.offset,
|
|
15
|
+
});
|
|
16
|
+
return toolSuccess(result);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/tools/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAcxE,MAAM,UAAU,kBAAkB,CAChC,EAAmB,EACnB,IAA6B;IAE7B,MAAM,CAAC,GAAG,IAA2B,CAAC;IAEtC,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE;QACjC,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;QAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;KACjB,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD,OAAO,EAAsC,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAWnF,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,UAAU,CAkFZ"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { searchThoughts } from "../db/fts.js";
|
|
2
|
+
import { searchByEmbedding, bufferToEmbedding, cosineSimilarity } from "../db/vectors.js";
|
|
3
|
+
import { toolSuccess, toolError, clampLimit } from "./helpers.js";
|
|
4
|
+
export function handleSearchThoughts(db, args) {
|
|
5
|
+
const a = args;
|
|
6
|
+
if (!a.query && !a.embedding) {
|
|
7
|
+
return toolError("invalid_input", "Either query (for full-text search) or embedding (for vector search) is required.");
|
|
8
|
+
}
|
|
9
|
+
const limit = clampLimit(a.limit);
|
|
10
|
+
const offset = a.offset ?? 0;
|
|
11
|
+
// Vector-only search
|
|
12
|
+
if (a.embedding && !a.query) {
|
|
13
|
+
if (!Array.isArray(a.embedding) || a.embedding.length === 0) {
|
|
14
|
+
return toolError("invalid_input", "embedding must be a non-empty number array");
|
|
15
|
+
}
|
|
16
|
+
const results = searchByEmbedding(db.db, a.embedding, limit);
|
|
17
|
+
return toolSuccess({
|
|
18
|
+
mode: "vector",
|
|
19
|
+
results,
|
|
20
|
+
total_count: results.length,
|
|
21
|
+
has_more: false,
|
|
22
|
+
offset: 0,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// FTS search
|
|
26
|
+
if (a.query && !a.embedding) {
|
|
27
|
+
const ftsResult = searchThoughts(db.db, {
|
|
28
|
+
query: a.query,
|
|
29
|
+
limit,
|
|
30
|
+
offset,
|
|
31
|
+
type: a.type,
|
|
32
|
+
project: a.project,
|
|
33
|
+
});
|
|
34
|
+
return toolSuccess({
|
|
35
|
+
mode: "fts",
|
|
36
|
+
...ftsResult,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
// Hybrid: FTS first, then rerank by embedding similarity
|
|
40
|
+
if (a.query && a.embedding) {
|
|
41
|
+
// Get a larger FTS pool to rerank from
|
|
42
|
+
const ftsPool = searchThoughts(db.db, {
|
|
43
|
+
query: a.query,
|
|
44
|
+
limit: Math.min(limit * 3, 100),
|
|
45
|
+
offset: 0,
|
|
46
|
+
type: a.type,
|
|
47
|
+
project: a.project,
|
|
48
|
+
});
|
|
49
|
+
// Rerank by embedding similarity
|
|
50
|
+
const reranked = ftsPool.results.map((r) => {
|
|
51
|
+
const row = db.db
|
|
52
|
+
.prepare("SELECT embedding FROM thoughts WHERE id = ?")
|
|
53
|
+
.get(r.id);
|
|
54
|
+
let similarity = 0;
|
|
55
|
+
if (row?.embedding) {
|
|
56
|
+
const emb = bufferToEmbedding(row.embedding);
|
|
57
|
+
similarity = cosineSimilarity(a.embedding, emb);
|
|
58
|
+
}
|
|
59
|
+
return { ...r, similarity };
|
|
60
|
+
});
|
|
61
|
+
reranked.sort((x, y) => y.similarity - x.similarity);
|
|
62
|
+
const sliced = reranked.slice(offset, offset + limit);
|
|
63
|
+
return toolSuccess({
|
|
64
|
+
mode: "hybrid",
|
|
65
|
+
results: sliced,
|
|
66
|
+
total_count: ftsPool.total_count,
|
|
67
|
+
has_more: offset + sliced.length < ftsPool.total_count,
|
|
68
|
+
offset,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return toolError("invalid_input", "Unexpected search parameter combination");
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/tools/stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE5D,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,eAAe,GAClB,UAAU,CAyCZ"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { countThoughts } from "../db/thoughts.js";
|
|
2
|
+
import { toolSuccess } from "./helpers.js";
|
|
3
|
+
export function handleThoughtStats(db) {
|
|
4
|
+
const thoughtCount = countThoughts(db.db);
|
|
5
|
+
const edgeCount = db.db.prepare("SELECT COUNT(*) AS cnt FROM edges").get().cnt;
|
|
6
|
+
// Type breakdown
|
|
7
|
+
const typeRows = db.db
|
|
8
|
+
.prepare("SELECT type, COUNT(*) AS cnt FROM thoughts GROUP BY type ORDER BY cnt DESC")
|
|
9
|
+
.all();
|
|
10
|
+
const byType = {};
|
|
11
|
+
for (const row of typeRows) {
|
|
12
|
+
byType[row.type] = row.cnt;
|
|
13
|
+
}
|
|
14
|
+
// Edge type breakdown
|
|
15
|
+
const edgeTypeRows = db.db
|
|
16
|
+
.prepare("SELECT edge_type, COUNT(*) AS cnt FROM edges GROUP BY edge_type ORDER BY cnt DESC")
|
|
17
|
+
.all();
|
|
18
|
+
const byEdgeType = {};
|
|
19
|
+
for (const row of edgeTypeRows) {
|
|
20
|
+
byEdgeType[row.edge_type] = row.cnt;
|
|
21
|
+
}
|
|
22
|
+
// Count thoughts with embeddings
|
|
23
|
+
const embeddingCount = db.db
|
|
24
|
+
.prepare("SELECT COUNT(*) AS cnt FROM thoughts WHERE embedding IS NOT NULL")
|
|
25
|
+
.get().cnt;
|
|
26
|
+
return toolSuccess({
|
|
27
|
+
thought_count: thoughtCount,
|
|
28
|
+
edge_count: edgeCount,
|
|
29
|
+
embedding_count: embeddingCount,
|
|
30
|
+
by_type: byType,
|
|
31
|
+
by_edge_type: byEdgeType,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/tools/stats.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAmB,MAAM,cAAc,CAAC;AAE5D,MAAM,UAAU,kBAAkB,CAChC,EAAmB;IAEnB,MAAM,YAAY,GAAG,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAE1C,MAAM,SAAS,GACb,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC,GAAG,EACvD,CAAC,GAAG,CAAC;IAEN,iBAAiB;IACjB,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE;SACnB,OAAO,CAAC,4EAA4E,CAAC;SACrF,GAAG,EAA0C,CAAC;IAEjD,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC;IAC7B,CAAC;IAED,sBAAsB;IACtB,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE;SACvB,OAAO,CAAC,mFAAmF,CAAC;SAC5F,GAAG,EAA+C,CAAC;IAEtD,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC;IACtC,CAAC;IAED,iCAAiC;IACjC,MAAM,cAAc,GAClB,EAAE,CAAC,EAAE;SACF,OAAO,CAAC,kEAAkE,CAAC;SAC3E,GAAG,EACP,CAAC,GAAG,CAAC;IAEN,OAAO,WAAW,CAAC;QACjB,aAAa,EAAE,YAAY;QAC3B,UAAU,EAAE,SAAS;QACrB,eAAe,EAAE,cAAc;QAC/B,OAAO,EAAE,MAAM;QACf,YAAY,EAAE,UAAU;KACzB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/tools/update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAgBvE,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,UAAU,CAqDZ"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { updateThought, getThought } from "../db/thoughts.js";
|
|
2
|
+
import { toolSuccess, toolError } from "./helpers.js";
|
|
3
|
+
export function handleUpdateThought(db, args) {
|
|
4
|
+
const a = args;
|
|
5
|
+
// Determine target IDs
|
|
6
|
+
const targetIds = [];
|
|
7
|
+
if (a.ids && Array.isArray(a.ids)) {
|
|
8
|
+
targetIds.push(...a.ids);
|
|
9
|
+
}
|
|
10
|
+
else if (a.id && typeof a.id === "string") {
|
|
11
|
+
targetIds.push(a.id);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return toolError("invalid_input", "Either id (string) or ids (string[]) is required");
|
|
15
|
+
}
|
|
16
|
+
if (targetIds.length === 0) {
|
|
17
|
+
return toolError("invalid_input", "No target IDs provided");
|
|
18
|
+
}
|
|
19
|
+
// Build updates object (exclude id/ids)
|
|
20
|
+
const updates = {};
|
|
21
|
+
if (a.content !== undefined)
|
|
22
|
+
updates.content = a.content;
|
|
23
|
+
if (a.summary !== undefined)
|
|
24
|
+
updates.summary = a.summary;
|
|
25
|
+
if (a.type !== undefined)
|
|
26
|
+
updates.type = a.type;
|
|
27
|
+
if (a.source !== undefined)
|
|
28
|
+
updates.source = a.source;
|
|
29
|
+
if (a.project !== undefined)
|
|
30
|
+
updates.project = a.project;
|
|
31
|
+
if (a.topics !== undefined)
|
|
32
|
+
updates.topics = a.topics;
|
|
33
|
+
if (a.people !== undefined)
|
|
34
|
+
updates.people = a.people;
|
|
35
|
+
if (a.metadata !== undefined)
|
|
36
|
+
updates.metadata = a.metadata;
|
|
37
|
+
if (a.visibility !== undefined)
|
|
38
|
+
updates.visibility = a.visibility;
|
|
39
|
+
if (Object.keys(updates).length === 0) {
|
|
40
|
+
return toolError("invalid_input", "No fields to update were provided");
|
|
41
|
+
}
|
|
42
|
+
let updatedCount = 0;
|
|
43
|
+
const notFound = [];
|
|
44
|
+
for (const tid of targetIds) {
|
|
45
|
+
const exists = getThought(db.db, tid);
|
|
46
|
+
if (!exists) {
|
|
47
|
+
notFound.push(tid);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const ok = updateThought(db.db, tid, updates);
|
|
51
|
+
if (ok)
|
|
52
|
+
updatedCount++;
|
|
53
|
+
}
|
|
54
|
+
return toolSuccess({
|
|
55
|
+
updated: updatedCount,
|
|
56
|
+
not_found: notFound,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/tools/update.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "shelbymcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Knowledge-graph memory server for AI tools via MCP",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"shelbymcp": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"skills"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc && shx chmod +x dist/*.js",
|
|
15
|
+
"prepare": "npm run build",
|
|
16
|
+
"watch": "tsc --watch",
|
|
17
|
+
"dev": "tsx src/index.ts",
|
|
18
|
+
"test": "vitest run --coverage",
|
|
19
|
+
"test:watch": "vitest --watch",
|
|
20
|
+
"lint": "tsc --noEmit"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
24
|
+
"better-sqlite3": "^11.0.0",
|
|
25
|
+
"uuid": "^11.0.0",
|
|
26
|
+
"zod": "^3.24.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
30
|
+
"@types/node": "^22.0.0",
|
|
31
|
+
"@types/uuid": "^10.0.0",
|
|
32
|
+
"@vitest/coverage-v8": "^2.1.8",
|
|
33
|
+
"shx": "^0.3.4",
|
|
34
|
+
"tsx": "^4.19.0",
|
|
35
|
+
"typescript": "^5.6.2",
|
|
36
|
+
"vitest": "^2.1.8"
|
|
37
|
+
},
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"author": "Studio Moser",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/Studio-Moser/shelbymcp.git"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/Studio-Moser/shelbymcp",
|
|
45
|
+
"bugs": "https://github.com/Studio-Moser/shelbymcp/issues",
|
|
46
|
+
"keywords": [
|
|
47
|
+
"mcp",
|
|
48
|
+
"memory",
|
|
49
|
+
"knowledge-graph",
|
|
50
|
+
"ai",
|
|
51
|
+
"claude",
|
|
52
|
+
"sqlite",
|
|
53
|
+
"model-context-protocol"
|
|
54
|
+
],
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": ">=20"
|
|
57
|
+
}
|
|
58
|
+
}
|