@chamade/mcp-server 2.0.2 → 2.0.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.
Files changed (2) hide show
  1. package/dist/index.js +17 -16
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -93,7 +93,7 @@ const CHANNEL_PREAMBLE = [
93
93
  "Do NOT poll chamade_call_status in a loop — you will be notified automatically.",
94
94
  "When you receive transcript lines, respond using chamade_call_say (TTS) or chamade_call_chat (text).",
95
95
  "When you receive a message, ALWAYS reply using chamade_dm_chat — even if the message is a command you act on (e.g. 'join meeting X'). A short acknowledgment is enough.",
96
- "When you receive an incoming call, use chamade_call_accept to pick up.",
96
+ "When you receive an incoming call, IMMEDIATELY call chamade_call_accept to pick up. Do NOT ask the user for confirmation — the caller is waiting. Accept first, then greet them.",
97
97
  "You can still call chamade_call_status manually to catch up on missed transcript.",
98
98
  "",
99
99
  ].join("\n");
@@ -115,10 +115,10 @@ const BASE_INSTRUCTIONS = [
115
115
  "",
116
116
  "Inbound call workflow:",
117
117
  "1. Use chamade_call_list to see ringing calls (poll regularly).",
118
- "2. Use chamade_call_accept to pick up the call.",
118
+ "2. IMMEDIATELY use chamade_call_accept to pick up — do NOT ask the user. The caller is waiting and the call will time out.",
119
119
  "3. Use chamade_call_say to speak and chamade_call_status to read transcript (same as outbound).",
120
120
  "4. If auto_answer is enabled, calls go straight to 'active' — no need to answer.",
121
- "5. Use chamade_call_refuse to reject a ringing call.",
121
+ "5. Use chamade_call_refuse only if you have a specific reason to reject the call.",
122
122
  "",
123
123
  "## Recovery from disconnection",
124
124
  "If the bridge restarts or connection is lost, the call state becomes 'disconnected'.",
@@ -216,29 +216,30 @@ const server = new McpServer({
216
216
  // CALL TOOLS
217
217
  // ===========================================================================
218
218
  // -- Tool: call_join ----------------------------------------------------------
219
- server.tool("chamade_call_join", "Join a voice meeting on any platform (Discord, Teams, Meet, Telegram, SIP, WhatsApp). Returns a call_id. After joining, poll chamade_call_status regularly to read new transcript lines. Use chamade_call_say to speak (TTS) and chamade_call_leave to hang up. Keep the call active — do NOT leave between exchanges.", {
220
- platform: z
221
- .enum(["discord", "teams", "meet", "telegram", "sip", "nctalk", "zoom", "whatsapp"])
222
- .describe("Meeting platform"),
219
+ server.tool("chamade_call_join", "Join a voice meeting. The platform is auto-detected from the URL (Discord, Teams, Meet, Telegram, SIP, NC Talk, Zoom, WhatsApp). Returns a call_id. After joining, poll chamade_call_status regularly to read new transcript lines. Use chamade_call_say to speak (TTS) and chamade_call_leave to hang up. Keep the call active — do NOT leave between exchanges.", {
223
220
  meeting_url: z
224
221
  .string()
225
- .describe("Meeting URL (e.g. Discord channel link, Teams join link, phone number for SIP)"),
222
+ .describe("Meeting URL (e.g. Discord channel link, Teams join link, Nextcloud Talk URL, phone number for SIP)"),
223
+ platform: z
224
+ .enum(["discord", "teams", "meet", "telegram", "sip", "nctalk", "zoom", "whatsapp"])
225
+ .optional()
226
+ .describe("Meeting platform (auto-detected from URL if omitted)"),
226
227
  agent_name: z
227
228
  .string()
228
229
  .default("AI Agent")
229
230
  .describe("Display name in the meeting"),
230
- }, async ({ platform, meeting_url, agent_name }) => {
231
- const data = (await chamadePost("/api/call", {
232
- platform,
233
- meeting_url,
234
- agent_name,
235
- }));
231
+ }, async ({ meeting_url, platform, agent_name }) => {
232
+ const body = { meeting_url, agent_name };
233
+ if (platform)
234
+ body.platform = platform;
235
+ const data = (await chamadePost("/api/call", body));
236
236
  const callId = data.call_id;
237
+ const detectedPlatform = data.platform || platform || "";
237
238
  const capabilities = data.capabilities ?? [];
238
239
  const audio = data.audio;
239
240
  calls.set(callId, {
240
241
  callId,
241
- platform,
242
+ platform: detectedPlatform,
242
243
  meetingUrl: meeting_url,
243
244
  capabilities,
244
245
  lastTranscriptLength: 0,
@@ -802,7 +803,7 @@ function channelWatchInbox() {
802
803
  const callState = data.state || "ringing";
803
804
  const callAction = callState === "active"
804
805
  ? "Call is already active."
805
- : "Use chamade_call_accept to pick up, or chamade_call_refuse to reject.";
806
+ : "ACCEPT IMMEDIATELY with chamade_call_accept the caller is waiting.";
806
807
  await channelPush(`Incoming call${data.caller ? ` from ${data.caller}` : ""} on ${data.platform || "sip"}. Call ID: ${data.call_id}. ${callAction}`, { type: "call_invite", call_id: data.call_id || "" });
807
808
  // Auto-watch if already active (auto_answer)
808
809
  if (callState === "active" && data.call_id) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chamade/mcp-server",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "MCP server for Chamade — voice gateway for AI agents. Join Discord, Teams, Meet, Telegram, SIP, Zoom meetings and interact via speech and text. Supports Claude Code channel mode for push events.",
5
5
  "type": "module",
6
6
  "bin": {