Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,10 @@ This project implements an MCP server that exposes tools for querying and managi

| Tool | Description |
|------|-------------|
| `get_work_item` | Gets details of a specific work item by ID |
| `get_work_items` | Gets multiple work items by IDs (batch retrieval) |
| `get_work_item` | Gets details of a specific work item by ID (supports optional `includeRelations` parameter) |
| `get_work_items` | Gets multiple work items by IDs (batch retrieval, supports optional `includeRelations` parameter) |
| `get_work_item_relations` | Gets the normalized list of relationships (Parent, Child, Related, Predecessor, Successor, Tests, Tested By, Hyperlink, Attachment) associated with a work item |
| `get_work_item_tree` | Recursively gets parent and child work items starting from a root work item, up to a specified depth limit. Includes cycle detection |
| `query_work_items` | Queries work items using WIQL (Work Item Query Language) |
| `get_work_items_by_state` | Filters work items by state (Active, New, Closed, etc.) |
| `get_work_items_assigned_to` | Gets work items assigned to a specific user |
Expand Down
60 changes: 60 additions & 0 deletions docs/workitem-relations-analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Technical Analysis: Azure DevOps Work Item Relationship Collection

**Feature:** Work Item Relationship Collection Visibility
**Target Repository:** `SouzaEduardoAC/mcp-azure-devops`
**Phase:** 2a — Discovery & Forensic Analysis

---

## 1. Codebase Forensics & Current Architecture

### Existing Code Structure
- **Service Layer (`AzureDevOpsService.cs`):**
- Uses `Microsoft.TeamFoundation.WorkItemTracking.WebApi.WorkItemTrackingHttpClient` to communicate with Azure DevOps.
- In `GetWorkItemAsync` and `GetWorkItemsAsync`, calls `WitClient.GetWorkItemAsync(..., expand: WorkItemExpand.All)` which already retrieves the complete `relations` array from Azure DevOps REST API.
- `MapToDto` currently iterates over `workItem.Relations` solely to extract `ParentId` (from `System.LinkTypes.Hierarchy-Reverse`), `LinkedCommits` (from `vstfs:///Git/Commit/...`), and `LinkedPullRequests` (from `vstfs:///Git/PullRequestId/...`).
- All other relations (such as `System.LinkTypes.Related`, `System.LinkTypes.Dependency-Forward`/`Reverse`, `Microsoft.VSTS.Common.TestedBy-Forward`/`Reverse`) are currently discarded during DTO projection.

- **DTO Models (`WorkItemDto.cs`, `WorkItemSummaryDto.cs`):**
- `WorkItemDto` currently lacks a `Relations` property.
- `WorkItemSummaryDto` contains basic scalar fields (`Id`, `Title`, `State`, `AssignedTo`, `ParentId`).

- **MCP Tools (`WorkItemTools.cs`):**
- `link_work_items` tool already exists for creating links (supporting relation types: `parent`, `child`, `predecessor`, `successor`, `related`).
- Read tools (`get_work_item`, `get_work_items`, `query_work_items`, `get_child_work_items`) do not return normalized relation collections.

---

## 2. Target API & Relation Type Normalization

### Azure DevOps Relation Types (`rel`)

| Raw Azure DevOps `rel` URI | Normalized Name | Directional Meaning |
| :--- | :--- | :--- |
| `System.LinkTypes.Hierarchy-Reverse` | `Parent` | Item's parent work item |
| `System.LinkTypes.Hierarchy-Forward` | `Child` | Item's child work item |
| `System.LinkTypes.Related` | `Related` | Bilateral link (e.g., origin defect link) |
| `System.LinkTypes.Dependency-Reverse` | `Predecessor` | Blocking item that must finish first |
| `System.LinkTypes.Dependency-Forward` | `Successor` | Blocked item depending on this |
| `Microsoft.VSTS.Common.TestedBy-Forward` | `Tested By` | Test Case testing this requirement |
| `Microsoft.VSTS.Common.TestedBy-Reverse` | `Tests` | Requirement tested by this test case |
| `Hyperlink` | `Hyperlink` | External web URL |
| `AttachedFile` | `Attachment` | File attachment |

