# Azure Devops Mcp Onprem

> MCP server for on-premises Azure DevOps Server (TFS) with TFVC support - shelvesets, changesets, Work Items, Git, Pipelines, Test Plans, Wiki for AI assistants.

- **Type:** MCP server
- **Install:** `agentstack add mcp-burcusipahioglu-azure-devops-mcp-onprem`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [burcusipahioglu](https://agentstack.voostack.com/s/burcusipahioglu)
- **Installs:** 0
- **Category:** [Cloud & Infrastructure](https://agentstack.voostack.com/c/cloud-infrastructure)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [burcusipahioglu](https://github.com/burcusipahioglu)
- **Source:** https://github.com/burcusipahioglu/azure-devops-mcp-onprem

## Install

```sh
agentstack add mcp-burcusipahioglu-azure-devops-mcp-onprem
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Azure DevOps MCP Server

[](https://nodejs.org/)
[](https://www.typescriptlang.org/)
[](https://modelcontextprotocol.io/)
[](https://learn.microsoft.com/en-us/azure/devops/server/)
[](LICENSE)
[](https://github.com/burcusipahioglu/azure-devops-mcp-onprem#tool-reference)
[](https://www.npmjs.com/package/@burcusg/azure-devops-mcp-onprem)

**Governed access to on-prem Azure DevOps (including TFVC) for AI agents and assistants, with typed tools, chainable workflows, and a server-side write-safety layer.**

Query work items, repositories, and pipelines in natural language — running locally, no cloud proxy, no telemetry.

[Coverage](#coverage) · [TFVC](#tfvc-support) · [Profiles](#profile-based-secrets) · [Write Safety](#write-safety) · [Setup](#setup)

  

---

## At a glance

| | |
|---|---|
| **TFVC native** | 10 dedicated tools — shelvesets (incl. shelved file content), changesets, diffs, work-item linkage. The reason this server exists. |
| **Write safety** | 6 layers — MCP annotations · confirmation directive · readonly kill switch · rate limit · dry-run on every write · audit log |
| **Local / on-prem only** | PAT auth, no cloud proxy, no third-party calls, no telemetry |
| **48 tools / 6 domains** | Work Items · Git · **TFVC** · Pipelines · Wiki · Test Plans |
| **Typed results** | `outputSchema` + `structuredContent` on the 8 most-chained read tools — schema-validated results an agent can chain into the next tool without parsing prose |
| **`@me` token** | `owner` / `author` / `reviewer` / `assignedTo` accept `@me` — resolved per tenant, stateless for multi-agent setups |
| **PR review flow** | `/review_pull_request` → structured advisory review → on request, published to the PR as file-anchored comments, each one confirmed first |
| **Profile-based secrets** | `AZURE_DEVOPS_PROFILE=name` → gitignored `.env.`; no PAT in cloud-synced `mcp.json`. Multi-instance is a natural byproduct. |
| **AI clients** | Claude (Code/Desktop), GitHub Copilot, Cursor, Visual Studio Code — any MCP-compatible client |

### Example questions

> *"Show me all active bugs assigned to me in this sprint"*
> *"What changed in changeset 12345?"*
> *"Review PR 123 and post the findings as comments"*
> *"List my latest shelvesets"*
> *"Trigger the nightly build on the release branch"*

---

## Coverage

  

One server across the whole development cycle — Plan, Code, Review, Build & Release, Test, Document — with your own templates exposed as MCP resources alongside the built-in tools and prompts. Every write passes a server-side governance layer — readonly mode, dry-run preview, rate limit, and audit log (see [Write Safety](#write-safety)); tools can also be scoped **per role** (see [Restrict tools per role](#restrict-tools-per-role) below).

Full per-tool parameter reference: [Tool Reference ↓](#tool-reference)

### Restrict tools per role

Set `AZURE_DEVOPS_ENABLED_DOMAINS` to a comma-separated list — disabled domains aren't registered, trimming the AI client's tool list and reducing tool-selection confusion. Default loads all 6. `get_current_user` is core and always registered.

| Role | Domains |
|------|---------|
| Project manager | `work_items,wiki` |
| Developer (TFVC) | `work_items,tfvc,pipelines` |
| Developer (Git) | `work_items,git,pipelines` |
| QA / tester | `work_items,test_plans,git` |
| DevOps / release | `work_items,pipelines,git,tfvc` |
| Read-only / analyst | `work_items,wiki` |

Unknown domain names fail at startup — no silent typos. Startup log reports what loaded:

```
Enabled domains (3/6): work_items, tfvc, pipelines
Disabled domains: git, wiki, test_plans
```

---

## TFVC support

**The reason this server exists.** Cloud Azure DevOps disabled new TFVC repos in February 2017, and Microsoft's official MCP server doesn't cover TFVC. If your team is still on Team Foundation Version Control, this is the only MCP server that exposes it natively to AI assistants.

10 dedicated TFVC tools:

- **Shelvesets** — `tfvc_list_shelvesets`, `tfvc_get_shelveset` (file changes + work item links), `tfvc_get_shelveset_file` (shelved, not-yet-checked-in file content — AI review before check-in, a workflow TFVC never had)
- **Changesets** — `tfvc_list_changesets`, `tfvc_get_changeset` (incl. linked work items), `tfvc_get_changeset_changes`
- **Browse, files & diffs** — `tfvc_browse`, `tfvc_get_file` (at any changeset version), `tfvc_get_file_diff` (changed hunks between two changesets)
- **Work-item linkage** — `get_work_item_changesets` (all TFVC changesets touching a work item, with file contents)

Filters accept `@me` where relevant. Requires Code (read & write) PAT scope.

---

## Prompts & Resources

Prompts are reusable, **advisory** workflows surfaced as slash commands in the AI client. Each one instructs the model to gather evidence with the read tools and ground every claim in concrete IDs — producing the report never calls a write tool. One exception by design: `review_pull_request` can afterwards publish its findings as file-anchored PR comments, but only when you explicitly ask, with every comment confirmed before posting. Prompts load on the **same domain axis** as tools, so disabling a domain hides its prompts.

| Domain | Prompt | What it does |
|--------|--------|--------------|
| `git` | `lessons_learned_git` | Root cause / detection / prevention report for a resolved bug, from its history and linked Git commits/PRs |
| `git` | `my_review_queue` | Active PRs assigned to me as a reviewer, project-wide, oldest first (no arguments) |
| `git` | `summarize_pull_request` | Plain-language "what this PR does" summary |
| `git` | `review_pull_request` | Structured advisory review: risks, test gaps, maintainability, questions — on request, publishes findings to the PR as file-anchored comments |
| `git` | `analyze_commit_range` | Release-notes style changelog between two branches |
| `tfvc` | `lessons_learned_tfvc` | Root cause / detection / prevention report for a resolved bug, from its history and linked TFVC changesets |
| `tfvc` | `changeset_summary` | Purpose, files, and scope/risk of a TFVC changeset |
| `work_items` | `work_item_report` | Counts by area + monthly timeline + AI-grouped recurring themes for a work-item filter (`titleContains`/`area`/`workItemTypes`/`days`) |

`lessons_learned` is split per backend (Git vs. TFVC) so each variant names its own read tools; both need `work_items` enabled to read the bug itself.

The table lists 8; a 9th prompt, `risk_impact_analysis`, is conditional — it appears only when a `risk-impact.md` template is present (see [External resources](#external-resources) below).

### External resources

Point `AZURE_DEVOPS_RESOURCE_DIR` at a folder and every `*.md` file in it is exposed as an MCP resource at `template:` (e.g. `release-checklist.md` → `template:release-checklist`; the filename is URI-encoded, so spaces are safe). Use this to share team templates and checklists with the AI without baking them into the server.

One template is wired to a prompt: dropping a **`risk-impact.md`** file in that folder enables the conditional `risk_impact_analysis` prompt, which fills the template from work-item evidence — optionally weighing an actual pending change via its `shelvesetName` argument. No template file → the prompt simply doesn't appear.

---

## Profile-based secrets

`mcp.json` configs sync to the cloud (Claude Desktop, VS Code Settings Sync), get pasted into tickets, end up in dotfile repos. **Inlining `AZURE_DEVOPS_PAT` there is one `git add .` away from a public leak.**

The convention: set `AZURE_DEVOPS_PROFILE=name` in `mcp.json`, keep credentials in a gitignored `.env.` next to the binary. The server resolves the profile name to that file path; `mcp.json` stays free of secrets and is safe to commit.

`.env.product-a` (gitignored):

```env
AZURE_DEVOPS_ORG_URL=https://tfs-1.example.com/tfs/ProductACollection
AZURE_DEVOPS_PROJECT=Product A
AZURE_DEVOPS_PAT=
# Optional per-profile domain restriction
AZURE_DEVOPS_ENABLED_DOMAINS=work_items,tfvc,pipelines
```

`mcp.json` (commitable):

```json
{
  "mcpServers": {
    "ado-product-a": {
      "command": "node",
      "args": ["/path/to/dist/index.js"],
      "env": { "AZURE_DEVOPS_PROFILE": "product-a" }
    }
  }
}
```

### Multi-instance

Once profiles are in place, running multiple ADO instances side-by-side is just adding entries. Each one loads its own `.env.` — own PAT, own project, own domain restriction. Per-process state means audit logs, rate limit counters, and `@me` identity caches never cross between tenants.

```json
{
  "mcpServers": {
    "ado-product-a": {
      "command": "node",
      "args": ["/path/to/dist/index.js"],
      "env": { "AZURE_DEVOPS_PROFILE": "product-a" }
    },
    "ado-product-b": {
      "command": "node",
      "args": ["/path/to/dist/index.js"],
      "env": { "AZURE_DEVOPS_PROFILE": "product-b" }
    }
  }
}
```

Tool names auto-prefix per server — `mcp__ado-product-a__list_repositories` vs `mcp__ado-product-b__list_repositories`.

### Env file precedence

| Set in `mcp.json` | File loaded |
|-------------------|-------------|
| `AZURE_DEVOPS_ENV_FILE=/abs/path` | That exact path |
| `AZURE_DEVOPS_PROFILE=name` | `/.env.name` |
| _(neither)_ | `/.env` |

Variables set directly in `mcp.json`'s `env` block always win over file contents.

Each instance's startup log line `env file: ...` confirms which file was loaded — handy for debugging "which profile did this tool actually call?".

---

## Write Safety

Six layers. The LLM cannot bypass the server-side ones — they short-circuit before any API call fires.

| Layer | Scope | Enable |
|-------|-------|--------|
| **MCP annotations** | All 48 tools tagged with `readOnlyHint` / `destructiveHint` / `idempotentHint` — clients can skip read confirmations, warn on destructive writes | Always on |
| **Confirmation directive** | Every write's description tells the LLM to show payload and ask before calling | Always on |
| **Readonly mode** | Server refuses all 8 write tools with a clear error; reads unaffected. CI, demos, sandbox, emergency stop | `AZURE_DEVOPS_MODE=readonly` |
| **Rate limit** | Global sliding 60s window across all writes — runaway-loop fence, not a throughput regulator | `AZURE_DEVOPS_RATE_LIMIT_WRITES_PER_MIN=10` (default; `0` disables) |
| **Dry-run** | All 8 write tools — pass `dryRun: true` for the literal API payload without firing; `update_work_item` also returns the current values next to the intended ones | Per-call |
| **Audit log** | JSONL append per write: timestamp, tool, user, input, result, `dryRun`, `ok`, `durationMs`, `blocked` reason. Each process opens with a `session_start` header (version, mode, domains, rate limit) so the file interprets itself | `AZURE_DEVOPS_AUDIT_LOG=/path/to/audit.jsonl` |

**Audit privacy:** add `AZURE_DEVOPS_AUDIT_REDACT=1` to keep numeric IDs and field shape but drop all string values (titles, comments, branch names). Useful when work-item content carries classified data.

Plus baseline hardening: WIQL injection sanitization, scrubbed errors (no internal paths/URLs/stack traces in client output), bounded pagination (1-1000).

---

## Privacy & data flow

The server runs entirely locally. ADO API calls go straight from your machine to your Azure DevOps Server. No telemetry, no phone-home, no cloud proxy, no shared analytics.

External destinations are limited to:

1. **Your Azure DevOps Server** — the URL in your `.env`.
2. **Your AI assistant** (Claude, GitHub Copilot, Cursor) — the AI client reads tool outputs as conversation context per its own privacy policy. The MCP server itself never talks to these services.

| Data | Leaves your machine? |
|------|---------------------|
| PAT | ❌ Never — stays in gitignored `.env` / `.env.` |
| Work items, code, commits, shelvesets | ➡ Your ADO Server, then back to your AI assistant |
| Server / URL / project names | ➡ Your AI assistant as part of tool outputs |
| Usage metrics, error logs | ❌ No collection |

Every network call is visible in [`src/`](src/) — they all route through `azure-devops-node-api` pointed at your configured URL.

---

## Cloud (Azure DevOps Services)

Technically works against `dev.azure.com`, but **this server isn't positioned for cloud**:

- **TFVC doesn't exist on cloud** — disabled for new orgs since February 2017.
- **PAT-only auth** — many cloud tenants require Microsoft Entra ID, which this server doesn't yet support.
- **Microsoft ships [`@azure-devops/mcp`](https://github.com/microsoft/azure-devops-mcp)** for cloud — officially maintained, Entra ID, broader cloud-specific coverage.

Use this server against cloud only if you specifically need `@me`, profile-based multi-tenant config, or a tool the official server lacks.

---

## Setup

Pick one path:
- **[Quick Start](#quick-start-npm)** — run from npm, no clone. ~2 minutes.
- **[Enterprise Setup](#enterprise-setup-clone)** — clone, build, pin a commit. For air-gapped or audited environments.

### Prerequisites

- **Node.js ≥ 18**
- **Azure DevOps Server 2022.2** (tested; older versions with REST API 7.x likely work but untested)
- **PAT** with the scopes below. Grant only what you need — omitted scopes make the affected tools fail at call time, but the server still starts.

| Scope | For |
|-------|-----|
| Work Items (read & write) | Work item tools, WIQL queries, statistics |
| Code (read & write) | Git tools, **TFVC tools**, PR creation |
| Build (read & execute) | Pipeline tools, `queue_build` |
| Release (read) | Release listing |
| Test Management (read & write) | Test plans, suites, runs, results; add test cases to a suite |
| Wiki (read) | Wiki tools |

Create the PAT at `https:///_usersSettings/tokens`. Set an expiration ≤ 90 days and rotate regularly.

### Quick Start (npm)

> **No public npm access?** Skip to [Enterprise Setup](#enterprise-setup-clone) — it builds from source and can use an internal npm mirror.

**1. Credential file** — create `~/.azure-devops-mcp.env` (Linux/macOS) or `C:\Users\you\.azure-devops-mcp.env` (Windows):

```env
AZURE_DEVOPS_ORG_URL=https://your-tfs-server/tfs/YourCollection
AZURE_DEVOPS_PROJECT=YourProjectName
AZURE_DEVOPS_PAT=your_pat_token
# AZURE_DEVOPS_SSL_IGNORE=true   # uncomment for self-signed certs
```

**2. Register with your AI client.** Shortest paths:

#### VS Code — one-click install

  
    
  

#### Claude Code — one command

```bash
claude mcp add azure-devops --env AZURE_DEVOPS_ENV_FILE=$HOME/.azure-devops-mcp.env -- npx -y @burcusg/azure-devops-mcp-onprem
```

#### Other clients (Claude Desktop / Cursor / Antigravity / Codex CLI)

JSON config — see [Configure AI client](#configure-ai-client) below.

### Enterprise Setup (clone)

```bash
git clone https://github.com/burcusipahioglu/azure-devops-mcp-onprem.git
cd azure-devops-mcp-onprem
npm install
npm run build
cp .env.example .env       # copy .env.example .env on Windows
# fill in .env with your TFS details
npm start                  # smoke-test the connection — Ctrl+C to stop
```

Expected stderr on startup:

```
Azure DevOps MCP Server "CompanyOrg" running on stdio
env file: /path/to/.env
Enabled domains (6/6): work_items, git, tfvc, pipelines, wiki, test_plans
External resources loaded: 0
Authenticated as: Your Name (your.email@company.com)
```

Then point your AI client at `dist/index.js` (see below). No `env` block needed — the server reads `.env` from the repo root.

### Configure AI client

> ⚠ **Never inline `AZURE_DEVOPS_PAT` / `AZURE_DEVOPS_ORG_URL` / `AZURE_DEVOPS_PROJECT` in client configs.** Client configs sync to the cloud (Claude Desktop sync, VS Code Settings Sync) or get pasted into tickets. Use `AZURE_DEVOPS_ENV_FILE` (Quick Start) or `.env` in the repo (Enterprise Setup). For multiple TFS instances see [Profile-based secrets](#profile-based-secrets).

| Client | Path |
|--------|------|
| **VS Code** | Includes `.vscode/mcp.json`. Copilot Chat → Agent mode (`Ctrl+Shift+I`) |
| **GitHub Copilot CLI** | `/mcp add` (

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [burcusipahioglu](https://github.com/burcusipahioglu)
- **Source:** [burcusipahioglu/azure-devops-mcp-onprem](https://github.com/burcusipahioglu/azure-devops-mcp-onprem)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-burcusipahioglu-azure-devops-mcp-onprem
- Seller: https://agentstack.voostack.com/s/burcusipahioglu
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
