Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

teams-cli

Microsoft Teams from your terminal—human-first and agent-first.

teams-cli is a Rust CLI and TUI for everyday Microsoft Teams work through supported Microsoft Graph APIs, with an optional experimental desktop backend for connection diagnostics. It is designed as two equally first-class experiences over one typed core: a fast, calm terminal interface for people and a deterministic, introspectable command contract for agents. The default Graph backend signs in as you with delegated OAuth and protects refresh credentials in your operating system's credential store. Output is readable text on a TTY and structured JSON when piped.

For humans, no arguments open guided onboarding on first use and the TUI afterward. For agents, no command ever waits for an undeclared prompt: teams schema works offline, collection sizes are caller-bounded, writes declare their effects, errors have stable kinds and exit codes, and stdout contains data only.

Install

pipx install teams-cli
# or
cargo install teams-cli --locked
# or run from PyPI without installing
uvx teams-cli --help

The PyPI distribution provides both teams and teams-cli as executable names.

To work from source:

cargo install --path .
# or build a local wheel
maturin build

Explore before configuring Microsoft 365

teams tui --demo
teams tui --demo --snapshot
teams capabilities
teams schema --command "messages send"

Onboarding

Run teams in a terminal on first use, or start explicitly:

teams init

teams-cli includes a maintained multitenant Microsoft Entra public-client registration, so normal setup does not require creating an app or copying a client ID:

teams init

Browser PKCE is the human-friendly default. The browser talks directly to Microsoft, and the CLI never receives or stores your password. Normal sign-in requests these delegated scopes:

openid profile offline_access User.Read Team.ReadBasic.All
Channel.ReadBasic.All Chat.Read Chat.Create ChatMessage.Send
ChannelMessage.Send

The TUI is also the recovery path: an unconfigured profile, missing credential, expired refresh session, or Microsoft 401 opens a focused connection screen. Press Enter or a to restore the normal terminal, complete Microsoft sign-in, and return directly to the inbox; q exits without changing anything.

Reading channel history is intentionally separate because ChannelMessage.Read.All requires administrator consent. Request it only when needed:

teams auth login --channel-history

The CLI surfaces missing consent as a stable permission_denied error instead of silently reaching for undocumented Teams APIs. Tenant policy can still require an administrator to approve otherwise user-consentable permissions.

Headless setup is explicit and never prompts:

teams init --no-login
teams auth login --device-code
teams whoami --output json

Organizations that prefer their own Entra registration can override the bundled application:

teams init --client-id "$TEAMS_CLIENT_ID" --tenant organizations --no-login

The custom app must be a public client with http://localhost registered for browser login, public-client flows enabled for device-code login, and the baseline delegated permissions listed above.

For short-lived automation, TEAMS_ACCESS_TOKEN overrides the stored credential. Refresh credentials are never written to the config file.

Everyday commands

teams list
teams channels list TEAM_ID
teams chats list --limit 25
teams messages list --chat CHAT_ID
teams auth login --channel-history  # once, with administrator approval
teams messages list --team TEAM_ID --channel CHANNEL_ID
teams messages send --chat CHAT_ID --body "On it."
printf 'Status update' | teams messages send --chat CHAT_ID --body -
teams auth status
teams auth status --offline
teams profile list
teams profile use work
teams profile remove old --yes
teams config show
teams config path
teams doctor --offline

Collection commands expose --limit and --fields; Graph-native collections use --cursor, while joined teams and channels use --offset because those endpoints do not accept $top. With a terminal they render concise text; when stdout is piped they emit JSON envelopes with continuation metadata and truncated.

Profiles can block every remote write while keeping reads, sign-in, diagnostics, and the TUI available:

teams init --no-login --read-only
# or for one invocation/environment
TEAMS_READ_ONLY=true teams messages send --chat CHAT_ID --body "Blocked"

Like the other tools in the suite, the config file is selected with --profile, overridden by TEAMS_* environment variables, and inspectable without exposing credentials through teams config show and teams config path.

Experimental desktop diagnostics

Use a desktop profile to inspect an existing Teams debugging endpoint on macOS, Windows, or WSL:

teams init --profile local --backend desktop --read-only --no-login
teams --profile local doctor --offline
teams --profile local doctor
teams --profile local auth status
# Match a separately enabled endpoint on another port:
teams init --profile local --backend desktop --desktop-port 19222 --no-login

Desktop currently supports configuration and connection metadata only. Chats, messages, identity, subscriptions, sends, and live TUI data return unsupported. Demo/snapshot TUI modes remain available. Desktop profiles are always read-only, including when TEAMS_READ_ONLY=false. Existing profiles without a backend field continue to use Graph; Graph remains the default for init.

The endpoint must already be enabled through an explicit Teams debugging launch. These commands never launch, restart, quit, or sign into Teams, and never enable debugging. init --no-login saves configuration without probing; ordinary desktop initialization probes the existing endpoint. A normal Teams launch usually has no endpoint, which doctor reports as no_listener.

macOS checks listener binding and installed Teams process ancestry before reading loopback metadata. Windows uses a fixed PowerShell helper with JSON stdin/stdout; WSL invokes that Windows helper through executable interop, so NAT mode needs no networking changes. Windows requires the installed MSTeams package and powershell.exe on PATH. Both paths refuse non-loopback listeners and unrelated owners. The Windows reader also verifies the Teams process belongs to the invoking Windows user. Requests are limited to GET /json/version and GET /json/list. Results omit titles, full URLs, target IDs, WebSocket URLs and private origins.