### ID Extraction Heuristics
Target URLs for work items follow the format:
`https://dev.azure.com/{organization}/{project}/_apis/wit/workItems/{targetId}`
`TargetId` can be parsed via standard regex or string segment parsing (`/workItems/(\d+)$`).

---

## 3. Impact & Risk Analysis

1. **Zero Extra REST Calls for Single/Batch Fetch:** Because `WitClient.GetWorkItemAsync` and `GetWorkItemsAsync` use `WorkItemExpand.All`, relation parsing occurs entirely in-memory without extra network calls.
2. **Token Efficiency:** Adding `includeRelations: false` by default preserves lightweight JSON responses for existing LLM prompts while allowing targeted inspection when relationship visibility is needed.
3. **Cycle Safety in Hierarchy Trees:** Recursive tree retrieval (`get_work_item_tree`) must track visited work item IDs (`HashSet<int>`) to prevent infinite recursion if invalid or circular link graphs exist.

---

## 4. Next Steps
Upon approval of this Technical Analysis (`discovery` gate), Phase 2b Architecture & ADR will specify the exact C# DTO contracts, interface additions, and unit testing strategy.
147 changes: 147 additions & 0 deletions docs/workitem-relations-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Architecture Decision Record (ADR) & Implementation Plan: Work Item Relationship Collection

**Feature Title:** Azure DevOps Work Item Relationship Collection Visibility
**Target Repository:** `SouzaEduardoAC/mcp-azure-devops`
**Phase:** 2b — Architecture & Design Specifications
**Status:** Proposed

---

## 1. Context & Architectural Strategy

Work items in Azure DevOps use relation collections to capture links between items. Currently, `mcp-azure-devops` strips out relation arrays during `MapToDto` except for parent ID, commit links, and pull request links.

To allow LLMs to trace defect origins, inspect parent/child hierarchies, analyze predecessor/successor blockers, and inspect test links, we are introducing structured relationship visibility into the MCP server.

---

## 2. Architectural Decisions (ADRs)

### ADR 001: Relation Type Normalization
Raw Azure DevOps relation URIs can be verbose (e.g. `System.LinkTypes.Hierarchy-Forward`, `Microsoft.VSTS.Common.TestedBy-Forward`).

**Decision:** We will map relation strings to standardized, human- and LLM-friendly aliases while retaining `rawRel` for full transparency:

```csharp
private static readonly Dictionary<string, string> RelationTypeMappings = new(StringComparer.OrdinalIgnoreCase)
{
["System.LinkTypes.Hierarchy-Reverse"] = "Parent",
["System.LinkTypes.Hierarchy-Forward"] = "Child",
["System.LinkTypes.Related"] = "Related",
["System.LinkTypes.Dependency-Reverse"] = "Predecessor",
["System.LinkTypes.Dependency-Forward"] = "Successor",
["Microsoft.VSTS.Common.TestedBy-Forward"] = "Tested By",
["Microsoft.VSTS.Common.TestedBy-Reverse"] = "Tests",
["Hyperlink"] = "Hyperlink",
["AttachedFile"] = "Attachment"
};
```

---

### ADR 002: Dedicated `get_work_item_relations` MCP Tool
**Decision:** Create a dedicated tool `get_work_item_relations` tailored specifically for relationship inspection.
- **Parameters:**
- `workItemId` (int, required)
- `relationTypeFilter` (string, optional): Filter by `"Related"`, `"Parent"`, `"Child"`, `"Predecessor"`, `"Successor"`, `"Tests"`, `"Tested By"`.
- `expandTargetSummary` (bool, optional, default: `false`): When `true`, fetches the target work item title, state, and type inline using batch `WitClient.GetWorkItemsAsync`.
- `project` (string, optional)
- `organization` (string, optional)

---

