@mcp-consultant-tools/azure-devops 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/AzureDevOpsService.d.ts +183 -0
- package/build/AzureDevOpsService.d.ts.map +1 -0
- package/build/AzureDevOpsService.js +596 -0
- package/build/AzureDevOpsService.js.map +1 -0
- package/build/index.d.ts +20 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +75 -0
- package/build/index.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
export interface AzureDevOpsConfig {
|
|
2
|
+
organization: string;
|
|
3
|
+
pat: string;
|
|
4
|
+
projects: string[];
|
|
5
|
+
apiVersion?: string;
|
|
6
|
+
enableWorkItemWrite?: boolean;
|
|
7
|
+
enableWorkItemDelete?: boolean;
|
|
8
|
+
enableWikiWrite?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface AdoApiCollectionResponse<T> {
|
|
11
|
+
value: T[];
|
|
12
|
+
count?: number;
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}
|
|
15
|
+
export declare class AzureDevOpsService {
|
|
16
|
+
private config;
|
|
17
|
+
private baseUrl;
|
|
18
|
+
private searchUrl;
|
|
19
|
+
private authHeader;
|
|
20
|
+
private apiVersion;
|
|
21
|
+
constructor(config: AzureDevOpsConfig);
|
|
22
|
+
/**
|
|
23
|
+
* Validate that a project is in the allowed list
|
|
24
|
+
*/
|
|
25
|
+
private validateProject;
|
|
26
|
+
/**
|
|
27
|
+
* Make an authenticated request to the Azure DevOps API
|
|
28
|
+
*/
|
|
29
|
+
private makeRequest;
|
|
30
|
+
/**
|
|
31
|
+
* Convert a git path (returned by search) to a wiki path (used by get-page API)
|
|
32
|
+
* Git paths use dashes and .md extensions: /Release-Notes/Page-Name.md
|
|
33
|
+
* Wiki paths use spaces and no extensions: /Release Notes/Page Name
|
|
34
|
+
* @param gitPath The git path from search results
|
|
35
|
+
* @returns The wiki path for use with get-page API
|
|
36
|
+
*/
|
|
37
|
+
private convertGitPathToWikiPath;
|
|
38
|
+
/**
|
|
39
|
+
* Count occurrences of a string in content
|
|
40
|
+
* @param content The content to search in
|
|
41
|
+
* @param searchStr The string to search for
|
|
42
|
+
* @returns Number of occurrences
|
|
43
|
+
*/
|
|
44
|
+
private countOccurrences;
|
|
45
|
+
/**
|
|
46
|
+
* Get locations where a string appears in content
|
|
47
|
+
* @param content The content to search in
|
|
48
|
+
* @param searchStr The string to search for
|
|
49
|
+
* @returns Formatted string showing line numbers and context
|
|
50
|
+
*/
|
|
51
|
+
private getMatchLocations;
|
|
52
|
+
/**
|
|
53
|
+
* Generate a unified diff showing changes
|
|
54
|
+
* @param oldContent Original content
|
|
55
|
+
* @param newContent Updated content
|
|
56
|
+
* @param oldStr The string that was replaced
|
|
57
|
+
* @param newStr The replacement string
|
|
58
|
+
* @returns Formatted diff output
|
|
59
|
+
*/
|
|
60
|
+
private generateUnifiedDiff;
|
|
61
|
+
/**
|
|
62
|
+
* Escape special regex characters
|
|
63
|
+
* @param str String to escape
|
|
64
|
+
* @returns Escaped string safe for use in regex
|
|
65
|
+
*/
|
|
66
|
+
private escapeRegExp;
|
|
67
|
+
/**
|
|
68
|
+
* Truncate a string for display
|
|
69
|
+
* @param str String to truncate
|
|
70
|
+
* @param maxLen Maximum length
|
|
71
|
+
* @returns Truncated string with ellipsis if needed
|
|
72
|
+
*/
|
|
73
|
+
private truncate;
|
|
74
|
+
/**
|
|
75
|
+
* Get all wikis in a project
|
|
76
|
+
* @param project The project name
|
|
77
|
+
* @returns List of wikis in the project
|
|
78
|
+
*/
|
|
79
|
+
getWikis(project: string): Promise<any>;
|
|
80
|
+
/**
|
|
81
|
+
* Search wiki pages across projects
|
|
82
|
+
* @param searchText The text to search for
|
|
83
|
+
* @param project Optional project filter
|
|
84
|
+
* @param maxResults Maximum number of results (default: 25)
|
|
85
|
+
* @returns Search results with highlighted content
|
|
86
|
+
*/
|
|
87
|
+
searchWikiPages(searchText: string, project?: string, maxResults?: number): Promise<any>;
|
|
88
|
+
/**
|
|
89
|
+
* Get a specific wiki page with content
|
|
90
|
+
* @param project The project name
|
|
91
|
+
* @param wikiId The wiki identifier (ID or name)
|
|
92
|
+
* @param pagePath The path to the page (e.g., "/Setup/Authentication")
|
|
93
|
+
* Accepts both wiki paths (with spaces) and git paths (with dashes and .md)
|
|
94
|
+
* @param includeContent Include page content (default: true)
|
|
95
|
+
* @returns Wiki page with content and metadata
|
|
96
|
+
*/
|
|
97
|
+
getWikiPage(project: string, wikiId: string, pagePath: string, includeContent?: boolean): Promise<any>;
|
|
98
|
+
/**
|
|
99
|
+
* Create a new wiki page
|
|
100
|
+
* @param project The project name
|
|
101
|
+
* @param wikiId The wiki identifier
|
|
102
|
+
* @param pagePath The path for the new page (will be normalized to wiki format)
|
|
103
|
+
* @param content The markdown content
|
|
104
|
+
* @returns Created page information
|
|
105
|
+
*/
|
|
106
|
+
createWikiPage(project: string, wikiId: string, pagePath: string, content: string): Promise<any>;
|
|
107
|
+
/**
|
|
108
|
+
* Update an existing wiki page
|
|
109
|
+
* @param project The project name
|
|
110
|
+
* @param wikiId The wiki identifier
|
|
111
|
+
* @param pagePath The path to the page (will be normalized to wiki format)
|
|
112
|
+
* @param content The updated markdown content
|
|
113
|
+
* @param version The ETag/version for optimistic concurrency (recommended to prevent conflicts)
|
|
114
|
+
* @returns Updated page information
|
|
115
|
+
*/
|
|
116
|
+
updateWikiPage(project: string, wikiId: string, pagePath: string, content: string, version?: string): Promise<any>;
|
|
117
|
+
/**
|
|
118
|
+
* Replace a specific string in a wiki page without rewriting entire content
|
|
119
|
+
* @param project The project name
|
|
120
|
+
* @param wikiId The wiki identifier
|
|
121
|
+
* @param pagePath The path to the page (will be normalized to wiki format)
|
|
122
|
+
* @param oldStr The exact string to replace
|
|
123
|
+
* @param newStr The replacement string
|
|
124
|
+
* @param replaceAll If true, replace all occurrences; if false, old_str must be unique
|
|
125
|
+
* @param description Optional description of the change for audit logging
|
|
126
|
+
* @returns Result with diff, occurrence count, version, and message
|
|
127
|
+
*/
|
|
128
|
+
strReplaceWikiPage(project: string, wikiId: string, pagePath: string, oldStr: string, newStr: string, replaceAll?: boolean, description?: string): Promise<any>;
|
|
129
|
+
/**
|
|
130
|
+
* Get a work item by ID with full details
|
|
131
|
+
* @param project The project name
|
|
132
|
+
* @param workItemId The work item ID
|
|
133
|
+
* @returns Complete work item details
|
|
134
|
+
*/
|
|
135
|
+
getWorkItem(project: string, workItemId: number): Promise<any>;
|
|
136
|
+
/**
|
|
137
|
+
* Query work items using WIQL (Work Item Query Language)
|
|
138
|
+
* @param project The project name
|
|
139
|
+
* @param wiql The WIQL query string
|
|
140
|
+
* @param maxResults Maximum number of results (default: 200)
|
|
141
|
+
* @returns Work items matching the query
|
|
142
|
+
*/
|
|
143
|
+
queryWorkItems(project: string, wiql: string, maxResults?: number): Promise<any>;
|
|
144
|
+
/**
|
|
145
|
+
* Get comments/discussion for a work item
|
|
146
|
+
* @param project The project name
|
|
147
|
+
* @param workItemId The work item ID
|
|
148
|
+
* @returns List of comments
|
|
149
|
+
*/
|
|
150
|
+
getWorkItemComments(project: string, workItemId: number): Promise<any>;
|
|
151
|
+
/**
|
|
152
|
+
* Add a comment to a work item
|
|
153
|
+
* @param project The project name
|
|
154
|
+
* @param workItemId The work item ID
|
|
155
|
+
* @param commentText The comment text (supports markdown)
|
|
156
|
+
* @returns Created comment information
|
|
157
|
+
*/
|
|
158
|
+
addWorkItemComment(project: string, workItemId: number, commentText: string): Promise<any>;
|
|
159
|
+
/**
|
|
160
|
+
* Update a work item using JSON Patch operations
|
|
161
|
+
* @param project The project name
|
|
162
|
+
* @param workItemId The work item ID
|
|
163
|
+
* @param patchOperations Array of JSON Patch operations
|
|
164
|
+
* @returns Updated work item
|
|
165
|
+
*/
|
|
166
|
+
updateWorkItem(project: string, workItemId: number, patchOperations: any[]): Promise<any>;
|
|
167
|
+
/**
|
|
168
|
+
* Create a new work item
|
|
169
|
+
* @param project The project name
|
|
170
|
+
* @param workItemType The work item type (e.g., "Bug", "Task", "User Story")
|
|
171
|
+
* @param fields Object with field values (e.g., { "System.Title": "Bug title" })
|
|
172
|
+
* @returns Created work item
|
|
173
|
+
*/
|
|
174
|
+
createWorkItem(project: string, workItemType: string, fields: any): Promise<any>;
|
|
175
|
+
/**
|
|
176
|
+
* Delete a work item
|
|
177
|
+
* @param project The project name
|
|
178
|
+
* @param workItemId The work item ID
|
|
179
|
+
* @returns Deletion confirmation
|
|
180
|
+
*/
|
|
181
|
+
deleteWorkItem(project: string, workItemId: number): Promise<any>;
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=AzureDevOpsService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AzureDevOpsService.d.ts","sourceRoot":"","sources":["../src/AzureDevOpsService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
export class AzureDevOpsService {
|
|
3
|
+
config;
|
|
4
|
+
baseUrl;
|
|
5
|
+
searchUrl;
|
|
6
|
+
authHeader;
|
|
7
|
+
apiVersion;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.config = {
|
|
10
|
+
...config,
|
|
11
|
+
apiVersion: config.apiVersion || '7.1',
|
|
12
|
+
enableWorkItemWrite: config.enableWorkItemWrite ?? false,
|
|
13
|
+
enableWorkItemDelete: config.enableWorkItemDelete ?? false,
|
|
14
|
+
enableWikiWrite: config.enableWikiWrite ?? false
|
|
15
|
+
};
|
|
16
|
+
this.baseUrl = `https://dev.azure.com/${this.config.organization}`;
|
|
17
|
+
this.searchUrl = `https://almsearch.dev.azure.com/${this.config.organization}`;
|
|
18
|
+
this.apiVersion = this.config.apiVersion;
|
|
19
|
+
// Encode PAT for Basic Auth (format is :PAT encoded in base64)
|
|
20
|
+
this.authHeader = `Basic ${Buffer.from(`:${this.config.pat}`).toString('base64')}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Validate that a project is in the allowed list
|
|
24
|
+
*/
|
|
25
|
+
validateProject(project) {
|
|
26
|
+
if (!this.config.projects.includes(project)) {
|
|
27
|
+
throw new Error(`Project '${project}' is not in the allowed projects list. Allowed projects: ${this.config.projects.join(', ')}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Make an authenticated request to the Azure DevOps API
|
|
32
|
+
*/
|
|
33
|
+
async makeRequest(endpoint, method = 'GET', data, useSearchUrl = false, customHeaders) {
|
|
34
|
+
try {
|
|
35
|
+
const baseUrl = useSearchUrl ? this.searchUrl : this.baseUrl;
|
|
36
|
+
const url = `${baseUrl}/${endpoint}`;
|
|
37
|
+
const response = await axios({
|
|
38
|
+
method,
|
|
39
|
+
url,
|
|
40
|
+
headers: {
|
|
41
|
+
'Authorization': this.authHeader,
|
|
42
|
+
'Content-Type': method === 'PATCH' ? 'application/json-patch+json' : 'application/json',
|
|
43
|
+
'Accept': 'application/json',
|
|
44
|
+
...customHeaders // Merge custom headers (can override defaults)
|
|
45
|
+
},
|
|
46
|
+
data
|
|
47
|
+
});
|
|
48
|
+
return response.data;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const errorDetails = error.response?.data?.message || error.response?.data || error.message;
|
|
52
|
+
console.error('Azure DevOps API request failed:', {
|
|
53
|
+
endpoint,
|
|
54
|
+
method,
|
|
55
|
+
status: error.response?.status,
|
|
56
|
+
statusText: error.response?.statusText,
|
|
57
|
+
error: errorDetails
|
|
58
|
+
});
|
|
59
|
+
// Provide user-friendly error messages
|
|
60
|
+
if (error.response?.status === 401) {
|
|
61
|
+
throw new Error('Azure DevOps authentication failed. Please check your PAT token and permissions.');
|
|
62
|
+
}
|
|
63
|
+
if (error.response?.status === 403) {
|
|
64
|
+
throw new Error('Azure DevOps access denied. Please check your PAT scopes and project permissions.');
|
|
65
|
+
}
|
|
66
|
+
if (error.response?.status === 404) {
|
|
67
|
+
throw new Error(`Azure DevOps resource not found: ${endpoint}`);
|
|
68
|
+
}
|
|
69
|
+
throw new Error(`Azure DevOps API request failed: ${error.message} - ${JSON.stringify(errorDetails)}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// ==================== WIKI OPERATIONS ====================
|
|
73
|
+
/**
|
|
74
|
+
* Convert a git path (returned by search) to a wiki path (used by get-page API)
|
|
75
|
+
* Git paths use dashes and .md extensions: /Release-Notes/Page-Name.md
|
|
76
|
+
* Wiki paths use spaces and no extensions: /Release Notes/Page Name
|
|
77
|
+
* @param gitPath The git path from search results
|
|
78
|
+
* @returns The wiki path for use with get-page API
|
|
79
|
+
*/
|
|
80
|
+
convertGitPathToWikiPath(gitPath) {
|
|
81
|
+
return gitPath
|
|
82
|
+
.replace(/\.md$/, '') // Remove .md extension
|
|
83
|
+
.replace(/-/g, ' ') // Replace ALL dashes with spaces
|
|
84
|
+
.replace(/%2D/gi, '-'); // Decode %2D back to - (actual dashes in page names)
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Count occurrences of a string in content
|
|
88
|
+
* @param content The content to search in
|
|
89
|
+
* @param searchStr The string to search for
|
|
90
|
+
* @returns Number of occurrences
|
|
91
|
+
*/
|
|
92
|
+
countOccurrences(content, searchStr) {
|
|
93
|
+
const regex = new RegExp(this.escapeRegExp(searchStr), 'g');
|
|
94
|
+
const matches = content.match(regex);
|
|
95
|
+
return matches ? matches.length : 0;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get locations where a string appears in content
|
|
99
|
+
* @param content The content to search in
|
|
100
|
+
* @param searchStr The string to search for
|
|
101
|
+
* @returns Formatted string showing line numbers and context
|
|
102
|
+
*/
|
|
103
|
+
getMatchLocations(content, searchStr) {
|
|
104
|
+
const lines = content.split('\n');
|
|
105
|
+
const matches = [];
|
|
106
|
+
lines.forEach((line, index) => {
|
|
107
|
+
if (line.includes(searchStr)) {
|
|
108
|
+
matches.push(`Line ${index + 1}: ${this.truncate(line.trim(), 100)}`);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
const maxDisplay = 10;
|
|
112
|
+
const result = matches.slice(0, maxDisplay).join('\n');
|
|
113
|
+
if (matches.length > maxDisplay) {
|
|
114
|
+
return result + `\n... and ${matches.length - maxDisplay} more`;
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Generate a unified diff showing changes
|
|
120
|
+
* @param oldContent Original content
|
|
121
|
+
* @param newContent Updated content
|
|
122
|
+
* @param oldStr The string that was replaced
|
|
123
|
+
* @param newStr The replacement string
|
|
124
|
+
* @returns Formatted diff output
|
|
125
|
+
*/
|
|
126
|
+
generateUnifiedDiff(oldContent, newContent, oldStr, newStr) {
|
|
127
|
+
const oldLines = oldContent.split('\n');
|
|
128
|
+
const newLines = newContent.split('\n');
|
|
129
|
+
// Find changed lines
|
|
130
|
+
const changedLineNumbers = [];
|
|
131
|
+
oldLines.forEach((line, index) => {
|
|
132
|
+
if (line.includes(oldStr)) {
|
|
133
|
+
changedLineNumbers.push(index);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
// Build diff output
|
|
137
|
+
const diffLines = [];
|
|
138
|
+
changedLineNumbers.forEach(lineNum => {
|
|
139
|
+
diffLines.push(`@@ Line ${lineNum + 1} @@`);
|
|
140
|
+
diffLines.push(`- ${oldLines[lineNum]}`);
|
|
141
|
+
diffLines.push(`+ ${newLines[lineNum]}`);
|
|
142
|
+
diffLines.push('');
|
|
143
|
+
});
|
|
144
|
+
return diffLines.join('\n');
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Escape special regex characters
|
|
148
|
+
* @param str String to escape
|
|
149
|
+
* @returns Escaped string safe for use in regex
|
|
150
|
+
*/
|
|
151
|
+
escapeRegExp(str) {
|
|
152
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Truncate a string for display
|
|
156
|
+
* @param str String to truncate
|
|
157
|
+
* @param maxLen Maximum length
|
|
158
|
+
* @returns Truncated string with ellipsis if needed
|
|
159
|
+
*/
|
|
160
|
+
truncate(str, maxLen) {
|
|
161
|
+
return str.length > maxLen ? str.substring(0, maxLen) + '...' : str;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get all wikis in a project
|
|
165
|
+
* @param project The project name
|
|
166
|
+
* @returns List of wikis in the project
|
|
167
|
+
*/
|
|
168
|
+
async getWikis(project) {
|
|
169
|
+
this.validateProject(project);
|
|
170
|
+
const response = await this.makeRequest(`${project}/_apis/wiki/wikis?api-version=${this.apiVersion}`);
|
|
171
|
+
return {
|
|
172
|
+
project,
|
|
173
|
+
totalCount: response.value.length,
|
|
174
|
+
wikis: response.value.map((wiki) => ({
|
|
175
|
+
id: wiki.id,
|
|
176
|
+
name: wiki.name,
|
|
177
|
+
type: wiki.type,
|
|
178
|
+
url: wiki.url,
|
|
179
|
+
projectId: wiki.projectId,
|
|
180
|
+
repositoryId: wiki.repositoryId,
|
|
181
|
+
mappedPath: wiki.mappedPath
|
|
182
|
+
}))
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Search wiki pages across projects
|
|
187
|
+
* @param searchText The text to search for
|
|
188
|
+
* @param project Optional project filter
|
|
189
|
+
* @param maxResults Maximum number of results (default: 25)
|
|
190
|
+
* @returns Search results with highlighted content
|
|
191
|
+
*/
|
|
192
|
+
async searchWikiPages(searchText, project, maxResults = 25) {
|
|
193
|
+
if (project) {
|
|
194
|
+
this.validateProject(project);
|
|
195
|
+
}
|
|
196
|
+
const searchBody = {
|
|
197
|
+
searchText,
|
|
198
|
+
$top: maxResults,
|
|
199
|
+
$skip: 0
|
|
200
|
+
};
|
|
201
|
+
// Add project filter if specified
|
|
202
|
+
if (project) {
|
|
203
|
+
searchBody.filters = {
|
|
204
|
+
Project: [project]
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
const response = await this.makeRequest(`_apis/search/wikisearchresults?api-version=${this.apiVersion}`, 'POST', searchBody, true // Use search URL
|
|
208
|
+
);
|
|
209
|
+
return {
|
|
210
|
+
searchText,
|
|
211
|
+
project: project || 'all',
|
|
212
|
+
totalCount: response.count || 0,
|
|
213
|
+
results: (response.results || []).map((result) => {
|
|
214
|
+
const gitPath = result.path;
|
|
215
|
+
const wikiPath = this.convertGitPathToWikiPath(gitPath);
|
|
216
|
+
return {
|
|
217
|
+
fileName: result.fileName,
|
|
218
|
+
gitPath: gitPath, // Original git path (for reference)
|
|
219
|
+
path: wikiPath, // Wiki path (for get-page API) - kept as 'path' for backward compatibility
|
|
220
|
+
wikiName: result.wiki?.name,
|
|
221
|
+
wikiId: result.wiki?.id,
|
|
222
|
+
project: result.project?.name,
|
|
223
|
+
highlights: result.hits?.map((hit) => hit.highlights).flat() || []
|
|
224
|
+
};
|
|
225
|
+
})
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Get a specific wiki page with content
|
|
230
|
+
* @param project The project name
|
|
231
|
+
* @param wikiId The wiki identifier (ID or name)
|
|
232
|
+
* @param pagePath The path to the page (e.g., "/Setup/Authentication")
|
|
233
|
+
* Accepts both wiki paths (with spaces) and git paths (with dashes and .md)
|
|
234
|
+
* @param includeContent Include page content (default: true)
|
|
235
|
+
* @returns Wiki page with content and metadata
|
|
236
|
+
*/
|
|
237
|
+
async getWikiPage(project, wikiId, pagePath, includeContent = true) {
|
|
238
|
+
this.validateProject(project);
|
|
239
|
+
// Always normalize paths to wiki format (removes .md, converts dashes to spaces)
|
|
240
|
+
// This ensures consistent behavior regardless of input format
|
|
241
|
+
const wikiPath = this.convertGitPathToWikiPath(pagePath);
|
|
242
|
+
// Log conversion if the path was changed (for debugging)
|
|
243
|
+
if (wikiPath !== pagePath) {
|
|
244
|
+
console.error(`Normalized wiki path: ${pagePath} -> ${wikiPath}`);
|
|
245
|
+
}
|
|
246
|
+
// Use axios directly to access response headers (for ETag)
|
|
247
|
+
const url = `${this.baseUrl}/${project}/_apis/wiki/wikis/${wikiId}/pages?path=${encodeURIComponent(wikiPath)}&includeContent=${includeContent}&api-version=${this.apiVersion}`;
|
|
248
|
+
try {
|
|
249
|
+
const axiosResponse = await axios({
|
|
250
|
+
method: 'GET',
|
|
251
|
+
url,
|
|
252
|
+
headers: {
|
|
253
|
+
'Authorization': this.authHeader,
|
|
254
|
+
'Content-Type': 'application/json',
|
|
255
|
+
'Accept': 'application/json'
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
const response = axiosResponse.data;
|
|
259
|
+
// Extract ETag from response headers (needed for updates)
|
|
260
|
+
const etag = axiosResponse.headers['etag'] || axiosResponse.headers['ETag'];
|
|
261
|
+
// The API returns the page data directly (not wrapped in a 'page' property)
|
|
262
|
+
return {
|
|
263
|
+
id: response.id,
|
|
264
|
+
path: response.path,
|
|
265
|
+
content: response.content,
|
|
266
|
+
gitItemPath: response.gitItemPath,
|
|
267
|
+
subPages: response.subPages || [],
|
|
268
|
+
url: response.url,
|
|
269
|
+
remoteUrl: response.remoteUrl,
|
|
270
|
+
version: etag, // Include ETag for use with updateWikiPage
|
|
271
|
+
project,
|
|
272
|
+
wikiId
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
// Handle errors similar to makeRequest
|
|
277
|
+
const errorDetails = error.response?.data?.message || error.response?.data || error.message;
|
|
278
|
+
console.error('Azure DevOps API request failed:', {
|
|
279
|
+
url,
|
|
280
|
+
status: error.response?.status,
|
|
281
|
+
error: errorDetails
|
|
282
|
+
});
|
|
283
|
+
if (error.response?.status === 401) {
|
|
284
|
+
throw new Error('Azure DevOps authentication failed. Please check your PAT token and permissions.');
|
|
285
|
+
}
|
|
286
|
+
if (error.response?.status === 403) {
|
|
287
|
+
throw new Error('Azure DevOps access denied. Please check your PAT scopes and project permissions.');
|
|
288
|
+
}
|
|
289
|
+
if (error.response?.status === 404) {
|
|
290
|
+
throw new Error(`Wiki page not found: ${wikiPath} (original input: ${pagePath})`);
|
|
291
|
+
}
|
|
292
|
+
throw new Error(`Azure DevOps API request failed: ${error.message} - ${JSON.stringify(errorDetails)}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Create a new wiki page
|
|
297
|
+
* @param project The project name
|
|
298
|
+
* @param wikiId The wiki identifier
|
|
299
|
+
* @param pagePath The path for the new page (will be normalized to wiki format)
|
|
300
|
+
* @param content The markdown content
|
|
301
|
+
* @returns Created page information
|
|
302
|
+
*/
|
|
303
|
+
async createWikiPage(project, wikiId, pagePath, content) {
|
|
304
|
+
this.validateProject(project);
|
|
305
|
+
if (!this.config.enableWikiWrite) {
|
|
306
|
+
throw new Error('Wiki write operations are disabled. Set AZUREDEVOPS_ENABLE_WIKI_WRITE=true to enable.');
|
|
307
|
+
}
|
|
308
|
+
// Always normalize paths to wiki format (removes .md, converts dashes to spaces)
|
|
309
|
+
const wikiPath = this.convertGitPathToWikiPath(pagePath);
|
|
310
|
+
// Log conversion if the path was changed (for debugging)
|
|
311
|
+
if (wikiPath !== pagePath) {
|
|
312
|
+
console.error(`Normalized wiki path for creation: ${pagePath} -> ${wikiPath}`);
|
|
313
|
+
}
|
|
314
|
+
const response = await this.makeRequest(`${project}/_apis/wiki/wikis/${wikiId}/pages?path=${encodeURIComponent(wikiPath)}&api-version=${this.apiVersion}`, 'PUT', { content });
|
|
315
|
+
return {
|
|
316
|
+
id: response.page?.id,
|
|
317
|
+
path: response.page?.path,
|
|
318
|
+
gitItemPath: response.page?.gitItemPath,
|
|
319
|
+
project,
|
|
320
|
+
wikiId
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Update an existing wiki page
|
|
325
|
+
* @param project The project name
|
|
326
|
+
* @param wikiId The wiki identifier
|
|
327
|
+
* @param pagePath The path to the page (will be normalized to wiki format)
|
|
328
|
+
* @param content The updated markdown content
|
|
329
|
+
* @param version The ETag/version for optimistic concurrency (recommended to prevent conflicts)
|
|
330
|
+
* @returns Updated page information
|
|
331
|
+
*/
|
|
332
|
+
async updateWikiPage(project, wikiId, pagePath, content, version) {
|
|
333
|
+
this.validateProject(project);
|
|
334
|
+
if (!this.config.enableWikiWrite) {
|
|
335
|
+
throw new Error('Wiki write operations are disabled. Set AZUREDEVOPS_ENABLE_WIKI_WRITE=true to enable.');
|
|
336
|
+
}
|
|
337
|
+
// Always normalize paths to wiki format (removes .md, converts dashes to spaces)
|
|
338
|
+
const wikiPath = this.convertGitPathToWikiPath(pagePath);
|
|
339
|
+
// Log conversion if the path was changed (for debugging)
|
|
340
|
+
if (wikiPath !== pagePath) {
|
|
341
|
+
console.error(`Normalized wiki path for update: ${pagePath} -> ${wikiPath}`);
|
|
342
|
+
}
|
|
343
|
+
// Add If-Match header if version is provided (for optimistic concurrency control)
|
|
344
|
+
const customHeaders = version ? { 'If-Match': version } : undefined;
|
|
345
|
+
const response = await this.makeRequest(`${project}/_apis/wiki/wikis/${wikiId}/pages?path=${encodeURIComponent(wikiPath)}&api-version=${this.apiVersion}`, 'PUT', { content }, false, // useSearchUrl
|
|
346
|
+
customHeaders);
|
|
347
|
+
return {
|
|
348
|
+
id: response.page?.id,
|
|
349
|
+
path: response.page?.path,
|
|
350
|
+
gitItemPath: response.page?.gitItemPath,
|
|
351
|
+
project,
|
|
352
|
+
wikiId
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Replace a specific string in a wiki page without rewriting entire content
|
|
357
|
+
* @param project The project name
|
|
358
|
+
* @param wikiId The wiki identifier
|
|
359
|
+
* @param pagePath The path to the page (will be normalized to wiki format)
|
|
360
|
+
* @param oldStr The exact string to replace
|
|
361
|
+
* @param newStr The replacement string
|
|
362
|
+
* @param replaceAll If true, replace all occurrences; if false, old_str must be unique
|
|
363
|
+
* @param description Optional description of the change for audit logging
|
|
364
|
+
* @returns Result with diff, occurrence count, version, and message
|
|
365
|
+
*/
|
|
366
|
+
async strReplaceWikiPage(project, wikiId, pagePath, oldStr, newStr, replaceAll = false, description) {
|
|
367
|
+
this.validateProject(project);
|
|
368
|
+
// 1. Validate write permission
|
|
369
|
+
if (!this.config.enableWikiWrite) {
|
|
370
|
+
throw new Error('Wiki write operations are disabled. Set AZUREDEVOPS_ENABLE_WIKI_WRITE=true to enable.');
|
|
371
|
+
}
|
|
372
|
+
// 2. Fetch current page content and version (auto-fetch latest)
|
|
373
|
+
const currentPage = await this.getWikiPage(project, wikiId, pagePath, true);
|
|
374
|
+
const currentContent = currentPage.content;
|
|
375
|
+
const currentVersion = currentPage.version;
|
|
376
|
+
// 3. Count occurrences of old_str
|
|
377
|
+
const occurrences = this.countOccurrences(currentContent, oldStr);
|
|
378
|
+
if (occurrences === 0) {
|
|
379
|
+
throw new Error(`String not found in page.\n\n` +
|
|
380
|
+
`Looking for: "${this.truncate(oldStr, 200)}"\n\n` +
|
|
381
|
+
`Page excerpt:\n${this.truncate(currentContent, 500)}`);
|
|
382
|
+
}
|
|
383
|
+
if (occurrences > 1 && !replaceAll) {
|
|
384
|
+
throw new Error(`String appears ${occurrences} times in the page. ` +
|
|
385
|
+
`Either provide more context to make old_str unique, or set replace_all=true.\n\n` +
|
|
386
|
+
`Matching locations:\n${this.getMatchLocations(currentContent, oldStr)}`);
|
|
387
|
+
}
|
|
388
|
+
// 4. Perform replacement
|
|
389
|
+
const regex = new RegExp(this.escapeRegExp(oldStr), replaceAll ? 'g' : '');
|
|
390
|
+
const newContent = currentContent.replace(regex, newStr);
|
|
391
|
+
// 5. Validate replacement succeeded
|
|
392
|
+
if (newContent === currentContent) {
|
|
393
|
+
throw new Error('Replacement failed - content unchanged');
|
|
394
|
+
}
|
|
395
|
+
// 6. Update wiki page with version conflict retry
|
|
396
|
+
let updateResult;
|
|
397
|
+
try {
|
|
398
|
+
updateResult = await this.updateWikiPage(project, wikiId, pagePath, newContent, currentVersion);
|
|
399
|
+
}
|
|
400
|
+
catch (error) {
|
|
401
|
+
// Version conflict - retry once with fresh version
|
|
402
|
+
if (error.message.includes('412') || error.message.includes('version') || error.message.includes('conflict')) {
|
|
403
|
+
console.error('Version conflict detected, retrying with fresh version...');
|
|
404
|
+
const freshPage = await this.getWikiPage(project, wikiId, pagePath, true);
|
|
405
|
+
const freshContent = freshPage.content;
|
|
406
|
+
const freshVersion = freshPage.version;
|
|
407
|
+
// Re-apply replacement to fresh content
|
|
408
|
+
const freshRegex = new RegExp(this.escapeRegExp(oldStr), replaceAll ? 'g' : '');
|
|
409
|
+
const freshNewContent = freshContent.replace(freshRegex, newStr);
|
|
410
|
+
updateResult = await this.updateWikiPage(project, wikiId, pagePath, freshNewContent, freshVersion);
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
throw error;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
// 7. Generate diff output
|
|
417
|
+
const diff = this.generateUnifiedDiff(currentContent, newContent, oldStr, newStr);
|
|
418
|
+
// 8. Return result with diff
|
|
419
|
+
return {
|
|
420
|
+
success: true,
|
|
421
|
+
diff,
|
|
422
|
+
occurrences: replaceAll ? occurrences : 1,
|
|
423
|
+
version: currentVersion,
|
|
424
|
+
message: `Successfully replaced ${replaceAll ? occurrences : 1} occurrence(s)`,
|
|
425
|
+
...updateResult
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
// ==================== WORK ITEM OPERATIONS ====================
|
|
429
|
+
/**
|
|
430
|
+
* Get a work item by ID with full details
|
|
431
|
+
* @param project The project name
|
|
432
|
+
* @param workItemId The work item ID
|
|
433
|
+
* @returns Complete work item details
|
|
434
|
+
*/
|
|
435
|
+
async getWorkItem(project, workItemId) {
|
|
436
|
+
this.validateProject(project);
|
|
437
|
+
const response = await this.makeRequest(`${project}/_apis/wit/workitems/${workItemId}?$expand=all&api-version=${this.apiVersion}`);
|
|
438
|
+
return {
|
|
439
|
+
id: response.id,
|
|
440
|
+
rev: response.rev,
|
|
441
|
+
url: response.url,
|
|
442
|
+
fields: response.fields,
|
|
443
|
+
relations: response.relations || [],
|
|
444
|
+
_links: response._links,
|
|
445
|
+
commentVersionRef: response.commentVersionRef,
|
|
446
|
+
project
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Query work items using WIQL (Work Item Query Language)
|
|
451
|
+
* @param project The project name
|
|
452
|
+
* @param wiql The WIQL query string
|
|
453
|
+
* @param maxResults Maximum number of results (default: 200)
|
|
454
|
+
* @returns Work items matching the query
|
|
455
|
+
*/
|
|
456
|
+
async queryWorkItems(project, wiql, maxResults = 200) {
|
|
457
|
+
this.validateProject(project);
|
|
458
|
+
// Execute WIQL query
|
|
459
|
+
const queryResult = await this.makeRequest(`${project}/_apis/wit/wiql?api-version=${this.apiVersion}`, 'POST', { query: wiql });
|
|
460
|
+
if (!queryResult.workItems || queryResult.workItems.length === 0) {
|
|
461
|
+
return {
|
|
462
|
+
query: wiql,
|
|
463
|
+
project,
|
|
464
|
+
totalCount: 0,
|
|
465
|
+
workItems: []
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
// Get work item IDs (limit to maxResults)
|
|
469
|
+
const workItemIds = queryResult.workItems
|
|
470
|
+
.slice(0, maxResults)
|
|
471
|
+
.map((wi) => wi.id);
|
|
472
|
+
// Batch get full work item details
|
|
473
|
+
const workItems = await this.makeRequest(`${project}/_apis/wit/workitemsbatch?api-version=${this.apiVersion}`, 'POST', {
|
|
474
|
+
ids: workItemIds,
|
|
475
|
+
$expand: 'all'
|
|
476
|
+
});
|
|
477
|
+
return {
|
|
478
|
+
query: wiql,
|
|
479
|
+
project,
|
|
480
|
+
totalCount: workItems.value.length,
|
|
481
|
+
workItems: workItems.value
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Get comments/discussion for a work item
|
|
486
|
+
* @param project The project name
|
|
487
|
+
* @param workItemId The work item ID
|
|
488
|
+
* @returns List of comments
|
|
489
|
+
*/
|
|
490
|
+
async getWorkItemComments(project, workItemId) {
|
|
491
|
+
this.validateProject(project);
|
|
492
|
+
const response = await this.makeRequest(`${project}/_apis/wit/workItems/${workItemId}/comments?api-version=${this.apiVersion}`);
|
|
493
|
+
return {
|
|
494
|
+
workItemId,
|
|
495
|
+
project,
|
|
496
|
+
totalCount: response.totalCount || response.value.length,
|
|
497
|
+
comments: response.value.map((comment) => ({
|
|
498
|
+
id: comment.id,
|
|
499
|
+
text: comment.text,
|
|
500
|
+
createdBy: comment.createdBy?.displayName,
|
|
501
|
+
createdDate: comment.createdDate,
|
|
502
|
+
modifiedBy: comment.modifiedBy?.displayName,
|
|
503
|
+
modifiedDate: comment.modifiedDate,
|
|
504
|
+
url: comment.url
|
|
505
|
+
}))
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Add a comment to a work item
|
|
510
|
+
* @param project The project name
|
|
511
|
+
* @param workItemId The work item ID
|
|
512
|
+
* @param commentText The comment text (supports markdown)
|
|
513
|
+
* @returns Created comment information
|
|
514
|
+
*/
|
|
515
|
+
async addWorkItemComment(project, workItemId, commentText) {
|
|
516
|
+
this.validateProject(project);
|
|
517
|
+
if (!this.config.enableWorkItemWrite) {
|
|
518
|
+
throw new Error('Work item write operations are disabled. Set AZUREDEVOPS_ENABLE_WORK_ITEM_WRITE=true to enable.');
|
|
519
|
+
}
|
|
520
|
+
const response = await this.makeRequest(`${project}/_apis/wit/workItems/${workItemId}/comments?api-version=${this.apiVersion}`, 'POST', { text: commentText });
|
|
521
|
+
return {
|
|
522
|
+
id: response.id,
|
|
523
|
+
workItemId,
|
|
524
|
+
project,
|
|
525
|
+
text: response.text,
|
|
526
|
+
createdBy: response.createdBy?.displayName,
|
|
527
|
+
createdDate: response.createdDate
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Update a work item using JSON Patch operations
|
|
532
|
+
* @param project The project name
|
|
533
|
+
* @param workItemId The work item ID
|
|
534
|
+
* @param patchOperations Array of JSON Patch operations
|
|
535
|
+
* @returns Updated work item
|
|
536
|
+
*/
|
|
537
|
+
async updateWorkItem(project, workItemId, patchOperations) {
|
|
538
|
+
this.validateProject(project);
|
|
539
|
+
if (!this.config.enableWorkItemWrite) {
|
|
540
|
+
throw new Error('Work item write operations are disabled. Set AZUREDEVOPS_ENABLE_WORK_ITEM_WRITE=true to enable.');
|
|
541
|
+
}
|
|
542
|
+
const response = await this.makeRequest(`${project}/_apis/wit/workitems/${workItemId}?api-version=${this.apiVersion}`, 'PATCH', patchOperations);
|
|
543
|
+
return {
|
|
544
|
+
id: response.id,
|
|
545
|
+
rev: response.rev,
|
|
546
|
+
fields: response.fields,
|
|
547
|
+
project
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Create a new work item
|
|
552
|
+
* @param project The project name
|
|
553
|
+
* @param workItemType The work item type (e.g., "Bug", "Task", "User Story")
|
|
554
|
+
* @param fields Object with field values (e.g., { "System.Title": "Bug title" })
|
|
555
|
+
* @returns Created work item
|
|
556
|
+
*/
|
|
557
|
+
async createWorkItem(project, workItemType, fields) {
|
|
558
|
+
this.validateProject(project);
|
|
559
|
+
if (!this.config.enableWorkItemWrite) {
|
|
560
|
+
throw new Error('Work item write operations are disabled. Set AZUREDEVOPS_ENABLE_WORK_ITEM_WRITE=true to enable.');
|
|
561
|
+
}
|
|
562
|
+
// Convert fields object to JSON Patch operations
|
|
563
|
+
const patchOperations = Object.keys(fields).map(field => ({
|
|
564
|
+
op: 'add',
|
|
565
|
+
path: `/fields/${field}`,
|
|
566
|
+
value: fields[field]
|
|
567
|
+
}));
|
|
568
|
+
const response = await this.makeRequest(`${project}/_apis/wit/workitems/$${workItemType}?api-version=${this.apiVersion}`, 'PATCH', patchOperations);
|
|
569
|
+
return {
|
|
570
|
+
id: response.id,
|
|
571
|
+
rev: response.rev,
|
|
572
|
+
fields: response.fields,
|
|
573
|
+
url: response._links?.html?.href,
|
|
574
|
+
project
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Delete a work item
|
|
579
|
+
* @param project The project name
|
|
580
|
+
* @param workItemId The work item ID
|
|
581
|
+
* @returns Deletion confirmation
|
|
582
|
+
*/
|
|
583
|
+
async deleteWorkItem(project, workItemId) {
|
|
584
|
+
this.validateProject(project);
|
|
585
|
+
if (!this.config.enableWorkItemDelete) {
|
|
586
|
+
throw new Error('Work item delete operations are disabled. Set AZUREDEVOPS_ENABLE_WORK_ITEM_DELETE=true to enable.');
|
|
587
|
+
}
|
|
588
|
+
await this.makeRequest(`${project}/_apis/wit/workitems/${workItemId}?api-version=${this.apiVersion}`, 'DELETE');
|
|
589
|
+
return {
|
|
590
|
+
workItemId,
|
|
591
|
+
project,
|
|
592
|
+
deleted: true
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
//# sourceMappingURL=AzureDevOpsService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AzureDevOpsService.js","sourceRoot":"","sources":["../src/AzureDevOpsService.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @mcp-consultant-tools/azure-devops
|
|
4
|
+
*
|
|
5
|
+
* MCP server for Azure DevOps integration.
|
|
6
|
+
* Provides wikis, work items, and project management capabilities.
|
|
7
|
+
*/
|
|
8
|
+
import { AzureDevOpsService } from "./AzureDevOpsService.js";
|
|
9
|
+
/**
|
|
10
|
+
* Register Azure DevOps tools and prompts to an MCP server
|
|
11
|
+
* @param server - The MCP server instance
|
|
12
|
+
* @param azureDevOpsService - Optional pre-configured AzureDevOpsService (for testing or custom configs)
|
|
13
|
+
*/
|
|
14
|
+
export declare function registerAzureDevOpsTools(server: any, azureDevOpsService?: AzureDevOpsService): void;
|
|
15
|
+
/**
|
|
16
|
+
* Export service class for direct usage
|
|
17
|
+
*/
|
|
18
|
+
export { AzureDevOpsService } from "./AzureDevOpsService.js";
|
|
19
|
+
export type { AzureDevOpsConfig } from "./AzureDevOpsService.js";
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,GAAG,EAAE,kBAAkB,CAAC,EAAE,kBAAkB,QAuC5F;AAED;;GAEG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @mcp-consultant-tools/azure-devops
|
|
4
|
+
*
|
|
5
|
+
* MCP server for Azure DevOps integration.
|
|
6
|
+
* Provides wikis, work items, and project management capabilities.
|
|
7
|
+
*/
|
|
8
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
9
|
+
import { createMcpServer, createEnvLoader } from "@mcp-consultant-tools/core";
|
|
10
|
+
import { AzureDevOpsService } from "./AzureDevOpsService.js";
|
|
11
|
+
/**
|
|
12
|
+
* Register Azure DevOps tools and prompts to an MCP server
|
|
13
|
+
* @param server - The MCP server instance
|
|
14
|
+
* @param azureDevOpsService - Optional pre-configured AzureDevOpsService (for testing or custom configs)
|
|
15
|
+
*/
|
|
16
|
+
export function registerAzureDevOpsTools(server, azureDevOpsService) {
|
|
17
|
+
let service = azureDevOpsService || null;
|
|
18
|
+
function getAzureDevOpsService() {
|
|
19
|
+
if (!service) {
|
|
20
|
+
const missingConfig = [];
|
|
21
|
+
if (!process.env.AZUREDEVOPS_ORGANIZATION)
|
|
22
|
+
missingConfig.push("AZUREDEVOPS_ORGANIZATION");
|
|
23
|
+
if (!process.env.AZUREDEVOPS_PAT)
|
|
24
|
+
missingConfig.push("AZUREDEVOPS_PAT");
|
|
25
|
+
if (!process.env.AZUREDEVOPS_PROJECTS)
|
|
26
|
+
missingConfig.push("AZUREDEVOPS_PROJECTS");
|
|
27
|
+
if (missingConfig.length > 0) {
|
|
28
|
+
throw new Error(`Missing required Azure DevOps configuration: ${missingConfig.join(", ")}. ` +
|
|
29
|
+
`Set environment variables for organization, PAT, and allowed projects.`);
|
|
30
|
+
}
|
|
31
|
+
const config = {
|
|
32
|
+
organization: process.env.AZUREDEVOPS_ORGANIZATION,
|
|
33
|
+
pat: process.env.AZUREDEVOPS_PAT,
|
|
34
|
+
projects: process.env.AZUREDEVOPS_PROJECTS.split(",").map(p => p.trim()),
|
|
35
|
+
apiVersion: process.env.AZUREDEVOPS_API_VERSION || "7.1",
|
|
36
|
+
enableWorkItemWrite: process.env.AZUREDEVOPS_ENABLE_WORK_ITEM_WRITE === "true",
|
|
37
|
+
enableWorkItemDelete: process.env.AZUREDEVOPS_ENABLE_WORK_ITEM_DELETE === "true",
|
|
38
|
+
enableWikiWrite: process.env.AZUREDEVOPS_ENABLE_WIKI_WRITE === "true",
|
|
39
|
+
};
|
|
40
|
+
service = new AzureDevOpsService(config);
|
|
41
|
+
console.error("Azure DevOps service initialized");
|
|
42
|
+
}
|
|
43
|
+
return service;
|
|
44
|
+
}
|
|
45
|
+
// TODO: Extract and register all Azure DevOps tools here
|
|
46
|
+
// Tools include: wikis, work items, and search
|
|
47
|
+
// This will be filled during meta-package creation phase
|
|
48
|
+
console.error("Azure DevOps tools registered (tool extraction pending)");
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Export service class for direct usage
|
|
52
|
+
*/
|
|
53
|
+
export { AzureDevOpsService } from "./AzureDevOpsService.js";
|
|
54
|
+
/**
|
|
55
|
+
* Standalone CLI server (when run directly)
|
|
56
|
+
*/
|
|
57
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
58
|
+
const loadEnv = createEnvLoader();
|
|
59
|
+
loadEnv();
|
|
60
|
+
const server = createMcpServer({
|
|
61
|
+
name: "@mcp-consultant-tools/azure-devops",
|
|
62
|
+
version: "1.0.0",
|
|
63
|
+
capabilities: {
|
|
64
|
+
tools: {},
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
registerAzureDevOpsTools(server);
|
|
68
|
+
const transport = new StdioServerTransport();
|
|
69
|
+
server.connect(transport).catch((error) => {
|
|
70
|
+
console.error("Failed to start Azure DevOps MCP server:", error);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
});
|
|
73
|
+
console.error("@mcp-consultant-tools/azure-devops server running on stdio");
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcp-consultant-tools/azure-devops",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for Azure DevOps integration - wikis, work items, and project management",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./build/index.js",
|
|
7
|
+
"types": "./build/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"mcp-azuredevops": "./build/index.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./build/index.js",
|
|
14
|
+
"types": "./build/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"build",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc",
|
|
23
|
+
"clean": "rm -rf build *.tsbuildinfo",
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"mcp",
|
|
28
|
+
"model-context-protocol",
|
|
29
|
+
"azure-devops",
|
|
30
|
+
"devops",
|
|
31
|
+
"wikis",
|
|
32
|
+
"work-items",
|
|
33
|
+
"azure"
|
|
34
|
+
],
|
|
35
|
+
"author": "Michal Sobieraj",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/klemensms/mcp-consultant-tools.git",
|
|
40
|
+
"directory": "packages/azure-devops"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=16.0.0"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@mcp-consultant-tools/core": "^1.0.0",
|
|
47
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
48
|
+
"axios": "^1.8.3",
|
|
49
|
+
"zod": "^3.24.1"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "^22.10.5",
|
|
53
|
+
"typescript": "^5.8.2"
|
|
54
|
+
}
|
|
55
|
+
}
|