msteams-mcp 0.2.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 +229 -0
- package/dist/__fixtures__/api-responses.d.ts +228 -0
- package/dist/__fixtures__/api-responses.js +217 -0
- package/dist/api/chatsvc-api.d.ts +171 -0
- package/dist/api/chatsvc-api.js +459 -0
- package/dist/api/csa-api.d.ts +44 -0
- package/dist/api/csa-api.js +148 -0
- package/dist/api/index.d.ts +6 -0
- package/dist/api/index.js +6 -0
- package/dist/api/substrate-api.d.ts +50 -0
- package/dist/api/substrate-api.js +305 -0
- package/dist/auth/crypto.d.ts +32 -0
- package/dist/auth/crypto.js +66 -0
- package/dist/auth/index.d.ts +6 -0
- package/dist/auth/index.js +6 -0
- package/dist/auth/session-store.d.ts +82 -0
- package/dist/auth/session-store.js +136 -0
- package/dist/auth/token-extractor.d.ts +69 -0
- package/dist/auth/token-extractor.js +330 -0
- package/dist/browser/auth.d.ts +43 -0
- package/dist/browser/auth.js +232 -0
- package/dist/browser/context.d.ts +40 -0
- package/dist/browser/context.js +121 -0
- package/dist/browser/session.d.ts +34 -0
- package/dist/browser/session.js +92 -0
- package/dist/constants.d.ts +54 -0
- package/dist/constants.js +72 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +12 -0
- package/dist/research/explore.d.ts +11 -0
- package/dist/research/explore.js +267 -0
- package/dist/research/search-research.d.ts +17 -0
- package/dist/research/search-research.js +317 -0
- package/dist/server.d.ts +64 -0
- package/dist/server.js +291 -0
- package/dist/teams/api-interceptor.d.ts +54 -0
- package/dist/teams/api-interceptor.js +391 -0
- package/dist/teams/direct-api.d.ts +321 -0
- package/dist/teams/direct-api.js +1305 -0
- package/dist/teams/messages.d.ts +14 -0
- package/dist/teams/messages.js +142 -0
- package/dist/teams/search.d.ts +40 -0
- package/dist/teams/search.js +458 -0
- package/dist/test/cli.d.ts +12 -0
- package/dist/test/cli.js +328 -0
- package/dist/test/debug-search.d.ts +10 -0
- package/dist/test/debug-search.js +147 -0
- package/dist/test/manual-test.d.ts +11 -0
- package/dist/test/manual-test.js +160 -0
- package/dist/test/mcp-harness.d.ts +17 -0
- package/dist/test/mcp-harness.js +427 -0
- package/dist/tools/auth-tools.d.ts +26 -0
- package/dist/tools/auth-tools.js +127 -0
- package/dist/tools/index.d.ts +45 -0
- package/dist/tools/index.js +12 -0
- package/dist/tools/message-tools.d.ts +139 -0
- package/dist/tools/message-tools.js +433 -0
- package/dist/tools/people-tools.d.ts +46 -0
- package/dist/tools/people-tools.js +123 -0
- package/dist/tools/registry.d.ts +23 -0
- package/dist/tools/registry.js +61 -0
- package/dist/tools/search-tools.d.ts +79 -0
- package/dist/tools/search-tools.js +168 -0
- package/dist/types/errors.d.ts +58 -0
- package/dist/types/errors.js +132 -0
- package/dist/types/result.d.ts +43 -0
- package/dist/types/result.js +51 -0
- package/dist/types/teams.d.ts +79 -0
- package/dist/types/teams.js +5 -0
- package/dist/utils/api-config.d.ts +66 -0
- package/dist/utils/api-config.js +113 -0
- package/dist/utils/auth-guards.d.ts +29 -0
- package/dist/utils/auth-guards.js +54 -0
- package/dist/utils/http.d.ts +29 -0
- package/dist/utils/http.js +111 -0
- package/dist/utils/parsers.d.ts +187 -0
- package/dist/utils/parsers.js +574 -0
- package/dist/utils/parsers.test.d.ts +7 -0
- package/dist/utils/parsers.test.js +360 -0
- package/package.json +58 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure parsing functions for Teams API responses.
|
|
3
|
+
*
|
|
4
|
+
* These functions transform raw API responses into our internal types.
|
|
5
|
+
* They are extracted here for testability - no side effects or external dependencies.
|
|
6
|
+
*/
|
|
7
|
+
import type { TeamsSearchResult } from '../types/teams.js';
|
|
8
|
+
/** Person search result from Substrate suggestions API. */
|
|
9
|
+
export interface PersonSearchResult {
|
|
10
|
+
id: string;
|
|
11
|
+
mri: string;
|
|
12
|
+
displayName: string;
|
|
13
|
+
email?: string;
|
|
14
|
+
givenName?: string;
|
|
15
|
+
surname?: string;
|
|
16
|
+
jobTitle?: string;
|
|
17
|
+
department?: string;
|
|
18
|
+
companyName?: string;
|
|
19
|
+
}
|
|
20
|
+
/** User profile extracted from JWT tokens. */
|
|
21
|
+
export interface UserProfile {
|
|
22
|
+
id: string;
|
|
23
|
+
mri: string;
|
|
24
|
+
email: string;
|
|
25
|
+
displayName: string;
|
|
26
|
+
givenName?: string;
|
|
27
|
+
surname?: string;
|
|
28
|
+
tenantId?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Strips HTML tags from content for display.
|
|
32
|
+
*/
|
|
33
|
+
export declare function stripHtml(html: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Builds a deep link to open a message in Teams.
|
|
36
|
+
*
|
|
37
|
+
* Format: https://teams.microsoft.com/l/message/{conversationId}/{messageTimestamp}
|
|
38
|
+
*
|
|
39
|
+
* @param conversationId - The conversation/thread ID (e.g., "19:xxx@thread.tacv2")
|
|
40
|
+
* @param messageTimestamp - The message timestamp in epoch milliseconds
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildMessageLink(conversationId: string, messageTimestamp: string | number): string;
|
|
43
|
+
/**
|
|
44
|
+
* Extracts a timestamp-based message ID from various sources.
|
|
45
|
+
* Teams uses epoch milliseconds as message IDs in URLs.
|
|
46
|
+
*
|
|
47
|
+
* IMPORTANT: For channel threaded replies, the ;messageid= in ClientConversationId
|
|
48
|
+
* is the PARENT thread's ID, not this message's ID. We must prefer the actual
|
|
49
|
+
* message timestamp (DateTimeReceived/DateTimeSent) for accurate deep links.
|
|
50
|
+
*/
|
|
51
|
+
export declare function extractMessageTimestamp(source: Record<string, unknown> | undefined, timestamp?: string): string | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Parses a person suggestion from the Substrate API response.
|
|
54
|
+
*
|
|
55
|
+
* The API can return IDs in various formats:
|
|
56
|
+
* - GUID with tenant: "ab76f827-...@tenant.onmicrosoft.com"
|
|
57
|
+
* - Base64-encoded GUID: "93qkaTtFGWpUHjyRafgdhg=="
|
|
58
|
+
*/
|
|
59
|
+
export declare function parsePersonSuggestion(item: Record<string, unknown>): PersonSearchResult | null;
|
|
60
|
+
/**
|
|
61
|
+
* Parses a v2 query result item into a search result.
|
|
62
|
+
*/
|
|
63
|
+
export declare function parseV2Result(item: Record<string, unknown>): TeamsSearchResult | null;
|
|
64
|
+
/**
|
|
65
|
+
* Parses user profile from a JWT payload.
|
|
66
|
+
*
|
|
67
|
+
* @param payload - Decoded JWT payload object
|
|
68
|
+
* @returns User profile or null if required fields are missing
|
|
69
|
+
*/
|
|
70
|
+
export declare function parseJwtProfile(payload: Record<string, unknown>): UserProfile | null;
|
|
71
|
+
/**
|
|
72
|
+
* Calculates token expiry status from an expiry timestamp.
|
|
73
|
+
*
|
|
74
|
+
* @param expiryMs - Token expiry time in milliseconds since epoch
|
|
75
|
+
* @param nowMs - Current time in milliseconds (for testing)
|
|
76
|
+
* @returns Token status including whether it's valid and time remaining
|
|
77
|
+
*/
|
|
78
|
+
export declare function calculateTokenStatus(expiryMs: number, nowMs?: number): {
|
|
79
|
+
isValid: boolean;
|
|
80
|
+
expiresAt: string;
|
|
81
|
+
minutesRemaining: number;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Parses the pagination result from a search API response.
|
|
85
|
+
*
|
|
86
|
+
* @param entitySets - Raw EntitySets array from API response
|
|
87
|
+
* @param from - Starting offset used in request
|
|
88
|
+
* @param size - Page size used in request
|
|
89
|
+
* @returns Parsed results and pagination metadata
|
|
90
|
+
*/
|
|
91
|
+
export declare function parseSearchResults(entitySets: unknown[] | undefined, from: number, size: number): {
|
|
92
|
+
results: TeamsSearchResult[];
|
|
93
|
+
total?: number;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Parses people search results from the Groups/Suggestions structure.
|
|
97
|
+
*
|
|
98
|
+
* @param groups - Raw Groups array from suggestions API response
|
|
99
|
+
* @returns Array of parsed person results
|
|
100
|
+
*/
|
|
101
|
+
export declare function parsePeopleResults(groups: unknown[] | undefined): PersonSearchResult[];
|
|
102
|
+
/** Channel search result from Substrate suggestions API or Teams List API. */
|
|
103
|
+
export interface ChannelSearchResult {
|
|
104
|
+
channelId: string;
|
|
105
|
+
channelName: string;
|
|
106
|
+
teamName: string;
|
|
107
|
+
teamId: string;
|
|
108
|
+
channelType: string;
|
|
109
|
+
description?: string;
|
|
110
|
+
isMember?: boolean;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Parses a single channel suggestion from the API response.
|
|
114
|
+
*
|
|
115
|
+
* @param suggestion - Raw suggestion object from API
|
|
116
|
+
* @returns Parsed channel result or null if required fields are missing
|
|
117
|
+
*/
|
|
118
|
+
export declare function parseChannelSuggestion(suggestion: Record<string, unknown>): ChannelSearchResult | null;
|
|
119
|
+
/**
|
|
120
|
+
* Parses channel search results from the Groups/Suggestions structure.
|
|
121
|
+
*
|
|
122
|
+
* @param groups - Raw Groups array from suggestions API response
|
|
123
|
+
* @returns Array of parsed channel results
|
|
124
|
+
*/
|
|
125
|
+
export declare function parseChannelResults(groups: unknown[] | undefined): ChannelSearchResult[];
|
|
126
|
+
/** Team with channels from the Teams List API response. */
|
|
127
|
+
export interface TeamWithChannels {
|
|
128
|
+
teamId: string;
|
|
129
|
+
teamName: string;
|
|
130
|
+
threadId: string;
|
|
131
|
+
description?: string;
|
|
132
|
+
channels: ChannelSearchResult[];
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Parses the Teams List API response to extract all teams and channels.
|
|
136
|
+
*
|
|
137
|
+
* @param data - Raw response data from /api/csa/{region}/api/v3/teams/users/me
|
|
138
|
+
* @returns Array of teams with their channels
|
|
139
|
+
*/
|
|
140
|
+
export declare function parseTeamsList(data: Record<string, unknown> | undefined): TeamWithChannels[];
|
|
141
|
+
/**
|
|
142
|
+
* Filters channels from the Teams List by name.
|
|
143
|
+
*
|
|
144
|
+
* @param teams - Array of teams with channels from parseTeamsList
|
|
145
|
+
* @param query - Search query (case-insensitive partial match)
|
|
146
|
+
* @returns Matching channels flattened into a single array
|
|
147
|
+
*/
|
|
148
|
+
export declare function filterChannelsByName(teams: TeamWithChannels[], query: string): ChannelSearchResult[];
|
|
149
|
+
/**
|
|
150
|
+
* Decodes a base64-encoded GUID to its standard string representation.
|
|
151
|
+
*
|
|
152
|
+
* Microsoft encodes GUIDs as 16 bytes with little-endian ordering for the
|
|
153
|
+
* first three groups (Data1, Data2, Data3).
|
|
154
|
+
*
|
|
155
|
+
* @param base64 - Base64-encoded GUID (typically 24 chars with == padding)
|
|
156
|
+
* @returns The GUID string in standard format, or null if invalid
|
|
157
|
+
*/
|
|
158
|
+
export declare function decodeBase64Guid(base64: string): string | null;
|
|
159
|
+
/**
|
|
160
|
+
* Extracts the Azure AD object ID (GUID) from various formats.
|
|
161
|
+
*
|
|
162
|
+
* Handles:
|
|
163
|
+
* - MRI format: "8:orgid:ab76f827-27e2-4c67-a765-f1a53145fa24"
|
|
164
|
+
* - MRI with base64: "8:orgid:93qkaTtFGWpUHjyRafgdhg=="
|
|
165
|
+
* - Skype ID format: "orgid:ab76f827-27e2-4c67-a765-f1a53145fa24"
|
|
166
|
+
* - ID with tenant: "ab76f827-27e2-4c67-a765-f1a53145fa24@56b731a8-..."
|
|
167
|
+
* - Raw GUID: "ab76f827-27e2-4c67-a765-f1a53145fa24"
|
|
168
|
+
* - Base64-encoded GUID: "93qkaTtFGWpUHjyRafgdhg=="
|
|
169
|
+
*
|
|
170
|
+
* @param identifier - User identifier in any supported format
|
|
171
|
+
* @returns The extracted GUID or null if invalid format
|
|
172
|
+
*/
|
|
173
|
+
export declare function extractObjectId(identifier: string): string | null;
|
|
174
|
+
/**
|
|
175
|
+
* Builds a 1:1 conversation ID from two user object IDs.
|
|
176
|
+
*
|
|
177
|
+
* The conversation ID format for 1:1 chats in Teams is:
|
|
178
|
+
* `19:{userId1}_{userId2}@unq.gbl.spaces`
|
|
179
|
+
*
|
|
180
|
+
* The user IDs are sorted lexicographically to ensure consistency -
|
|
181
|
+
* both participants will generate the same conversation ID.
|
|
182
|
+
*
|
|
183
|
+
* @param userId1 - First user's object ID (GUID, MRI, or ID with tenant)
|
|
184
|
+
* @param userId2 - Second user's object ID (GUID, MRI, or ID with tenant)
|
|
185
|
+
* @returns The constructed conversation ID, or null if either ID is invalid
|
|
186
|
+
*/
|
|
187
|
+
export declare function buildOneOnOneConversationId(userId1: string, userId2: string): string | null;
|