### ADR 003: Recursive Hierarchy Tree Tool `get_work_item_tree`
**Decision:** Provide `get_work_item_tree` to render recursive Parent/Child trees for Epics, Features, User Stories, and Tasks.
- **Parameters:**
- `workItemId` (int, required)
- `maxDepth` (int, optional, default: 2, max: 5)
- `project` (string, optional)
- `organization` (string, optional)
- **Cycle Safety:** Employs a `HashSet<int> visitedWorkItemIds` during traversal to prevent infinite loops if circular relationships exist.

---

### ADR 004: Opt-In Extension on `get_work_item` & `get_work_items`
**Decision:** Add `includeRelations` (bool, default: `false`) to `GetWorkItem` and `GetWorkItems` tools.
When `includeRelations: true`, `WorkItemDto` populates its `Relations` property (`List<WorkItemRelationDto>`).

---

## 3. Data Transfer Object (DTO) Contracts

### `WorkItemRelationDto.cs`
```csharp
namespace Viamus.Azure.Devops.Mcp.Server.Models;

public sealed record WorkItemRelationDto
{
public string RelationType { get; init; } = null!;
public string RawRel { get; init; } = null!;
public int? TargetId { get; init; }
public string? TargetUrl { get; init; }
public string? Comment { get; init; }
public WorkItemSummaryDto? TargetSummary { get; init; }
}

public sealed record WorkItemRelationsResultDto
{
public int WorkItemId { get; init; }
public int Count { get; init; }
public IReadOnlyList<WorkItemRelationDto> Relations { get; init; } = [];
}

public sealed record WorkItemTreeNodeDto
{
public WorkItemDto WorkItem { get; init; } = null!;
public IReadOnlyList<WorkItemTreeNodeDto> Children { get; init; } = [];
}
```

---

## 4. Modified Component Map

```
┌────────────────────────────────────────────────────────┐
│ WorkItemTools.cs │
│ - get_work_item_relations (NEW) │
│ - get_work_item_tree (NEW) │
│ - get_work_item (UPDATED: includeRelations) │
│ - get_work_items (UPDATED: includeRelations) │
└──────────────────────────┬─────────────────────────────┘
┌────────────────────────────────────────────────────────┐
│ IAzureDevOpsService.cs │
│ - GetWorkItemRelationsAsync (NEW) │
│ - GetWorkItemTreeAsync (NEW) │
│ - GetWorkItemAsync (UPDATED: includeRelations) │
│ - GetWorkItemsAsync (UPDATED: includeRelations) │
└──────────────────────────┬─────────────────────────────┘
┌────────────────────────────────────────────────────────┐
│ AzureDevOpsService.cs │
│ - MapToDto (UPDATED: relation parsing logic) │
│ - ParseRelations (NEW static helper) │
└────────────────────────────────────────────────────────┘
```

---

## 5. Verification & Testing Plan

### Automated Unit Tests
- `WorkItemRelationTests.cs`:
- Tests relation type normalization for all known Azure DevOps relation URIs.
- Tests `TargetId` parsing from URLs.
- Tests `MapToDto` with `includeRelations = true`.
- Tests `get_work_item_tree` cycle detection on self-referential or cyclic links.

---

## 6. Definition of Done
- [x] Architecture & ADR drafted and saved to `docs/workitem-relations-architecture.md`.
- [ ] Sign-off received for `plan` gate via `request_approval`.
- [ ] Phase 3 Compliance Evaluation complete.
- [ ] Phase 4 Implementation & Peer Review complete.
136 changes: 136 additions & 0 deletions docs/workitem-relations-prd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Product Requirements Document (PRD): Work Item Relationship Collection Visibility

**Feature Title:** Azure DevOps Work Item Relationship Collection (Related, Parent, Child, Predecessor, Successor, Tests)
**Target Repository:** `SouzaEduardoAC/mcp-azure-devops` (Forked from `viamus/mcp-azure-devops`)
**Document Status:** Draft — Pending Phase 1 Gate Sign-off

---

