Skip to main content

MCP server that surfaces Azure DevOps work-item activity for one or more team rosters (multi-org / multi-tenant), so VS Code Copilot Chat can answer manager-style questions like 'what did Ashish work on last week?' or 'analyze the team's last 6 months'.

Project description

ado-team-activity-mcp

Ask Copilot Chat in VS Code about your team's Azure DevOps work — in plain English.

A local Model Context Protocol (MCP) server that turns your ADO orgs into something a manager / PM / tech lead can interrogate from the chat panel.

"What did Ashish work on yesterday?" "Give me a standup for the team for the last 3 days." "Analyze Vibhuti's last 6 months — is she ramping up or down?" "Anything blocked on the team this week?" "Run a perf-review packet for Abhishek over 6 months."

Read-only against ADO. Multi-org, multi-tenant. No PATs in config — uses your existing az login.


Why this exists

Tracking what your team is actually doing in Azure DevOps means clicking through dashboards, hand-rolling WIQL queries, or pestering people for status updates. This MCP server lets your AI assistant do the legwork:

  • Standups"What did the team ship yesterday?" gets a real, dated, linked answer in seconds.
  • 1:1 prep"What's on <alias>'s plate right now? Any blockers in the comments?" before every 1:1.
  • Perf reviews"Pull a 6-month contribution packet for <alias> — ownership, cadence, gap months, active items." Honest evidence instead of vibes.
  • Coverage gaps"Find Active items assigned to teammates who haven't logged anything in 30+ days." Catch orphan work before it ages.
  • Cross-team / cross-org rollups"Compare Ashish across the pcoe and contoso orgs." One question, multiple ADOs.
  • Triage"Tell me more about WI 1738 — what's the discussion say?" Pulls full comment thread.

Use cases — what you actually get back

"What did Ashish work on yesterday?"

Returns a structured digest grouped by activity bucket (assigned_and_changed, changed_by, created_by, closed_by) — each item links back to ADO. Comments are pulled by default, so the model can mention blockers like "Doc Intelligence 403 raised Jun 1, resolved Jun 2."

"Standup for the team for the last 3 days"

Walks every teammate in your config, in one round-trip per org. Returns per-person item lists. Copilot turns it into a "Yesterday / Today / Blockers" digest you can paste into Slack.

"Analyze <alias>'s last 6 months"

Routes to summarize_contributions — returns server-side aggregations:

  • by_month with gap months surfaced explicitly (catches silent periods)
  • ownership: User Stories owned, Bugs resolved, Active items still open
  • cadence: same-day-close ratio (catches "I closed 14 tickets on March 16" backlog cleanups)
  • comment samples — so you can judge documentation quality without a second tool call

Copilot then writes a manager-ready review with honest gaps highlighted.

"Anything blocked across the team this week?"

Pulls team activity, scans titles + tags + comment text for "blocked" / "waiting on" / Blocked state. Lists them with owner and link.

"Refresh my roster"

Calls refresh_roster — pulls fresh members from ADO Teams (and/or recent contributors), reports new joiners + departures, dry-runs the diff, waits for your confirmation before writing.

"Discover what orgs I have access to and add them"

One-time setup. Calls init --discover for you under the hood (or you can run it from the terminal). Auto-populates every org + project + roster you can see.


3-minute setup

You need Python 3.11+, Azure CLI, VS Code with GitHub Copilot Chat.

1. Install

python -m pip install --user pipx
python -m pipx ensurepath
# Close PowerShell + fully quit VS Code, then reopen:
pipx install ado-team-activity-mcp
ado-team-activity-mcp --version

2. Sign in to Azure DevOps

az login

Use az login --tenant <tenant-id> if your org is in a non-default tenant.

3. Auto-create your config

ado-team-activity-mcp init --discover

This:

  1. Finds every ADO org reachable via your az login
  2. Lists their projects (you pick which to add)
  3. For each picked project, lists ADO Teams and scans recent contributors (last 360 days)
  4. Merges into a deduped roster — catches both formally-assigned team members AND people who actually do work but aren't on a team
  5. Writes ~/.ado-team-activity/config.yaml
  6. Prints the exact mcp.json snippet you paste into VS Code's user MCP config

4. Register with VS Code

Command Palette → "MCP: Open User Configuration" → paste the snippet init printed.

5. Reload VS Code

Command Palette → "Developer: Reload Window". Open Copilot Chat, switch to Agent mode, ask:

call list_orgs

You'll see your configured orgs. Then try a real question.


What it can do — full tool reference

Read tools (no writes)

Tool What it does
list_orgs() What's configured (id, URL, project, tenant, team size).
list_team_members(org=None) Roster for one org or all orgs.
get_teammate_activity(name, days=?, org=?, include_comments=True) One teammate's items over the window. Comments by default. If alias collides across orgs without org=, returns needs_disambiguation.
get_team_activity(days=?, org=?, include_comments=True) Whole-roster sweep — one org or all. Per-org needs_reauth propagated.
summarize_contributions(name, days=180, org=?) Long-window aggregations: by-month gaps, ownership, cadence, active items, comment samples. Use for trend/perf/quarter questions.
get_work_item(id, org, include_comments=True) One item — fields + last 10 revisions + comments. org required (IDs are per-org).
get_work_item_comments(id, org, top=50) Comments only. org required.

Discovery + config-write tools

All writes are dry-run-by-default — return a structured diff, you confirm, then a .bak.<timestamp> is made before atomic save.

