teams_list_conversations
List Teams Conversations
List conversations (chats, group chats, meetings, channels). Returns conversation ID, topic, type, and last message time.
emaillimitformat
io.github.Maxim-Mazurok由 GitHub 账号 Maxim-Mazurok 发布v1.10.1更新于 Oct 29, 2026
AI-native Microsoft Teams integration — read chats, send messages, search people
发布方自己的服务:Microsoft Learn MCP
非官方的 Microsoft Teams 集成,让助手读取聊天与频道、搜索消息和人员、发送或编辑消息,并获取会议转录。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
参照 仓库 中的启动说明。
AI-native Microsoft Teams integration — read conversations, send messages, and manage members via the Teams Chat Service REST API.
Designed for autonomous AI agents that need to interact with Teams: read messages, reply to people, monitor conversations, and participate in team workflows.
[Install in VS Code] [Install in VS Code Insiders] [Install in Cursor] [npm version] [MCP Registry]
[!NOTE] This project was AI-generated using Claude Opus 4.6 with human guidance and review.
teams-api can be used in three ways:
npx, which all MCP and CLI commands use.The quickest way to get started is to click one of the install badges above, or follow the instructions for your editor below.
Option 1 — One-click install:
[Install in VS Code] [Install in VS Code Insiders]
Option 2 — CLI:
macOS / Linux:
Windows (PowerShell):
Windows (CMD):
Option 3 — Manual config:
Add to your VS Code MCP config (.vscode/mcp.json or User Settings):
Add to claude_desktop_config.json (how to find it):
Then set the environment variable TEAMS_LOGIN=true in your shell before starting Claude Code. The server will ask for your email interactively on first use.
Add to ~/.codeium/windsurf/mcp_config.json:
[!TIP] On macOS with a FIDO2 passkey, replace
TEAMS_LOGINwithTEAMS_AUTOfor fully unattended auth. See Authentication for details.
You can also use the CLI directly without installing anything:
If you use the CLI often, a global install is optional:
Compatible coding agents can install the optional teams-api skill to learn when and how to use the CLI or SDK:
The installer detects supported agents and asks whether to install the skill for the current project or globally. Once installed, the agent loads it automatically for relevant Teams tasks.
Manual token usage, debug-session auth, and programmatic Node.js usage are covered later in this README.
[!NOTE] Windows Defender false positive: Older versions of this package used inline PowerShell to call the Windows DPAPI — a pattern that Windows Defender flags as ransomware-like behavior. This has been replaced with native Windows Credential Manager storage via keytar. If you hit issues on an older version, upgrade and re-run
teams-api auth --login. See SECURITY.md for details.
Most users do not need to manage tokens manually.
If you use interactive login, auto-login, or a Chrome debug session, teams-api captures the full token bundle automatically from Teams web traffic. That includes the base skypeToken plus the extra bearer tokens used for profile resolution and reliable people/chat/channel search.
Those flows also detect the Teams chat region automatically from the intercepted request URLs, so most users do not need to set --region or TEAMS_REGION.
On macOS, prefer auto-login when you have a platform authenticator / FIDO2 passkey set up. On other platforms, use interactive login.
Direct token usage is the advanced/manual path.
Requires macOS with a platform authenticator (e.g. Intune Company Portal) and a FIDO2 passkey enrolled. Fully unattended — no browser window appears.
The easiest cross-platform option. A browser window opens, you log in with any method your organization supports (password, MFA, passkey, etc.), and the token is captured automatically:
Optionally pre-fill your email:
[!NOTE] Interactive login prefers an installed browser (Edge or Chrome) when available, and falls back to Playwright's bundled Chromium.
Debug session — start Chrome with --remote-debugging-port=9222, navigate to Teams and log in, then run:
Direct token — advanced/manual only. Extract x-skypetoken from browser DevTools (Network tab) and pass it directly:
If you want reliable people/chat/channel lookup and profile resolution on the direct-token path, also pass the extra bearer tokens captured from Teams requests:
[!TIP] Skip this section if you are using
--login,--auto,TEAMS_LOGIN, orTEAMS_AUTO. Those modes capture the full token bundle automatically.
[!TIP] Direct-token mode still needs an explicit region. See API regions below.
Preferred without install:
Optional global install for frequent use:
The examples below use teams-api for readability. If you are not installing globally, replace it with npx -y -p teams-api@latest teams-api.
Search indexed message content across accessible Teams chats and channel posts/replies without opening conversations, sending messages, or marking messages read:
Options: --query (required; * for filter-only searches), --from (sender email), --message-type (all, chat, or channel), --conversation-id, --sent-after, --sent-before, --page-size (1-100, default 25), and --offset (default 0). Date bounds are inclusive and use YYYY-MM-DD. Advanced query syntax is passed to the Teams search service; structured filters are combined with it.
Each call returns one page: messages, approximate total, hasMore, and nextOffset when another page is available. Pass nextOffset as the next call's offset, retaining the same query and filters. Results include previews rather than full message bodies, sender details, conversation/message IDs, reply parent IDs, and Teams permalinks. Use get-messages to retrieve a known message or thread in full.
Result metadata is optional: missing values remain undefined in the SDK and are omitted from JSON, while explicit empty strings are preserved. Permalinks are available only when both conversation and message IDs are present. The approximate total sums the server's result-set totals without deduplication across result sets; it is not a unique-message count.
MCP exposes the same operation as teams_search_messages, with camelCase parameters such as messageType, sentAfter, and pageSize.
Message search requires a Substrate bearer token. Login capture attempts a neutral read-only search if reload traffic did not expose that token. For older cached credentials, run the command with --login to capture a fresh bundle. If browser search is unavailable or blocked, message search reports an authentication error instead of returning an empty result. Direct-token users must provide --substrate-token or TEAMS_SUBSTRATE_TOKEN.
Search is limited by the signed-in user's permissions, search indexing, and retention policies. Zero matches do not establish that no messages exist. HTTP failures, invalid queries, and incomplete search responses are reported as errors, not empty results.
The MCP server exposes Teams operations as tools for AI agents via stdio transport. See Getting Started for editor-specific setup.
Use this only if you already have tokens from another flow or need to avoid browser-based auth entirely:
[!TIP] If you do use direct tokens,
teams-api auth --loginprints the full token object as JSON. For basic chat operations,skypeTokenis enough. For reliable people/chat/channel search and profile resolution, also passbearerTokenandsubstrateToken.
When an AI agent sends or edits messages on behalf of a user, it can be hard to tell which messages were composed by the agent and which by the human. The TEAMS_AGENT_MARKER environment variable (or --agent-marker CLI flag / agentMarker MCP parameter) automatically prepends a configurable string to message content:
When set, every send-message and edit-message call prepends the marker followed by a space to the content. For example, with TEAMS_AGENT_MARKER=Ⓜ, sending "Hello world" produces "Ⓜ Hello world".
The per-call parameter takes precedence over the environment variable. Pass an empty string to disable the marker for a specific call.
When editing a message that already has replies, the original context can be lost — replies may no longer make sense. The TEAMS_EDIT_REPLY_GUARD environment variable (or --reply-guard CLI flag / replyGuard MCP parameter) controls this:
The per-call parameter takes precedence over the environment variable.
Hard-deleting messages removes content permanently, which can be problematic for auditability and conversation flow in group chats. The TEAMS_DELETE_MODE environment variable (or --delete-mode CLI flag / deleteMode MCP parameter) controls how message deletion is handled:
When using soft mode, the message content is replaced with ~~This message was removed by an agent~~ by default. Customize the tombstone text with TEAMS_DELETE_TOMBSTONE (or --delete-tombstone / deleteTombstone):
The per-call parameters take precedence over environment variables.
State-modifying actions (edit and delete) can emit structured audit events for compliance and traceability. The TEAMS_AUDIT_LOG environment variable controls where events are written:
Each event is a single JSON line with the following fields:
Audit logging is designed to be silent — errors in the audit pipeline never affect tool execution.
Some conversations contain sensitive or compliance-relevant information where accidental edits or deletions could be harmful. The TEAMS_PROTECTED_CONVERSATIONS environment variable (or --protected-conversations CLI flag / protectedConversations MCP parameter) blocks edit and delete actions in matching conversations:
Patterns are comma-separated and support * as a wildcard (matches any characters). Matching is case-insensitive. When a conversation's name matches any pattern, both edit-message and delete-message throw an error before making any changes — the message is left untouched.
The per-call parameter takes precedence over the environment variable, so individual tool invocations can override the configured patterns when needed.
All MCP tools accept an optional format parameter (concise or detailed). Default format is concise.
Workflow guidance, tips, and important notes are served automatically via the MCP server's instructions field — no separate skill file needed. For the same content on the CLI, run teams-api guide.
teams_describe_image reuses the existing Teams AMS image download support and sends the image bytes to an OpenAI-compatible vision endpoint. Configure it with TEAMS_IMAGE_DESCRIPTION_API_KEY or OPENAI_API_KEY. Optional overrides: TEAMS_IMAGE_DESCRIPTION_MODEL and TEAMS_IMAGE_DESCRIPTION_BASE_URL.
Examples:
The Teams Chat Service URL varies by region. Login-based and debug-session auth detect it automatically. You only need to set --region or TEAMS_REGION when you are supplying tokens directly or want to force an override:
--file / --image paths must exist on your local filesystem. Cloud-hosted AI clients run in isolated containers and cannot access local paths. Use a local MCP client (Claude Desktop, Cursor, VS Code) or the CLI for file attachments.--auto or TEAMS_AUTO=true; add --headless or TEAMS_HEADLESS=true only when unattended browser auth is wanted.--login) instead.findOneOnOneConversation() to resolve names from message history.emotions field in message payloads. Parsing handles both JSON-string and array formats.This is the advanced integration path. Most users should start with MCP or CLI instead.
Install the package in your project:
Example:
TeamsClient.fromToken(tokenBundle) accepts the complete TeamsToken returned
by getToken(), including chatBearerToken for accounts without a Skype token.
The string form accepts a Skype token and region.
listConversations() returns one page and enriches untitled chat names by
default. SDK consumers can pass { enrichNames: false } to avoid member and
profile lookups. CLI and MCP behavior and options are unchanged.
For complete, lightweight enumeration, use listConversationsPage():
Follow backwardLink until it is null, even when a page is short or becomes
empty after system-stream filtering. Continuation URLs must use the current
Chat Service origin. Name enrichment defaults to enabled on both SDK methods.
Use getMessages(id, { since }) to stop message pagination at a creation-time
cutoff. This is not an edit/deletion delta feed; applications own checkpoint
storage and reconciliation policy.
See CONTRIBUTING.md for development setup, architecture, and implementation notes.
MIT
来源:README.md,提交 c149aa5
List Teams Conversations
List conversations (chats, group chats, meetings, channels). Returns conversation ID, topic, type, and last message time.
emaillimitformatFind Teams Conversation
Find a conversation by topic name (case-insensitive partial match). When Substrate search is available, also matches by member names. For 1:1 chats (which have no topic), use find-one-on-one instead. Use the returned conversation ID for subsequent operations like get-messages or send-message.
emailquery必填formatFind 1:1 Conversation
Find or create a 1:1 conversation with a person by name. Uses Substrate people/chat search when available — if a conversation already exists it is returned; if the person is found in the org directory but no chat exists yet, a new 1:1 is started. Falls back to scanning message senders when Substrate is unavailable. Also finds the self-chat if the name matches the current user.
emailformatpersonName必填Get User Profiles
Get Teams profiles for one or more people by MRI. Returns display name, email, job title, office location, and user type.
emailformatuserIdentifiers必填Find People
Search for people in the organization directory by name. Uses the Substrate search API (requires authentication via auto-login or interactive). Returns matching people with emails, job titles, and departments.
emailquery必填formatmaxResultsFind Chats
Search for chats by name or member name. Uses the Substrate search API (requires authentication via auto-login or interactive). Returns matching chats with member lists and thread IDs.
emailquery必填formatmaxResultsSearch Messages
Search message content across accessible Teams chats and channel posts/replies. Read-only; does not open chats, send messages, or mark messages read. Requires a Substrate search token. Returns one page with message IDs, previews, Teams links, total estimate, and nextOffset. Search visibility and retention policies apply; zero results do not prove no messages exist.
fromemailquery必填formatoffsetpageSizesentAftersentBeforemessageTypeconversationIdGet Messages
Get messages from a conversation. Identify the conversation by topic name (--chat), person name for 1:1 chats (--to), or direct ID (--conversation-id). At least one identifier is required. For channel threads, provide --message-id to read replies under a specific post. Messages include reactions, mentions, followers (thread subscribers), and quoted message references.
tochatemaillimitordersinceformattextOnlymessageIdconversationIdSend Message
Send a message to a conversation. Identify the conversation by topic name (--chat), person name for 1:1 chats (--to), or direct ID (--conversation-id). At least one identifier is required. For channel thread replies, provide --message-id to reply under a specific post. Content is interpreted as Markdown by default and converted to rich HTML. To send images, provide file paths via --image. To send file attachments (documents, videos, etc.), provide file paths via --file. Use [image] placeholders in --content to interleave text and images (e.g. --content 'Before [image] after [image] done' --image a.png --image b.png). Without placeholders, text appears first followed by all images.
tochatfileemailimageformatcontentsubjectmessageIdscheduleAtagentMarkermessageFormat另有 3 个Edit Message
Edit an existing message in a conversation. Identify the conversation by topic name (--chat), person name for 1:1 chats (--to), or direct ID (--conversation-id). At least one identifier is required. The message to edit is identified by --message-id. Content is interpreted as Markdown by default and converted to rich HTML.
tochatemailformatcontent必填messageId必填replyGuardagentMarkermessageFormatconversationIdquoteMessageIdprotectedConversationsDelete Message
Delete a message from a conversation. Identify the conversation by topic name (--chat), person name for 1:1 chats (--to), or direct ID (--conversation-id). At least one identifier is required. The message to delete is identified by --message-id.
tochatemailformatmessageId必填deleteModeconversationIddeleteTombstoneprotectedConversationsAdd Reaction
Add a reaction (emoji) to a message. Identify the conversation by topic name (--chat), person name for 1:1 chats (--to), or direct ID (--conversation-id). At least one identifier is required. Standard reaction keys: "like", "heart", "laugh", "surprised", "angry", "sad". User-friendly names are auto-resolved to Teams emoji IDs (e.g. "horse" → "1f40e_horse").
tochatemailformatmessageId必填reactionKey必填conversationIdRemove Reaction
Remove a reaction (emoji) from a message. Identify the conversation by topic name (--chat), person name for 1:1 chats (--to), or direct ID (--conversation-id). At least one identifier is required. Only removes the current user's reaction of the specified type. User-friendly names are auto-resolved to Teams emoji IDs (e.g. "horse" → "1f40e_horse").
tochatemailformatmessageId必填reactionKey必填conversationIdGet Conversation Members
List members of a conversation. Identify the conversation by topic name (--chat), person name for 1:1 chats (--to), or direct ID (--conversation-id). At least one identifier is required. Display names are resolved via the Teams profile API when available, with message history as fallback. Note: 1:1 chat members may have empty display names if profile resolution is unavailable.
tochatemailformatconversationIdCurrent User Info
Get the display name and region of the currently authenticated user.
emailformatGet Meeting Transcript
Get the meeting transcript from a conversation that contains a recorded meeting. Identify the conversation by topic name (--chat), person name for 1:1 chats (--to), or direct ID (--conversation-id). Use --raw-vtt to get the original VTT file instead of parsed output.
tochatemailformatrawVttconversationIdDownload File
Download file attachment(s) from a message. Identify the conversation by topic name (--chat), person name for 1:1 chats (--to), or direct ID (--conversation-id). Specify the message containing the file(s) via --message-id. Use --output-directory to save files to a specific directory. Without --output-directory, files are saved to a temporary directory. Text file contents and images are returned inline in the response. Other binary files (PDFs, videos, archives, etc.) are saved to disk only; the response reports the local save path.
tochatemailformatmessageId必填conversationIdoutputDirectoryDescribe Image
Describe an inline Teams image using a configured OpenAI-compatible vision model. Use amsObjectId directly, or identify a message by chat/to/conversationId plus messageId. Set TEAMS_IMAGE_DESCRIPTION_API_KEY or OPENAI_API_KEY before using this tool.
tochatemailformatpromptfullSizemessageIdimageIndexamsObjectIdconversationId已满足适用检查项的 90%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