## 1. Executive Summary & Problem Statement

In Azure DevOps, work items are linked via rich relationship collections (`System.LinkTypes.Hierarchy-Reverse` [Parent], `System.LinkTypes.Hierarchy-Forward` [Child], `System.LinkTypes.Related` [Related Work], `System.LinkTypes.Dependency-Reverse` [Predecessor], `System.LinkTypes.Dependency-Forward` [Successor], `Microsoft.VSTS.Common.TestedBy-Forward`/`Reverse` [Tests/Tested By], etc.).

Currently, when LLMs query work items via `mcp-azure-devops` tools (`get_work_item`, `get_work_items`, `query_work_items`), the returned work item model omits the `relations` collection. Consequently, LLM agents have zero visibility into linked items.

### Business & Workflow Context
When a work item (e.g., User Story or Feature) encounters an issue during implementation or QA, engineering teams create a related work item (e.g., Bug or Issue) linked directly to the defective one to track origin and traceability.
Without relationship visibility in `mcp-azure-devops`:
- Downstream LLM agents cannot trace defects back to their originating work item.
- LLMs cannot understand hierarchy trees (Parent Epics / Child Tasks) or blocking dependencies (Predecessors / Successors).
- LLMs cannot verify test coverage links (Tested By / Tests).

This PRD specifies the functional requirements to expose work item relationship collections in `mcp-azure-devops`.

---

## 2. Target Users & Use Cases

### Target Users
- **LLM Bug & Origin Traceability Agents:** AI assistants identifying defect origins, duplicate issues, and root causes across related work items.
- **Project & Portfolio Management AI:** Agents analyzing parent/child breakdown, epic completion, and dependency blockers.
- **QA Automation & Test Analysts:** LLMs verifying whether work items have associated test cases or bug reports attached.

### Key Use Cases
1. **Defect Origin Tracing:** An LLM inspects a Bug work item, finds its `Related` or `Parent` work item, and determines which original user story or task introduced the defective code.
2. **Hierarchy & Epic Breakdown:** An LLM queries a Parent Feature to list all Child User Stories and Tasks to generate progress reports.
3. **Dependency Analysis:** An LLM inspects a work item's `Predecessor` links to identify unblocked tasks or potential delivery bottlenecks.

---

## 3. Scope & Requirements (MoSCoW)

### 3.1 Must Have (V1 Scope)

#### 1. Relation Model & Type Normalization
Map raw Azure DevOps relation URIs / relation types to clean, user-friendly relationship names:

| Azure DevOps Relation Type (`rel`) | Normalized Name | Description |
| :--- | :--- | :--- |
| `System.LinkTypes.Hierarchy-Reverse` | `Parent` | Parent work item in hierarchy |
| `System.LinkTypes.Hierarchy-Forward` | `Child` | Child work item in hierarchy |
| `System.LinkTypes.Related` | `Related` | Direct bilateral relationship (e.g. bug tracking origin) |
| `System.LinkTypes.Dependency-Reverse` | `Predecessor` | Work item that must be completed prior |
| `System.LinkTypes.Dependency-Forward` | `Successor` | Work item dependent on this item |
| `Microsoft.VSTS.Common.TestedBy-Forward` | `Tested By` | Test Case testing this work item |
| `Microsoft.VSTS.Common.TestedBy-Reverse` | `Tests` | Work item tested by this test case |
| `Hyperlink` | `Hyperlink` | External web URL link |
| `AttachedFile` | `Attachment` | File attachment link |

#### 2. `WorkItemRelation` Data Model
```json
{
"relationType": "Related",
"rawRel": "System.LinkTypes.Related",
"targetId": 1234,
"targetUrl": "https://dev.azure.com/org/proj/_apis/wit/workItems/1234",
"comment": "Origin bug reported during Sprint 5 testing"
}
```

#### 3. Azure DevOps REST Integration
- Use `$expand=relations` parameter on Azure DevOps WIT REST API endpoints (`GET _apis/wit/workitems/{id}?$expand=relations` and `GET _apis/wit/workitems?ids={ids}&$expand=relations`).
- Parse the `relations` JSON array returned by Azure DevOps.

