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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +335 -0
  3. package/dist/config.d.ts +9 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +35 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/db/database.d.ts +8 -0
  8. package/dist/db/database.d.ts.map +1 -0
  9. package/dist/db/database.js +25 -0
  10. package/dist/db/database.js.map +1 -0
  11. package/dist/db/edges.d.ts +65 -0
  12. package/dist/db/edges.d.ts.map +1 -0
  13. package/dist/db/edges.js +256 -0
  14. package/dist/db/edges.js.map +1 -0
  15. package/dist/db/fts.d.ts +25 -0
  16. package/dist/db/fts.d.ts.map +1 -0
  17. package/dist/db/fts.js +53 -0
  18. package/dist/db/fts.js.map +1 -0
  19. package/dist/db/migrations.d.ts +11 -0
  20. package/dist/db/migrations.d.ts.map +1 -0
  21. package/dist/db/migrations.js +95 -0
  22. package/dist/db/migrations.js.map +1 -0
  23. package/dist/db/thoughts.d.ts +60 -0
  24. package/dist/db/thoughts.d.ts.map +1 -0
  25. package/dist/db/thoughts.js +194 -0
  26. package/dist/db/thoughts.js.map +1 -0
  27. package/dist/db/vectors.d.ts +16 -0
  28. package/dist/db/vectors.d.ts.map +1 -0
  29. package/dist/db/vectors.js +74 -0
  30. package/dist/db/vectors.js.map +1 -0
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +24 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/mcp/server.d.ts +8 -0
  36. package/dist/mcp/server.d.ts.map +1 -0
  37. package/dist/mcp/server.js +229 -0
  38. package/dist/mcp/server.js.map +1 -0
  39. package/dist/tools/capture.d.ts +4 -0
  40. package/dist/tools/capture.d.ts.map +1 -0
  41. package/dist/tools/capture.js +79 -0
  42. package/dist/tools/capture.js.map +1 -0
  43. package/dist/tools/delete.d.ts +4 -0
  44. package/dist/tools/delete.d.ts.map +1 -0
  45. package/dist/tools/delete.js +18 -0
  46. package/dist/tools/delete.js.map +1 -0
  47. package/dist/tools/get.d.ts +4 -0
  48. package/dist/tools/get.d.ts.map +1 -0
  49. package/dist/tools/get.js +19 -0
  50. package/dist/tools/get.js.map +1 -0
  51. package/dist/tools/graph.d.ts +5 -0
  52. package/dist/tools/graph.d.ts.map +1 -0
  53. package/dist/tools/graph.js +55 -0
  54. package/dist/tools/graph.js.map +1 -0
  55. package/dist/tools/helpers.d.ts +12 -0
  56. package/dist/tools/helpers.d.ts.map +1 -0
  57. package/dist/tools/helpers.js +21 -0
  58. package/dist/tools/helpers.js.map +1 -0
  59. package/dist/tools/list.d.ts +4 -0
  60. package/dist/tools/list.d.ts.map +1 -0
  61. package/dist/tools/list.js +18 -0
  62. package/dist/tools/list.js.map +1 -0
  63. package/dist/tools/search.d.ts +4 -0
  64. package/dist/tools/search.d.ts.map +1 -0
  65. package/dist/tools/search.js +73 -0
  66. package/dist/tools/search.js.map +1 -0
  67. package/dist/tools/stats.d.ts +4 -0
  68. package/dist/tools/stats.d.ts.map +1 -0
  69. package/dist/tools/stats.js +34 -0
  70. package/dist/tools/stats.js.map +1 -0
  71. package/dist/tools/update.d.ts +4 -0
  72. package/dist/tools/update.d.ts.map +1 -0
  73. package/dist/tools/update.js +59 -0
  74. package/dist/tools/update.js.map +1 -0
  75. package/package.json +58 -0
  76. 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":"AACA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAmB,MAAM,cAAc,CAAC;AAyBvE,SAAS,aAAa,CACpB,EAAmB,EACnB,IAUC;IAED,MAAM,EAAE,GAAG,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE;QAC9B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,IAAI,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACxB,SAAS;YACX,CAAC;YACD,IAAI,CAAC;gBACH,YAAY,CAAC,EAAE,EAAE;oBACf,SAAS,EAAE,EAAE;oBACb,SAAS,EAAE,SAAS;oBACpB,SAAS,EAAE,SAAS;iBACrB,CAAC,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACzB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,EAAmB,EACnB,IAA6B;IAE7B,MAAM,CAAC,GAAG,IAA8B,CAAC;IAEzC,oBAAoB;IACpB,IAAI,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,SAAS,CAAC,eAAe,EAAE,yBAAyB,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,OAAO,GAA+D,EAAE,CAAC;QAC/E,KAAK,MAAM,OAAO,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC5D,OAAO,SAAS,CACd,eAAe,EACf,yDAAyD,CAC1D,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,WAAW,CAAC;YACjB,QAAQ,EAAE,OAAO,CAAC,MAAM;YACxB,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;IACL,CAAC;IAED,sBAAsB;IACtB,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,SAAS,CACd,eAAe,EACf,uFAAuF,CACxF,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,EAAE;QAC/B,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,UAAU,EAAE,CAAC,CAAC,UAAU;KACzB,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ThoughtDatabase } from "../db/database.js";
2
+ import { type ToolResult } from "./helpers.js";
3
+ export declare function handleDeleteThought(db: ThoughtDatabase, args: Record<string, unknown>): ToolResult;
4
+ //# sourceMappingURL=delete.d.ts.map
@@ -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,4 @@
1
+ import type { ThoughtDatabase } from "../db/database.js";
2
+ import { type ToolResult } from "./helpers.js";
3
+ export declare function handleGetThought(db: ThoughtDatabase, args: Record<string, unknown>): ToolResult;
4
+ //# sourceMappingURL=get.d.ts.map
@@ -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,4 @@
1
+ import type { ThoughtDatabase } from "../db/database.js";
2
+ import { type ToolResult } from "./helpers.js";
3
+ export declare function handleListThoughts(db: ThoughtDatabase, args: Record<string, unknown>): ToolResult;
4
+ //# sourceMappingURL=list.d.ts.map
@@ -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,4 @@
1
+ import type { ThoughtDatabase } from "../db/database.js";
2
+ import { type ToolResult } from "./helpers.js";
3
+ export declare function handleSearchThoughts(db: ThoughtDatabase, args: Record<string, unknown>): ToolResult;
4
+ //# sourceMappingURL=search.d.ts.map
@@ -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,4 @@
1
+ import type { ThoughtDatabase } from "../db/database.js";
2
+ import { type ToolResult } from "./helpers.js";
3
+ export declare function handleThoughtStats(db: ThoughtDatabase): ToolResult;
4
+ //# sourceMappingURL=stats.d.ts.map
@@ -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,4 @@
1
+ import type { ThoughtDatabase } from "../db/database.js";
2
+ import { type ToolResult } from "./helpers.js";
3
+ export declare function handleUpdateThought(db: ThoughtDatabase, args: Record<string, unknown>): ToolResult;
4
+ //# sourceMappingURL=update.d.ts.map
@@ -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
+ }