msteams-mcp 0.25.0 → 0.25.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.
@@ -110,6 +110,16 @@ export interface CreateGroupChatResult {
110
110
  /** Optional note about the result, e.g. if the ID could not be retrieved. */
111
111
  note?: string;
112
112
  }
113
+ /**
114
+ * Generates a Teams client message ID.
115
+ *
116
+ * Teams requires this to be "a number in string format" — a UUID is rejected
117
+ * with `StoreInvalidInput - ClientMessageId must be a number in string format`.
118
+ * This mirrors the Teams web client's large random integer: current time in
119
+ * milliseconds plus 6 random digits, keeping IDs numeric and unique even for
120
+ * rapid successive sends.
121
+ */
122
+ export declare function generateClientMessageId(): string;
113
123
  /**
114
124
  * Sends a message to a Teams conversation.
115
125
  *
@@ -25,6 +25,19 @@ function getActualMri(mri) {
25
25
  // ─────────────────────────────────────────────────────────────────────────────
26
26
  // Message Sending
27
27
  // ─────────────────────────────────────────────────────────────────────────────
28
+ /**
29
+ * Generates a Teams client message ID.
30
+ *
31
+ * Teams requires this to be "a number in string format" — a UUID is rejected
32
+ * with `StoreInvalidInput - ClientMessageId must be a number in string format`.
33
+ * This mirrors the Teams web client's large random integer: current time in
34
+ * milliseconds plus 6 random digits, keeping IDs numeric and unique even for
35
+ * rapid successive sends.
36
+ */
37
+ export function generateClientMessageId() {
38
+ const random = Math.floor(Math.random() * 1_000_000).toString().padStart(6, '0');
39
+ return `${Date.now()}${random}`;
40
+ }
28
41
  /**
29
42
  * Sends a message to a Teams conversation.
30
43
  *
@@ -43,7 +56,7 @@ export async function sendMessage(conversationId, content, options = {}) {
43
56
  const { auth, region, baseUrl } = authResult.value;
44
57
  const { replyToMessageId, contentType = 'markdown', subject, scheduleAt } = options;
45
58
  const displayName = getUserDisplayName() || 'User';
46
- const clientMessageId = crypto.randomUUID();
59
+ const clientMessageId = generateClientMessageId();
47
60
  // Resolve content per the requested content type (markdown by default).
48
61
  const resolved = resolveMessageContent(content, contentType);
49
62
  // Scheduled send goes through the chatsvc drafts API (same as the Teams web
@@ -5,7 +5,7 @@
5
5
  * and mentions property serialisation.
6
6
  */
7
7
  import { describe, it, expect } from 'vitest';
8
- import { buildMentionHtml, buildMentionsProperty, parseContentWithMentionsAndLinks, resolveMessageContent, parseScheduleTime, buildScheduledDraftBody, extractOneOnOneMemberIds, buildOneOnOneThreadBody, clampWaitParams, selectNewMessages, resolveWaitBaseline, } from './chatsvc-messaging.js';
8
+ import { buildMentionHtml, buildMentionsProperty, parseContentWithMentionsAndLinks, resolveMessageContent, parseScheduleTime, buildScheduledDraftBody, extractOneOnOneMemberIds, buildOneOnOneThreadBody, clampWaitParams, selectNewMessages, resolveWaitBaseline, generateClientMessageId, } from './chatsvc-messaging.js';
9
9
  import { MAX_WAIT_SECONDS } from '../constants.js';
10
10
  // ─────────────────────────────────────────────────────────────────────────────
11
11
  // buildMentionHtml
@@ -297,6 +297,19 @@ describe('selectNewMessages', () => {
297
297
  expect(selectNewMessages(msgs, 110, true)).toEqual([]);
298
298
  });
299
299
  });
300
+ describe('generateClientMessageId', () => {
301
+ it('returns a numeric string (Teams rejects non-numeric client message IDs)', () => {
302
+ // Regression: a UUID (crypto.randomUUID) is rejected by Teams with
303
+ // "StoreInvalidInput - ClientMessageId must be a number in string format".
304
+ const id = generateClientMessageId();
305
+ expect(id).toMatch(/^\d+$/);
306
+ expect(id.length).toBeGreaterThan(0);
307
+ });
308
+ it('produces distinct IDs across rapid calls', () => {
309
+ const ids = new Set(Array.from({ length: 50 }, () => generateClientMessageId()));
310
+ expect(ids.size).toBeGreaterThan(1);
311
+ });
312
+ });
300
313
  describe('resolveWaitBaseline', () => {
301
314
  it('prefers the caller\'s own most recent message', () => {
302
315
  const baseline = resolveWaitBaseline([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "msteams-mcp",
3
- "version": "0.25.0",
3
+ "version": "0.25.1",
4
4
  "description": "MCP server for Microsoft Teams - search messages, send replies, manage favourites",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",