#### 4. Dedicated MCP Tool: `get_work_item_relations`
- **Name:** `get_work_item_relations`
- **Parameters:**
- `workItemId` (integer, required): ID of the work item.
- `relationTypeFilter` (string, optional): Filter by normalized relation type (e.g. `"Related"`, `"Parent"`, `"Child"`, `"Predecessor"`, `"Successor"`).
- `project` (string, optional): Azure DevOps project.
- `organization` (string, optional): Azure DevOps organization.
- **Returns:** List of normalized `WorkItemRelation` objects, with target work item summary metadata (ID, Title, WorkItemType, State) expanded where applicable.

#### 5. Opt-in `includeRelations` Parameter on Existing Query Tools
- Add optional `includeRelations` (boolean, default: `false`) parameter to:
- `get_work_item`
- `get_work_items`
- `query_work_items`
- When `includeRelations: true`, populate a `relations` list on each returned `WorkItemDto`.

---

### 3.2 Should Have (V1 Scope)
- **`get_work_item_tree` Tool:**
- Recursively fetches `Parent` and `Child` relationships up to a configurable `depth` (default: 2, max: 5) to return a full tree structure for Epics/Features/Stories/Tasks.

---

### 3.3 Could Have (V1.1 Scope)
- Summary counts of relations per type (e.g., `relatedCount`, `childCount`, `bugCount`) embedded directly in basic `WorkItemDto`.

---

### 3.4 Won't Have (Out of V1 Scope)
- Relation creation/deletion (writing link updates to Azure DevOps). V1 focuses exclusively on visibility and read queries for LLMs.

---

## 4. Technical Constraints & Performance Considerations

1. **REST API Batching:**
- Azure DevOps API supports `$expand=relations` on batch work item calls (`/workitems?ids=1,2,3&$expand=relations`).
- Using `$expand=relations` on single or bulk GETs requires zero extra HTTP calls per work item.
2. **Backward Compatibility:**
- `includeRelations` defaults to `false` on existing query endpoints to ensure existing JSON contracts and prompt token consumption remain optimized.
3. **Target ID Extraction:**
- Azure DevOps relation objects contain `url` like `https://dev.azure.com/org/project/_apis/wit/workItems/42`. `targetId` must be reliably extracted via regex/URL parsing (`/workItems/(\d+)$`).

---

## 5. RICE Prioritization

| Feature Component | Reach | Impact | Confidence | Effort | RICE Score |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **`WorkItemRelation` model & `$expand=relations` REST integration** | High (100%) | Massive (3.0) | High (100%) | Low (2) | **150.0** |
| **`get_work_item_relations` tool** | High (100%) | High (2.0) | High (100%) | Low (1) | **200.0** |
| **`includeRelations` flag on `get_work_item(s)` / `query_work_items`** | High (80%) | High (2.0) | High (95%) | Low (1) | **152.0** |
| **`get_work_item_tree` tool** | Medium (50%) | Medium (1.0) | High (90%) | Medium (2) | **22.5** |

---

## 6. Definition of Done (Phase 1 Exit Criteria)

- [x] PRD written to `docs/workitem-relations-prd.md`.
- [ ] PRD submitted for human review (`prd` gate).
- [ ] Approval received via `/squad:approve prd`.
- [ ] Phase 2 Architecture & ADR design initiated.
5 changes: 5 additions & 0 deletions src/Viamus.Azure.Devops.Mcp.Server/Models/WorkItemDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public sealed record WorkItemDto
/// List of pull request IDs linked to this work item.
/// </summary>
public List<WorkItemPullRequestLinkDto>? LinkedPullRequests { get; init; }

/// <summary>
/// List of all normalized relationships associated with this work item.
/// </summary>
public List<WorkItemRelationDto>? Relations { get; init; }
}

/// <summary>
Expand Down
Loading
Loading