mcp-consultant-tools 7.0.0 → 9.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/README.md +165 -6
- package/build/AzureDevOpsService.js +77 -27
- package/build/GitHubEnterpriseService.js +1100 -0
- package/build/LogAnalyticsService.js +409 -0
- package/build/index.js +1920 -146
- package/build/utils/ghe-formatters.js +330 -0
- package/build/utils/loganalytics-formatters.js +371 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MCP Consultant Tools
|
|
2
2
|
|
|
3
|
-
A Model Context Protocol (MCP) server providing intelligent access to PowerPlatform/Dataverse, Azure DevOps, Figma, Azure Application Insights,
|
|
3
|
+
A Model Context Protocol (MCP) server providing intelligent access to PowerPlatform/Dataverse, Azure DevOps, Figma, Azure Application Insights, Azure Log Analytics, Azure SQL Database, and GitHub Enterprise through an AI-friendly interface.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
@@ -16,11 +16,13 @@ This MCP server enables AI assistants to:
|
|
|
16
16
|
- **Azure DevOps** (12 tools): Search wikis, manage work items, execute WIQL queries
|
|
17
17
|
- **Figma** (2 tools): Extract design data in simplified, AI-friendly format
|
|
18
18
|
- **Application Insights** (10 tools): Query telemetry, analyze exceptions, monitor performance, troubleshoot issues
|
|
19
|
+
- **Log Analytics** (10 tools): Query Azure Functions logs, analyze errors, monitor function performance, search workspace logs
|
|
19
20
|
- **Azure SQL Database** (9 tools): Explore database schema, query tables safely with read-only access, investigate database structure
|
|
21
|
+
- **GitHub Enterprise** (22 tools): Access source code, commits, branches, pull requests, correlate with deployed plugins and ADO work items
|
|
20
22
|
|
|
21
23
|
All integrations are **optional** - configure only the services you need.
|
|
22
24
|
|
|
23
|
-
**Total:
|
|
25
|
+
**Total: 138 MCP tools & 28 prompts** providing comprehensive access to your development and operations lifecycle.
|
|
24
26
|
|
|
25
27
|
## Known limitations
|
|
26
28
|
- Cannot create Model-Driven-Apps
|
|
@@ -81,11 +83,26 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
|
81
83
|
"APPINSIGHTS_CLIENT_SECRET": "your-client-secret",
|
|
82
84
|
"APPINSIGHTS_RESOURCES": "[{\"id\":\"prod-api\",\"name\":\"Production API\",\"appId\":\"your-app-id\",\"active\":true}]",
|
|
83
85
|
|
|
86
|
+
"LOGANALYTICS_AUTH_METHOD": "entra-id",
|
|
87
|
+
"LOGANALYTICS_TENANT_ID": "your-tenant-id",
|
|
88
|
+
"LOGANALYTICS_CLIENT_ID": "your-client-id",
|
|
89
|
+
"LOGANALYTICS_CLIENT_SECRET": "your-client-secret",
|
|
90
|
+
"LOGANALYTICS_RESOURCES": "[{\"id\":\"prod-functions\",\"name\":\"Production Functions\",\"workspaceId\":\"your-workspace-id\",\"active\":true}]",
|
|
91
|
+
|
|
84
92
|
"AZURE_SQL_SERVER": "yourserver.database.windows.net",
|
|
85
93
|
"AZURE_SQL_DATABASE": "yourdatabase",
|
|
86
94
|
"AZURE_SQL_USERNAME": "your-username",
|
|
87
95
|
"AZURE_SQL_PASSWORD": "your-password",
|
|
88
|
-
"AZURE_SQL_USE_AZURE_AD": "false"
|
|
96
|
+
"AZURE_SQL_USE_AZURE_AD": "false",
|
|
97
|
+
|
|
98
|
+
"GHE_URL": "https://github.yourcompany.com",
|
|
99
|
+
"GHE_PAT": "ghp_your_personal_access_token",
|
|
100
|
+
"GHE_AUTH_METHOD": "pat",
|
|
101
|
+
"GHE_REPOS": "[{\"id\":\"plugin-core\",\"owner\":\"yourorg\",\"repo\":\"PluginCore\",\"defaultBranch\":\"release/9.0\",\"active\":true}]",
|
|
102
|
+
"GHE_ENABLE_CACHE": "true",
|
|
103
|
+
"GHE_CACHE_TTL": "300",
|
|
104
|
+
"GHE_ENABLE_WRITE": "false",
|
|
105
|
+
"GHE_ENABLE_CREATE": "false"
|
|
89
106
|
}
|
|
90
107
|
}
|
|
91
108
|
}
|
|
@@ -130,11 +147,26 @@ Create `.vscode/mcp.json` in your project:
|
|
|
130
147
|
"APPINSIGHTS_CLIENT_SECRET": "your-client-secret",
|
|
131
148
|
"APPINSIGHTS_RESOURCES": "[{\"id\":\"prod-api\",\"name\":\"Production API\",\"appId\":\"your-app-id\",\"active\":true}]",
|
|
132
149
|
|
|
150
|
+
"LOGANALYTICS_AUTH_METHOD": "entra-id",
|
|
151
|
+
"LOGANALYTICS_TENANT_ID": "your-tenant-id",
|
|
152
|
+
"LOGANALYTICS_CLIENT_ID": "your-client-id",
|
|
153
|
+
"LOGANALYTICS_CLIENT_SECRET": "your-client-secret",
|
|
154
|
+
"LOGANALYTICS_RESOURCES": "[{\"id\":\"prod-functions\",\"name\":\"Production Functions\",\"workspaceId\":\"your-workspace-id\",\"active\":true}]",
|
|
155
|
+
|
|
133
156
|
"AZURE_SQL_SERVER": "yourserver.database.windows.net",
|
|
134
157
|
"AZURE_SQL_DATABASE": "yourdatabase",
|
|
135
158
|
"AZURE_SQL_USERNAME": "your-username",
|
|
136
159
|
"AZURE_SQL_PASSWORD": "your-password",
|
|
137
|
-
"AZURE_SQL_USE_AZURE_AD": "false"
|
|
160
|
+
"AZURE_SQL_USE_AZURE_AD": "false",
|
|
161
|
+
|
|
162
|
+
"GHE_URL": "https://github.yourcompany.com",
|
|
163
|
+
"GHE_PAT": "ghp_your_personal_access_token",
|
|
164
|
+
"GHE_AUTH_METHOD": "pat",
|
|
165
|
+
"GHE_REPOS": "[{\"id\":\"plugin-core\",\"owner\":\"yourorg\",\"repo\":\"PluginCore\",\"defaultBranch\":\"release/9.0\",\"active\":true}]",
|
|
166
|
+
"GHE_ENABLE_CACHE": "true",
|
|
167
|
+
"GHE_CACHE_TTL": "300",
|
|
168
|
+
"GHE_ENABLE_WRITE": "false",
|
|
169
|
+
"GHE_ENABLE_CREATE": "false"
|
|
138
170
|
}
|
|
139
171
|
}
|
|
140
172
|
}
|
|
@@ -278,9 +310,70 @@ Reload VS Code window after saving.
|
|
|
278
310
|
- `appinsights-get-availability` - Get availability test results and uptime stats
|
|
279
311
|
- `appinsights-get-custom-events` - Get custom application events
|
|
280
312
|
|
|
313
|
+
### Log Analytics (10 tools)
|
|
314
|
+
|
|
315
|
+
- `loganalytics-list-workspaces` - List all configured Log Analytics workspaces
|
|
316
|
+
- `loganalytics-get-metadata` - Get workspace schema (tables and columns)
|
|
317
|
+
- `loganalytics-execute-query` - Execute custom KQL queries
|
|
318
|
+
- `loganalytics-get-function-logs` - Get Azure Function logs with filtering
|
|
319
|
+
- `loganalytics-get-function-errors` - Get function error logs with exception details
|
|
320
|
+
- `loganalytics-get-function-stats` - Get execution statistics (count, success rate)
|
|
321
|
+
- `loganalytics-get-function-invocations` - Get function invocation records
|
|
322
|
+
- `loganalytics-get-recent-events` - Get recent events from any table
|
|
323
|
+
- `loganalytics-search-logs` - Search logs across tables
|
|
324
|
+
- `loganalytics-test-workspace-access` - Validate workspace access
|
|
325
|
+
|
|
326
|
+
### Azure SQL Database (9 tools)
|
|
327
|
+
|
|
328
|
+
- `sql-test-connection` - Test database connectivity
|
|
329
|
+
- `sql-list-tables` - List all tables with row counts and sizes
|
|
330
|
+
- `sql-list-views` - List all views
|
|
331
|
+
- `sql-list-stored-procedures` - List all stored procedures
|
|
332
|
+
- `sql-list-triggers` - List all triggers
|
|
333
|
+
- `sql-list-functions` - List all user-defined functions
|
|
334
|
+
- `sql-get-table-schema` - Get complete table schema (columns, indexes, FKs)
|
|
335
|
+
- `sql-get-object-definition` - Get SQL definition for views, procedures, functions, triggers
|
|
336
|
+
- `sql-execute-query` - Execute SELECT queries safely with validation
|
|
337
|
+
|
|
338
|
+
### GitHub Enterprise (22 tools)
|
|
339
|
+
|
|
340
|
+
**Repository & Branch Management:**
|
|
341
|
+
- `ghe-list-repos` - List all configured repositories
|
|
342
|
+
- `ghe-list-branches` - List all branches for a repository
|
|
343
|
+
- `ghe-get-default-branch` - Auto-detect default branch with typo handling
|
|
344
|
+
- `ghe-get-branch-details` - Get detailed branch information
|
|
345
|
+
- `ghe-compare-branches` - Compare two branches and show differences
|
|
346
|
+
- `ghe-search-repos` - Search repositories by name or description
|
|
347
|
+
|
|
348
|
+
**File Operations:**
|
|
349
|
+
- `ghe-get-file` - Get file content from a specific branch
|
|
350
|
+
- `ghe-search-code` - Search code across repositories
|
|
351
|
+
- `ghe-list-files` - List files in a directory
|
|
352
|
+
- `ghe-get-directory-structure` - Get recursive directory tree structure
|
|
353
|
+
- `ghe-get-file-history` - Get commit history for a specific file
|
|
354
|
+
|
|
355
|
+
**Commit & History:**
|
|
356
|
+
- `ghe-get-commits` - Get commit history for a branch
|
|
357
|
+
- `ghe-get-commit-details` - Get detailed information about a specific commit
|
|
358
|
+
- `ghe-search-commits` - Search commits by message or hash (supports #1234 work item refs)
|
|
359
|
+
- `ghe-get-commit-diff` - Get detailed diff for a commit
|
|
360
|
+
|
|
361
|
+
**Pull Requests:**
|
|
362
|
+
- `ghe-list-pull-requests` - List pull requests for a repository
|
|
363
|
+
- `ghe-get-pull-request` - Get detailed pull request information
|
|
364
|
+
- `ghe-get-pr-files` - Get files changed in a pull request
|
|
365
|
+
|
|
366
|
+
**Write Operations (disabled by default):**
|
|
367
|
+
- `ghe-create-branch` - Create a new branch (requires GHE_ENABLE_CREATE=true)
|
|
368
|
+
- `ghe-update-file` - Update file content (requires GHE_ENABLE_WRITE=true)
|
|
369
|
+
- `ghe-create-file` - Create a new file (requires GHE_ENABLE_CREATE=true)
|
|
370
|
+
|
|
371
|
+
**Cache Management:**
|
|
372
|
+
- `ghe-clear-cache` - Clear cached GitHub API responses
|
|
373
|
+
|
|
281
374
|
## Available Prompts
|
|
282
375
|
|
|
283
|
-
The server includes **
|
|
376
|
+
The server includes **28 prompts** that provide formatted, context-rich output:
|
|
284
377
|
|
|
285
378
|
**PowerPlatform:**
|
|
286
379
|
- `entity-overview` - Comprehensive entity overview
|
|
@@ -306,15 +399,42 @@ The server includes **18 prompts** that provide formatted, context-rich output:
|
|
|
306
399
|
- `appinsights-availability-report` - Availability and uptime report
|
|
307
400
|
- `appinsights-troubleshooting-guide` - Comprehensive troubleshooting guide combining all telemetry
|
|
308
401
|
|
|
402
|
+
**Log Analytics:**
|
|
403
|
+
- `loganalytics-workspace-summary` - Workspace health overview with all functions
|
|
404
|
+
- `loganalytics-function-troubleshooting` - Comprehensive function troubleshooting report
|
|
405
|
+
- `loganalytics-function-performance-report` - Performance analysis with recommendations
|
|
406
|
+
- `loganalytics-logs-report` - Formatted logs with insights for any table
|
|
407
|
+
|
|
309
408
|
**Azure SQL Database:**
|
|
310
409
|
- `sql-database-overview` - Comprehensive database schema overview with all objects
|
|
311
410
|
- `sql-table-details` - Detailed table report with columns, indexes, and relationships
|
|
312
411
|
- `sql-query-results` - Formatted query results with column headers
|
|
313
412
|
|
|
413
|
+
**GitHub Enterprise:**
|
|
414
|
+
- `ghe-repo-overview` - Repository overview with branch analysis and recent commits
|
|
415
|
+
- `ghe-code-search-report` - Formatted code search results with relevance scoring
|
|
416
|
+
- `ghe-branch-comparison-report` - Branch comparison with deployment checklist
|
|
417
|
+
- `ghe-troubleshooting-guide` - Bug troubleshooting with cross-service correlation (ADO + GHE + PowerPlatform)
|
|
418
|
+
- `ghe-deployment-report` - Deployment-ready report with rollback plan
|
|
419
|
+
|
|
314
420
|
## Documentation
|
|
315
421
|
|
|
422
|
+
### Per-Integration Documentation
|
|
423
|
+
|
|
424
|
+
Comprehensive documentation for each integration with setup, tools, prompts, examples, best practices, and troubleshooting:
|
|
425
|
+
|
|
426
|
+
- **[PowerPlatform/Dataverse](docs/documentation/POWERPLATFORM.md)** - 76 tools, 9 prompts (entity metadata, plugins, workflows, customization API)
|
|
427
|
+
- **[Azure DevOps](docs/documentation/AZURE_DEVOPS.md)** - 11 tools, 4 prompts (wikis, work items, WIQL queries)
|
|
428
|
+
- **[Figma](docs/documentation/FIGMA.md)** - 2 tools (design data extraction, AI-friendly format)
|
|
429
|
+
- **[Application Insights](docs/documentation/APPLICATION_INSIGHTS.md)** - 10 tools, 5 prompts (telemetry, exceptions, performance, dependencies)
|
|
430
|
+
- **[Log Analytics](docs/documentation/LOG_ANALYTICS.md)** - 10 tools, 5 prompts (Azure Functions logs, KQL queries, function diagnostics)
|
|
431
|
+
- **[Azure SQL Database](docs/documentation/AZURE_SQL.md)** - 9 tools, 3 prompts (schema exploration, read-only querying)
|
|
432
|
+
- **[GitHub Enterprise](docs/documentation/GITHUB_ENTERPRISE.md)** - 22 tools, 5 prompts (source code, commits, branches, PRs, code correlation)
|
|
433
|
+
|
|
434
|
+
### General Documentation
|
|
435
|
+
|
|
316
436
|
- **[SETUP.md](SETUP.md)** - Complete setup guide with credentials, troubleshooting, and security
|
|
317
|
-
- **[TOOLS.md](TOOLS.md)** - Full reference for all
|
|
437
|
+
- **[TOOLS.md](TOOLS.md)** - Full reference for all 138 tools and 28 prompts
|
|
318
438
|
- **[USAGE.md](USAGE.md)** - Examples and use cases for all integrations
|
|
319
439
|
- **[CLAUDE.md](CLAUDE.md)** - Architecture details and development guide
|
|
320
440
|
|
|
@@ -416,6 +536,20 @@ All integrations are optional and can be configured independently:
|
|
|
416
536
|
- Read-only access to telemetry data
|
|
417
537
|
- Entra ID recommended for production (higher rate limits)
|
|
418
538
|
|
|
539
|
+
**Log Analytics:**
|
|
540
|
+
- Supports Entra ID (OAuth) or API Key authentication
|
|
541
|
+
- Read-only access to workspace logs
|
|
542
|
+
- Can share credentials with Application Insights (automatic fallback)
|
|
543
|
+
- Entra ID recommended for production (higher rate limits)
|
|
544
|
+
|
|
545
|
+
**GitHub Enterprise:**
|
|
546
|
+
- Supports Personal Access Token (PAT) or GitHub App authentication
|
|
547
|
+
- PAT authentication is simpler (recommended for individual use)
|
|
548
|
+
- GitHub App authentication for organization-wide deployments (higher rate limits)
|
|
549
|
+
- Write operations disabled by default (enable with environment flags)
|
|
550
|
+
- Response caching with configurable TTL (default: 5 minutes)
|
|
551
|
+
- Required scopes for PAT: `repo` (required), `read:org` (optional)
|
|
552
|
+
|
|
419
553
|
See [SETUP.md](SETUP.md#security-best-practices) for security best practices.
|
|
420
554
|
|
|
421
555
|
## Examples
|
|
@@ -466,6 +600,31 @@ AI: [uses sql-execute-query tool with "SELECT TOP 10 * FROM dbo.Users WHERE IsAc
|
|
|
466
600
|
Returns formatted query results with column headers
|
|
467
601
|
```
|
|
468
602
|
|
|
603
|
+
### Troubleshoot bugs with GitHub Enterprise cross-service correlation
|
|
604
|
+
|
|
605
|
+
```
|
|
606
|
+
User: "Investigate bug reported in ADO work item #1234"
|
|
607
|
+
AI: [uses ghe-troubleshooting-guide prompt]
|
|
608
|
+
1. Gets work item details from Azure DevOps
|
|
609
|
+
2. Searches GitHub commits for "AB#1234" references
|
|
610
|
+
3. Retrieves changed code files
|
|
611
|
+
4. Checks deployed plugin assembly in PowerPlatform
|
|
612
|
+
5. Analyzes Application Insights exceptions
|
|
613
|
+
Returns comprehensive troubleshooting report with code changes, deployment status, and runtime errors
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
```
|
|
617
|
+
User: "Search GitHub for ContactPlugin implementation"
|
|
618
|
+
AI: [uses ghe-search-code tool]
|
|
619
|
+
Returns code search results with file paths and line numbers
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
```
|
|
623
|
+
User: "Compare release/9.0 and main branches"
|
|
624
|
+
AI: [uses ghe-branch-comparison-report prompt]
|
|
625
|
+
Returns formatted comparison with deployment checklist
|
|
626
|
+
```
|
|
627
|
+
|
|
469
628
|
See [USAGE.md](USAGE.md) for more examples.
|
|
470
629
|
|
|
471
630
|
## Development
|
|
@@ -30,7 +30,7 @@ export class AzureDevOpsService {
|
|
|
30
30
|
/**
|
|
31
31
|
* Make an authenticated request to the Azure DevOps API
|
|
32
32
|
*/
|
|
33
|
-
async makeRequest(endpoint, method = 'GET', data, useSearchUrl = false) {
|
|
33
|
+
async makeRequest(endpoint, method = 'GET', data, useSearchUrl = false, customHeaders) {
|
|
34
34
|
try {
|
|
35
35
|
const baseUrl = useSearchUrl ? this.searchUrl : this.baseUrl;
|
|
36
36
|
const url = `${baseUrl}/${endpoint}`;
|
|
@@ -40,7 +40,8 @@ export class AzureDevOpsService {
|
|
|
40
40
|
headers: {
|
|
41
41
|
'Authorization': this.authHeader,
|
|
42
42
|
'Content-Type': method === 'PATCH' ? 'application/json-patch+json' : 'application/json',
|
|
43
|
-
'Accept': 'application/json'
|
|
43
|
+
'Accept': 'application/json',
|
|
44
|
+
...customHeaders // Merge custom headers (can override defaults)
|
|
44
45
|
},
|
|
45
46
|
data
|
|
46
47
|
});
|
|
@@ -158,33 +159,67 @@ export class AzureDevOpsService {
|
|
|
158
159
|
*/
|
|
159
160
|
async getWikiPage(project, wikiId, pagePath, includeContent = true) {
|
|
160
161
|
this.validateProject(project);
|
|
161
|
-
//
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
162
|
+
// Always normalize paths to wiki format (removes .md, converts dashes to spaces)
|
|
163
|
+
// This ensures consistent behavior regardless of input format
|
|
164
|
+
const wikiPath = this.convertGitPathToWikiPath(pagePath);
|
|
165
|
+
// Log conversion if the path was changed (for debugging)
|
|
166
|
+
if (wikiPath !== pagePath) {
|
|
167
|
+
console.error(`Normalized wiki path: ${pagePath} -> ${wikiPath}`);
|
|
168
|
+
}
|
|
169
|
+
// Use axios directly to access response headers (for ETag)
|
|
170
|
+
const url = `${this.baseUrl}/${project}/_apis/wiki/wikis/${wikiId}/pages?path=${encodeURIComponent(wikiPath)}&includeContent=${includeContent}&api-version=${this.apiVersion}`;
|
|
171
|
+
try {
|
|
172
|
+
const axiosResponse = await axios({
|
|
173
|
+
method: 'GET',
|
|
174
|
+
url,
|
|
175
|
+
headers: {
|
|
176
|
+
'Authorization': this.authHeader,
|
|
177
|
+
'Content-Type': 'application/json',
|
|
178
|
+
'Accept': 'application/json'
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
const response = axiosResponse.data;
|
|
182
|
+
// Extract ETag from response headers (needed for updates)
|
|
183
|
+
const etag = axiosResponse.headers['etag'] || axiosResponse.headers['ETag'];
|
|
184
|
+
// The API returns the page data directly (not wrapped in a 'page' property)
|
|
185
|
+
return {
|
|
186
|
+
id: response.id,
|
|
187
|
+
path: response.path,
|
|
188
|
+
content: response.content,
|
|
189
|
+
gitItemPath: response.gitItemPath,
|
|
190
|
+
subPages: response.subPages || [],
|
|
191
|
+
url: response.url,
|
|
192
|
+
remoteUrl: response.remoteUrl,
|
|
193
|
+
version: etag, // Include ETag for use with updateWikiPage
|
|
194
|
+
project,
|
|
195
|
+
wikiId
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
// Handle errors similar to makeRequest
|
|
200
|
+
const errorDetails = error.response?.data?.message || error.response?.data || error.message;
|
|
201
|
+
console.error('Azure DevOps API request failed:', {
|
|
202
|
+
url,
|
|
203
|
+
status: error.response?.status,
|
|
204
|
+
error: errorDetails
|
|
205
|
+
});
|
|
206
|
+
if (error.response?.status === 401) {
|
|
207
|
+
throw new Error('Azure DevOps authentication failed. Please check your PAT token and permissions.');
|
|
208
|
+
}
|
|
209
|
+
if (error.response?.status === 403) {
|
|
210
|
+
throw new Error('Azure DevOps access denied. Please check your PAT scopes and project permissions.');
|
|
211
|
+
}
|
|
212
|
+
if (error.response?.status === 404) {
|
|
213
|
+
throw new Error(`Wiki page not found: ${wikiPath} (original input: ${pagePath})`);
|
|
214
|
+
}
|
|
215
|
+
throw new Error(`Azure DevOps API request failed: ${error.message} - ${JSON.stringify(errorDetails)}`);
|
|
168
216
|
}
|
|
169
|
-
const response = await this.makeRequest(`${project}/_apis/wiki/wikis/${wikiId}/pages?path=${encodeURIComponent(wikiPath)}&includeContent=${includeContent}&api-version=${this.apiVersion}`);
|
|
170
|
-
// The API returns the page data directly (not wrapped in a 'page' property)
|
|
171
|
-
return {
|
|
172
|
-
id: response.id,
|
|
173
|
-
path: response.path,
|
|
174
|
-
content: response.content,
|
|
175
|
-
gitItemPath: response.gitItemPath,
|
|
176
|
-
subPages: response.subPages || [],
|
|
177
|
-
url: response.url,
|
|
178
|
-
remoteUrl: response.remoteUrl,
|
|
179
|
-
project,
|
|
180
|
-
wikiId
|
|
181
|
-
};
|
|
182
217
|
}
|
|
183
218
|
/**
|
|
184
219
|
* Create a new wiki page
|
|
185
220
|
* @param project The project name
|
|
186
221
|
* @param wikiId The wiki identifier
|
|
187
|
-
* @param pagePath The path for the new page
|
|
222
|
+
* @param pagePath The path for the new page (will be normalized to wiki format)
|
|
188
223
|
* @param content The markdown content
|
|
189
224
|
* @returns Created page information
|
|
190
225
|
*/
|
|
@@ -193,7 +228,13 @@ export class AzureDevOpsService {
|
|
|
193
228
|
if (!this.config.enableWikiWrite) {
|
|
194
229
|
throw new Error('Wiki write operations are disabled. Set AZUREDEVOPS_ENABLE_WIKI_WRITE=true to enable.');
|
|
195
230
|
}
|
|
196
|
-
|
|
231
|
+
// Always normalize paths to wiki format (removes .md, converts dashes to spaces)
|
|
232
|
+
const wikiPath = this.convertGitPathToWikiPath(pagePath);
|
|
233
|
+
// Log conversion if the path was changed (for debugging)
|
|
234
|
+
if (wikiPath !== pagePath) {
|
|
235
|
+
console.error(`Normalized wiki path for creation: ${pagePath} -> ${wikiPath}`);
|
|
236
|
+
}
|
|
237
|
+
const response = await this.makeRequest(`${project}/_apis/wiki/wikis/${wikiId}/pages?path=${encodeURIComponent(wikiPath)}&api-version=${this.apiVersion}`, 'PUT', { content });
|
|
197
238
|
return {
|
|
198
239
|
id: response.page?.id,
|
|
199
240
|
path: response.page?.path,
|
|
@@ -206,9 +247,9 @@ export class AzureDevOpsService {
|
|
|
206
247
|
* Update an existing wiki page
|
|
207
248
|
* @param project The project name
|
|
208
249
|
* @param wikiId The wiki identifier
|
|
209
|
-
* @param pagePath The path to the page
|
|
250
|
+
* @param pagePath The path to the page (will be normalized to wiki format)
|
|
210
251
|
* @param content The updated markdown content
|
|
211
|
-
* @param version The ETag/version for optimistic concurrency
|
|
252
|
+
* @param version The ETag/version for optimistic concurrency (recommended to prevent conflicts)
|
|
212
253
|
* @returns Updated page information
|
|
213
254
|
*/
|
|
214
255
|
async updateWikiPage(project, wikiId, pagePath, content, version) {
|
|
@@ -216,7 +257,16 @@ export class AzureDevOpsService {
|
|
|
216
257
|
if (!this.config.enableWikiWrite) {
|
|
217
258
|
throw new Error('Wiki write operations are disabled. Set AZUREDEVOPS_ENABLE_WIKI_WRITE=true to enable.');
|
|
218
259
|
}
|
|
219
|
-
|
|
260
|
+
// Always normalize paths to wiki format (removes .md, converts dashes to spaces)
|
|
261
|
+
const wikiPath = this.convertGitPathToWikiPath(pagePath);
|
|
262
|
+
// Log conversion if the path was changed (for debugging)
|
|
263
|
+
if (wikiPath !== pagePath) {
|
|
264
|
+
console.error(`Normalized wiki path for update: ${pagePath} -> ${wikiPath}`);
|
|
265
|
+
}
|
|
266
|
+
// Add If-Match header if version is provided (for optimistic concurrency control)
|
|
267
|
+
const customHeaders = version ? { 'If-Match': version } : undefined;
|
|
268
|
+
const response = await this.makeRequest(`${project}/_apis/wiki/wikis/${wikiId}/pages?path=${encodeURIComponent(wikiPath)}&api-version=${this.apiVersion}`, 'PUT', { content }, false, // useSearchUrl
|
|
269
|
+
customHeaders);
|
|
220
270
|
return {
|
|
221
271
|
id: response.page?.id,
|
|
222
272
|
path: response.page?.path,
|