@knowsuchagency/fulcrum 2.17.0 → 2.17.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/bin/fulcrum.js CHANGED
@@ -46247,7 +46247,7 @@ async function runMcpServer(urlOverride, portOverride) {
46247
46247
  const client = new FulcrumClient(urlOverride, portOverride);
46248
46248
  const server = new McpServer({
46249
46249
  name: "fulcrum",
46250
- version: "2.17.0"
46250
+ version: "2.17.1"
46251
46251
  });
46252
46252
  registerTools(server, client);
46253
46253
  const transport = new StdioServerTransport;
@@ -48596,7 +48596,7 @@ var marketplace_default = `{
48596
48596
  "name": "fulcrum",
48597
48597
  "source": "./",
48598
48598
  "description": "Task orchestration for Claude Code",
48599
- "version": "2.17.0",
48599
+ "version": "2.17.1",
48600
48600
  "skills": [
48601
48601
  "./skills/fulcrum"
48602
48602
  ],
@@ -49784,7 +49784,7 @@ function compareVersions(v1, v2) {
49784
49784
  var package_default = {
49785
49785
  name: "@knowsuchagency/fulcrum",
49786
49786
  private: true,
49787
- version: "2.17.0",
49787
+ version: "2.17.1",
49788
49788
  description: "Harness Attention. Orchestrate Agents. Ship.",
49789
49789
  license: "PolyForm-Perimeter-1.0.0",
49790
49790
  type: "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowsuchagency/fulcrum",
3
- "version": "2.17.0",
3
+ "version": "2.17.1",
4
4
  "description": "Harness Attention. Orchestrate Agents. Ship.",
5
5
  "license": "PolyForm-Perimeter-1.0.0",
6
6
  "repository": {
package/server/index.js CHANGED
@@ -361553,289 +361553,359 @@ var require_dist20 = __commonJS((exports) => {
361553
361553
  });
361554
361554
 
361555
361555
  // server/services/channels/slack-channel.ts
361556
- class SlackChannel {
361557
- type = "slack";
361558
- connectionId;
361559
- app = null;
361560
- events = null;
361561
- status = "disconnected";
361562
- reconnectTimer = null;
361563
- isShuttingDown = false;
361564
- botToken = null;
361565
- appToken = null;
361566
- constructor(connectionId) {
361567
- this.connectionId = connectionId;
361568
- }
361569
- async initialize(events) {
361570
- this.events = events;
361571
- this.isShuttingDown = false;
361572
- const settings = getSettings();
361573
- const slackConfig = settings.channels.slack;
361574
- if (!slackConfig.botToken || !slackConfig.appToken) {
361575
- log2.messaging.warn("Slack channel missing credentials", {
361576
- connectionId: this.connectionId
361577
- });
361578
- this.updateStatus("disconnected");
361579
- return;
361556
+ var import_bolt, SlackChannel;
361557
+ var init_slack_channel = __esm(() => {
361558
+ init_drizzle_orm();
361559
+ init_db2();
361560
+ init_logger3();
361561
+ init_settings();
361562
+ import_bolt = __toESM(require_dist20(), 1);
361563
+ SlackChannel = class SlackChannel {
361564
+ type = "slack";
361565
+ connectionId;
361566
+ app = null;
361567
+ events = null;
361568
+ status = "disconnected";
361569
+ reconnectTimer = null;
361570
+ healthCheckTimer = null;
361571
+ isShuttingDown = false;
361572
+ botToken = null;
361573
+ appToken = null;
361574
+ static HEALTH_CHECK_INTERVAL = 5 * 60 * 1000;
361575
+ constructor(connectionId) {
361576
+ this.connectionId = connectionId;
361577
+ }
361578
+ async initialize(events) {
361579
+ this.events = events;
361580
+ this.isShuttingDown = false;
361581
+ const settings = getSettings();
361582
+ const slackConfig = settings.channels.slack;
361583
+ if (!slackConfig.botToken || !slackConfig.appToken) {
361584
+ log2.messaging.warn("Slack channel missing credentials", {
361585
+ connectionId: this.connectionId
361586
+ });
361587
+ this.updateStatus("disconnected");
361588
+ return;
361589
+ }
361590
+ this.botToken = slackConfig.botToken;
361591
+ this.appToken = slackConfig.appToken;
361592
+ await this.connect();
361580
361593
  }
361581
- this.botToken = slackConfig.botToken;
361582
- this.appToken = slackConfig.appToken;
361583
- await this.connect();
361584
- }
361585
- async connect() {
361586
- if (this.isShuttingDown || !this.botToken || !this.appToken)
361587
- return;
361588
- try {
361589
- this.updateStatus("connecting");
361590
- this.app = new import_bolt.App({
361591
- token: this.botToken,
361592
- appToken: this.appToken,
361593
- socketMode: true,
361594
- logLevel: import_bolt.LogLevel.WARN
361595
- });
361596
- this.app.command(/.*/, async ({ ack, command, respond }) => {
361597
- await ack();
361598
- await this.handleSlashCommand(command, respond);
361594
+ async connect() {
361595
+ if (this.isShuttingDown || !this.botToken || !this.appToken)
361596
+ return;
361597
+ try {
361598
+ this.updateStatus("connecting");
361599
+ this.app = new import_bolt.App({
361600
+ token: this.botToken,
361601
+ appToken: this.appToken,
361602
+ socketMode: true,
361603
+ logLevel: import_bolt.LogLevel.WARN
361604
+ });
361605
+ this.app.command(/.*/, async ({ ack, command, respond }) => {
361606
+ await ack();
361607
+ await this.handleSlashCommand(command, respond);
361608
+ });
361609
+ this.app.message(async ({ message }) => {
361610
+ if (message.channel_type === "im") {
361611
+ await this.handleMessage(message);
361612
+ }
361613
+ });
361614
+ await this.app.start();
361615
+ this.setupSocketModeListeners();
361616
+ const authTest = await this.app.client.auth.test();
361617
+ log2.messaging.info("Slack bot connected", {
361618
+ connectionId: this.connectionId,
361619
+ botId: authTest.bot_id,
361620
+ userId: authTest.user_id
361621
+ });
361622
+ this.updateStatus("connected");
361623
+ this.startHealthCheck();
361624
+ const displayName = authTest.user || "Slack Bot";
361625
+ db2.update(messagingConnections).set({
361626
+ displayName,
361627
+ updatedAt: new Date().toISOString()
361628
+ }).where(eq(messagingConnections.id, this.connectionId)).run();
361629
+ this.events?.onDisplayNameChange?.(displayName);
361630
+ } catch (err) {
361631
+ log2.messaging.error("Slack connect error", {
361632
+ connectionId: this.connectionId,
361633
+ error: String(err)
361634
+ });
361635
+ this.updateStatus("disconnected");
361636
+ this.scheduleReconnect();
361637
+ }
361638
+ }
361639
+ setupSocketModeListeners() {
361640
+ const receiver2 = this.app?.receiver;
361641
+ const socketClient = receiver2?.client;
361642
+ if (!socketClient) {
361643
+ log2.messaging.warn("Could not access Socket Mode client for health monitoring", {
361644
+ connectionId: this.connectionId
361645
+ });
361646
+ return;
361647
+ }
361648
+ socketClient.on("disconnected", () => {
361649
+ if (this.isShuttingDown)
361650
+ return;
361651
+ log2.messaging.warn("Slack Socket Mode disconnected", {
361652
+ connectionId: this.connectionId
361653
+ });
361654
+ this.updateStatus("disconnected");
361599
361655
  });
361600
- this.app.message(async ({ message }) => {
361601
- if (message.channel_type === "im") {
361602
- await this.handleMessage(message);
361603
- }
361656
+ socketClient.on("reconnecting", () => {
361657
+ if (this.isShuttingDown)
361658
+ return;
361659
+ log2.messaging.info("Slack Socket Mode reconnecting", {
361660
+ connectionId: this.connectionId
361661
+ });
361662
+ this.updateStatus("connecting");
361604
361663
  });
361605
- await this.app.start();
361606
- const authTest = await this.app.client.auth.test();
361607
- log2.messaging.info("Slack bot connected", {
361608
- connectionId: this.connectionId,
361609
- botId: authTest.bot_id,
361610
- userId: authTest.user_id
361664
+ socketClient.on("connected", () => {
361665
+ if (this.isShuttingDown)
361666
+ return;
361667
+ log2.messaging.info("Slack Socket Mode reconnected", {
361668
+ connectionId: this.connectionId
361669
+ });
361670
+ this.updateStatus("connected");
361611
361671
  });
361612
- this.updateStatus("connected");
361613
- const displayName = authTest.user || "Slack Bot";
361614
- db2.update(messagingConnections).set({
361615
- displayName,
361616
- updatedAt: new Date().toISOString()
361617
- }).where(eq(messagingConnections.id, this.connectionId)).run();
361618
- this.events?.onDisplayNameChange?.(displayName);
361619
- } catch (err) {
361620
- log2.messaging.error("Slack connect error", {
361621
- connectionId: this.connectionId,
361622
- error: String(err)
361672
+ log2.messaging.debug("Socket Mode event listeners attached", {
361673
+ connectionId: this.connectionId
361623
361674
  });
361624
- this.updateStatus("disconnected");
361625
- this.scheduleReconnect();
361626
361675
  }
361627
- }
361628
- async handleMessage(message) {
361629
- if (message.bot_id || message.subtype === "bot_message")
361630
- return;
361631
- const content = message.text;
361632
- if (!content)
361633
- return;
361634
- const userId = message.user;
361635
- if (!userId)
361636
- return;
361637
- let senderName;
361638
- try {
361639
- if (this.app) {
361640
- const userInfo = await this.app.client.users.info({ user: userId });
361641
- senderName = userInfo.user?.real_name || userInfo.user?.name;
361676
+ startHealthCheck() {
361677
+ this.stopHealthCheck();
361678
+ this.healthCheckTimer = setInterval(async () => {
361679
+ if (this.isShuttingDown || !this.app || this.status !== "connected")
361680
+ return;
361681
+ try {
361682
+ await this.app.client.auth.test();
361683
+ } catch (err) {
361684
+ log2.messaging.warn("Slack health check failed, triggering reconnect", {
361685
+ connectionId: this.connectionId,
361686
+ error: String(err)
361687
+ });
361688
+ this.updateStatus("disconnected");
361689
+ try {
361690
+ await this.app?.stop();
361691
+ } catch {}
361692
+ this.app = null;
361693
+ this.scheduleReconnect();
361694
+ }
361695
+ }, SlackChannel.HEALTH_CHECK_INTERVAL);
361696
+ }
361697
+ stopHealthCheck() {
361698
+ if (this.healthCheckTimer) {
361699
+ clearInterval(this.healthCheckTimer);
361700
+ this.healthCheckTimer = null;
361642
361701
  }
361643
- } catch {}
361644
- const incomingMessage = {
361645
- channelType: "slack",
361646
- connectionId: this.connectionId,
361647
- senderId: userId,
361648
- senderName,
361649
- content,
361650
- timestamp: new Date(parseFloat(message.ts) * 1000)
361651
- };
361652
- log2.messaging.info("Slack message received", {
361653
- connectionId: this.connectionId,
361654
- from: userId,
361655
- contentLength: content.length
361656
- });
361657
- try {
361658
- await this.events?.onMessage(incomingMessage);
361659
- } catch (err) {
361660
- log2.messaging.error("Error processing Slack message", {
361702
+ }
361703
+ async handleMessage(message) {
361704
+ if (message.bot_id || message.subtype === "bot_message")
361705
+ return;
361706
+ const content = message.text;
361707
+ if (!content)
361708
+ return;
361709
+ const userId = message.user;
361710
+ if (!userId)
361711
+ return;
361712
+ let senderName;
361713
+ try {
361714
+ if (this.app) {
361715
+ const userInfo = await this.app.client.users.info({ user: userId });
361716
+ senderName = userInfo.user?.real_name || userInfo.user?.name;
361717
+ }
361718
+ } catch {}
361719
+ const incomingMessage = {
361720
+ channelType: "slack",
361661
361721
  connectionId: this.connectionId,
361662
- error: String(err)
361722
+ senderId: userId,
361723
+ senderName,
361724
+ content,
361725
+ timestamp: new Date(parseFloat(message.ts) * 1000)
361726
+ };
361727
+ log2.messaging.info("Slack message received", {
361728
+ connectionId: this.connectionId,
361729
+ from: userId,
361730
+ contentLength: content.length
361663
361731
  });
361664
- }
361665
- }
361666
- async handleSlashCommand(command, respond) {
361667
- log2.messaging.info("Slack slash command received", {
361668
- connectionId: this.connectionId,
361669
- command: command.command,
361670
- userId: command.user_id,
361671
- userName: command.user_name
361672
- });
361673
- const incomingMessage = {
361674
- channelType: "slack",
361675
- connectionId: this.connectionId,
361676
- senderId: command.user_id,
361677
- senderName: command.user_name,
361678
- content: command.command,
361679
- timestamp: new Date,
361680
- metadata: {
361681
- isSlashCommand: true
361732
+ try {
361733
+ await this.events?.onMessage(incomingMessage);
361734
+ } catch (err) {
361735
+ log2.messaging.error("Error processing Slack message", {
361736
+ connectionId: this.connectionId,
361737
+ error: String(err)
361738
+ });
361682
361739
  }
361683
- };
361684
- try {
361685
- await this.events?.onMessage(incomingMessage);
361686
- await respond({ text: "\u2713 Command received", response_type: "ephemeral" });
361687
- } catch (err) {
361688
- log2.messaging.error("Error processing Slack slash command", {
361740
+ }
361741
+ async handleSlashCommand(command, respond) {
361742
+ log2.messaging.info("Slack slash command received", {
361689
361743
  connectionId: this.connectionId,
361690
361744
  command: command.command,
361691
- error: String(err)
361692
- });
361693
- await respond({
361694
- text: "Sorry, something went wrong processing your command.",
361695
- response_type: "ephemeral"
361745
+ userId: command.user_id,
361746
+ userName: command.user_name
361696
361747
  });
361697
- }
361698
- }
361699
- async shutdown() {
361700
- this.isShuttingDown = true;
361701
- if (this.reconnectTimer) {
361702
- clearTimeout(this.reconnectTimer);
361703
- this.reconnectTimer = null;
361704
- }
361705
- if (this.app) {
361706
- await this.app.stop();
361707
- this.app = null;
361708
- }
361709
- this.updateStatus("disconnected");
361710
- log2.messaging.info("Slack channel shutdown", {
361711
- connectionId: this.connectionId
361712
- });
361713
- }
361714
- async sendMessage(recipientId, content, metadata) {
361715
- if (!this.app || this.status !== "connected") {
361716
- log2.messaging.warn("Cannot send Slack message - not connected", {
361748
+ const incomingMessage = {
361749
+ channelType: "slack",
361717
361750
  connectionId: this.connectionId,
361718
- status: this.status
361719
- });
361720
- return false;
361751
+ senderId: command.user_id,
361752
+ senderName: command.user_name,
361753
+ content: command.command,
361754
+ timestamp: new Date,
361755
+ metadata: {
361756
+ isSlashCommand: true
361757
+ }
361758
+ };
361759
+ try {
361760
+ await this.events?.onMessage(incomingMessage);
361761
+ await respond({ text: "\u2713 Command received", response_type: "ephemeral" });
361762
+ } catch (err) {
361763
+ log2.messaging.error("Error processing Slack slash command", {
361764
+ connectionId: this.connectionId,
361765
+ command: command.command,
361766
+ error: String(err)
361767
+ });
361768
+ await respond({
361769
+ text: "Sorry, something went wrong processing your command.",
361770
+ response_type: "ephemeral"
361771
+ });
361772
+ }
361721
361773
  }
361722
- try {
361723
- const conversation = await this.app.client.conversations.open({
361724
- users: recipientId
361774
+ async shutdown() {
361775
+ this.isShuttingDown = true;
361776
+ this.stopHealthCheck();
361777
+ if (this.reconnectTimer) {
361778
+ clearTimeout(this.reconnectTimer);
361779
+ this.reconnectTimer = null;
361780
+ }
361781
+ if (this.app) {
361782
+ await this.app.stop();
361783
+ this.app = null;
361784
+ }
361785
+ this.updateStatus("disconnected");
361786
+ log2.messaging.info("Slack channel shutdown", {
361787
+ connectionId: this.connectionId
361725
361788
  });
361726
- const channelId = conversation.channel?.id;
361727
- if (!channelId) {
361728
- throw new Error("Failed to open DM channel");
361789
+ }
361790
+ async sendMessage(recipientId, content, metadata) {
361791
+ if (!this.app || this.status !== "connected") {
361792
+ log2.messaging.warn("Cannot send Slack message - not connected", {
361793
+ connectionId: this.connectionId,
361794
+ status: this.status
361795
+ });
361796
+ return false;
361729
361797
  }
361730
- if (content.length <= 4000) {
361731
- const messageOptions = {
361732
- channel: channelId,
361733
- text: content
361734
- };
361735
- if (metadata?.blocks) {
361736
- messageOptions.blocks = metadata.blocks;
361737
- } else {
361738
- messageOptions.mrkdwn = true;
361798
+ try {
361799
+ const conversation = await this.app.client.conversations.open({
361800
+ users: recipientId
361801
+ });
361802
+ const channelId = conversation.channel?.id;
361803
+ if (!channelId) {
361804
+ throw new Error("Failed to open DM channel");
361739
361805
  }
361740
- await this.app.client.chat.postMessage(messageOptions);
361741
- } else {
361742
- const parts = this.splitMessage(content, 4000);
361743
- for (const part of parts) {
361744
- await this.app.client.chat.postMessage({
361806
+ if (content.length <= 4000) {
361807
+ const messageOptions = {
361745
361808
  channel: channelId,
361746
- text: part,
361747
- mrkdwn: true
361748
- });
361749
- await new Promise((resolve6) => setTimeout(resolve6, 100));
361809
+ text: content
361810
+ };
361811
+ if (metadata?.blocks) {
361812
+ messageOptions.blocks = metadata.blocks;
361813
+ } else {
361814
+ messageOptions.mrkdwn = true;
361815
+ }
361816
+ await this.app.client.chat.postMessage(messageOptions);
361817
+ } else {
361818
+ const parts = this.splitMessage(content, 4000);
361819
+ for (const part of parts) {
361820
+ await this.app.client.chat.postMessage({
361821
+ channel: channelId,
361822
+ text: part,
361823
+ mrkdwn: true
361824
+ });
361825
+ await new Promise((resolve6) => setTimeout(resolve6, 100));
361826
+ }
361750
361827
  }
361828
+ log2.messaging.info("Slack message sent", {
361829
+ connectionId: this.connectionId,
361830
+ to: recipientId,
361831
+ contentLength: content.length,
361832
+ hasBlocks: !!metadata?.blocks
361833
+ });
361834
+ return true;
361835
+ } catch (err) {
361836
+ log2.messaging.error("Failed to send Slack message", {
361837
+ connectionId: this.connectionId,
361838
+ to: recipientId,
361839
+ error: String(err)
361840
+ });
361841
+ return false;
361751
361842
  }
361752
- log2.messaging.info("Slack message sent", {
361753
- connectionId: this.connectionId,
361754
- to: recipientId,
361755
- contentLength: content.length,
361756
- hasBlocks: !!metadata?.blocks
361757
- });
361758
- return true;
361759
- } catch (err) {
361760
- log2.messaging.error("Failed to send Slack message", {
361761
- connectionId: this.connectionId,
361762
- to: recipientId,
361763
- error: String(err)
361764
- });
361765
- return false;
361766
361843
  }
361767
- }
361768
- splitMessage(content, maxLength) {
361769
- const parts = [];
361770
- let remaining = content;
361771
- while (remaining.length > 0) {
361772
- if (remaining.length <= maxLength) {
361773
- parts.push(remaining);
361774
- break;
361775
- }
361776
- let breakPoint = remaining.lastIndexOf(`
361844
+ splitMessage(content, maxLength) {
361845
+ const parts = [];
361846
+ let remaining = content;
361847
+ while (remaining.length > 0) {
361848
+ if (remaining.length <= maxLength) {
361849
+ parts.push(remaining);
361850
+ break;
361851
+ }
361852
+ let breakPoint = remaining.lastIndexOf(`
361777
361853
 
361778
361854
  `, maxLength);
361779
- if (breakPoint === -1 || breakPoint < maxLength / 2) {
361780
- breakPoint = remaining.lastIndexOf(`
361855
+ if (breakPoint === -1 || breakPoint < maxLength / 2) {
361856
+ breakPoint = remaining.lastIndexOf(`
361781
361857
  `, maxLength);
361858
+ }
361859
+ if (breakPoint === -1 || breakPoint < maxLength / 2) {
361860
+ breakPoint = remaining.lastIndexOf(" ", maxLength);
361861
+ }
361862
+ if (breakPoint === -1 || breakPoint < maxLength / 2) {
361863
+ breakPoint = maxLength;
361864
+ }
361865
+ parts.push(remaining.slice(0, breakPoint));
361866
+ remaining = remaining.slice(breakPoint).trimStart();
361782
361867
  }
361783
- if (breakPoint === -1 || breakPoint < maxLength / 2) {
361784
- breakPoint = remaining.lastIndexOf(" ", maxLength);
361785
- }
361786
- if (breakPoint === -1 || breakPoint < maxLength / 2) {
361787
- breakPoint = maxLength;
361868
+ return parts;
361869
+ }
361870
+ getStatus() {
361871
+ return this.status;
361872
+ }
361873
+ async logout() {
361874
+ this.stopHealthCheck();
361875
+ if (this.app) {
361876
+ await this.app.stop();
361877
+ this.app = null;
361788
361878
  }
361789
- parts.push(remaining.slice(0, breakPoint));
361790
- remaining = remaining.slice(breakPoint).trimStart();
361879
+ this.botToken = null;
361880
+ this.appToken = null;
361881
+ db2.update(messagingConnections).set({
361882
+ displayName: null,
361883
+ status: "disconnected",
361884
+ updatedAt: new Date().toISOString()
361885
+ }).where(eq(messagingConnections.id, this.connectionId)).run();
361886
+ this.updateStatus("disconnected");
361791
361887
  }
361792
- return parts;
361793
- }
361794
- getStatus() {
361795
- return this.status;
361796
- }
361797
- async logout() {
361798
- if (this.app) {
361799
- await this.app.stop();
361800
- this.app = null;
361888
+ updateStatus(status) {
361889
+ this.status = status;
361890
+ db2.update(messagingConnections).set({
361891
+ status,
361892
+ updatedAt: new Date().toISOString()
361893
+ }).where(eq(messagingConnections.id, this.connectionId)).run();
361894
+ this.events?.onConnectionChange(status);
361801
361895
  }
361802
- this.botToken = null;
361803
- this.appToken = null;
361804
- db2.update(messagingConnections).set({
361805
- displayName: null,
361806
- status: "disconnected",
361807
- updatedAt: new Date().toISOString()
361808
- }).where(eq(messagingConnections.id, this.connectionId)).run();
361809
- this.updateStatus("disconnected");
361810
- }
361811
- updateStatus(status) {
361812
- this.status = status;
361813
- db2.update(messagingConnections).set({
361814
- status,
361815
- updatedAt: new Date().toISOString()
361816
- }).where(eq(messagingConnections.id, this.connectionId)).run();
361817
- this.events?.onConnectionChange(status);
361818
- }
361819
- scheduleReconnect() {
361820
- if (this.reconnectTimer || this.isShuttingDown)
361821
- return;
361822
- log2.messaging.debug("Scheduling Slack reconnect", {
361823
- connectionId: this.connectionId,
361824
- delayMs: 5000
361825
- });
361826
- this.reconnectTimer = setTimeout(() => {
361827
- this.reconnectTimer = null;
361828
- this.connect();
361829
- }, 5000);
361830
- }
361831
- }
361832
- var import_bolt;
361833
- var init_slack_channel = __esm(() => {
361834
- init_drizzle_orm();
361835
- init_db2();
361836
- init_logger3();
361837
- init_settings();
361838
- import_bolt = __toESM(require_dist20(), 1);
361896
+ scheduleReconnect() {
361897
+ if (this.reconnectTimer || this.isShuttingDown)
361898
+ return;
361899
+ log2.messaging.debug("Scheduling Slack reconnect", {
361900
+ connectionId: this.connectionId,
361901
+ delayMs: 5000
361902
+ });
361903
+ this.reconnectTimer = setTimeout(() => {
361904
+ this.reconnectTimer = null;
361905
+ this.connect();
361906
+ }, 5000);
361907
+ }
361908
+ };
361839
361909
  });
361840
361910
 
361841
361911
  // node_modules/imapflow/node_modules/pino/lib/caller.js
@@ -1260548,7 +1260618,7 @@ mcpRoutes.all("/", async (c) => {
1260548
1260618
  });
1260549
1260619
  const server = new McpServer({
1260550
1260620
  name: "fulcrum",
1260551
- version: "2.17.0"
1260621
+ version: "2.17.1"
1260552
1260622
  });
1260553
1260623
  const client = new FulcrumClient(`http://localhost:${port}`);
1260554
1260624
  registerTools(server, client);