com.microsoft官方发布者
一个免费的远程 MCP 服务器,让 AI 助手搜索微软官方 Learn 文档、查找代码示例,并把文档页面抓取为 markdown。

com.microsoft官方发布者
远程 MCP 服务器,为 AI 智能体提供托管的 Playwright 云端浏览器,可创建会话、访问并检查页面、与页面元素交互。

com.microsoft官方发布者
远程 Microsoft Sentinel MCP 服务器,让助手用自然语言查找相关表并从 Sentinel 数据湖检索安全数据。
com.microsoft
让助手通过桌面自动化在用户的 Windows 机器上创建、更新和读取 Microsoft Visio 图表。

由 GitHub 账号 surendranb 发布
本地 MCP 服务器,把 Microsoft Clarity 的行为 UX 数据(暴怒点击、无效点击、快速返回、JS 错误)提供给 AI 助手分析。
# VS Codecode --add-mcp '{"name":"teams","command":"npx","args":["-y","-p","teams-api@latest","teams-api-mcp"],"env":{"TEAMS_LOGIN":"true"}}'
# VS Code Insiderscode-insiders --add-mcp '{"name":"teams","command":"npx","args":["-y","-p","teams-api@latest","teams-api-mcp"],"env":{"TEAMS_LOGIN":"true"}}'# VS Codecode --add-mcp '{"name":"teams","command":"npx","args":["-y","-p","teams-api@latest","teams-api-mcp"],"env":{"TEAMS_LOGIN":"true"}}'
# VS Code Insiderscode-insiders --add-mcp '{"name":"teams","command":"npx","args":["-y","-p","teams-api@latest","teams-api-mcp"],"env":{"TEAMS_LOGIN":"true"}}'rem VS Codecode --add-mcp "{\"name\":\"teams\",\"command\":\"npx\",\"args\":[\"-y\",\"-p\",\"teams-api@latest\",\"teams-api-mcp\"],\"env\":{\"TEAMS_LOGIN\":\"true\"}}"
rem VS Code Insiderscode-insiders --add-mcp "{\"name\":\"teams\",\"command\":\"npx\",\"args\":[\"-y\",\"-p\",\"teams-api@latest\",\"teams-api-mcp\"],\"env\":{\"TEAMS_LOGIN\":\"true\"}}"{ "mcpServers": { "teams": { "command": "npx", "args": ["-y", "-p", "teams-api@latest", "teams-api-mcp"], "env": { "TEAMS_LOGIN": "true" } } }}{ "mcpServers": { "teams": { "command": "npx", "args": ["-y", "-p", "teams-api@latest", "teams-api-mcp"], "env": { "TEAMS_LOGIN": "true" } } }}{ "mcpServers": { "teams": { "command": "npx", "args": ["-y", "-p", "teams-api@latest", "teams-api-mcp"], "env": { "TEAMS_LOGIN": "true" } } }}claude mcp add teams -- npx -y -p teams-api@latest teams-api-mcp{ "mcpServers": { "teams": { "command": "npx", "args": ["-y", "-p", "teams-api@latest", "teams-api-mcp"], "env": { "TEAMS_LOGIN": "true" } } }}npx -y -p teams-api@latest teams-api auth --loginnpx -y -p teams-api@latest teams-api list-conversations --login --limit 20npm install -g teams-apiteams-api auth --loginnpx -y skills add Maxim-Mazurok/teams-api --skill teams-apiteams-api auth --loginteams-api auth --login --email [email protected]teams-api auth --debug-port 9222teams-api list-conversations --token "<paste-token-here>" --region emeateams-api find-people \ --token "<paste-skype-token-here>" \ --bearer-token "<paste-api-spaces-skype-bearer-token-here>" \ --substrate-token "<paste-substrate-bearer-token-here>" \ --region emea \ --query "Jane Doe"npx -y -p teams-api@latest teams-api <command> [options]npm install -g teams-apiteams-api <command> [options]# Acquire a token (interactive — all platforms)teams-api auth --login
# Acquire a token (headed auto-login — macOS with FIDO2)teams-api auth --auto --email [email protected]
# Acquire a token (headless auto-login — explicit opt-in)teams-api auth --auto --headless --email [email protected]
# List conversationsteams-api list-conversations --login --limit 20 --format detailed
# Find a conversation by topicteams-api find-conversation --auto --email [email protected] --query "Design Review"
# Find a 1:1 chat by person nameteams-api find-one-on-one --auto --email [email protected] --person-name "Jane Doe"
# Find people, including office location when profile enrichment is availableteams-api find-people --auto --email [email protected] --query "Jane Doe"
# Get profiles for MRIs returned by people search or member listingteams-api get-profiles --auto --email [email protected] \ --user-identifiers "8:orgid:00000000-0000-0000-0000-000000000000"
# Read messages (by topic name, person name, or direct ID)teams-api get-messages --auto --email [email protected] --chat "Design Review"teams-api get-messages --auto --email [email protected] --to "Jane Doe" --max-pages 5teams-api get-messages --auto --email [email protected] --conversation-id "19:[email protected]" --format detailed
# Newest-first order (API returns newest-first; default is oldest-first/chronological)teams-api get-messages --auto --email [email protected] --chat "General" --order newest-first
# Send a messageteams-api send-message --auto --email [email protected] --to "Jane Doe" --content "Hello!"teams-api send-message --auto --email [email protected] --chat "Design Review" --content "Status update"
# List membersteams-api get-members --auto --email [email protected] --chat "Design Review"
# Get current user infoteams-api whoami --auto --email [email protected]
# Export messages to a file (default format: concise)teams-api get-messages --auto --email [email protected] --chat "General" --output exports/general.md
# Export as JSON to a fileteams-api get-messages --auto --email [email protected] --chat "General" --format detailed --output exports/general.jsonteams-api search-messages --login --query "release" --message-type channel
teams-api search-messages --query "*" --from [email protected] \ --sent-after 2026-10-01 --sent-before 2026-10-26 \ --page-size 25 --offset 0 --format detailedimport { TeamsClient } from "teams-api";
const client = await TeamsClient.connect({ email: "[email protected]" });const page = await client.searchMessages({ query: "release", messageType: "channel", from: "[email protected]", pageSize: 25,});{ "mcpServers": { "teams": { "command": "npx", "args": ["-y", "-p", "teams-api@latest", "teams-api-mcp"], "env": { "TEAMS_TOKEN": "<paste-skype-token-here>", "TEAMS_BEARER_TOKEN": "<optional-api-spaces-skype-bearer-token>", "TEAMS_SUBSTRATE_TOKEN": "<optional-substrate-bearer-token>", "TEAMS_REGION": "emea" } } }}{ "env": { "TEAMS_AGENT_MARKER": "Ⓜ", // or "🤖", "[Bot]", etc. },}{ "env": { "TEAMS_DELETE_MODE": "soft", "TEAMS_DELETE_TOMBSTONE": "🗑️ [removed by automation]", },}{ "env": { "TEAMS_AUDIT_LOG": "file:/var/log/teams-audit.jsonl", },}{ "env": { "TEAMS_PROTECTED_CONVERSATIONS": "Incident *,*compliance*,Architecture Decisions", },}teams-api describe-image --chat "Project Chat" --message-id 1773736076914 --image-index 0teams-api describe-image --ams-object-id 0-eaua-d2-877b82634f4e978692f2243d445a6650npm install teams-apiimport { TeamsClient } from "teams-api";
// Interactive login — opens a browser, you log in manually (all platforms)const client = await TeamsClient.fromInteractiveLogin();
// Or auto-login via platform authenticator (macOS + FIDO2 passkey)const autoClient = await TeamsClient.fromAutoLogin({ email: "[email protected]",});
// Advanced/manual: create a client from previously captured tokensconst manualClient = TeamsClient.fromToken("skype-token-here", "emea");
const restoredClient = TeamsClient.fromToken(client.getToken());
const conversations = await client.listConversations();const messages = await client.getMessages(conversations[0].id, { maxPages: 5, onProgress: (count) => console.log(`Fetched ${count} messages`),});
await client.sendMessage(conversations[0].id, "Hello from the API!");
const oneOnOne = await client.findOneOnOneConversation("Jane Doe");const members = await client.getMembers(conversations[0].id);const profiles = await client.getProfiles(members.map((member) => member.id));console.log(profiles.map((profile) => profile.userLocation));let backwardLink: string | undefined;do { const page = await client.listConversationsPage({ pageSize: 500, enrichNames: false, backwardLink, }); for (const conversation of page.conversations) { console.log( conversation.id, conversation.version, conversation.lastMessageTime, ); } backwardLink = page.backwardLink ?? undefined;} while (backwardLink);