Endpoint discovery does not verify sign-in: signed_in stays null, verified and session_verified stay false, and endpoint_available describes metadata access only. doctor.healthy means the requested diagnostic checks passed; it does not imply that desktop messaging works. Offline commands do not contact the endpoint. Desktop profiles ignore Graph OAuth environment settings and credentials; auth login/logout return unsupported because Teams owns its session. A CLI profile selects connection configuration, not a Teams account. There is no automatic fallback to Graph.

The helper timeout is 45 seconds. Cancellation stops the local helper, but WSL can retain a Windows-side helper process until its own bounded request completes. Microsoft treats WebView2 flags as development diagnostics and advises against relying on them in production. This backend is experimental; actual CDP attachment and chat access remain unverified.

Windows CI runs synthetic tests against the production PowerShell reader. To run them elsewhere with an installed PowerShell:

TEAMS_TEST_POWERSHELL=/path/to/pwsh cargo test --test desktop_bridge -- --ignored

Graph boundaries

  • Microsoft 365 work or school accounts only. The relevant Teams Graph endpoints do not support personal Microsoft accounts.
  • A work account can authenticate successfully before Microsoft Teams is licensed or provisioned; teams doctor distinguishes identity access from Teams availability.
  • Calling and screen sharing are not available as a delegated user CLI; Graph calling is built around bot/application scenarios.
  • No extracted desktop tokens, browser interception, or private Teams protocols.
  • Tenant policy and admin consent can restrict delegated capabilities.

CLI Spec

teams schema is offline, unauthenticated, and follows CLI Spec v0.3: flat invocable command paths, declared effects and cardinality, bounded collections, stable error kinds and exit codes, stdout/stderr separation, and safe noninteractive behavior. Its backend capabilities and per-command backend extensions distinguish Graph operations from experimental desktop diagnostics.

Releasing

Vership owns versioning, changelog generation, release commits, and tags. See the release runbook for the verified workflow and recovery policy.

Metadata

Release files for teams-cli 0.1.9a1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for teams-cli 0.1.9a1
File Size Uploaded Provenance
teams_cli-0.1.9a1.tar.gz 81.9 kB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for teams-cli 0.1.9a1
File
teams_cli-0.1.9a1-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
teams_cli-0.1.9a1-py3-none-manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.28+ x86-64 Details
teams_cli-0.1.9a1-py3-none-manylinux_2_28_aarch64.whl Python 3 none Linux glibc 2.28+ ARM64 Details
teams_cli-0.1.9a1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl Python 3 none macOS 10.12+ x86-64, macOS 11.0+ ARM64, macOS 10.12+ universal2 (ARM64, x86-64) Details

Total release size: 18.3 MB

Release files / teams_cli-0.1.9a1.tar.gz

Download URL teams_cli-0.1.9a1.tar.gz
Size 81.9 kB
Tags Source
SHA-256 checksum
How to use checksums
916fbcf49f4aad81e354590934598626b8ecdec0915baaff03d517a462a20f0a
BLAKE2b-256 checksum
How to use checksums
963f4c334f0345fb85b2b7c9b40e806d85116524a113d429ffb4bc36b1d53b5a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / teams_cli-0.1.9a1-py3-none-win_amd64.whl

Download URL teams_cli-0.1.9a1-py3-none-win_amd64.whl
Size 3.3 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
22abd8d1203c0b3d46d7e2b90d38ecabc66965f6a0be50338bd62164131365a3
BLAKE2b-256 checksum
How to use checksums
e2e27d63772addfd28d0e30cd13a8b458b3670dd055c4e87ce2c4be6d3c84148
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / teams_cli-0.1.9a1-py3-none-manylinux_2_28_x86_64.whl

Download URL teams_cli-0.1.9a1-py3-none-manylinux_2_28_x86_64.whl
Size 4.1 MB
Tags Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
cb7fecc8d52f93a694278d191351108abe2e749a7acc707fadd5d253dd5a6583
BLAKE2b-256 checksum
How to use checksums
141be6dedcf9d728e6c5f18dc839d82c27fecfc2d1fcd254095a4aab7e183688
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / teams_cli-0.1.9a1-py3-none-manylinux_2_28_aarch64.whl

Download URL teams_cli-0.1.9a1-py3-none-manylinux_2_28_aarch64.whl
Size 3.7 MB
Tags Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
656238d41e0ad89764b4fbb6f564d649ed7622e10235adbd2ef5bf8437b4a2bc
BLAKE2b-256 checksum
How to use checksums
b9caa9cc54a4316eebf90eeaae7e0fcc515acd94ad9d4059a8b102420181dd87
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / teams_cli-0.1.9a1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl

Download URL teams_cli-0.1.9a1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Size 7.1 MB
Tags Python 3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
86e7accd34105ed36389b98e9d71a55690ff6dda1d50780a4d4ba0c21468b467
BLAKE2b-256 checksum
How to use checksums
893c1d9f264b5dc29c0ebd098b998851fe402d1c3cf9afdd04c0adce58c247ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Security for teams-cli 0.1.9a1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 5 files in this release have been uploaded with provenance metadata.

Select from 5 files

Attestation for teams_cli-0.1.9a1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page