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 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, and Azure SQL Database through an AI-friendly interface.
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: 105+ MCP tools & 21 prompts** providing comprehensive access to your development and operations lifecycle.
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 **18 prompts** that provide formatted, context-rich output:
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 105+ tools and 21 prompts
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
- // Auto-convert git paths to wiki paths for better compatibility
162
- // If the path ends with .md, it's likely a git path from search results
163
- let wikiPath = pagePath;
164
- if (pagePath.endsWith('.md')) {
165
- wikiPath = this.convertGitPathToWikiPath(pagePath);
166
- // Log to stderr (not stdout) to avoid breaking MCP protocol
167
- console.error(`Auto-converted git path to wiki path: ${pagePath} -> ${wikiPath}`);
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
- const response = await this.makeRequest(`${project}/_apis/wiki/wikis/${wikiId}/pages?path=${encodeURIComponent(pagePath)}&api-version=${this.apiVersion}`, 'PUT', { content });
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
- const response = await this.makeRequest(`${project}/_apis/wiki/wikis/${wikiId}/pages?path=${encodeURIComponent(pagePath)}&api-version=${this.apiVersion}`, 'PUT', { content });
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,