Skip to content

Add teams CLI: browser sign-in, channel search, and JSON output for agents - #1

Merged
glenthomas merged 6 commits into
mainfrom
copilot/build-cli-for-teams-data-access
Sep 30, 2026
Merged

glenthomas merged 6 commits into
mainfrom
copilot/build-cli-for-teams-data-access

Conversation

Copilot AI commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Adds a Go CLI that AI coding agents can call instead of an MCP server to read Microsoft Teams data through Microsoft Graph. Users sign in through a browser window opened by the CLI.

teams login
teams search --channel platform-engineering --since 30d --query "private endpoints"
teams thread --channel platform-engineering --id <threadId>

Auth (internal/auth, internal/config)

  • teams login uses MSAL's interactive flow (auth code + PKCE, http://localhost redirect). If the browser can't be opened, the sign-in URL is printed to stderr. --device-code covers headless machines; --timeout defaults to 5m.
  • The MSAL token cache is stored in a single file with mode 0600 ($TEAMS_CLI_CONFIG_DIR or the OS config dir). Tokens refresh silently. Login keeps only the account that just signed in.
  • Default app is the public Microsoft Graph Command Line Tools client (14d82eec-…) with tenant organizations. Override with --client-id/--tenant or the TEAMS_CLI_CLIENT_ID/TEAMS_CLI_TENANT_ID env vars. The values used at login are saved and reused by later commands.
  • TEAMS_CLI_ACCESS_TOKEN skips MSAL entirely (CI, or bring your own token).
  • Delegated scopes: User.Read, Team.ReadBasic.All, Channel.ReadBasic.All, ChannelMessage.Read.All. The last one usually needs admin consent.

Graph client (internal/graph)

  • Minimal client: generic paging over @odata.nextLink, and retries on 429/502/503/504 that honour Retry-After (capped at 60s).
  • Follows a nextLink only if it points to the Graph host, so the bearer token is never sent anywhere else.
  • graphtest is an in-memory fake Graph server with seeded fixtures, used by the tests.

Commands (internal/cli, internal/teams)

  • login, logout, whoami, teams, channels, messages, search, thread.
  • Name resolution: --channel/--team take a name or an ID. Names match case-insensitively and ignoring punctuation, so platform-engineering finds "Platform Engineering". If a name matches in several teams, the CLI returns an ambiguous error listing the matches. Not-found errors include the available names, capped at 100.
  • Search runs client-side, because Graph has no text filter for channel messages:
    • Pages through /messages?$top=50&$expand=replies, assuming Graph returns threads newest-activity-first, then filters locally by time window and query terms.
    • Stops at the first page with no activity since --since, and caps the scan at --max-threads (default 1000) per channel.
    • Query terms are ANDed; "quoted phrases" must match exactly. HTML bodies are converted to plain text.
  • Output: JSON on stdout. Each message is flattened: type (message or reply), threadId, team/channel, author, text, webUrl, replyCount. Envelope fields truncated and warnings say when results were cut short. --format text gives human-readable output.
  • Errors: JSON on stderr as {"error":{code,message,details}}, with stable exit codes:
Exit Codes
0 success
1 error, timeout
2 usage
3 not_logged_in (missing session, or Graph 401)
4 not_found, ambiguous
5 forbidden, throttled, graph_error

Review notes

  • The early-stop rule relies on Graph returning threads newest-activity-first, which I couldn't confirm against the docs from the sandbox. If that ordering is wrong, a search can miss older matches without flagging truncated.
  • Replies come from $expand=replies, and replies beyond whatever Graph returns inline are not paged separately.
  • Interactive login has not been run against a real tenant: the sandbox can't reach login.microsoftonline.com.
Original prompt

I want to build a CLI for accessing data from Microsoft Teams. The CLI would be used by AI coding agents as an alternative to an MCP.

Example command:

teams search \
--channel platform-engineering \
--since 30d \
--query "private endpoints"

Agents can invoke CLI tools and consume structured output.

Ideally the user would authenticate with Teams via the CLI opening a browser window to fetch a token.

Copilot AI and others added 2 commits September 30, 2026 15:13
…output

Co-authored-by: glenthomas <20847558+glenthomas@users.noreply.github.com>
Co-authored-by: glenthomas <20847558+glenthomas@users.noreply.github.com>
Copilot AI changed the title [WIP] Add CLI for accessing data from Microsoft Teams Add teams CLI: browser sign-in, channel search, and JSON output for agents Sep 30, 2026
Copilot AI requested a review from glenthomas September 30, 2026 15:16
@glenthomas
glenthomas marked this pull request as ready for review September 30, 2026 19:22
@glenthomas
glenthomas merged commit 2d3473c into main Sep 30, 2026
1 check passed
@glenthomas
glenthomas deleted the copilot/build-cli-for-teams-data-access branch September 30, 2026 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants