@knowsuchagency/fulcrum 2.7.1 → 2.8.1
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 +12 -0
- package/bin/fulcrum.js +80 -4
- package/dist/assets/{index-_cFoHsjb.js → index-COqMlavt.js} +165 -165
- package/dist/assets/index-TyeuSbkG.css +1 -0
- package/dist/index.html +2 -2
- package/drizzle/0052_agent_memory.sql +27 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/server/index.js +324 -47
- package/dist/assets/index-Bajq2D5F.css +0 -1
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Fulcrum doesn't replace your tools—it gives you leverage over them. You config
|
|
|
19
19
|
- **Work From Anywhere** — Run Fulcrum on a remote server. Close your laptop, agents keep working.
|
|
20
20
|
- **Project Management** — Tasks with dependencies, due dates, labels, and attachments. Visual kanban boards.
|
|
21
21
|
- **Production Deployment** — Docker Compose with automatic Traefik routing and Cloudflare DNS/tunnels.
|
|
22
|
+
- **Agent Memory** — Persistent knowledge store with full-text search. Agents remember across sessions.
|
|
22
23
|
- **MCP-First Architecture** — 60+ tools exposed via Model Context Protocol. Agents discover what they need.
|
|
23
24
|
|
|
24
25
|
## MCP-First Architecture
|
|
@@ -183,6 +184,16 @@ Chat with the AI assistant from anywhere via your favorite messaging platform.
|
|
|
183
184
|
|
|
184
185
|
Enable in Settings → Messaging and follow the setup instructions for each platform.
|
|
185
186
|
|
|
187
|
+
### Agent Memory
|
|
188
|
+
|
|
189
|
+
Agents can store and recall knowledge across conversations using a persistent memory system backed by SQLite FTS5 full-text search.
|
|
190
|
+
|
|
191
|
+
- **Persistent** — Memories survive across sessions and agent restarts
|
|
192
|
+
- **Searchable** — Full-text search with boolean operators, phrase matching, and prefix queries
|
|
193
|
+
- **Tagged** — Categorize memories with tags (preferences, decisions, architecture, etc.)
|
|
194
|
+
- **Browsable** — View, search, edit, and delete memories from the Monitoring > Memory tab
|
|
195
|
+
- **MCP tools** — `memory_store` and `memory_search` available to all connected agents
|
|
196
|
+
|
|
186
197
|
### System Monitoring
|
|
187
198
|
|
|
188
199
|
Track CPU, memory, and disk usage while your agents work. The Jobs tab manages systemd (Linux) or launchd (macOS) timers. The Messages tab shows all channel messages (WhatsApp, Discord, Telegram, Slack, Email) with filtering by channel and direction.
|
|
@@ -235,6 +246,7 @@ Both plugins include an MCP server with 60+ tools:
|
|
|
235
246
|
| **Notifications** | Send notifications to enabled channels |
|
|
236
247
|
| **Backup & Restore** | Snapshot database and settings; auto-safety-backup on restore |
|
|
237
248
|
| **Settings** | View and update configuration; manage notification channels |
|
|
249
|
+
| **Memory** | Store and search persistent knowledge with FTS5 full-text search |
|
|
238
250
|
| **Assistant Events** | Track actionable events; query decision history |
|
|
239
251
|
|
|
240
252
|
Use `search_tools` to discover available tools by keyword or category.
|
package/bin/fulcrum.js
CHANGED
|
@@ -1583,6 +1583,34 @@ class FulcrumClient {
|
|
|
1583
1583
|
method: "DELETE"
|
|
1584
1584
|
});
|
|
1585
1585
|
}
|
|
1586
|
+
async storeMemory(input) {
|
|
1587
|
+
return this.fetch("/api/memory", {
|
|
1588
|
+
method: "POST",
|
|
1589
|
+
body: JSON.stringify(input)
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
async searchMemories(input) {
|
|
1593
|
+
const params = new URLSearchParams({ q: input.query });
|
|
1594
|
+
if (input.tags?.length)
|
|
1595
|
+
params.set("tags", input.tags.join(","));
|
|
1596
|
+
if (input.limit)
|
|
1597
|
+
params.set("limit", String(input.limit));
|
|
1598
|
+
return this.fetch(`/api/memory/search?${params.toString()}`);
|
|
1599
|
+
}
|
|
1600
|
+
async listMemories(input) {
|
|
1601
|
+
const params = new URLSearchParams;
|
|
1602
|
+
if (input?.tags?.length)
|
|
1603
|
+
params.set("tags", input.tags.join(","));
|
|
1604
|
+
if (input?.limit)
|
|
1605
|
+
params.set("limit", String(input.limit));
|
|
1606
|
+
if (input?.offset)
|
|
1607
|
+
params.set("offset", String(input.offset));
|
|
1608
|
+
const query = params.toString();
|
|
1609
|
+
return this.fetch(`/api/memory${query ? `?${query}` : ""}`);
|
|
1610
|
+
}
|
|
1611
|
+
async deleteMemory(id) {
|
|
1612
|
+
return this.fetch(`/api/memory/${id}`, { method: "DELETE" });
|
|
1613
|
+
}
|
|
1586
1614
|
async getAssistantStats() {
|
|
1587
1615
|
return this.fetch("/api/assistant/stats");
|
|
1588
1616
|
}
|
|
@@ -43421,7 +43449,8 @@ var init_types4 = __esm(() => {
|
|
|
43421
43449
|
"email",
|
|
43422
43450
|
"messaging",
|
|
43423
43451
|
"assistant",
|
|
43424
|
-
"caldav"
|
|
43452
|
+
"caldav",
|
|
43453
|
+
"memory"
|
|
43425
43454
|
]);
|
|
43426
43455
|
AgentTypeSchema = exports_external.enum(["claude", "opencode"]);
|
|
43427
43456
|
});
|
|
@@ -44173,6 +44202,20 @@ var init_registry = __esm(() => {
|
|
|
44173
44202
|
category: "caldav",
|
|
44174
44203
|
keywords: ["calendar", "event", "delete", "remove", "cancel"],
|
|
44175
44204
|
defer_loading: true
|
|
44205
|
+
},
|
|
44206
|
+
{
|
|
44207
|
+
name: "memory_store",
|
|
44208
|
+
description: "Store a piece of knowledge in persistent memory",
|
|
44209
|
+
category: "memory",
|
|
44210
|
+
keywords: ["memory", "store", "save", "remember", "knowledge", "persist", "fact"],
|
|
44211
|
+
defer_loading: false
|
|
44212
|
+
},
|
|
44213
|
+
{
|
|
44214
|
+
name: "memory_search",
|
|
44215
|
+
description: "Search persistent memory using full-text search",
|
|
44216
|
+
category: "memory",
|
|
44217
|
+
keywords: ["memory", "search", "find", "recall", "knowledge", "retrieve", "remember"],
|
|
44218
|
+
defer_loading: false
|
|
44176
44219
|
}
|
|
44177
44220
|
];
|
|
44178
44221
|
});
|
|
@@ -45782,6 +45825,37 @@ var init_caldav = __esm(() => {
|
|
|
45782
45825
|
init_utils();
|
|
45783
45826
|
});
|
|
45784
45827
|
|
|
45828
|
+
// cli/src/mcp/tools/memory.ts
|
|
45829
|
+
var registerMemoryTools = (server, client) => {
|
|
45830
|
+
server.tool("memory_store", "Store a piece of knowledge in persistent memory. Use this to remember facts, preferences, decisions, patterns, or any information that should persist across conversations.", {
|
|
45831
|
+
content: exports_external.string().describe("The memory content to store. Be specific and self-contained."),
|
|
45832
|
+
tags: exports_external.optional(exports_external.array(exports_external.string())).describe('Optional tags for categorization (e.g., ["preference", "architecture", "decision"])')
|
|
45833
|
+
}, async ({ content, tags }) => {
|
|
45834
|
+
try {
|
|
45835
|
+
const result = await client.storeMemory({ content, tags });
|
|
45836
|
+
return formatSuccess(result);
|
|
45837
|
+
} catch (err) {
|
|
45838
|
+
return handleToolError(err);
|
|
45839
|
+
}
|
|
45840
|
+
});
|
|
45841
|
+
server.tool("memory_search", 'Search persistent memory using full-text search. Supports boolean operators (AND, OR, NOT), phrase matching ("quoted phrases"), and prefix matching (term*). Try different search terms or synonyms if initial results are insufficient.', {
|
|
45842
|
+
query: exports_external.string().describe('FTS5 search query. Supports: AND, OR, NOT operators, "quoted phrases", prefix* matching. Example: "user preference" OR settings'),
|
|
45843
|
+
tags: exports_external.optional(exports_external.array(exports_external.string())).describe("Optional tag filter - only return memories with at least one of these tags"),
|
|
45844
|
+
limit: exports_external.optional(exports_external.number()).describe("Maximum results to return (default: 20)")
|
|
45845
|
+
}, async ({ query, tags, limit }) => {
|
|
45846
|
+
try {
|
|
45847
|
+
const results = await client.searchMemories({ query, tags, limit });
|
|
45848
|
+
return formatSuccess(results);
|
|
45849
|
+
} catch (err) {
|
|
45850
|
+
return handleToolError(err);
|
|
45851
|
+
}
|
|
45852
|
+
});
|
|
45853
|
+
};
|
|
45854
|
+
var init_memory = __esm(() => {
|
|
45855
|
+
init_zod2();
|
|
45856
|
+
init_utils();
|
|
45857
|
+
});
|
|
45858
|
+
|
|
45785
45859
|
// cli/src/mcp/tools/index.ts
|
|
45786
45860
|
function registerTools(server, client) {
|
|
45787
45861
|
registerCoreTools(server, client);
|
|
@@ -45797,6 +45871,7 @@ function registerTools(server, client) {
|
|
|
45797
45871
|
registerEmailTools(server, client);
|
|
45798
45872
|
registerAssistantEventTools(server, client);
|
|
45799
45873
|
registerCaldavTools(server, client);
|
|
45874
|
+
registerMemoryTools(server, client);
|
|
45800
45875
|
}
|
|
45801
45876
|
var init_tools = __esm(() => {
|
|
45802
45877
|
init_core5();
|
|
@@ -45812,6 +45887,7 @@ var init_tools = __esm(() => {
|
|
|
45812
45887
|
init_email();
|
|
45813
45888
|
init_assistant_events();
|
|
45814
45889
|
init_caldav();
|
|
45890
|
+
init_memory();
|
|
45815
45891
|
init_types4();
|
|
45816
45892
|
});
|
|
45817
45893
|
|
|
@@ -45830,7 +45906,7 @@ async function runMcpServer(urlOverride, portOverride) {
|
|
|
45830
45906
|
const client = new FulcrumClient(urlOverride, portOverride);
|
|
45831
45907
|
const server = new McpServer({
|
|
45832
45908
|
name: "fulcrum",
|
|
45833
|
-
version: "2.
|
|
45909
|
+
version: "2.8.1"
|
|
45834
45910
|
});
|
|
45835
45911
|
registerTools(server, client);
|
|
45836
45912
|
const transport = new StdioServerTransport;
|
|
@@ -48179,7 +48255,7 @@ var marketplace_default = `{
|
|
|
48179
48255
|
"name": "fulcrum",
|
|
48180
48256
|
"source": "./",
|
|
48181
48257
|
"description": "Task orchestration for Claude Code",
|
|
48182
|
-
"version": "2.
|
|
48258
|
+
"version": "2.8.1",
|
|
48183
48259
|
"skills": [
|
|
48184
48260
|
"./skills/fulcrum"
|
|
48185
48261
|
],
|
|
@@ -49367,7 +49443,7 @@ function compareVersions(v1, v2) {
|
|
|
49367
49443
|
var package_default = {
|
|
49368
49444
|
name: "@knowsuchagency/fulcrum",
|
|
49369
49445
|
private: true,
|
|
49370
|
-
version: "2.
|
|
49446
|
+
version: "2.8.1",
|
|
49371
49447
|
description: "Harness Attention. Orchestrate Agents. Ship.",
|
|
49372
49448
|
license: "PolyForm-Perimeter-1.0.0",
|
|
49373
49449
|
type: "module",
|