agenthub-multiagent-mcp 1.1.2 → 1.1.4

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/src/heartbeat.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Background heartbeat manager
2
+ * Background heartbeat manager with enhanced logging for pending tasks/messages
3
3
  */
4
4
 
5
5
  import { ApiClient } from "./client.js";
@@ -9,6 +9,9 @@ export class HeartbeatManager {
9
9
  private intervalId?: NodeJS.Timeout;
10
10
  private agentId?: string;
11
11
  private status: "online" | "busy" = "online";
12
+ private lastPendingTasks = 0;
13
+ private lastUnreadMessages = 0;
14
+ private heartbeatCount = 0;
12
15
 
13
16
  constructor(client: ApiClient) {
14
17
  this.client = client;
@@ -17,13 +20,16 @@ export class HeartbeatManager {
17
20
  start(agentId: string): void {
18
21
  this.stop(); // Clear any existing interval
19
22
  this.agentId = agentId;
23
+ this.heartbeatCount = 0;
24
+ this.lastPendingTasks = 0;
25
+ this.lastUnreadMessages = 0;
20
26
 
21
27
  // Send heartbeat every 30 seconds
22
28
  this.intervalId = setInterval(async () => {
23
29
  if (!this.agentId) return;
24
30
 
25
31
  try {
26
- await this.client.heartbeat(this.agentId, this.status);
32
+ await this.sendHeartbeat();
27
33
  } catch (error) {
28
34
  console.error("Heartbeat failed:", error);
29
35
  }
@@ -58,9 +64,45 @@ export class HeartbeatManager {
58
64
  if (!this.agentId) return;
59
65
 
60
66
  try {
61
- await this.client.heartbeat(this.agentId, this.status);
67
+ const response = await this.client.heartbeat(this.agentId, this.status);
68
+ this.heartbeatCount++;
69
+
70
+ const { pending_tasks_count, unread_messages_count } = response;
71
+
72
+ // Log if there are new pending tasks
73
+ if (pending_tasks_count > 0 && pending_tasks_count !== this.lastPendingTasks) {
74
+ console.error(`\nšŸ”” [AgentHub] You have ${pending_tasks_count} pending task(s) waiting! Use get_pending_tasks to view them.\n`);
75
+ }
76
+
77
+ // Log if there are new unread messages
78
+ if (unread_messages_count > 0 && unread_messages_count !== this.lastUnreadMessages) {
79
+ console.error(`\nšŸ“¬ [AgentHub] You have ${unread_messages_count} unread message(s)! Use check_inbox to read them.\n`);
80
+ }
81
+
82
+ // Periodic reminder every 5 heartbeats (2.5 minutes) if there are pending items
83
+ if (this.heartbeatCount % 5 === 0) {
84
+ if (pending_tasks_count > 0 || unread_messages_count > 0) {
85
+ const parts = [];
86
+ if (pending_tasks_count > 0) parts.push(`${pending_tasks_count} pending task(s)`);
87
+ if (unread_messages_count > 0) parts.push(`${unread_messages_count} unread message(s)`);
88
+ console.error(`\nā° [AgentHub] Reminder: You have ${parts.join(" and ")}.\n`);
89
+ }
90
+ }
91
+
92
+ this.lastPendingTasks = pending_tasks_count;
93
+ this.lastUnreadMessages = unread_messages_count;
62
94
  } catch (error) {
63
95
  console.error("Heartbeat failed:", error);
64
96
  }
65
97
  }
98
+
99
+ /**
100
+ * Get the current pending counts (for use by tools)
101
+ */
102
+ getPendingCounts(): { pendingTasks: number; unreadMessages: number } {
103
+ return {
104
+ pendingTasks: this.lastPendingTasks,
105
+ unreadMessages: this.lastUnreadMessages,
106
+ };
107
+ }
66
108
  }
package/src/index.ts CHANGED
@@ -1,123 +1,123 @@
1
- #!/usr/bin/env node
2
-
3
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
- import {
6
- CallToolRequestSchema,
7
- ListToolsRequestSchema,
8
- } from "@modelcontextprotocol/sdk/types.js";
9
-
10
- import { ApiClient } from "./client.js";
11
- import { registerTools, handleToolCall } from "./tools/index.js";
12
- import { HeartbeatManager } from "./heartbeat.js";
13
-
14
- // Environment configuration
15
- const AGENTHUB_URL = process.env.AGENTHUB_URL || "http://localhost:8787";
16
- const AGENTHUB_API_KEY = process.env.AGENTHUB_API_KEY || "";
17
- const AGENTHUB_AGENT_ID = process.env.AGENTHUB_AGENT_ID || "";
18
-
19
- // Validate configuration
20
- if (!AGENTHUB_API_KEY) {
21
- console.error("Error: AGENTHUB_API_KEY environment variable is required");
22
- process.exit(1);
23
- }
24
-
25
- // Initialize API client
26
- const client = new ApiClient(AGENTHUB_URL, AGENTHUB_API_KEY);
27
-
28
- // Initialize heartbeat manager
29
- const heartbeat = new HeartbeatManager(client);
30
-
31
- // Track current agent ID
32
- let currentAgentId = AGENTHUB_AGENT_ID;
33
-
34
- // Create MCP server
35
- const server = new Server(
36
- {
37
- name: "agenthub",
38
- version: "1.1.2",
39
- },
40
- {
41
- capabilities: {
42
- tools: {},
43
- },
44
- }
45
- );
46
-
47
- // List available tools
48
- server.setRequestHandler(ListToolsRequestSchema, async () => {
49
- return {
50
- tools: registerTools(),
51
- };
52
- });
53
-
54
- // Handle tool calls
55
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
56
- const { name, arguments: args } = request.params;
57
-
58
- try {
59
- const result = await handleToolCall(name, args || {}, client, {
60
- getCurrentAgentId: () => currentAgentId,
61
- setCurrentAgentId: (id: string) => {
62
- currentAgentId = id;
63
- heartbeat.start(id);
64
- },
65
- stopHeartbeat: () => heartbeat.stop(),
66
- getWorkingDir: () => process.cwd(),
67
- });
68
-
69
- return {
70
- content: [
71
- {
72
- type: "text",
73
- text: JSON.stringify(result, null, 2),
74
- },
75
- ],
76
- };
77
- } catch (error) {
78
- const message = error instanceof Error ? error.message : String(error);
79
- return {
80
- content: [
81
- {
82
- type: "text",
83
- text: `Error: ${message}`,
84
- },
85
- ],
86
- isError: true,
87
- };
88
- }
89
- });
90
-
91
- // Graceful shutdown
92
- process.on("SIGINT", () => {
93
- heartbeat.stop();
94
- process.exit(0);
95
- });
96
-
97
- process.on("SIGTERM", () => {
98
- heartbeat.stop();
99
- process.exit(0);
100
- });
101
-
102
- // Start server
103
- async function main() {
104
- const transport = new StdioServerTransport();
105
- await server.connect(transport);
106
- console.error("AgentHub MCP server running");
107
-
108
- // Auto-register if agent ID is provided
109
- if (AGENTHUB_AGENT_ID) {
110
- try {
111
- await client.registerAgent(AGENTHUB_AGENT_ID);
112
- heartbeat.start(AGENTHUB_AGENT_ID);
113
- console.error(`Auto-registered as agent: ${AGENTHUB_AGENT_ID}`);
114
- } catch (error) {
115
- console.error(`Failed to auto-register: ${error}`);
116
- }
117
- }
118
- }
119
-
120
- main().catch((error) => {
121
- console.error("Fatal error:", error);
122
- process.exit(1);
123
- });
1
+ #!/usr/bin/env node
2
+
3
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import {
6
+ CallToolRequestSchema,
7
+ ListToolsRequestSchema,
8
+ } from "@modelcontextprotocol/sdk/types.js";
9
+
10
+ import { ApiClient } from "./client.js";
11
+ import { registerTools, handleToolCall } from "./tools/index.js";
12
+ import { HeartbeatManager } from "./heartbeat.js";
13
+
14
+ // Environment configuration
15
+ const AGENTHUB_URL = process.env.AGENTHUB_URL || "http://localhost:8787";
16
+ const AGENTHUB_API_KEY = process.env.AGENTHUB_API_KEY || "";
17
+ const AGENTHUB_AGENT_ID = process.env.AGENTHUB_AGENT_ID || "";
18
+
19
+ // Validate configuration
20
+ if (!AGENTHUB_API_KEY) {
21
+ console.error("Error: AGENTHUB_API_KEY environment variable is required");
22
+ process.exit(1);
23
+ }
24
+
25
+ // Initialize API client
26
+ const client = new ApiClient(AGENTHUB_URL, AGENTHUB_API_KEY);
27
+
28
+ // Initialize heartbeat manager
29
+ const heartbeat = new HeartbeatManager(client);
30
+
31
+ // Track current agent ID
32
+ let currentAgentId = AGENTHUB_AGENT_ID;
33
+
34
+ // Create MCP server
35
+ const server = new Server(
36
+ {
37
+ name: "agenthub",
38
+ version: "1.1.4",
39
+ },
40
+ {
41
+ capabilities: {
42
+ tools: {},
43
+ },
44
+ }
45
+ );
46
+
47
+ // List available tools
48
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
49
+ return {
50
+ tools: registerTools(),
51
+ };
52
+ });
53
+
54
+ // Handle tool calls
55
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
56
+ const { name, arguments: args } = request.params;
57
+
58
+ try {
59
+ const result = await handleToolCall(name, args || {}, client, {
60
+ getCurrentAgentId: () => currentAgentId,
61
+ setCurrentAgentId: (id: string) => {
62
+ currentAgentId = id;
63
+ heartbeat.start(id);
64
+ },
65
+ stopHeartbeat: () => heartbeat.stop(),
66
+ getWorkingDir: () => process.cwd(),
67
+ });
68
+
69
+ return {
70
+ content: [
71
+ {
72
+ type: "text",
73
+ text: JSON.stringify(result, null, 2),
74
+ },
75
+ ],
76
+ };
77
+ } catch (error) {
78
+ const message = error instanceof Error ? error.message : String(error);
79
+ return {
80
+ content: [
81
+ {
82
+ type: "text",
83
+ text: `Error: ${message}`,
84
+ },
85
+ ],
86
+ isError: true,
87
+ };
88
+ }
89
+ });
90
+
91
+ // Graceful shutdown
92
+ process.on("SIGINT", () => {
93
+ heartbeat.stop();
94
+ process.exit(0);
95
+ });
96
+
97
+ process.on("SIGTERM", () => {
98
+ heartbeat.stop();
99
+ process.exit(0);
100
+ });
101
+
102
+ // Start server
103
+ async function main() {
104
+ const transport = new StdioServerTransport();
105
+ await server.connect(transport);
106
+ console.error("AgentHub MCP server running");
107
+
108
+ // Auto-register if agent ID is provided
109
+ if (AGENTHUB_AGENT_ID) {
110
+ try {
111
+ await client.registerAgent(AGENTHUB_AGENT_ID);
112
+ heartbeat.start(AGENTHUB_AGENT_ID);
113
+ console.error(`Auto-registered as agent: ${AGENTHUB_AGENT_ID}`);
114
+ } catch (error) {
115
+ console.error(`Failed to auto-register: ${error}`);
116
+ }
117
+ }
118
+ }
119
+
120
+ main().catch((error) => {
121
+ console.error("Fatal error:", error);
122
+ process.exit(1);
123
+ });