@knowsuchagency/fulcrum 2.8.2 → 2.10.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/README.md +10 -7
- package/bin/fulcrum.js +184 -134
- package/dist/assets/index-CuJCUrcM.css +1 -0
- package/dist/assets/{index-BfBfuxBH.js → index-DDg3hDUp.js} +168 -167
- package/dist/index.html +2 -2
- package/drizzle/0054_remove_actionable_events.sql +1 -0
- package/drizzle/0055_caldav_multi_account.sql +40 -0
- package/drizzle/meta/_journal.json +14 -0
- package/package.json +1 -1
- package/server/index.js +13086 -12320
- package/dist/assets/index-TyeuSbkG.css +0 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ Fulcrum doesn't replace your tools—it gives you leverage over them. You config
|
|
|
15
15
|
**Six pillars:**
|
|
16
16
|
|
|
17
17
|
- **Claude Code Ecosystem** — Deep integration with Claude Code. Connect via messaging channels, manage tasks, deploy from one dashboard.
|
|
18
|
-
- **Proactive AI Concierge** — Your assistant monitors messages,
|
|
18
|
+
- **Proactive AI Concierge** — Your assistant monitors messages, stores important observations as memories, creates daily plans, and sends morning/evening briefings automatically.
|
|
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.
|
|
@@ -42,13 +42,13 @@ Fulcrum's AI assistant doesn't just respond—it actively monitors and manages y
|
|
|
42
42
|
|
|
43
43
|
When messages arrive via Email, WhatsApp, Discord, Telegram, or Slack:
|
|
44
44
|
|
|
45
|
-
- **Actionable requests** (deadlines, meetings, tasks) →
|
|
45
|
+
- **Actionable requests** (deadlines, meetings, tasks) → Stored as memories with `actionable` tag, optionally creates tasks
|
|
46
46
|
- **Casual conversations** → Responded to naturally, no tracking overhead
|
|
47
47
|
- **Spam/newsletters** → Silently ignored
|
|
48
48
|
|
|
49
|
-
###
|
|
49
|
+
### Persistent Memory
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
Important observations are stored as **memories** with tags like `actionable` or `monitoring`—searchable via full-text search, with recency-weighted results so recent items surface first.
|
|
52
52
|
|
|
53
53
|
### Daily Planning
|
|
54
54
|
|
|
@@ -156,11 +156,13 @@ Create documents with live preview. Generate charts and visualizations. The assi
|
|
|
156
156
|
|
|
157
157
|
### Calendar Integration
|
|
158
158
|
|
|
159
|
-
Connect
|
|
159
|
+
Connect multiple calendar accounts via CalDAV so the AI assistant knows your schedule. Copy events between calendars across accounts.
|
|
160
160
|
|
|
161
|
+
- **Multiple accounts** — Add as many CalDAV accounts as you need
|
|
161
162
|
- **Google Calendar** — OAuth2 flow, no password needed
|
|
162
163
|
- **Any CalDAV server** — Nextcloud, Radicale, Baikal, iCloud
|
|
163
|
-
- **Automatic sync** —
|
|
164
|
+
- **Automatic sync** — Each account syncs independently on a configurable interval
|
|
165
|
+
- **One-way event copying** — Copy events between calendars across accounts via configurable rules
|
|
164
166
|
- **Assistant awareness** — The AI assistant uses your calendar context for planning and scheduling
|
|
165
167
|
|
|
166
168
|
Enable in Settings → Calendar Integration.
|
|
@@ -247,7 +249,8 @@ Both plugins include an MCP server with 60+ tools:
|
|
|
247
249
|
| **Backup & Restore** | Snapshot database and settings; auto-safety-backup on restore |
|
|
248
250
|
| **Settings** | View and update configuration; manage notification channels |
|
|
249
251
|
| **Memory** | Store and search persistent knowledge with FTS5 full-text search |
|
|
250
|
-
| **
|
|
252
|
+
| **Calendar** | Manage CalDAV accounts, sync calendars, configure event copy rules |
|
|
253
|
+
| **Assistant** | Send messages via channels; query sweep history |
|
|
251
254
|
|
|
252
255
|
Use `search_tools` to discover available tools by keyword or category.
|
|
253
256
|
|
package/bin/fulcrum.js
CHANGED
|
@@ -1197,6 +1197,13 @@ class FulcrumClient {
|
|
|
1197
1197
|
method: "DELETE"
|
|
1198
1198
|
});
|
|
1199
1199
|
}
|
|
1200
|
+
async deleteTag(tagName) {
|
|
1201
|
+
const allTags = await this.fetch("/api/tags");
|
|
1202
|
+
const tag = allTags.find((t2) => t2.name === tagName);
|
|
1203
|
+
if (!tag)
|
|
1204
|
+
throw new ApiError(404, "Tag not found");
|
|
1205
|
+
return this.fetch(`/api/tags/${tag.id}`, { method: "DELETE" });
|
|
1206
|
+
}
|
|
1200
1207
|
async setTaskDueDate(taskId, dueDate) {
|
|
1201
1208
|
return this.fetch(`/api/tasks/${taskId}/due-date`, {
|
|
1202
1209
|
method: "PATCH",
|
|
@@ -1487,39 +1494,6 @@ class FulcrumClient {
|
|
|
1487
1494
|
body: JSON.stringify({ uids, limit })
|
|
1488
1495
|
});
|
|
1489
1496
|
}
|
|
1490
|
-
async listActionableEvents(options) {
|
|
1491
|
-
const params = new URLSearchParams;
|
|
1492
|
-
if (options?.status)
|
|
1493
|
-
params.set("status", options.status);
|
|
1494
|
-
if (options?.channel)
|
|
1495
|
-
params.set("channel", options.channel);
|
|
1496
|
-
if (options?.limit)
|
|
1497
|
-
params.set("limit", String(options.limit));
|
|
1498
|
-
if (options?.offset)
|
|
1499
|
-
params.set("offset", String(options.offset));
|
|
1500
|
-
const query = params.toString();
|
|
1501
|
-
return this.fetch(`/api/assistant/events${query ? `?${query}` : ""}`);
|
|
1502
|
-
}
|
|
1503
|
-
async getActionableEvent(id) {
|
|
1504
|
-
return this.fetch(`/api/assistant/events/${id}`);
|
|
1505
|
-
}
|
|
1506
|
-
async createActionableEvent(data) {
|
|
1507
|
-
return this.fetch("/api/assistant/events", {
|
|
1508
|
-
method: "POST",
|
|
1509
|
-
body: JSON.stringify(data)
|
|
1510
|
-
});
|
|
1511
|
-
}
|
|
1512
|
-
async updateActionableEvent(id, updates) {
|
|
1513
|
-
return this.fetch(`/api/assistant/events/${id}`, {
|
|
1514
|
-
method: "PATCH",
|
|
1515
|
-
body: JSON.stringify(updates)
|
|
1516
|
-
});
|
|
1517
|
-
}
|
|
1518
|
-
async deleteActionableEvent(id) {
|
|
1519
|
-
return this.fetch(`/api/assistant/events/${id}`, {
|
|
1520
|
-
method: "DELETE"
|
|
1521
|
-
});
|
|
1522
|
-
}
|
|
1523
1497
|
async listSweepRuns(options) {
|
|
1524
1498
|
const params = new URLSearchParams;
|
|
1525
1499
|
if (options?.type)
|
|
@@ -1544,8 +1518,39 @@ class FulcrumClient {
|
|
|
1544
1518
|
async getCaldavStatus() {
|
|
1545
1519
|
return this.fetch("/api/caldav/status");
|
|
1546
1520
|
}
|
|
1547
|
-
async listCalendars() {
|
|
1548
|
-
|
|
1521
|
+
async listCalendars(accountId) {
|
|
1522
|
+
const params = accountId ? `?accountId=${accountId}` : "";
|
|
1523
|
+
return this.fetch(`/api/caldav/calendars${params}`);
|
|
1524
|
+
}
|
|
1525
|
+
async listCaldavAccounts() {
|
|
1526
|
+
return this.fetch("/api/caldav/accounts");
|
|
1527
|
+
}
|
|
1528
|
+
async createCaldavAccount(input) {
|
|
1529
|
+
return this.fetch("/api/caldav/accounts", {
|
|
1530
|
+
method: "POST",
|
|
1531
|
+
body: JSON.stringify(input)
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
async deleteCaldavAccount(id) {
|
|
1535
|
+
return this.fetch(`/api/caldav/accounts/${id}`, { method: "DELETE" });
|
|
1536
|
+
}
|
|
1537
|
+
async syncCaldavAccount(id) {
|
|
1538
|
+
return this.fetch(`/api/caldav/accounts/${id}/sync`, { method: "POST" });
|
|
1539
|
+
}
|
|
1540
|
+
async listCaldavCopyRules() {
|
|
1541
|
+
return this.fetch("/api/caldav/copy-rules");
|
|
1542
|
+
}
|
|
1543
|
+
async createCaldavCopyRule(input) {
|
|
1544
|
+
return this.fetch("/api/caldav/copy-rules", {
|
|
1545
|
+
method: "POST",
|
|
1546
|
+
body: JSON.stringify(input)
|
|
1547
|
+
});
|
|
1548
|
+
}
|
|
1549
|
+
async deleteCaldavCopyRule(id) {
|
|
1550
|
+
return this.fetch(`/api/caldav/copy-rules/${id}`, { method: "DELETE" });
|
|
1551
|
+
}
|
|
1552
|
+
async executeCaldavCopyRule(id) {
|
|
1553
|
+
return this.fetch(`/api/caldav/copy-rules/${id}/execute`, { method: "POST" });
|
|
1549
1554
|
}
|
|
1550
1555
|
async syncCalendars() {
|
|
1551
1556
|
return this.fetch("/api/caldav/sync", { method: "POST" });
|
|
@@ -1611,9 +1616,6 @@ class FulcrumClient {
|
|
|
1611
1616
|
async deleteMemory(id) {
|
|
1612
1617
|
return this.fetch(`/api/memory/${id}`, { method: "DELETE" });
|
|
1613
1618
|
}
|
|
1614
|
-
async getAssistantStats() {
|
|
1615
|
-
return this.fetch("/api/assistant/stats");
|
|
1616
|
-
}
|
|
1617
1619
|
}
|
|
1618
1620
|
var init_client = __esm(() => {
|
|
1619
1621
|
init_server();
|
|
@@ -43951,6 +43953,13 @@ var init_registry = __esm(() => {
|
|
|
43951
43953
|
keywords: ["tags", "categories", "filter", "search", "discover"],
|
|
43952
43954
|
defer_loading: false
|
|
43953
43955
|
},
|
|
43956
|
+
{
|
|
43957
|
+
name: "delete_tag",
|
|
43958
|
+
description: "Delete a tag from the database and all its associations",
|
|
43959
|
+
category: "tasks",
|
|
43960
|
+
keywords: ["tag", "delete", "remove", "cleanup"],
|
|
43961
|
+
defer_loading: false
|
|
43962
|
+
},
|
|
43954
43963
|
{
|
|
43955
43964
|
name: "list_task_attachments",
|
|
43956
43965
|
description: "List all file attachments for a task",
|
|
@@ -44113,46 +44122,67 @@ var init_registry = __esm(() => {
|
|
|
44113
44122
|
defer_loading: false
|
|
44114
44123
|
},
|
|
44115
44124
|
{
|
|
44116
|
-
name: "
|
|
44117
|
-
description: "
|
|
44125
|
+
name: "get_last_sweep",
|
|
44126
|
+
description: "Get information about the last sweep run of a type",
|
|
44118
44127
|
category: "assistant",
|
|
44119
|
-
keywords: ["
|
|
44128
|
+
keywords: ["sweep", "last", "hourly", "morning", "evening", "ritual"],
|
|
44120
44129
|
defer_loading: false
|
|
44121
44130
|
},
|
|
44122
44131
|
{
|
|
44123
|
-
name: "
|
|
44124
|
-
description: "List
|
|
44125
|
-
category: "
|
|
44126
|
-
keywords: ["
|
|
44127
|
-
defer_loading:
|
|
44132
|
+
name: "list_caldav_accounts",
|
|
44133
|
+
description: "List all CalDAV accounts configured for calendar sync",
|
|
44134
|
+
category: "caldav",
|
|
44135
|
+
keywords: ["caldav", "account", "list", "calendar", "google", "nextcloud"],
|
|
44136
|
+
defer_loading: true
|
|
44128
44137
|
},
|
|
44129
44138
|
{
|
|
44130
|
-
name: "
|
|
44131
|
-
description: "
|
|
44132
|
-
category: "
|
|
44133
|
-
keywords: ["
|
|
44134
|
-
defer_loading:
|
|
44139
|
+
name: "create_caldav_account",
|
|
44140
|
+
description: "Create a new CalDAV account with basic authentication",
|
|
44141
|
+
category: "caldav",
|
|
44142
|
+
keywords: ["caldav", "account", "create", "add", "calendar", "connect"],
|
|
44143
|
+
defer_loading: true
|
|
44135
44144
|
},
|
|
44136
44145
|
{
|
|
44137
|
-
name: "
|
|
44138
|
-
description: "
|
|
44139
|
-
category: "
|
|
44140
|
-
keywords: ["
|
|
44141
|
-
defer_loading:
|
|
44146
|
+
name: "delete_caldav_account",
|
|
44147
|
+
description: "Delete a CalDAV account and all its calendars and events",
|
|
44148
|
+
category: "caldav",
|
|
44149
|
+
keywords: ["caldav", "account", "delete", "remove", "disconnect"],
|
|
44150
|
+
defer_loading: true
|
|
44142
44151
|
},
|
|
44143
44152
|
{
|
|
44144
|
-
name: "
|
|
44145
|
-
description: "
|
|
44146
|
-
category: "
|
|
44147
|
-
keywords: ["
|
|
44148
|
-
defer_loading:
|
|
44153
|
+
name: "sync_caldav_account",
|
|
44154
|
+
description: "Trigger a manual sync for a specific CalDAV account",
|
|
44155
|
+
category: "caldav",
|
|
44156
|
+
keywords: ["caldav", "account", "sync", "refresh", "calendar"],
|
|
44157
|
+
defer_loading: true
|
|
44149
44158
|
},
|
|
44150
44159
|
{
|
|
44151
|
-
name: "
|
|
44152
|
-
description: "
|
|
44153
|
-
category: "
|
|
44154
|
-
keywords: ["
|
|
44155
|
-
defer_loading:
|
|
44160
|
+
name: "list_caldav_copy_rules",
|
|
44161
|
+
description: "List all CalDAV copy rules for one-way event replication between calendars",
|
|
44162
|
+
category: "caldav",
|
|
44163
|
+
keywords: ["caldav", "copy", "rule", "list", "replicate", "sync", "calendar"],
|
|
44164
|
+
defer_loading: true
|
|
44165
|
+
},
|
|
44166
|
+
{
|
|
44167
|
+
name: "create_caldav_copy_rule",
|
|
44168
|
+
description: "Create a copy rule to replicate events from one calendar to another",
|
|
44169
|
+
category: "caldav",
|
|
44170
|
+
keywords: ["caldav", "copy", "rule", "create", "replicate", "calendar"],
|
|
44171
|
+
defer_loading: true
|
|
44172
|
+
},
|
|
44173
|
+
{
|
|
44174
|
+
name: "delete_caldav_copy_rule",
|
|
44175
|
+
description: "Delete a CalDAV copy rule",
|
|
44176
|
+
category: "caldav",
|
|
44177
|
+
keywords: ["caldav", "copy", "rule", "delete", "remove"],
|
|
44178
|
+
defer_loading: true
|
|
44179
|
+
},
|
|
44180
|
+
{
|
|
44181
|
+
name: "execute_caldav_copy_rule",
|
|
44182
|
+
description: "Manually execute a copy rule to replicate events now",
|
|
44183
|
+
category: "caldav",
|
|
44184
|
+
keywords: ["caldav", "copy", "rule", "execute", "run", "replicate"],
|
|
44185
|
+
defer_loading: true
|
|
44156
44186
|
},
|
|
44157
44187
|
{
|
|
44158
44188
|
name: "list_calendars",
|
|
@@ -44683,6 +44713,16 @@ var registerTaskTools = (server, client) => {
|
|
|
44683
44713
|
return handleToolError(err);
|
|
44684
44714
|
}
|
|
44685
44715
|
});
|
|
44716
|
+
server.tool("delete_tag", "Delete a tag from the database. This removes the tag and all its associations with tasks and projects.", {
|
|
44717
|
+
tag: exports_external.string().describe("The exact name of the tag to delete")
|
|
44718
|
+
}, async ({ tag }) => {
|
|
44719
|
+
try {
|
|
44720
|
+
await client.deleteTag(tag);
|
|
44721
|
+
return formatSuccess({ deleted: tag });
|
|
44722
|
+
} catch (err) {
|
|
44723
|
+
return handleToolError(err);
|
|
44724
|
+
}
|
|
44725
|
+
});
|
|
44686
44726
|
server.tool("list_tasks_by_due_date", "List tasks within a date range based on due date", {
|
|
44687
44727
|
startDate: exports_external.optional(exports_external.string()).describe("Start date (YYYY-MM-DD), inclusive"),
|
|
44688
44728
|
endDate: exports_external.optional(exports_external.string()).describe("End date (YYYY-MM-DD), inclusive"),
|
|
@@ -45615,8 +45655,8 @@ var init_email = __esm(() => {
|
|
|
45615
45655
|
init_utils();
|
|
45616
45656
|
});
|
|
45617
45657
|
|
|
45618
|
-
// cli/src/mcp/tools/assistant
|
|
45619
|
-
var
|
|
45658
|
+
// cli/src/mcp/tools/assistant.ts
|
|
45659
|
+
var ChannelSchema, registerAssistantTools = (server, client) => {
|
|
45620
45660
|
server.tool("message", "Send a message to a messaging channel (email, WhatsApp, etc.). Use this to reply to messages or send proactive communications.", {
|
|
45621
45661
|
channel: ChannelSchema.describe("Target channel: email, whatsapp, discord, telegram, slack, or all"),
|
|
45622
45662
|
to: exports_external.string().describe("Recipient (email address, phone number, or channel ID)"),
|
|
@@ -45639,102 +45679,112 @@ var ActionableEventStatusSchema, ChannelSchema, registerAssistantEventTools = (s
|
|
|
45639
45679
|
return handleToolError(err);
|
|
45640
45680
|
}
|
|
45641
45681
|
});
|
|
45642
|
-
server.tool("
|
|
45643
|
-
|
|
45644
|
-
|
|
45645
|
-
source_metadata: exports_external.optional(exports_external.record(exports_external.string(), exports_external.any())).describe("Additional context (sender, subject, etc.)"),
|
|
45646
|
-
summary: exports_external.optional(exports_external.string()).describe("AI-generated description of what this event is about"),
|
|
45647
|
-
status: exports_external.optional(ActionableEventStatusSchema).describe("Event status (default: pending)"),
|
|
45648
|
-
linked_task_id: exports_external.optional(exports_external.string()).describe("Fulcrum task ID if this event relates to a task")
|
|
45649
|
-
}, async ({ source_channel, source_id, source_metadata, summary, status, linked_task_id }) => {
|
|
45682
|
+
server.tool("get_last_sweep", "Get information about the last sweep run of a specific type. Useful for context about what was last reviewed.", {
|
|
45683
|
+
type: exports_external.enum(["hourly", "morning_ritual", "evening_ritual"]).describe("Type of sweep")
|
|
45684
|
+
}, async ({ type }) => {
|
|
45650
45685
|
try {
|
|
45651
|
-
const result = await client.
|
|
45652
|
-
|
|
45653
|
-
sourceId: source_id,
|
|
45654
|
-
sourceMetadata: source_metadata,
|
|
45655
|
-
summary,
|
|
45656
|
-
status,
|
|
45657
|
-
linkedTaskId: linked_task_id
|
|
45658
|
-
});
|
|
45659
|
-
return formatSuccess(result);
|
|
45686
|
+
const result = await client.getLastSweepRun(type);
|
|
45687
|
+
return formatSuccess(result || { message: "No sweep of this type has run yet" });
|
|
45660
45688
|
} catch (err) {
|
|
45661
45689
|
return handleToolError(err);
|
|
45662
45690
|
}
|
|
45663
45691
|
});
|
|
45664
|
-
|
|
45665
|
-
|
|
45666
|
-
|
|
45667
|
-
|
|
45668
|
-
|
|
45692
|
+
};
|
|
45693
|
+
var init_assistant = __esm(() => {
|
|
45694
|
+
init_zod2();
|
|
45695
|
+
init_utils();
|
|
45696
|
+
ChannelSchema = exports_external.enum(["email", "whatsapp", "discord", "telegram", "slack", "all"]);
|
|
45697
|
+
});
|
|
45698
|
+
|
|
45699
|
+
// cli/src/mcp/tools/caldav.ts
|
|
45700
|
+
var registerCaldavTools = (server, client) => {
|
|
45701
|
+
server.tool("list_caldav_accounts", "List all CalDAV accounts configured for calendar sync.", {}, async () => {
|
|
45669
45702
|
try {
|
|
45670
|
-
const
|
|
45671
|
-
|
|
45672
|
-
channel: source_channel,
|
|
45673
|
-
limit: limit ?? 50
|
|
45674
|
-
});
|
|
45675
|
-
return formatSuccess(result);
|
|
45703
|
+
const accounts = await client.listCaldavAccounts();
|
|
45704
|
+
return formatSuccess(accounts);
|
|
45676
45705
|
} catch (err) {
|
|
45677
45706
|
return handleToolError(err);
|
|
45678
45707
|
}
|
|
45679
45708
|
});
|
|
45680
|
-
server.tool("
|
|
45681
|
-
|
|
45709
|
+
server.tool("create_caldav_account", "Create a new CalDAV account with basic authentication.", {
|
|
45710
|
+
name: exports_external.string().describe("Display name for the account"),
|
|
45711
|
+
serverUrl: exports_external.string().describe("CalDAV server URL"),
|
|
45712
|
+
username: exports_external.string().describe("Username for authentication"),
|
|
45713
|
+
password: exports_external.string().describe("Password for authentication"),
|
|
45714
|
+
syncIntervalMinutes: exports_external.optional(exports_external.number()).describe("Sync interval in minutes (default: 15)")
|
|
45715
|
+
}, async (input) => {
|
|
45716
|
+
try {
|
|
45717
|
+
const account = await client.createCaldavAccount(input);
|
|
45718
|
+
return formatSuccess(account);
|
|
45719
|
+
} catch (err) {
|
|
45720
|
+
return handleToolError(err);
|
|
45721
|
+
}
|
|
45722
|
+
});
|
|
45723
|
+
server.tool("delete_caldav_account", "Delete a CalDAV account and all its calendars and events.", {
|
|
45724
|
+
id: exports_external.string().describe("Account ID to delete")
|
|
45682
45725
|
}, async ({ id }) => {
|
|
45683
45726
|
try {
|
|
45684
|
-
const result = await client.
|
|
45727
|
+
const result = await client.deleteCaldavAccount(id);
|
|
45685
45728
|
return formatSuccess(result);
|
|
45686
45729
|
} catch (err) {
|
|
45687
45730
|
return handleToolError(err);
|
|
45688
45731
|
}
|
|
45689
45732
|
});
|
|
45690
|
-
server.tool("
|
|
45691
|
-
id: exports_external.string().describe("
|
|
45692
|
-
|
|
45693
|
-
linked_task_id: exports_external.optional(exports_external.string()).describe("Link to a Fulcrum task (use empty string to unlink)"),
|
|
45694
|
-
action_log_entry: exports_external.optional(exports_external.string()).describe('Action to log (e.g., "Replied with project update")')
|
|
45695
|
-
}, async ({ id, status, linked_task_id, action_log_entry }) => {
|
|
45733
|
+
server.tool("sync_caldav_account", "Trigger a manual sync for a specific CalDAV account.", {
|
|
45734
|
+
id: exports_external.string().describe("Account ID to sync")
|
|
45735
|
+
}, async ({ id }) => {
|
|
45696
45736
|
try {
|
|
45697
|
-
const result = await client.
|
|
45698
|
-
status,
|
|
45699
|
-
linkedTaskId: linked_task_id === "" ? null : linked_task_id,
|
|
45700
|
-
actionLogEntry: action_log_entry
|
|
45701
|
-
});
|
|
45737
|
+
const result = await client.syncCaldavAccount(id);
|
|
45702
45738
|
return formatSuccess(result);
|
|
45703
45739
|
} catch (err) {
|
|
45704
45740
|
return handleToolError(err);
|
|
45705
45741
|
}
|
|
45706
45742
|
});
|
|
45707
|
-
server.tool("
|
|
45743
|
+
server.tool("list_caldav_copy_rules", "List all CalDAV copy rules for one-way event replication between calendars.", {}, async () => {
|
|
45744
|
+
try {
|
|
45745
|
+
const rules = await client.listCaldavCopyRules();
|
|
45746
|
+
return formatSuccess(rules);
|
|
45747
|
+
} catch (err) {
|
|
45748
|
+
return handleToolError(err);
|
|
45749
|
+
}
|
|
45750
|
+
});
|
|
45751
|
+
server.tool("create_caldav_copy_rule", "Create a copy rule to replicate events from one calendar to another.", {
|
|
45752
|
+
sourceCalendarId: exports_external.string().describe("Source calendar ID"),
|
|
45753
|
+
destCalendarId: exports_external.string().describe("Destination calendar ID"),
|
|
45754
|
+
name: exports_external.optional(exports_external.string()).describe("Optional label for the rule")
|
|
45755
|
+
}, async (input) => {
|
|
45756
|
+
try {
|
|
45757
|
+
const rule = await client.createCaldavCopyRule(input);
|
|
45758
|
+
return formatSuccess(rule);
|
|
45759
|
+
} catch (err) {
|
|
45760
|
+
return handleToolError(err);
|
|
45761
|
+
}
|
|
45762
|
+
});
|
|
45763
|
+
server.tool("delete_caldav_copy_rule", "Delete a CalDAV copy rule.", {
|
|
45764
|
+
id: exports_external.string().describe("Copy rule ID to delete")
|
|
45765
|
+
}, async ({ id }) => {
|
|
45708
45766
|
try {
|
|
45709
|
-
const result = await client.
|
|
45767
|
+
const result = await client.deleteCaldavCopyRule(id);
|
|
45710
45768
|
return formatSuccess(result);
|
|
45711
45769
|
} catch (err) {
|
|
45712
45770
|
return handleToolError(err);
|
|
45713
45771
|
}
|
|
45714
45772
|
});
|
|
45715
|
-
server.tool("
|
|
45716
|
-
|
|
45717
|
-
}, async ({
|
|
45773
|
+
server.tool("execute_caldav_copy_rule", "Manually execute a copy rule to replicate events now.", {
|
|
45774
|
+
id: exports_external.string().describe("Copy rule ID to execute")
|
|
45775
|
+
}, async ({ id }) => {
|
|
45718
45776
|
try {
|
|
45719
|
-
const result = await client.
|
|
45720
|
-
return formatSuccess(result
|
|
45777
|
+
const result = await client.executeCaldavCopyRule(id);
|
|
45778
|
+
return formatSuccess(result);
|
|
45721
45779
|
} catch (err) {
|
|
45722
45780
|
return handleToolError(err);
|
|
45723
45781
|
}
|
|
45724
45782
|
});
|
|
45725
|
-
|
|
45726
|
-
|
|
45727
|
-
|
|
45728
|
-
init_utils();
|
|
45729
|
-
ActionableEventStatusSchema = exports_external.enum(["pending", "acted_upon", "dismissed", "monitoring"]);
|
|
45730
|
-
ChannelSchema = exports_external.enum(["email", "whatsapp", "discord", "telegram", "slack", "all"]);
|
|
45731
|
-
});
|
|
45732
|
-
|
|
45733
|
-
// cli/src/mcp/tools/caldav.ts
|
|
45734
|
-
var registerCaldavTools = (server, client) => {
|
|
45735
|
-
server.tool("list_calendars", "List all CalDAV calendars synced from the configured server.", {}, async () => {
|
|
45783
|
+
server.tool("list_calendars", "List all CalDAV calendars synced from the configured server.", {
|
|
45784
|
+
accountId: exports_external.optional(exports_external.string()).describe("Filter by account ID")
|
|
45785
|
+
}, async ({ accountId }) => {
|
|
45736
45786
|
try {
|
|
45737
|
-
const calendars = await client.listCalendars();
|
|
45787
|
+
const calendars = await client.listCalendars(accountId);
|
|
45738
45788
|
return formatSuccess(calendars);
|
|
45739
45789
|
} catch (err) {
|
|
45740
45790
|
return handleToolError(err);
|
|
@@ -45884,7 +45934,7 @@ function registerTools(server, client) {
|
|
|
45884
45934
|
registerSettingsTools(server, client);
|
|
45885
45935
|
registerBackupTools(server, client);
|
|
45886
45936
|
registerEmailTools(server, client);
|
|
45887
|
-
|
|
45937
|
+
registerAssistantTools(server, client);
|
|
45888
45938
|
registerCaldavTools(server, client);
|
|
45889
45939
|
registerMemoryTools(server, client);
|
|
45890
45940
|
}
|
|
@@ -45900,7 +45950,7 @@ var init_tools = __esm(() => {
|
|
|
45900
45950
|
init_settings();
|
|
45901
45951
|
init_backup();
|
|
45902
45952
|
init_email();
|
|
45903
|
-
|
|
45953
|
+
init_assistant();
|
|
45904
45954
|
init_caldav();
|
|
45905
45955
|
init_memory();
|
|
45906
45956
|
init_types4();
|
|
@@ -45921,7 +45971,7 @@ async function runMcpServer(urlOverride, portOverride) {
|
|
|
45921
45971
|
const client = new FulcrumClient(urlOverride, portOverride);
|
|
45922
45972
|
const server = new McpServer({
|
|
45923
45973
|
name: "fulcrum",
|
|
45924
|
-
version: "2.
|
|
45974
|
+
version: "2.10.0"
|
|
45925
45975
|
});
|
|
45926
45976
|
registerTools(server, client);
|
|
45927
45977
|
const transport = new StdioServerTransport;
|
|
@@ -48270,7 +48320,7 @@ var marketplace_default = `{
|
|
|
48270
48320
|
"name": "fulcrum",
|
|
48271
48321
|
"source": "./",
|
|
48272
48322
|
"description": "Task orchestration for Claude Code",
|
|
48273
|
-
"version": "2.
|
|
48323
|
+
"version": "2.10.0",
|
|
48274
48324
|
"skills": [
|
|
48275
48325
|
"./skills/fulcrum"
|
|
48276
48326
|
],
|
|
@@ -49458,7 +49508,7 @@ function compareVersions(v1, v2) {
|
|
|
49458
49508
|
var package_default = {
|
|
49459
49509
|
name: "@knowsuchagency/fulcrum",
|
|
49460
49510
|
private: true,
|
|
49461
|
-
version: "2.
|
|
49511
|
+
version: "2.10.0",
|
|
49462
49512
|
description: "Harness Attention. Orchestrate Agents. Ship.",
|
|
49463
49513
|
license: "PolyForm-Perimeter-1.0.0",
|
|
49464
49514
|
type: "module",
|