Tool What it does
discover_team_members(org, team_name=None) List ADO Teams in a project, or fetch members of one team.
apply_discovered_team(org, team_name, overwrite=False, dry_run=True) Merge one team's members into config.
refresh_roster(org=None, source='teams', contributors_days=360, remove_departed=False, dry_run=True) Resync roster(s) from ADO. source='contributors' catches people NOT on any team. 'both' = union. Reports new joiners + departures.
add_org / remove_org Org-level edits.
add_team_member / update_team_member / remove_team_member Roster edits.
set_default_lookback_days Change the default day window.

Slash-prompts (PM workflows)

Type / in Copilot Chat to invoke:

  • /standup — daily standup digest, grouped by person, blockers first.
  • /weekly_digest — themes from the last 7 days, with coverage suggestions.
  • /perf_review — 6-month evidence packet for one person, refuses to recommend a raise % (that needs comp data outside ADO).
  • /coverage_check — finds Active items assigned to absent owners; suggests reassignment.
  • /cross_team_lookup — resolves a name across every configured org.

Multi-org / multi-tenant — really

The config supports any number of ADO orgs, each in any Entra tenant. Per-tenant tokens are cached automatically.

default_lookback_days: 1

orgs:
  - id: pcoe
    organization_url: https://dev.azure.com/your-org
    project: YourProject
    # tenant_id is optional; set it for cross-tenant orgs
    team: [...]
  - id: contoso
    organization_url: https://dev.azure.com/Contoso
    project: ContosoApp
    tenant_id: 00000000-0000-0000-0000-000000000000
    team: [...]

When a tool fails because your az login is in the wrong tenant, the response is a structured needs_reauth payload — Copilot will tell you exactly what to run:

{
  "error": "needs_reauth",
  "remediation": "az login --tenant 00000000-0000-0000-0000-000000000000",
  "org_id": "contoso"
}

No stack traces.


Setup variations

Power-user init --discover flags

ado-team-activity-mcp init --discover \
    --orgs all \
    --all-projects \
    --source both \
    --contributors-days 360
Flag Effect
--orgs name1,name2 or --orgs all Non-interactive org pick
--all-projects Add every project in each org
--source teams|contributors|both|none How to populate rosters (default both)
--contributors-days N Activity lookback for contributor discovery (default 360)
--team "Team A,Team B" or --team all Non-interactive team pick
--skip-members Empty rosters (you'll populate later)
--tenant <id> Scope discovery to a specific tenant
--config <path> Custom save location
--force Overwrite an existing config (auto-backup first)

Don't want auto-discovery?

Skip step 3 and create config.yaml by hand — example template lives at config.example.yaml in the source tree. The schema is small.

Don't want pipx?

Plain pip install --user ado-team-activity-mcp works too. You'll just need to find the installed exe path with (Get-Command ado-team-activity-mcp).Source and use that as the command in your mcp.json.


Privacy & security

  • Read-only against ADO. The server calls only query_by_wiql, get_work_items, get_work_item, get_revisions, get_comments, get_projects, get_teams, get_team_members_with_extended_properties. There are zero create/update/delete endpoints anywhere.
  • Writes are local-only (your config.yaml), always dry-run-by-default, always preceded by a timestamped .bak.
  • Tokens stay in memory — per-tenant cache, refreshed before expiry. No PAT in config, no credentials in YAML.
  • No telemetry. Network traffic is only to Azure DevOps + Entra ID for token acquisition.
  • Roster is local to you — every manager keeps their own config.yaml.

Troubleshooting

Symptom Fix
ado-team-activity-mcp: command not found pipx ensurepath, restart shell + fully quit VS Code. Or pin the absolute path from (Get-Command ado-team-activity-mcp).Source into mcp.json.
PermissionError writing config Re-run with --config "$HOME\.ado-team-activity\config.yaml" (default since 0.3.3 — this should never happen on fresh installs).
init --discover finds 0 orgs Your orgs are in a different tenant. Re-run with --tenant <tenant-id>.
error: needs_reauth in a tool response Run the remediation command from the payload verbatim.
error: needs_disambiguation Alias exists in multiple orgs. Re-call with org="<one of the candidates>".
Tool not visible in Copilot Chat Reload the VS Code window after editing user MCP config.
Zero items for someone you know is active Their unique_name doesn't match their ADO UPN. Re-copy from the Assignee chip on a real work item.

Develop locally (contributors)

git clone <repo>
cd ado-team-activity-mcp
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
az login
python scripts\check_auth.py
pytest

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ado_team_activity_mcp-0.4.0.tar.gz (36.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ado_team_activity_mcp-0.4.0-py3-none-any.whl (37.2 kB view details)

Uploaded Python 3

File details

Details for the file ado_team_activity_mcp-0.4.0.tar.gz.

File metadata

  • Download URL: ado_team_activity_mcp-0.4.0.tar.gz
  • Upload date:
  • Size: 36.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for ado_team_activity_mcp-0.4.0.tar.gz
Algorithm Hash digest
SHA256 15d273e02067256f648aad89dc600b79aa0087cb7da133188582569e729176b2
MD5 7b9d3dca8c7bb6095ec3f2785d611cc2
BLAKE2b-256 d0b4c22eb65c425305b0348408c556b9d8c19b094480e7018b6cbcd5e595c7ba

See more details on using hashes here.

File details

Details for the file ado_team_activity_mcp-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for ado_team_activity_mcp-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b2e3761dc66023a90d0868bfe318fc7d5236423bfc6e54e8b4af82dd2a27b986
MD5 2972cfbde1df261218fea13b554734d9
BLAKE2b-256 ae95362ca0d1c2cd7ce4e7c58dd23d0a67254366d5b3b5c603a77f4efe46c76f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page