You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

cursor-azure-devops-mcp

Package Overview
Dependencies
Maintainers
0
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cursor-azure-devops-mcp - npm Package Compare versions

Comparing version

to
1.0.6

75

build/azure-devops-service.js

@@ -217,2 +217,77 @@ import * as azdev from 'azure-devops-node-api';

/**
* Get all links associated with a work item (parent, child, related, etc.)
* @param workItemId The ID of the work item
* @returns Object with work item links grouped by relationship type
*/
async getWorkItemLinks(workItemId) {
await this.initialize();
if (!this.workItemClient) {
throw new Error('Work item client not initialized');
}
// Get work item with relations
const workItem = await this.workItemClient.getWorkItem(workItemId, undefined, undefined, 4 // 4 = WorkItemExpand.Relations in the SDK
);
if (!workItem || !workItem.relations) {
return {};
}
// Filter for work item link relations (exclude attachments and hyperlinks)
const linkRelations = workItem.relations.filter((relation) => relation.rel.includes('Link') &&
relation.rel !== 'AttachedFile' &&
relation.rel !== 'Hyperlink');
// Group relations by relationship type
const groupedRelations = {};
linkRelations.forEach((relation) => {
const relType = relation.rel;
// Extract work item ID from URL
// URL format is typically like: https://dev.azure.com/{org}/{project}/_apis/wit/workItems/{id}
let targetId = 0;
try {
const urlParts = relation.url.split('/');
targetId = parseInt(urlParts[urlParts.length - 1], 10);
}
catch (error) {
console.error('Failed to extract work item ID from URL:', relation.url);
}
if (!groupedRelations[relType]) {
groupedRelations[relType] = [];
}
const workItemLink = {
...relation,
targetId,
title: relation.attributes?.name || `Work Item ${targetId}`,
};
groupedRelations[relType].push(workItemLink);
});
return groupedRelations;
}
/**
* Get all linked work items with their full details
* @param workItemId The ID of the work item to get links from
* @returns Array of work items that are linked to the specified work item
*/
async getLinkedWorkItems(workItemId) {
await this.initialize();
if (!this.workItemClient) {
throw new Error('Work item client not initialized');
}
// First get all links
const linkGroups = await this.getWorkItemLinks(workItemId);
// Extract all target IDs from all link groups
const linkedIds = [];
Object.values(linkGroups).forEach(links => {
links.forEach(link => {
if (link.targetId > 0) {
linkedIds.push(link.targetId);
}
});
});
// If no linked items found, return empty array
if (linkedIds.length === 0) {
return [];
}
// Get the full work item details for all linked items
const linkedWorkItems = await this.getWorkItems(linkedIds);
return linkedWorkItems;
}
/**
* Get detailed changes for a pull request

@@ -219,0 +294,0 @@ */

@@ -350,2 +350,30 @@ #!/usr/bin/env node

});
// New tool for work item links
server.tool('azure_devops_work_item_links', 'Get links for a specific work item', {
id: z.number().describe('Work item ID'),
}, async ({ id }) => {
const result = await azureDevOpsService.getWorkItemLinks(id);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
});
// New tool for linked work items with full details
server.tool('azure_devops_linked_work_items', 'Get all linked work items with their full details', {
id: z.number().describe('Work item ID'),
}, async ({ id }) => {
const result = await azureDevOpsService.getLinkedWorkItems(id);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
});
// New tool for pull request changes with file contents

@@ -550,2 +578,4 @@ server.tool('azure_devops_pull_request_changes', 'Get detailed code changes for a pull request', {

console.error('- azure_devops_work_item_attachments: Get attachments for a work item');
console.error('- azure_devops_work_item_links: Get links for a work item');
console.error('- azure_devops_linked_work_items: Get all linked work items with their full details');
console.error('- azure_devops_pull_request_changes: Get detailed code changes for a pull request');

@@ -552,0 +582,0 @@ console.error('- azure_devops_pull_request_file_content: Get content of a specific file in chunks (for large files)');

@@ -160,2 +160,30 @@ #!/usr/bin/env node

});
// New tool for work item links
server.tool('azure_devops_work_item_links', 'Get links for a specific work item', {
id: z.number().describe('Work item ID'),
}, async ({ id }) => {
const result = await azureDevOpsService.getWorkItemLinks(id);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
});
// New tool for linked work items with full details
server.tool('azure_devops_linked_work_items', 'Get all linked work items with their full details', {
id: z.number().describe('Work item ID'),
}, async ({ id }) => {
const result = await azureDevOpsService.getLinkedWorkItems(id);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
});
// New tool for pull request changes with file contents

@@ -162,0 +190,0 @@ server.tool('azure_devops_pull_request_changes', 'Get detailed code changes for a pull request', {

2

package.json
{
"name": "cursor-azure-devops-mcp",
"version": "1.0.5",
"version": "1.0.6",
"description": "MCP Server for Cursor IDE-Azure DevOps Integration",

@@ -5,0 +5,0 @@ "main": "build/index.js",