diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a86330c --- /dev/null +++ b/LICENSE @@ -0,0 +1,18 @@ +MIT No Attribution + +Copyright (c) 2025 Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 5fc0fee..a701721 100644 --- a/README.md +++ b/README.md @@ -141,8 +141,16 @@ Documentation is available at https://kiro.dev/docs/powers/ --- +## Disclaimer + +These powers are provided as **base templates** for reference and starting points only. Each organization must perform their own due diligence before using them in production environments. You may need additional customization, security review, and configuration specific to your infrastructure, compliance requirements, and operational standards. + +The authors and contributors make no guarantees about the accuracy, completeness, or suitability of these templates for any particular use case. Use at your own risk. + ## License +This project is licensed under the [MIT-0 (MIT No Attribution)](LICENSE) license. + Unless otherwise specified by the license in the individual power or the repository that hosts it, Kiro users have a non-exclusive license to access, download, and otherwise use the power for their personal or business purposes. ## Security diff --git a/azure-devops/POWER.md b/azure-devops/POWER.md new file mode 100644 index 0000000..95dbd28 --- /dev/null +++ b/azure-devops/POWER.md @@ -0,0 +1,526 @@ +--- +name: "azure-devops" +displayName: "Azure DevOps" +description: "Manage repositories, pipelines, work items, pull requests, and boards in Azure DevOps for end-to-end software delivery" +keywords: ["azure-devops", "ado", "wiql", "azure-pipelines", "azure-boards", "azure-repos", "work-items"] +author: "Community" +--- + +# Azure DevOps Power + +## Overview + +The Azure DevOps Power connects to Azure DevOps Services for managing repositories, CI/CD pipelines, work items, pull requests, boards, and sprints. Work with Azure DevOps directly from your IDE. + +**Key capabilities:** +- **Repositories**: Create, manage, and search Git repositories +- **Pull Requests**: Create, review, approve, and complete PRs +- **Pipelines**: Trigger, monitor, and manage CI/CD pipelines +- **Work Items**: Create, update, query, and manage work items (bugs, tasks, user stories) +- **Boards**: View and manage sprint boards and backlogs +- **Build & Release**: Monitor builds, releases, and deployment status +- **Wiki**: Search and manage project wikis +- **Artifacts**: Manage package feeds and artifacts + +**Authentication**: Requires Azure DevOps organization URL and Personal Access Token (PAT). + +## Onboarding + +### Prerequisites + +1. **Azure DevOps organization** - Azure DevOps Services or Azure DevOps Server +2. **Personal Access Token (PAT)** - With appropriate scopes for your workflows +3. **Node.js 18+** - Required to run the MCP server via npx + +### Quick Start + +1. Install the power in Kiro +2. Replace placeholders in `mcp.json` with your organization URL and PAT +3. Test with: *"List my active work items"* or *"Show open pull requests"* + +### MCP Config Placeholders + +Before using this power, replace the following placeholders in `mcp.json`: + +- **`YOUR_ORGANIZATION`**: Your Azure DevOps organization name. + - **How to get it:** This is the organization name in your Azure DevOps URL: `https://dev.azure.com/YOUR_ORGANIZATION`. You can find it in Organization Settings. + +- **`YOUR_PERSONAL_ACCESS_TOKEN`**: An Azure DevOps Personal Access Token. + - **How to get it:** + 1. Log in to Azure DevOps + 2. Click your profile icon → Personal Access Tokens + 3. Click "New Token" + 4. Set scopes: Code (Read & Write), Work Items (Read & Write), Build (Read & Execute), Project (Read) + 5. Set expiration (recommend 90 days max) + 6. Copy the generated token (you won't see it again) + +## Available Steering Files + +- **steering/steering.md** - WIQL query syntax, pipeline patterns, and PR workflows + +## Available MCP Servers + +### azure-devops +**Package:** `@microsoft/azure-devops-mcp-server` +**Connection:** stdio via npx + +**Tools:** + +1. **get_work_item** - Get work item details + - Required: `id` (number) - Work item ID + - Optional: `expand` (string) - relations, fields, all + - Returns: Work item with fields and relations + +2. **create_work_item** - Create a new work item + - Required: `project` (string) - Project name + - Required: `type` (string) - Work item type (Bug, Task, User Story, Epic, Feature) + - Required: `title` (string) - Work item title + - Optional: `description` (string) - HTML description + - Optional: `assigned_to` (string) - Assignee email + - Optional: `area_path` (string) - Area path + - Optional: `iteration_path` (string) - Sprint/iteration + - Optional: `priority` (number) - 1-4 + - Optional: `parent_id` (number) - Parent work item ID + - Returns: Created work item + +3. **update_work_item** - Update a work item + - Required: `id` (number) - Work item ID + - Optional: `title` (string), `state` (string), `assigned_to` (string), `priority` (number), `description` (string) + - Returns: Updated work item + +4. **query_work_items** - Execute a WIQL query + - Required: `query` (string) - WIQL query + - Optional: `project` (string) - Project scope + - Returns: Matching work items + +5. **create_pull_request** - Create a pull request + - Required: `repository_id` (string) - Repository name or ID + - Required: `source_branch` (string) - Source branch (refs/heads/...) + - Required: `target_branch` (string) - Target branch + - Required: `title` (string) - PR title + - Optional: `description` (string) - PR description + - Optional: `reviewers` (array) - Reviewer IDs or emails + - Optional: `work_item_ids` (array) - Linked work items + - Optional: `is_draft` (boolean) - Create as draft + - Returns: Created PR details + +6. **get_pull_request** - Get PR details + - Required: `repository_id` (string) - Repository name or ID + - Required: `pull_request_id` (number) - PR ID + - Returns: Full PR with reviewers, status, and threads + +7. **list_pull_requests** - List pull requests + - Required: `repository_id` (string) - Repository name or ID + - Optional: `status` (string) - active, completed, abandoned + - Optional: `creator_id` (string) - Filter by creator + - Optional: `reviewer_id` (string) - Filter by reviewer + - Returns: List of PRs + +8. **complete_pull_request** - Complete (merge) a PR + - Required: `repository_id` (string) - Repository name or ID + - Required: `pull_request_id` (number) - PR ID + - Optional: `merge_strategy` (string) - squash, rebase, noFastForward + - Optional: `delete_source_branch` (boolean) - Delete branch after merge + - Optional: `transition_work_items` (boolean) - Move linked work items + - Returns: Completed PR + +9. **get_pipeline** - Get pipeline details + - Required: `pipeline_id` (number) - Pipeline ID + - Returns: Pipeline configuration and recent runs + +10. **list_pipelines** - List pipelines + - Optional: `project` (string) - Project name + - Returns: Pipelines with status + +11. **run_pipeline** - Trigger a pipeline run + - Required: `pipeline_id` (number) - Pipeline ID + - Optional: `branch` (string) - Branch to build + - Optional: `variables` (object) - Pipeline variables + - Returns: Pipeline run details + +12. **get_pipeline_run** - Get pipeline run status + - Required: `pipeline_id` (number) - Pipeline ID + - Required: `run_id` (number) - Run ID + - Returns: Run status, stages, and logs + +13. **list_repositories** - List repositories + - Optional: `project` (string) - Project name + - Returns: Repositories with metadata + +14. **get_file_contents** - Get file from repository + - Required: `repository_id` (string) - Repository name or ID + - Required: `path` (string) - File path + - Optional: `branch` (string) - Branch name + - Returns: File content + +15. **search_code** - Search code across repositories + - Required: `search_text` (string) - Search query + - Optional: `project` (string) - Project scope + - Optional: `repository` (string) - Repository filter + - Returns: Matching code with file paths + +16. **add_pr_comment** - Add comment to a PR + - Required: `repository_id` (string), `pull_request_id` (number), `content` (string) + - Optional: `file_path` (string), `line` (number) - For inline comments + - Returns: Created comment thread + +17. **get_iterations** - List sprint iterations + - Required: `project` (string) - Project name + - Optional: `timeframe` (string) - current, past, future + - Returns: Iterations with dates and paths + +## Tool Usage Examples + +### Work Item Management + +**Query open bugs:** +```javascript +usePower("azure-devops", "azure-devops", "query_work_items", { + "query": "SELECT [System.Id], [System.Title], [System.State], [System.AssignedTo], [Microsoft.VSTS.Common.Priority] FROM WorkItems WHERE [System.WorkItemType] = 'Bug' AND [System.State] <> 'Closed' AND [System.State] <> 'Resolved' ORDER BY [Microsoft.VSTS.Common.Priority] ASC", + "project": "MyProject" +}) +``` + +**Create a user story:** +```javascript +usePower("azure-devops", "azure-devops", "create_work_item", { + "project": "MyProject", + "type": "User Story", + "title": "As a user, I want to reset my password via email", + "description": "

Acceptance Criteria

", + "assigned_to": "developer@company.com", + "iteration_path": "MyProject\\Sprint 15", + "priority": 2 +}) +``` + +**Create a bug:** +```javascript +usePower("azure-devops", "azure-devops", "create_work_item", { + "project": "MyProject", + "type": "Bug", + "title": "Checkout fails with 500 error when cart has more than 50 items", + "description": "

Steps to Reproduce

  1. Add 51 items to cart
  2. Click checkout
  3. Observe 500 error

Expected

Checkout succeeds

Actual

HTTP 500 Internal Server Error

", + "priority": 1, + "area_path": "MyProject\\Backend" +}) +``` + +**Update work item state:** +```javascript +usePower("azure-devops", "azure-devops", "update_work_item", { + "id": 12345, + "state": "Active", + "assigned_to": "developer@company.com" +}) +``` + +### Pull Request Workflow + +**Create a PR:** +```javascript +usePower("azure-devops", "azure-devops", "create_pull_request", { + "repository_id": "my-repo", + "source_branch": "refs/heads/feature/password-reset", + "target_branch": "refs/heads/main", + "title": "feat: add password reset via email", + "description": "## Summary\nImplements password reset flow.\n\n## Changes\n- Reset endpoint\n- Email service integration\n- Token generation and validation\n\n## Testing\n- Unit tests added\n- Integration tests pass\n\nCloses #12345", + "work_item_ids": [12345], + "reviewers": ["reviewer@company.com"], + "is_draft": false +}) +``` + +**Complete a PR:** +```javascript +usePower("azure-devops", "azure-devops", "complete_pull_request", { + "repository_id": "my-repo", + "pull_request_id": 99, + "merge_strategy": "squash", + "delete_source_branch": true, + "transition_work_items": true +}) +``` + +### Pipeline Management + +**Trigger a build:** +```javascript +usePower("azure-devops", "azure-devops", "run_pipeline", { + "pipeline_id": 42, + "branch": "refs/heads/main", + "variables": { + "environment": "staging", + "skipTests": "false" + } +}) +``` + +**Check pipeline status:** +```javascript +usePower("azure-devops", "azure-devops", "get_pipeline_run", { + "pipeline_id": 42, + "run_id": 1001 +}) +``` + +## Combining Tools (Workflows) + +### Workflow 1: Feature Development + +```javascript +// Step 1: Create user story +const story = usePower("azure-devops", "azure-devops", "create_work_item", { + "project": "MyProject", + "type": "User Story", + "title": "Implement order history page", + "iteration_path": "MyProject\\Sprint 15", + "priority": 2 +}) + +// Step 2: Create tasks under the story +const task = usePower("azure-devops", "azure-devops", "create_work_item", { + "project": "MyProject", + "type": "Task", + "title": "Create order history API endpoint", + "parent_id": story.id, + "assigned_to": "developer@company.com" +}) + +// Step 3: After implementation, create PR +const pr = usePower("azure-devops", "azure-devops", "create_pull_request", { + "repository_id": "backend-api", + "source_branch": "refs/heads/feature/order-history", + "target_branch": "refs/heads/main", + "title": "feat: add order history endpoint", + "work_item_ids": [story.id, task.id] +}) + +// Step 4: After review, complete PR +const completed = usePower("azure-devops", "azure-devops", "complete_pull_request", { + "repository_id": "backend-api", + "pull_request_id": pr.pullRequestId, + "merge_strategy": "squash", + "delete_source_branch": true, + "transition_work_items": true +}) +``` + +### Workflow 2: Bug Fix Pipeline + +```javascript +// Step 1: Get bug details +const bug = usePower("azure-devops", "azure-devops", "get_work_item", { + "id": 54321, + "expand": "relations" +}) + +// Step 2: Search for related code +const code = usePower("azure-devops", "azure-devops", "search_code", { + "search_text": "checkout cart limit", + "repository": "backend-api" +}) + +// Step 3: Update bug to Active +const updated = usePower("azure-devops", "azure-devops", "update_work_item", { + "id": 54321, + "state": "Active", + "assigned_to": "developer@company.com" +}) + +// Step 4: Create PR with fix +const pr = usePower("azure-devops", "azure-devops", "create_pull_request", { + "repository_id": "backend-api", + "source_branch": "refs/heads/fix/checkout-cart-limit", + "target_branch": "refs/heads/main", + "title": "fix: handle large cart sizes in checkout", + "description": "Fixes #54321. Increases cart item limit and adds pagination for large carts.", + "work_item_ids": [54321] +}) + +// Step 5: Trigger pipeline +const run = usePower("azure-devops", "azure-devops", "run_pipeline", { + "pipeline_id": 42, + "branch": "refs/heads/fix/checkout-cart-limit" +}) + +// Step 6: Check pipeline result +const status = usePower("azure-devops", "azure-devops", "get_pipeline_run", { + "pipeline_id": 42, + "run_id": run.id +}) +``` + +### Workflow 3: Sprint Planning + +```javascript +// Step 1: Get current sprint +const iterations = usePower("azure-devops", "azure-devops", "get_iterations", { + "project": "MyProject", + "timeframe": "current" +}) + +// Step 2: Query sprint backlog +const backlog = usePower("azure-devops", "azure-devops", "query_work_items", { + "query": "SELECT [System.Id], [System.Title], [System.State], [System.AssignedTo], [Microsoft.VSTS.Scheduling.StoryPoints] FROM WorkItems WHERE [System.IterationPath] = 'MyProject\\Sprint 15' AND [System.WorkItemType] IN ('User Story', 'Bug') ORDER BY [Microsoft.VSTS.Common.Priority] ASC", + "project": "MyProject" +}) + +// Step 3: Check unfinished items from last sprint +const carryover = usePower("azure-devops", "azure-devops", "query_work_items", { + "query": "SELECT [System.Id], [System.Title], [System.State] FROM WorkItems WHERE [System.IterationPath] = 'MyProject\\Sprint 14' AND [System.State] <> 'Closed' AND [System.State] <> 'Resolved' AND [System.WorkItemType] IN ('User Story', 'Bug')", + "project": "MyProject" +}) +``` + +## WIQL Query Syntax + +### Basic Structure +```sql +SELECT [Field1], [Field2] +FROM WorkItems +WHERE [Condition] +ORDER BY [Field] ASC|DESC +``` + +### Common Fields +| Field | Description | +|-------|-------------| +| `[System.Id]` | Work item ID | +| `[System.Title]` | Title | +| `[System.State]` | State (New, Active, Resolved, Closed) | +| `[System.WorkItemType]` | Type (Bug, Task, User Story, Epic, Feature) | +| `[System.AssignedTo]` | Assignee | +| `[System.CreatedDate]` | Creation date | +| `[System.ChangedDate]` | Last modified date | +| `[System.AreaPath]` | Area path | +| `[System.IterationPath]` | Sprint/iteration | +| `[System.Tags]` | Tags | +| `[Microsoft.VSTS.Common.Priority]` | Priority (1-4) | +| `[Microsoft.VSTS.Scheduling.StoryPoints]` | Story points | +| `[Microsoft.VSTS.Common.Severity]` | Bug severity | + +### Operators +- `=`, `<>`, `>`, `<`, `>=`, `<=` +- `IN ('value1', 'value2')` +- `NOT IN ('value1')` +- `CONTAINS 'text'` +- `UNDER 'path'` (for area/iteration paths) +- `= @Me` (current user) +- `= @Today` (today's date) +- `>= @Today - 7` (7 days ago) + +### Example Queries + +**Active bugs by priority:** +```sql +SELECT [System.Id], [System.Title], [Microsoft.VSTS.Common.Priority] +FROM WorkItems +WHERE [System.WorkItemType] = 'Bug' + AND [System.State] = 'Active' +ORDER BY [Microsoft.VSTS.Common.Priority] ASC +``` + +**My work items:** +```sql +SELECT [System.Id], [System.Title], [System.State], [System.WorkItemType] +FROM WorkItems +WHERE [System.AssignedTo] = @Me + AND [System.State] <> 'Closed' +ORDER BY [System.ChangedDate] DESC +``` + +**Sprint burndown:** +```sql +SELECT [System.Id], [System.Title], [System.State], [Microsoft.VSTS.Scheduling.StoryPoints] +FROM WorkItems +WHERE [System.IterationPath] UNDER 'MyProject\Sprint 15' + AND [System.WorkItemType] IN ('User Story', 'Bug') +``` + +**Recently created items:** +```sql +SELECT [System.Id], [System.Title], [System.CreatedDate] +FROM WorkItems +WHERE [System.CreatedDate] >= @Today - 7 + AND [System.WorkItemType] <> 'Task' +ORDER BY [System.CreatedDate] DESC +``` + +## Best Practices + +### ✅ Do: +- **Link PRs to work items** - Enables traceability and auto-transitions +- **Use squash merge** - Keeps main branch history clean +- **Write descriptive PR descriptions** - Include summary, changes, and testing +- **Use WIQL for complex queries** - More powerful than UI filters +- **Delete source branches** - Keep repository clean after merge +- **Use draft PRs** - Signal work-in-progress +- **Transition work items** - Let PR completion move items to Done +- **Use branch policies** - Enforce reviews and build validation + +### ❌ Don't: +- **Push directly to main** - Always use PRs with branch policies +- **Create PRs without linked work items** - Breaks traceability +- **Skip pipeline checks** - Wait for green builds before merging +- **Leave stale branches** - Delete after merge +- **Use vague work item titles** - Be specific about what and why +- **Ignore failed pipelines** - Investigate and fix before merging + +## Configuration + +**Authentication Required**: Azure DevOps organization URL and PAT + +**Setup Steps:** + +1. **Create a Personal Access Token:** + - Go to Azure DevOps → User Settings → Personal Access Tokens + - Create token with scopes: Code (Read & Write), Work Items (Read & Write), Build (Read & Execute), Project (Read) + +2. **Configure in mcp.json:** + ```json + { + "mcpServers": { + "azure-devops": { + "command": "npx", + "args": ["-y", "@microsoft/azure-devops-mcp-server"], + "env": { + "AZURE_DEVOPS_ORG_URL": "https://dev.azure.com/YOUR_ORGANIZATION", + "AZURE_DEVOPS_PAT": "your-personal-access-token" + } + } + } + } + ``` + +3. **For Azure DevOps Server (on-prem):** + ```json + "env": { + "AZURE_DEVOPS_ORG_URL": "https://tfs.yourcompany.com/tfs/DefaultCollection", + "AZURE_DEVOPS_PAT": "your-pat" + } + ``` + +## Tips + +1. **Link everything** - PRs to work items, work items to each other +2. **Use WIQL** - More powerful than basic search for complex queries +3. **Squash merge** - Clean history, easy to revert +4. **Branch policies** - Enforce quality gates automatically +5. **Pipeline variables** - Parameterize builds for flexibility +6. **Sprint iterations** - Use iteration paths for sprint planning +7. **Area paths** - Organize by team or component +8. **Draft PRs** - Get early feedback before code is complete +9. **Auto-transition** - Let PR completion move work items +10. **Code search** - Find patterns across all repositories + +## Disclaimer + +This power is provided as a **base template** for reference and as a starting point only. Each organization must perform their own due diligence before using it in production environments. You may need additional customization, security review, and configuration specific to your infrastructure, compliance requirements, and operational standards. + +--- + +**Package:** `@microsoft/azure-devops-mcp-server` +**Source:** Microsoft +**License:** MIT-0 +**Documentation:** https://learn.microsoft.com/en-us/azure/devops/ diff --git a/azure-devops/mcp.json b/azure-devops/mcp.json new file mode 100644 index 0000000..402508f --- /dev/null +++ b/azure-devops/mcp.json @@ -0,0 +1,14 @@ +{ + "mcpServers": { + "azure-devops": { + "command": "npx", + "args": ["-y", "@microsoft/azure-devops-mcp-server"], + "env": { + "AZURE_DEVOPS_ORG_URL": "https://dev.azure.com/YOUR_ORGANIZATION", + "AZURE_DEVOPS_PAT": "YOUR_PERSONAL_ACCESS_TOKEN" + }, + "disabled": false, + "autoApprove": [] + } + } +} diff --git a/azure-devops/steering/steering.md b/azure-devops/steering/steering.md new file mode 100644 index 0000000..0507365 --- /dev/null +++ b/azure-devops/steering/steering.md @@ -0,0 +1,461 @@ +# Azure DevOps MCP Server Steering Guide + +This steering file covers the Azure DevOps MCP server to manage work items, pull requests, pipelines, and repositories. + +## When to Use the Azure DevOps MCP Server + +Use Azure DevOps MCP tools when you need to: +- **Manage work items**: Create, update, and query bugs, tasks, user stories, and epics +- **Handle pull requests**: Create, review, comment on, and complete PRs +- **Run pipelines**: Trigger builds, check status, and monitor deployments +- **Search code**: Find patterns across repositories +- **Plan sprints**: Query backlogs, manage iterations, and track progress + +## Core Principles + +### 1. Link Everything +Always link PRs to work items and work items to each other. This enables traceability, auto-transitions, and reporting. + +### 2. Use Branch Policies +Enforce code review, build validation, and work item linking through branch policies on main/release branches. + +### 3. Automate State Transitions +Configure PR completion to automatically transition linked work items to the next state. + +--- + +## WIQL (Work Item Query Language) Reference + +### Basic Syntax +```sql +SELECT [Field1], [Field2], ... +FROM WorkItems +WHERE [Condition1] AND [Condition2] +ORDER BY [Field] ASC|DESC +``` + +### Field Reference + +**System fields:** +| Field | Description | Example Values | +|-------|-------------|----------------| +| `[System.Id]` | Work item ID | 12345 | +| `[System.Title]` | Title text | "Fix login bug" | +| `[System.State]` | Current state | New, Active, Resolved, Closed | +| `[System.WorkItemType]` | Item type | Bug, Task, User Story, Epic, Feature | +| `[System.AssignedTo]` | Assignee | "user@company.com" | +| `[System.CreatedDate]` | Created date | 2024-01-15 | +| `[System.ChangedDate]` | Last modified | 2024-01-20 | +| `[System.CreatedBy]` | Creator | "user@company.com" | +| `[System.AreaPath]` | Area path | "Project\\Backend" | +| `[System.IterationPath]` | Sprint | "Project\\Sprint 15" | +| `[System.Tags]` | Tags | "api, urgent" | +| `[System.Description]` | Description | HTML content | +| `[System.Reason]` | State change reason | "Fixed" | + +**VSTS fields:** +| Field | Description | Example Values | +|-------|-------------|----------------| +| `[Microsoft.VSTS.Common.Priority]` | Priority | 1, 2, 3, 4 | +| `[Microsoft.VSTS.Common.Severity]` | Bug severity | 1-Critical, 2-High, 3-Medium, 4-Low | +| `[Microsoft.VSTS.Scheduling.StoryPoints]` | Story points | 1, 2, 3, 5, 8, 13 | +| `[Microsoft.VSTS.Scheduling.RemainingWork]` | Remaining hours | 4.0 | +| `[Microsoft.VSTS.Scheduling.OriginalEstimate]` | Original estimate | 8.0 | +| `[Microsoft.VSTS.Scheduling.CompletedWork]` | Completed hours | 4.0 | +| `[Microsoft.VSTS.Common.AcceptanceCriteria]` | Acceptance criteria | HTML content | +| `[Microsoft.VSTS.TCM.ReproSteps]` | Repro steps (bugs) | HTML content | + +### Operators + +| Operator | Description | Example | +|----------|-------------|---------| +| `=` | Equals | `[System.State] = 'Active'` | +| `<>` | Not equals | `[System.State] <> 'Closed'` | +| `>`, `<`, `>=`, `<=` | Comparison | `[Microsoft.VSTS.Common.Priority] <= 2` | +| `IN` | In list | `[System.State] IN ('Active', 'New')` | +| `NOT IN` | Not in list | `[System.WorkItemType] NOT IN ('Task')` | +| `CONTAINS` | Text contains | `[System.Title] CONTAINS 'checkout'` | +| `NOT CONTAINS` | Text doesn't contain | `[System.Title] NOT CONTAINS 'test'` | +| `UNDER` | Path hierarchy | `[System.AreaPath] UNDER 'Project\\Backend'` | +| `NOT UNDER` | Not in path | `[System.IterationPath] NOT UNDER 'Project\\Archive'` | +| `WAS EVER` | Historical | `[System.AssignedTo] WAS EVER @Me` | + +### Macros + +| Macro | Description | +|-------|-------------| +| `@Me` | Current user | +| `@Today` | Today's date | +| `@Today - N` | N days ago | +| `@Today + N` | N days from now | +| `@CurrentIteration` | Current sprint | +| `@CurrentIteration + 1` | Next sprint | +| `@CurrentIteration - 1` | Previous sprint | +| `@Project` | Current project | +| `@TeamAreas` | Current team's area paths | + +### Common Query Patterns + +**My active work:** +```sql +SELECT [System.Id], [System.Title], [System.State], [System.WorkItemType] +FROM WorkItems +WHERE [System.AssignedTo] = @Me + AND [System.State] NOT IN ('Closed', 'Resolved', 'Removed') +ORDER BY [Microsoft.VSTS.Common.Priority] ASC, [System.ChangedDate] DESC +``` + +**Sprint backlog:** +```sql +SELECT [System.Id], [System.Title], [System.State], [System.AssignedTo], + [Microsoft.VSTS.Scheduling.StoryPoints] +FROM WorkItems +WHERE [System.IterationPath] = @CurrentIteration + AND [System.WorkItemType] IN ('User Story', 'Bug') +ORDER BY [Microsoft.VSTS.Common.Priority] ASC +``` + +**Unresolved bugs by severity:** +```sql +SELECT [System.Id], [System.Title], [Microsoft.VSTS.Common.Severity], + [System.AssignedTo], [System.CreatedDate] +FROM WorkItems +WHERE [System.WorkItemType] = 'Bug' + AND [System.State] NOT IN ('Closed', 'Resolved') +ORDER BY [Microsoft.VSTS.Common.Severity] ASC, [System.CreatedDate] ASC +``` + +**Items changed this week:** +```sql +SELECT [System.Id], [System.Title], [System.State], [System.ChangedDate] +FROM WorkItems +WHERE [System.ChangedDate] >= @Today - 7 + AND [System.WorkItemType] <> 'Task' +ORDER BY [System.ChangedDate] DESC +``` + +**Blocked items:** +```sql +SELECT [System.Id], [System.Title], [System.State], [System.Tags] +FROM WorkItems +WHERE [System.Tags] CONTAINS 'blocked' + AND [System.State] NOT IN ('Closed', 'Resolved') +``` + +**Items without estimates:** +```sql +SELECT [System.Id], [System.Title], [System.WorkItemType] +FROM WorkItems +WHERE [System.IterationPath] = @CurrentIteration + AND [System.WorkItemType] = 'User Story' + AND [Microsoft.VSTS.Scheduling.StoryPoints] = '' +``` + +**Carry-over from last sprint:** +```sql +SELECT [System.Id], [System.Title], [System.State], + [Microsoft.VSTS.Scheduling.StoryPoints] +FROM WorkItems +WHERE [System.IterationPath] = @CurrentIteration - 1 + AND [System.State] NOT IN ('Closed', 'Resolved', 'Removed') + AND [System.WorkItemType] IN ('User Story', 'Bug') +``` + +--- + +## Pull Request Best Practices + +### Branch Naming +- `feature/description` - New features +- `fix/description` - Bug fixes +- `hotfix/description` - Production hotfixes +- `refactor/description` - Code refactoring +- `docs/description` - Documentation updates + +### PR Title Format +Follow conventional commits: +- `feat: add password reset flow` +- `fix: handle null pointer in checkout` +- `refactor: extract payment validation` +- `docs: update API documentation` + +### PR Description Template +```markdown +## Summary +Brief description of what this PR does. + +## Changes +- Change 1 +- Change 2 +- Change 3 + +## Testing +- [ ] Unit tests pass +- [ ] Integration tests pass +- [ ] Manual testing completed + +## Related Work Items +Closes #12345 +``` + +### Merge Strategies + +| Strategy | When to Use | +|----------|-------------| +| Squash | Default for feature branches - clean history | +| Rebase | When you want linear history without merge commits | +| No Fast-Forward | When you want to preserve branch history | + +--- + +## Pipeline Patterns + +### Triggering Pipelines + +**Standard build:** +```javascript +run_pipeline({ + "pipeline_id": 42, + "branch": "refs/heads/main" +}) +``` + +**With variables:** +```javascript +run_pipeline({ + "pipeline_id": 42, + "branch": "refs/heads/release/v2.0", + "variables": { + "environment": "production", + "skipTests": "false", + "deployRegion": "us-east-1" + } +}) +``` + +### Monitoring Pipeline Runs + +1. Trigger the pipeline +2. Get the run ID from the response +3. Poll `get_pipeline_run` for status +4. Check for failed stages/jobs +5. If failed, investigate logs + +### Common Pipeline States +- `notStarted` - Queued +- `inProgress` - Running +- `completed` - Finished (check result) +- `canceling` / `canceled` - Cancelled + +### Pipeline Results +- `succeeded` - All stages passed +- `failed` - One or more stages failed +- `canceled` - Run was cancelled +- `partiallySucceeded` - Some stages failed but run continued + +--- + +## Work Item State Transitions + +### User Story +``` +New → Active → Resolved → Closed + ↓ ↑ + Removed Active (reactivated) +``` + +### Bug +``` +New → Active → Resolved → Closed + ↓ ↓ ↑ + ↓ Removed Active (reactivated) + └→ Resolved (by design / cannot reproduce) +``` + +### Task +``` +New → Active → Closed + ↓ + Removed +``` + +--- + +## Sprint Planning Workflow + +### 1. Review Previous Sprint +```sql +-- Completed items +SELECT [System.Id], [System.Title], [Microsoft.VSTS.Scheduling.StoryPoints] +FROM WorkItems +WHERE [System.IterationPath] = @CurrentIteration - 1 + AND [System.State] IN ('Closed', 'Resolved') + AND [System.WorkItemType] IN ('User Story', 'Bug') + +-- Carry-over items +SELECT [System.Id], [System.Title], [Microsoft.VSTS.Scheduling.StoryPoints] +FROM WorkItems +WHERE [System.IterationPath] = @CurrentIteration - 1 + AND [System.State] NOT IN ('Closed', 'Resolved', 'Removed') +``` + +### 2. Plan Current Sprint +```sql +-- Backlog items ready for sprint +SELECT [System.Id], [System.Title], [Microsoft.VSTS.Common.Priority], + [Microsoft.VSTS.Scheduling.StoryPoints] +FROM WorkItems +WHERE [System.IterationPath] = @Project + AND [System.State] = 'New' + AND [System.WorkItemType] IN ('User Story', 'Bug') +ORDER BY [Microsoft.VSTS.Common.Priority] ASC +``` + +### 3. Track Progress +```sql +-- Sprint burndown data +SELECT [System.Id], [System.State], [Microsoft.VSTS.Scheduling.StoryPoints] +FROM WorkItems +WHERE [System.IterationPath] = @CurrentIteration + AND [System.WorkItemType] IN ('User Story', 'Bug') +``` + +--- + +## Troubleshooting + +### WIQL Query Errors +1. Check field names are correct (case-sensitive) +2. Verify string values are in single quotes +3. Ensure dates use correct format +4. Check that macros are supported in your context +5. Verify area/iteration paths exist + +### PR Creation Fails +1. Verify branch names include `refs/heads/` prefix +2. Check source branch exists and has commits ahead of target +3. Verify repository name or ID is correct +4. Check branch policies aren't blocking creation + +### Pipeline Not Triggering +1. Verify pipeline ID is correct +2. Check branch name format +3. Verify PAT has Build (Execute) permission +4. Check pipeline isn't disabled or paused + +--- + +## Summary Checklist + +For effective Azure DevOps usage: +- ✅ Link PRs to work items for traceability +- ✅ Use WIQL for complex work item queries +- ✅ Follow conventional commit format for PR titles +- ✅ Use squash merge for clean history +- ✅ Delete source branches after merge +- ✅ Include `refs/heads/` prefix for branch names +- ✅ Set up branch policies for quality gates +- ✅ Use iteration paths for sprint planning +- ✅ Monitor pipeline status after triggering +- ✅ Auto-transition work items on PR completion + +--- + +## Security Guardrails + +### Credential Protection +- **NEVER** log, echo, or expose `AZURE_DEVOPS_PAT` values in responses +- When referencing tokens, use placeholder names (e.g., "your PAT") not actual values +- Do not include PATs in work item descriptions, PR comments, or pipeline variables + +### Repository and Code Safety +- **Never push secrets to repositories** - if file content contains API keys, passwords, or tokens, refuse and warn the user +- **Never push directly to `main` or protected branches** - always use feature branches and PRs +- **Do not modify pipeline YAML** (`azure-pipelines.yml`) without explicit user approval - CI/CD changes can have security implications +- **Do not set pipeline variables containing secrets** without explicit user confirmation +- When using `push_files` or `create_or_update_file`, verify content does not contain hardcoded credentials + +### Data Sensitivity +- Work items may contain sensitive information - customer details, security vulnerabilities, internal architecture +- Code search results may contain sensitive patterns - do not reproduce large blocks that appear to contain secrets +- Pipeline logs may contain secrets - summarize errors rather than reproducing full logs verbatim +- Do not expose internal project names, organization URLs, or infrastructure details to unauthorized contexts +- WIQL query results may contain PII in work item fields - summarize rather than reproduce verbatim + +### Access Control +- Only access projects and repositories the configured PAT has permissions for +- Do not attempt to enumerate organizations, projects, or teams beyond what's needed +- If an operation returns 403/401, report the error without retrying with different credentials +- Do not attempt to bypass branch policies, required reviewers, or build validation +- Do not attempt to modify project-level settings, policies, or permissions +- Respect area path and iteration path security - some paths may be restricted + +## Anti-Hallucination Guardrails + +### Query Accuracy +- **Only use valid WIQL syntax** - do not invent field names, operators, or clauses +- **Only use documented field references** - valid system fields start with `[System.]`, VSTS fields with `[Microsoft.VSTS.]` +- **Do not fabricate work item IDs, PR IDs, or pipeline IDs** - always query first to confirm they exist +- **Do not assume branch names** - verify branches exist before creating PRs (use `refs/heads/` prefix) +- **Do not invent WIQL macros** - valid macros: `@Me`, `@Today`, `@Today - N`, `@CurrentIteration`, `@Project`, `@TeamAreas` +- **Do not assume work item types** - valid types vary by process template (Agile, Scrum, CMMI); common types: Bug, Task, User Story, Epic, Feature + +### Result Interpretation +- **Never invent API responses** - if a tool hasn't been called, say "I need to check this" rather than guessing +- **Do not assume PR status** - always check current state before suggesting merge or review actions +- **Do not assume pipeline status** - verify before claiming a pipeline passed or failed +- **Do not assume work item states** - states vary by work item type and process template +- **If a query returns no results**, report that clearly rather than speculating +- **Do not fabricate iteration paths, area paths, or team names** - these are organization-specific + +### Tool Capability Boundaries +- Do not claim ability to approve PRs on behalf of other users +- Do not claim ability to modify branch policies or project settings +- Do not claim ability to manage build agents, service connections, or variable groups +- Do not claim ability to create or modify pipeline definitions (only trigger existing ones) +- Clearly state when an action requires the user to perform it in the Azure DevOps UI + +## Operational Optimization Guardrails + +### API Rate Limiting +- **Azure DevOps has rate limits** (varies by plan, typically 200 requests/minute) - be mindful of call volume +- **Use WIQL for bulk queries** - a single WIQL query is more efficient than multiple individual work item fetches +- **Cache work item IDs and PR IDs** - once found, reuse without re-querying +- **Use `$top` / `limit` parameters** to control result sizes +- **Avoid paginating through all results** - use specific WIQL filters instead + +### Request Efficiency +- **Use WIQL over list operations** - `query_work_items` with specific WHERE clauses is more efficient than listing and filtering +- **Minimize diff fetches** - PR diffs can be large; only fetch when reviewing +- **Don't repeatedly check pipeline status** - check once, wait, then check again if needed +- **Use `expand` parameter wisely** - only expand relations when you need them; it adds overhead +- **Batch work item updates** when possible - plan changes before executing + +### Workflow Efficiency +- **Create branch + push + PR in sequence** - minimize intermediate operations +- **Link work items at PR creation** - use `work_item_ids` parameter rather than updating later +- **Use `transition_work_items: true`** on PR completion - automates state changes +- **Use `delete_source_branch: true`** on merge - keeps repository clean automatically +- **Use draft PRs** for work-in-progress - avoids triggering required reviewers prematurely + +## Cost Optimization Guardrails + +### API Usage +- **Minimize API calls** - plan the workflow before executing, determine minimum calls needed +- **Avoid redundant queries** - if you already have the information, don't query again +- **Use WIQL efficiently** - a well-crafted WIQL query replaces multiple API calls +- **Batch file operations** - push multiple files in one commit when possible + +### Pipeline Cost Awareness +- **Every pipeline run consumes compute** - don't trigger pipelines unnecessarily +- **Use `variables` parameter wisely** - skip expensive test stages during development with variables like `skipTests=true` +- **Don't trigger pipelines on every push** - consider using draft PRs that may skip CI +- **Consider parallel pipeline costs** - multiple simultaneous runs multiply compute usage +- **Avoid force-pushing repeatedly** - each push to a PR branch may trigger a new pipeline run + +### Work Item Efficiency +- **Use WIQL to find existing items** before creating duplicates +- **Proper categorization reduces rework** - correct area path and iteration path on creation +- **Link related items** - reduces duplicate investigation and improves traceability +- **Use tags for cross-cutting concerns** - more efficient than creating duplicate work items +- **Close completed items promptly** - reduces noise in queries and boards diff --git a/github/POWER.md b/github/POWER.md new file mode 100644 index 0000000..09354ca --- /dev/null +++ b/github/POWER.md @@ -0,0 +1,418 @@ +--- +name: "github" +displayName: "GitHub" +description: "Manage repositories, issues, pull requests, workflows, code search, and collaboration on GitHub directly from your IDE" +keywords: ["github", "git", "repository", "pull-request", "issues", "actions", "ci", "cd", "code-review", "collaboration", "workflows"] +author: "Community" +--- + +# GitHub Power + +## Overview + +The GitHub Power connects to GitHub's platform for repository management, code collaboration, issue tracking, CI/CD workflows, and code search. Work with GitHub directly from your IDE. + +**Key capabilities:** +- **Repository Management**: Create, fork, search, and manage repositories +- **Pull Requests**: Create, review, merge PRs with full diff and comment support +- **Issues**: Create, search, update, and manage issues with labels and assignees +- **Code Search**: Search code across repositories with advanced query syntax +- **Actions & Workflows**: Trigger and monitor CI/CD workflows +- **Branch Management**: Create, protect, and manage branches +- **File Operations**: Read, create, and update files directly in repositories +- **Collaboration**: Manage teams, reviews, and notifications + +**Authentication**: Requires a GitHub Personal Access Token (PAT). + +## Onboarding + +### Prerequisites + +1. **GitHub account** - GitHub.com or GitHub Enterprise +2. **Personal Access Token** - Fine-grained token with appropriate repository permissions +3. **Node.js 18+** - Required to run the MCP server via npx + +### Quick Start + +1. Install the power in Kiro +2. Replace the placeholder in `mcp.json` with your GitHub PAT +3. Test with: *"List my open pull requests"* or *"Search issues in my repo"* + +### MCP Config Placeholders + +Before using this power, replace the following placeholder in `mcp.json`: + +- **`YOUR_GITHUB_TOKEN`**: A GitHub Personal Access Token. + - **How to get it:** + 1. Go to GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens + 2. Click "Generate new token" + 3. Select the repositories you want to grant access to + 4. Set permissions: Contents (Read & Write), Issues (Read & Write), Pull requests (Read & Write), Metadata (Read) + 5. Click "Generate token" and copy the value (starts with `github_pat_`) + +## Available Steering Files + +- **steering/steering.md** - Search syntax, PR workflows, issue management, code search patterns, and branch conventions + +## Available MCP Servers + +### github +**Package:** `@modelcontextprotocol/server-github` +**Connection:** stdio via npx + +**Tools:** + +1. **create_or_update_file** - Create or update a file in a repository + - Required: `owner` (string), `repo` (string), `path` (string), `content` (string), `message` (string), `branch` (string) + - Optional: `sha` (string) - Required for updates + - Returns: File commit details + +2. **search_repositories** - Search GitHub repositories + - Required: `query` (string) - Search query + - Optional: `page` (number), `perPage` (number) + - Returns: Matching repositories with metadata + +3. **create_repository** - Create a new repository + - Required: `name` (string) + - Optional: `description` (string), `private` (boolean), `autoInit` (boolean) + - Returns: Created repository details + +4. **get_file_contents** - Get file or directory contents + - Required: `owner` (string), `repo` (string), `path` (string) + - Optional: `branch` (string) + - Returns: File content (base64) or directory listing + +5. **push_files** - Push multiple files in a single commit + - Required: `owner` (string), `repo` (string), `branch` (string), `files` (array), `message` (string) + - Returns: Commit details + +6. **create_issue** - Create a new issue + - Required: `owner` (string), `repo` (string), `title` (string) + - Optional: `body` (string), `assignees` (array), `labels` (array), `milestone` (number) + - Returns: Created issue details + +7. **create_pull_request** - Create a pull request + - Required: `owner` (string), `repo` (string), `title` (string), `head` (string), `base` (string) + - Optional: `body` (string), `draft` (boolean), `maintainer_can_modify` (boolean) + - Returns: Created PR details + +8. **fork_repository** - Fork a repository + - Required: `owner` (string), `repo` (string) + - Optional: `organization` (string) + - Returns: Forked repository details + +9. **create_branch** - Create a new branch + - Required: `owner` (string), `repo` (string), `branch` (string) + - Optional: `from_branch` (string) - Source branch (default: repo default branch) + - Returns: Branch reference details + +10. **list_issues** - List issues in a repository + - Required: `owner` (string), `repo` (string) + - Optional: `state` (string), `labels` (string), `sort` (string), `direction` (string), `page` (number) + - Returns: List of issues + +11. **update_issue** - Update an existing issue + - Required: `owner` (string), `repo` (string), `issue_number` (number) + - Optional: `title` (string), `body` (string), `state` (string), `labels` (array), `assignees` (array) + - Returns: Updated issue details + +12. **add_issue_comment** - Add a comment to an issue or PR + - Required: `owner` (string), `repo` (string), `issue_number` (number), `body` (string) + - Returns: Created comment details + +13. **search_code** - Search code across repositories + - Required: `q` (string) - Search query + - Optional: `page` (number), `perPage` (number) + - Returns: Matching code with file paths and snippets + +14. **search_issues** - Search issues and pull requests + - Required: `q` (string) - Search query + - Optional: `sort` (string), `order` (string), `page` (number), `perPage` (number) + - Returns: Matching issues/PRs + +15. **search_users** - Search GitHub users + - Required: `q` (string) - Search query + - Optional: `page` (number), `perPage` (number) + - Returns: Matching users + +16. **list_commits** - List commits in a repository + - Required: `owner` (string), `repo` (string) + - Optional: `sha` (string), `page` (number), `perPage` (number) + - Returns: Commit history + +17. **get_issue** - Get details of a specific issue + - Required: `owner` (string), `repo` (string), `issue_number` (number) + - Returns: Full issue details with comments + +18. **get_pull_request** - Get details of a pull request + - Required: `owner` (string), `repo` (string), `pull_number` (number) + - Returns: Full PR details with diff stats + +19. **list_pull_requests** - List pull requests + - Required: `owner` (string), `repo` (string) + - Optional: `state` (string), `head` (string), `base` (string), `sort` (string) + - Returns: List of pull requests + +20. **get_pull_request_diff** - Get the diff of a pull request + - Required: `owner` (string), `repo` (string), `pull_number` (number) + - Returns: PR diff content + +21. **merge_pull_request** - Merge a pull request + - Required: `owner` (string), `repo` (string), `pull_number` (number) + - Optional: `commit_title` (string), `commit_message` (string), `merge_method` (string) + - Returns: Merge result + +22. **get_pull_request_reviews** - Get reviews for a PR + - Required: `owner` (string), `repo` (string), `pull_number` (number) + - Returns: List of reviews with status + +23. **create_pull_request_review** - Submit a review on a PR + - Required: `owner` (string), `repo` (string), `pull_number` (number), `event` (string) + - Optional: `body` (string), `comments` (array) + - Returns: Created review + +## Tool Usage Examples + +### Repository Management + +**Search repositories:** +```javascript +usePower("github", "github", "search_repositories", { + "query": "language:typescript stars:>1000 topic:react" +}) +``` + +**Create a repository:** +```javascript +usePower("github", "github", "create_repository", { + "name": "my-new-project", + "description": "A new TypeScript project", + "private": true, + "autoInit": true +}) +``` + +### Pull Request Workflow + +**Create a PR:** +```javascript +usePower("github", "github", "create_pull_request", { + "owner": "myorg", + "repo": "myrepo", + "title": "feat: add user authentication", + "head": "feature/auth", + "base": "main", + "body": "## Summary\nAdds JWT-based authentication\n\n## Changes\n- Login endpoint\n- Token refresh\n- Middleware", + "draft": false +}) +``` + +**Review a PR:** +```javascript +usePower("github", "github", "get_pull_request_diff", { + "owner": "myorg", + "repo": "myrepo", + "pull_number": 42 +}) +``` + +### Issue Management + +**Create an issue:** +```javascript +usePower("github", "github", "create_issue", { + "owner": "myorg", + "repo": "myrepo", + "title": "Bug: Login fails with special characters in password", + "body": "## Steps to Reproduce\n1. Enter password with `&` character\n2. Click login\n\n## Expected\nSuccessful login\n\n## Actual\n400 Bad Request", + "labels": ["bug", "priority:high"], + "assignees": ["developer1"] +}) +``` + +**Search issues:** +```javascript +usePower("github", "github", "search_issues", { + "q": "repo:myorg/myrepo is:open label:bug sort:created-desc" +}) +``` + +### Code Search + +**Find usage patterns:** +```javascript +usePower("github", "github", "search_code", { + "q": "org:myorg useAuth filename:*.ts" +}) +``` + +## Combining Tools (Workflows) + +### Workflow 1: Feature Development + +```javascript +// Step 1: Create a branch +const branch = usePower("github", "github", "create_branch", { + "owner": "myorg", "repo": "myrepo", + "branch": "feature/new-api-endpoint" +}) + +// Step 2: Push implementation files +const commit = usePower("github", "github", "push_files", { + "owner": "myorg", "repo": "myrepo", + "branch": "feature/new-api-endpoint", + "files": [ + {"path": "src/routes/users.ts", "content": "..."}, + {"path": "src/tests/users.test.ts", "content": "..."} + ], + "message": "feat: add users API endpoint" +}) + +// Step 3: Create PR +const pr = usePower("github", "github", "create_pull_request", { + "owner": "myorg", "repo": "myrepo", + "title": "feat: add users API endpoint", + "head": "feature/new-api-endpoint", + "base": "main", + "body": "Adds CRUD operations for users" +}) + +// Step 4: Create tracking issue +const issue = usePower("github", "github", "create_issue", { + "owner": "myorg", "repo": "myrepo", + "title": "Track: Users API implementation", + "body": `PR: #${pr.number}\n\n- [x] Create endpoint\n- [ ] Add pagination\n- [ ] Add filtering`, + "labels": ["feature", "in-progress"] +}) +``` + +### Workflow 2: Bug Investigation + +```javascript +// Step 1: Search for related issues +const issues = usePower("github", "github", "search_issues", { + "q": "repo:myorg/myrepo is:issue label:bug authentication" +}) + +// Step 2: Search code for the problematic area +const code = usePower("github", "github", "search_code", { + "q": "repo:myorg/myrepo validatePassword filename:auth" +}) + +// Step 3: Check recent commits for changes +const commits = usePower("github", "github", "list_commits", { + "owner": "myorg", "repo": "myrepo", + "sha": "main" +}) + +// Step 4: Check open PRs that might be related +const prs = usePower("github", "github", "list_pull_requests", { + "owner": "myorg", "repo": "myrepo", + "state": "open" +}) +``` + +## Search Query Syntax + +### Repository Search +- `language:typescript` - Filter by language +- `stars:>1000` - Minimum stars +- `topic:react` - By topic +- `org:myorg` - Within organization +- `fork:true` - Include forks +- `archived:false` - Exclude archived + +### Code Search +- `org:myorg` - Within organization +- `repo:owner/repo` - Specific repository +- `filename:*.ts` - File type +- `path:src/` - Directory path +- `language:python` - Language filter +- `"exact phrase"` - Exact match + +### Issue/PR Search +- `is:open` / `is:closed` - State +- `is:issue` / `is:pr` - Type +- `label:bug` - By label +- `assignee:username` - By assignee +- `author:username` - By author +- `milestone:"v1.0"` - By milestone +- `created:>2024-01-01` - Date filter +- `sort:created-desc` - Sort order + +## Best Practices + +### ✅ Do: +- **Use descriptive PR titles** following conventional commits (feat:, fix:, docs:) +- **Include PR body** with summary, changes, and testing notes +- **Label issues** for easy filtering and prioritization +- **Search before creating** to avoid duplicate issues +- **Use draft PRs** for work-in-progress +- **Reference issues in PRs** with "Closes #123" syntax +- **Use branch naming conventions** (feature/, fix/, docs/) + +### ❌ Don't: +- **Push directly to main** - always use branches and PRs +- **Create PRs without description** - reviewers need context +- **Leave issues without labels** - makes triage difficult +- **Merge without reviews** - enforce review requirements +- **Use vague commit messages** - be specific about changes + +## Configuration + +**Authentication Required**: GitHub Personal Access Token (PAT) + +**Setup Steps:** + +1. **Create a Personal Access Token:** + - Go to GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens + - Select repositories to grant access + - Permissions needed: Contents (read/write), Issues (read/write), Pull requests (read/write), Metadata (read) + +2. **Configure in mcp.json:** + ```json + { + "mcpServers": { + "github": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-github"], + "env": { + "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here" + } + } + } + } + ``` + +3. **For GitHub Enterprise:** + Add `GITHUB_API_URL` environment variable: + ```json + "env": { + "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token", + "GITHUB_API_URL": "https://github.yourcompany.com/api/v3" + } + ``` + +## Tips + +1. **Use fine-grained tokens** - Scope access to specific repos for security +2. **Search before creating** - Check for existing issues/PRs first +3. **Use conventional commits** - Makes changelogs and releases easier +4. **Draft PRs for WIP** - Signal that code isn't ready for review +5. **Cross-reference** - Link issues to PRs with "Closes #N" or "Refs #N" +6. **Use labels consistently** - Establish a labeling taxonomy for your team +7. **Automate with Actions** - Trigger workflows on PR events +8. **Review diffs before merging** - Always check the full diff +9. **Keep PRs small** - Easier to review and less risky to merge +10. **Use code search** - Find patterns and usage across your org + +## Disclaimer + +This power is provided as a **base template** for reference and as a starting point only. Each organization must perform their own due diligence before using it in production environments. You may need additional customization, security review, and configuration specific to your infrastructure, compliance requirements, and operational standards. + +--- + +**Package:** `@modelcontextprotocol/server-github` +**Source:** Anthropic (Model Context Protocol) +**License:** MIT-0 +**Documentation:** https://github.com/modelcontextprotocol/servers/tree/main/src/github diff --git a/github/mcp.json b/github/mcp.json new file mode 100644 index 0000000..c9c55f5 --- /dev/null +++ b/github/mcp.json @@ -0,0 +1,13 @@ +{ + "mcpServers": { + "github": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-github"], + "env": { + "GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_TOKEN" + }, + "disabled": false, + "autoApprove": [] + } + } +} diff --git a/github/steering/steering.md b/github/steering/steering.md new file mode 100644 index 0000000..0ca4653 --- /dev/null +++ b/github/steering/steering.md @@ -0,0 +1,504 @@ +# GitHub MCP Server Steering Guide + +This steering file covers the GitHub MCP server to manage repositories, pull requests, issues, code search, and collaboration workflows. + +## When to Use the GitHub MCP Server + +Use GitHub MCP tools when you need to: +- **Manage pull requests**: Create, review, merge, and track PRs +- **Track issues**: Create, search, update, and manage issues +- **Search code**: Find patterns, usage, and implementations across repos +- **Manage repositories**: Create repos, branches, and push files +- **Collaborate**: Add comments, request reviews, and manage labels +- **Investigate bugs**: Search issues, code, and commit history + +## Core Principles + +### 1. Search Before Creating +Always search for existing issues or PRs before creating new ones to avoid duplicates. + +### 2. Link Everything +Reference issues in PRs with "Closes #N" or "Refs #N". Link related issues together. + +### 3. Use Conventional Commits +Structure PR titles and commit messages with prefixes: feat:, fix:, docs:, refactor:, test:, chore: + +--- + +## Search Syntax Reference + +### Code Search + +**Qualifiers:** +| Qualifier | Description | Example | +|-----------|-------------|---------| +| `org:` | Organization | `org:myorg useAuth` | +| `repo:` | Specific repo | `repo:myorg/api-service` | +| `path:` | File path | `path:src/auth/` | +| `filename:` | File name | `filename:*.test.ts` | +| `extension:` | File extension | `extension:py` | +| `language:` | Language | `language:typescript` | +| `"exact"` | Exact phrase | `"function authenticate"` | +| `NOT` | Exclude | `useAuth NOT test` | + +**Examples:** +``` +# Find authentication usage in TypeScript files +org:myorg useAuth filename:*.ts NOT test + +# Find API endpoint definitions +repo:myorg/backend "app.get(" path:src/routes/ + +# Find environment variable usage +org:myorg process.env.DATABASE_URL + +# Find import patterns +repo:myorg/frontend "import { useAuth }" extension:tsx + +# Find TODO comments +org:myorg TODO language:typescript +``` + +### Issue/PR Search + +**Qualifiers:** +| Qualifier | Description | Example | +|-----------|-------------|---------| +| `is:open` / `is:closed` | State | `is:open` | +| `is:issue` / `is:pr` | Type | `is:pr` | +| `is:merged` / `is:unmerged` | Merge status | `is:merged` | +| `is:draft` | Draft PRs | `is:draft` | +| `label:` | Label filter | `label:bug` | +| `assignee:` | Assigned to | `assignee:username` | +| `author:` | Created by | `author:username` | +| `reviewer:` | PR reviewer | `reviewer:username` | +| `milestone:` | Milestone | `milestone:"v2.0"` | +| `created:` | Creation date | `created:>2024-01-01` | +| `updated:` | Last updated | `updated:>2024-01-15` | +| `closed:` | Close date | `closed:>2024-01-01` | +| `comments:` | Comment count | `comments:>5` | +| `sort:` | Sort order | `sort:created-desc` | +| `no:` | Missing field | `no:assignee` | +| `linked:pr` | Has linked PR | `linked:pr` | +| `review:` | Review status | `review:required` | + +**Examples:** +``` +# Open bugs in my repo +repo:myorg/api is:open is:issue label:bug + +# My open PRs +is:open is:pr author:@me + +# PRs awaiting my review +is:open is:pr reviewer:@me review:required + +# High priority unassigned issues +repo:myorg/api is:open label:priority:high no:assignee + +# Recently created issues +repo:myorg/api is:open is:issue sort:created-desc created:>2024-01-01 + +# Stale PRs (no updates in 7 days) +repo:myorg/api is:open is:pr updated:<2024-01-08 + +# Issues with many comments (potentially complex) +repo:myorg/api is:open is:issue comments:>10 + +# Merged PRs this week +repo:myorg/api is:merged merged:>2024-01-08 +``` + +### Repository Search + +**Qualifiers:** +| Qualifier | Description | Example | +|-----------|-------------|---------| +| `language:` | Primary language | `language:typescript` | +| `stars:` | Star count | `stars:>1000` | +| `forks:` | Fork count | `forks:>100` | +| `topic:` | Topic tag | `topic:react` | +| `org:` | Organization | `org:myorg` | +| `archived:` | Archive status | `archived:false` | +| `is:public` / `is:private` | Visibility | `is:public` | +| `created:` | Creation date | `created:>2024-01-01` | +| `pushed:` | Last push | `pushed:>2024-01-01` | +| `size:` | Repo size (KB) | `size:>1000` | + +--- + +## Pull Request Workflows + +### Creating Effective PRs + +**Title format:** +``` +feat: add user authentication with JWT +fix: handle null pointer in checkout flow +docs: update API documentation for v2 +refactor: extract payment validation logic +test: add integration tests for order service +chore: upgrade dependencies to latest versions +``` + +**Description template:** +```markdown +## Summary +Brief description of what this PR does and why. + +## Changes +- Added JWT token generation and validation +- Created auth middleware for protected routes +- Added refresh token rotation + +## Testing +- [x] Unit tests pass +- [x] Integration tests pass +- [x] Manual testing with Postman + +## Screenshots (if UI changes) +Before: ... +After: ... + +## Related Issues +Closes #123 +Refs #456 +``` + +### PR Review Workflow + +```javascript +// Step 1: List PRs awaiting review +const prs = search_issues({ + "q": "repo:myorg/api is:open is:pr reviewer:@me review:required" +}) + +// Step 2: Get PR details +const pr = get_pull_request({ + "owner": "myorg", "repo": "api", "pull_number": 42 +}) + +// Step 3: Review the diff +const diff = get_pull_request_diff({ + "owner": "myorg", "repo": "api", "pull_number": 42 +}) + +// Step 4: Check existing reviews +const reviews = get_pull_request_reviews({ + "owner": "myorg", "repo": "api", "pull_number": 42 +}) + +// Step 5: Submit review +const review = create_pull_request_review({ + "owner": "myorg", "repo": "api", "pull_number": 42, + "event": "APPROVE", // or "REQUEST_CHANGES" or "COMMENT" + "body": "LGTM! Clean implementation." +}) +``` + +### Merge Strategies + +| Method | When to Use | Result | +|--------|-------------|--------| +| `merge` | Preserve full branch history | Merge commit | +| `squash` | Clean up messy commits | Single commit | +| `rebase` | Linear history, clean commits | No merge commit | + +--- + +## Issue Management Workflows + +### Bug Report Template +```javascript +create_issue({ + "owner": "myorg", "repo": "api", + "title": "Bug: Checkout fails with special characters in address", + "body": "## Environment\n- Production\n- API v2.3.1\n\n## Steps to Reproduce\n1. Add item to cart\n2. Enter address with `&` or `#` characters\n3. Submit checkout\n\n## Expected\nOrder is placed successfully\n\n## Actual\nHTTP 400 Bad Request\n\n## Additional Context\nStarted after deploy on Jan 15", + "labels": ["bug", "priority:high", "checkout"], + "assignees": ["developer1"] +}) +``` + +### Feature Request Template +```javascript +create_issue({ + "owner": "myorg", "repo": "api", + "title": "Feature: Add bulk order import via CSV", + "body": "## Problem\nCustomers with large orders must add items one by one.\n\n## Proposed Solution\nAllow CSV upload with columns: SKU, quantity, notes\n\n## Acceptance Criteria\n- [ ] CSV parsing with validation\n- [ ] Error reporting for invalid rows\n- [ ] Maximum 1000 items per upload\n- [ ] Progress indicator for large files", + "labels": ["enhancement", "priority:medium"] +}) +``` + +### Issue Triage Workflow + +```javascript +// Step 1: Find untriaged issues +const untriaged = search_issues({ + "q": "repo:myorg/api is:open is:issue no:label created:>2024-01-01" +}) + +// Step 2: Find unassigned high-priority issues +const unassigned = search_issues({ + "q": "repo:myorg/api is:open is:issue label:priority:high no:assignee" +}) + +// Step 3: Find stale issues (no updates in 30 days) +const stale = search_issues({ + "q": "repo:myorg/api is:open is:issue updated:<2023-12-15" +}) +``` + +--- + +## Code Search Patterns + +### Finding Usage Patterns +```javascript +// Find all uses of a function +search_code({ "q": "org:myorg validatePayment language:typescript" }) + +// Find configuration patterns +search_code({ "q": "repo:myorg/api DATABASE_URL filename:.env*" }) + +// Find test patterns +search_code({ "q": "repo:myorg/api describe( filename:*.test.ts path:src/" }) + +// Find API endpoint definitions +search_code({ "q": "repo:myorg/api router.post path:src/routes" }) + +// Find dependency usage +search_code({ "q": "org:myorg \"from 'lodash'\" extension:ts" }) +``` + +### Finding Security Issues +```javascript +// Hardcoded secrets (should be in env vars) +search_code({ "q": "org:myorg password= NOT .env NOT test" }) + +// SQL injection risks +search_code({ "q": "org:myorg \"query(\" + language:javascript" }) + +// Unsafe eval usage +search_code({ "q": "org:myorg eval( language:javascript NOT test" }) +``` + +--- + +## Branch Management + +### Branch Naming Conventions +``` +feature/TICKET-123-add-auth # Feature branches +fix/TICKET-456-null-pointer # Bug fix branches +hotfix/critical-security-patch # Production hotfixes +release/v2.0.0 # Release branches +docs/update-api-docs # Documentation +refactor/extract-payment-logic # Refactoring +``` + +### Branch Workflow +```javascript +// Step 1: Create feature branch +create_branch({ + "owner": "myorg", "repo": "api", + "branch": "feature/add-order-history", + "from_branch": "main" +}) + +// Step 2: Push implementation +push_files({ + "owner": "myorg", "repo": "api", + "branch": "feature/add-order-history", + "files": [ + {"path": "src/routes/orders.ts", "content": "..."}, + {"path": "src/tests/orders.test.ts", "content": "..."} + ], + "message": "feat: add order history endpoint" +}) + +// Step 3: Create PR +create_pull_request({ + "owner": "myorg", "repo": "api", + "title": "feat: add order history endpoint", + "head": "feature/add-order-history", + "base": "main" +}) +``` + +--- + +## Label Taxonomy + +### Recommended Labels + +**Type:** +- `bug` - Something isn't working +- `enhancement` - New feature request +- `documentation` - Documentation improvements +- `question` - Further information requested +- `tech-debt` - Technical debt cleanup + +**Priority:** +- `priority:critical` - Production down +- `priority:high` - Major feature/bug +- `priority:medium` - Normal priority +- `priority:low` - Nice to have + +**Status:** +- `needs-triage` - Needs initial review +- `in-progress` - Being worked on +- `blocked` - Blocked by dependency +- `needs-review` - Ready for review +- `wontfix` - Won't be addressed + +**Area:** +- `frontend` - UI/UX related +- `backend` - Server-side +- `infrastructure` - DevOps/infra +- `security` - Security related +- `performance` - Performance related + +--- + +## Automation Patterns + +### Auto-close Issues from PRs +Use keywords in PR body or commit messages: +- `Closes #123` - Closes issue when PR is merged +- `Fixes #123` - Same as Closes +- `Resolves #123` - Same as Closes +- `Refs #123` - References without closing + +### PR Templates +Create `.github/PULL_REQUEST_TEMPLATE.md` in your repo for consistent PR descriptions. + +### Issue Templates +Create `.github/ISSUE_TEMPLATE/` directory with templates for bugs, features, etc. + +--- + +## Troubleshooting + +### Search Returns No Results +1. Check repository name and organization +2. Verify search syntax (quotes for exact phrases) +3. Try broader search terms +4. Check if repo is private (needs appropriate token scope) + +### PR Creation Fails +1. Verify branch exists and has commits ahead of base +2. Check branch names are correct +3. Verify token has `repo` scope +4. Check if branch protection rules block creation + +### Permission Denied +1. Verify PAT has required scopes +2. Check if repo requires specific team membership +3. Verify organization SSO is authorized for the token +4. Check if fine-grained token has access to the specific repo + +--- + +## Summary Checklist + +For effective GitHub usage: +- ✅ Search before creating (avoid duplicates) +- ✅ Use conventional commit format for PR titles +- ✅ Include descriptive PR body with context +- ✅ Link PRs to issues with "Closes #N" +- ✅ Use labels consistently for categorization +- ✅ Request reviews from appropriate team members +- ✅ Check CI status before merging +- ✅ Use draft PRs for work-in-progress +- ✅ Keep PRs small and focused +- ✅ Use code search to find patterns before implementing + +--- + +## Security Guardrails + +### Credential Protection +- **NEVER** log, echo, or expose `GITHUB_PERSONAL_ACCESS_TOKEN` values in responses +- When referencing tokens, use placeholder names (e.g., "your GitHub token") not actual values +- Do not include tokens in URLs, commit messages, or file contents + +### Repository and Code Safety +- **Never push secrets to repositories** - if file content contains API keys, passwords, or tokens, refuse and warn the user +- **Never push directly to `main` or `master`** - always use feature branches and PRs +- **Do not create public repositories** unless the user explicitly requests it and confirms +- **Do not delete repositories or branches** without explicit user confirmation +- When using `push_files`, verify content does not contain hardcoded credentials, private keys, or connection strings +- Do not modify `.github/workflows/` files without explicit user approval - CI/CD changes can have security implications + +### Data Sensitivity +- Code search results may contain sensitive patterns - do not reproduce large blocks of code that appear to contain secrets +- When presenting search results, summarize file paths and patterns rather than reproducing full file contents +- Do not expose private repository names, internal URLs, or infrastructure details to unauthorized contexts +- Treat organization membership and team structure as sensitive information + +### Access Control +- Only access repositories the configured token has permissions for +- Do not attempt to enumerate organizations, teams, or members beyond what's needed +- If an operation returns 403/404, report the error without retrying with escalated permissions +- Do not attempt to bypass branch protection rules or required reviews +- Respect CODEOWNERS files - suggest appropriate reviewers based on changed paths + +## Anti-Hallucination Guardrails + +### API Accuracy +- **Only use documented tool parameters** - do not invent parameter names or values +- **Do not fabricate repository names, issue numbers, or PR numbers** - always search or list first to confirm they exist +- **Do not assume branch names** - verify branches exist before creating PRs or pushing files +- **Do not invent GitHub search qualifiers** - only use documented qualifiers (is:, label:, author:, repo:, org:, language:, etc.) + +### Result Interpretation +- **Never invent API responses** - if a tool hasn't been called, say "I need to check this" rather than guessing +- **Do not assume PR status** - always check current state before suggesting merge or review actions +- **Do not assume issue state** - verify whether issues are open/closed before suggesting updates +- **If a search returns no results**, report that clearly rather than speculating about what might exist +- **Do not fabricate commit SHAs, user handles, or timestamps** + +### Tool Capability Boundaries +- Do not claim ability to approve PRs on behalf of other users +- Do not claim ability to trigger GitHub Actions workflows directly (unless the tool supports it) +- Do not claim ability to manage GitHub Apps, webhooks, or organization settings +- Clearly state when an action requires the user to perform it in the GitHub UI + +## Operational Optimization Guardrails + +### API Rate Limiting +- **GitHub has strict rate limits** (5000 requests/hour for authenticated users) - be mindful of call volume +- **Batch operations when possible** - use `push_files` for multiple files instead of individual `create_or_update_file` calls +- **Use `perPage` parameter** to control result sizes - start with 10-20, increase only if needed +- **Cache entity references** - once you have a repo name, issue number, or PR number, reuse it without re-searching +- **Avoid paginating through all results** unless specifically needed - use search with specific filters instead + +### Request Efficiency +- **Search before listing** - `search_issues` with specific qualifiers is more efficient than `list_issues` with client-side filtering +- **Use specific queries** - `repo:owner/repo is:open is:pr` is better than listing all PRs and filtering +- **Minimize diff fetches** - `get_pull_request_diff` can return large payloads; only fetch when reviewing +- **Don't repeatedly check PR status** - check once, take action, then verify if needed + +### Workflow Efficiency +- **Create branch + push + PR in sequence** - don't create unnecessary intermediate operations +- **Link issues to PRs at creation time** - use `work_item_ids` or "Closes #N" in description rather than updating later +- **Use draft PRs** for work-in-progress - avoids triggering unnecessary CI runs and review notifications + +## Cost Optimization Guardrails + +### API Usage +- **Minimize API calls** - plan the workflow before executing, determine minimum calls needed +- **Avoid redundant searches** - if you already found the information, don't search again +- **Use webhooks awareness** - creating PRs, issues, and comments triggers notifications; be intentional about what you create +- **Batch file operations** - `push_files` with multiple files in one commit is one API call vs. N calls for individual files + +### CI/CD Cost Awareness +- **Draft PRs don't trigger all CI** in many configurations - use drafts for WIP to avoid unnecessary build costs +- **Don't create throwaway PRs** - each PR may trigger CI pipelines that consume compute resources +- **Consider PR size** - smaller, focused PRs are cheaper to build and test than large ones +- **Avoid force-pushing repeatedly** - each push may trigger a new CI run + +### Repository Hygiene +- **Delete branches after merge** - reduces clutter and potential confusion +- **Close stale issues and PRs** - reduces noise for the team +- **Use labels efficiently** - well-labeled issues reduce time spent searching and triaging diff --git a/gitlab/POWER.md b/gitlab/POWER.md new file mode 100644 index 0000000..4a5d0a2 --- /dev/null +++ b/gitlab/POWER.md @@ -0,0 +1,351 @@ +--- +name: "gitlab" +displayName: "GitLab" +description: "Manage repositories, merge requests, issues, pipelines, and CI/CD on GitLab directly from your IDE" +keywords: ["gitlab", "git", "repository", "merge-request", "issues", "ci", "cd", "pipelines", "code-review", "devops"] +author: "Community" +--- + +# GitLab Power + +## Overview + +The GitLab Power connects to GitLab's DevOps platform for repository management, merge requests, issue tracking, CI/CD pipelines, and project management. Work with GitLab directly from your IDE. + +**Key capabilities:** +- **Repository Management**: Create, fork, search, and manage projects +- **Merge Requests**: Create, review, approve, and merge MRs with full diff support +- **Issues**: Create, search, update, and manage issues with labels, milestones, and weights +- **CI/CD Pipelines**: Trigger, monitor, and manage pipeline runs and jobs +- **Code Search**: Search code across projects and groups +- **Branch Management**: Create, protect, and manage branches +- **File Operations**: Read, create, and update files directly in repositories +- **Wiki & Snippets**: Manage project wikis and code snippets + +**Authentication**: Requires a GitLab Personal Access Token. + +## Onboarding + +### Prerequisites + +1. **GitLab account** - GitLab.com or self-hosted GitLab instance +2. **Personal Access Token** - With `api`, `read_repository`, and `write_repository` scopes +3. **Node.js 18+** - Required to run the MCP server via npx + +### Quick Start + +1. Install the power in Kiro +2. Replace placeholders in `mcp.json` with your GitLab token and API URL +3. Test with: *"List my open merge requests"* or *"Show project issues"* + +### MCP Config Placeholders + +Before using this power, replace the following placeholders in `mcp.json`: + +- **`YOUR_GITLAB_TOKEN`**: A GitLab Personal Access Token. + - **How to get it:** + 1. Go to GitLab → User Settings (click avatar) → Access Tokens + 2. Click "Add new token" + 3. Set scopes: `api`, `read_repository`, `write_repository` + 4. Set expiration date + 5. Click "Create personal access token" and copy the value (starts with `glpat-`) + +- **`https://gitlab.com/api/v4`**: Your GitLab API URL. + - **How to set it:** For GitLab.com, keep the default. For self-hosted GitLab, change to `https://your-gitlab-instance.com/api/v4` + +## Available Steering Files + +- **steering/steering.md** - GitLab flow, MR best practices, CI/CD pipeline management, and scoped label patterns + +## Available MCP Servers + +### gitlab +**Package:** `@modelcontextprotocol/server-gitlab` +**Connection:** stdio via npx + +**Tools:** + +1. **create_or_update_file** - Create or update a file in a project + - Required: `project_id` (string), `file_path` (string), `content` (string), `commit_message` (string), `branch` (string) + - Optional: `previous_path` (string) - For renames + - Returns: File commit details + +2. **search_repositories** - Search GitLab projects + - Required: `search` (string) - Search query + - Optional: `page` (number), `per_page` (number) + - Returns: Matching projects with metadata + +3. **create_repository** - Create a new project + - Required: `name` (string) + - Optional: `description` (string), `visibility` (string), `initialize_with_readme` (boolean), `namespace_id` (number) + - Returns: Created project details + +4. **get_file_contents** - Get file or directory contents + - Required: `project_id` (string), `file_path` (string) + - Optional: `ref` (string) - Branch or tag + - Returns: File content or directory listing + +5. **create_issue** - Create a new issue + - Required: `project_id` (string), `title` (string) + - Optional: `description` (string), `assignee_ids` (array), `labels` (string), `milestone_id` (number), `weight` (number) + - Returns: Created issue details + +6. **create_merge_request** - Create a merge request + - Required: `project_id` (string), `title` (string), `source_branch` (string), `target_branch` (string) + - Optional: `description` (string), `assignee_ids` (array), `reviewer_ids` (array), `labels` (string), `draft` (boolean) + - Returns: Created MR details + +7. **fork_repository** - Fork a project + - Required: `project_id` (string) + - Optional: `namespace` (string) + - Returns: Forked project details + +8. **create_branch** - Create a new branch + - Required: `project_id` (string), `branch` (string), `ref` (string) + - Returns: Branch details + +9. **list_issues** - List issues in a project + - Required: `project_id` (string) + - Optional: `state` (string), `labels` (string), `milestone` (string), `assignee_id` (number), `page` (number) + - Returns: List of issues + +10. **update_issue** - Update an existing issue + - Required: `project_id` (string), `issue_iid` (number) + - Optional: `title` (string), `description` (string), `state_event` (string), `labels` (string), `assignee_ids` (array) + - Returns: Updated issue details + +11. **list_merge_requests** - List merge requests + - Required: `project_id` (string) + - Optional: `state` (string), `source_branch` (string), `target_branch` (string), `page` (number) + - Returns: List of merge requests + +12. **get_merge_request** - Get MR details + - Required: `project_id` (string), `merge_request_iid` (number) + - Returns: Full MR details with diff stats + +13. **get_merge_request_diffs** - Get MR diff content + - Required: `project_id` (string), `merge_request_iid` (number) + - Returns: File diffs for the MR + +14. **merge_merge_request** - Merge a merge request + - Required: `project_id` (string), `merge_request_iid` (number) + - Optional: `merge_commit_message` (string), `squash` (boolean), `should_remove_source_branch` (boolean) + - Returns: Merge result + +15. **list_pipelines** - List CI/CD pipelines + - Required: `project_id` (string) + - Optional: `status` (string), `ref` (string), `page` (number) + - Returns: Pipeline list with status + +16. **get_pipeline** - Get pipeline details + - Required: `project_id` (string), `pipeline_id` (number) + - Returns: Pipeline details with jobs + +17. **list_pipeline_jobs** - List jobs in a pipeline + - Required: `project_id` (string), `pipeline_id` (number) + - Returns: Jobs with status and duration + +18. **get_job_log** - Get job log output + - Required: `project_id` (string), `job_id` (number) + - Returns: Job log content + +19. **create_note** - Add a comment to an issue or MR + - Required: `project_id` (string), `noteable_type` (string), `noteable_iid` (number), `body` (string) + - Returns: Created note details + +## Tool Usage Examples + +### Merge Request Workflow + +**Create an MR:** +```javascript +usePower("gitlab", "gitlab", "create_merge_request", { + "project_id": "mygroup/myproject", + "title": "feat: add user authentication", + "source_branch": "feature/auth", + "target_branch": "main", + "description": "## Summary\nAdds OAuth2 authentication\n\n## Changes\n- Login flow\n- Token management\n- Session handling", + "reviewer_ids": [42], + "labels": "feature,auth", + "draft": false +}) +``` + +**Check pipeline status:** +```javascript +usePower("gitlab", "gitlab", "list_pipelines", { + "project_id": "mygroup/myproject", + "ref": "feature/auth", + "status": "failed" +}) +``` + +**Get failed job logs:** +```javascript +usePower("gitlab", "gitlab", "get_job_log", { + "project_id": "mygroup/myproject", + "job_id": 12345 +}) +``` + +### Issue Management + +**Create an issue:** +```javascript +usePower("gitlab", "gitlab", "create_issue", { + "project_id": "mygroup/myproject", + "title": "Bug: API returns 500 on concurrent requests", + "description": "## Steps to Reproduce\n1. Send 10 concurrent POST requests\n2. Observe 500 errors\n\n## Expected\nAll requests succeed\n\n## Actual\n3/10 requests fail with 500", + "labels": "bug,priority::high,backend", + "weight": 5 +}) +``` + +## Combining Tools (Workflows) + +### Workflow 1: MR Review and Pipeline Check + +```javascript +// Step 1: Get MR details +const mr = usePower("gitlab", "gitlab", "get_merge_request", { + "project_id": "mygroup/myproject", + "merge_request_iid": 99 +}) + +// Step 2: Review the diff +const diffs = usePower("gitlab", "gitlab", "get_merge_request_diffs", { + "project_id": "mygroup/myproject", + "merge_request_iid": 99 +}) + +// Step 3: Check pipeline status +const pipelines = usePower("gitlab", "gitlab", "list_pipelines", { + "project_id": "mygroup/myproject", + "ref": mr.source_branch +}) + +// Step 4: If pipeline failed, check job logs +const jobs = usePower("gitlab", "gitlab", "list_pipeline_jobs", { + "project_id": "mygroup/myproject", + "pipeline_id": pipelines[0].id +}) + +// Step 5: Get failed job log +const failedJob = jobs.find(j => j.status === "failed") +const log = usePower("gitlab", "gitlab", "get_job_log", { + "project_id": "mygroup/myproject", + "job_id": failedJob.id +}) +``` + +### Workflow 2: Feature Development + +```javascript +// Step 1: Create branch +const branch = usePower("gitlab", "gitlab", "create_branch", { + "project_id": "mygroup/myproject", + "branch": "feature/new-endpoint", + "ref": "main" +}) + +// Step 2: Push code +const file = usePower("gitlab", "gitlab", "create_or_update_file", { + "project_id": "mygroup/myproject", + "file_path": "src/routes/orders.ts", + "content": "// Orders API implementation...", + "commit_message": "feat: add orders endpoint", + "branch": "feature/new-endpoint" +}) + +// Step 3: Create MR +const mr = usePower("gitlab", "gitlab", "create_merge_request", { + "project_id": "mygroup/myproject", + "title": "feat: add orders endpoint", + "source_branch": "feature/new-endpoint", + "target_branch": "main", + "description": "Adds CRUD for orders" +}) + +// Step 4: Create tracking issue +const issue = usePower("gitlab", "gitlab", "create_issue", { + "project_id": "mygroup/myproject", + "title": "Implement orders API", + "description": `MR: !${mr.iid}\n\nTasks:\n- [x] Create endpoint\n- [ ] Add tests\n- [ ] Update docs`, + "labels": "feature,in-progress" +}) +``` + +## Best Practices + +### ✅ Do: +- **Use GitLab Flow** - feature branches → MR → main → deploy +- **Write descriptive MR descriptions** with context and testing notes +- **Use scoped labels** (priority::high, type::bug) for structured categorization +- **Set reviewers and assignees** on MRs for accountability +- **Check pipeline status** before merging +- **Use draft MRs** for work-in-progress +- **Reference issues** with "Closes #123" in MR descriptions +- **Use weights on issues** for sprint planning + +### ❌ Don't: +- **Push directly to protected branches** - use MRs +- **Merge with failing pipelines** - fix CI first +- **Create MRs without description** - reviewers need context +- **Skip code review** - enforce approval rules +- **Ignore pipeline failures** - investigate and fix + +## Configuration + +**Authentication Required**: GitLab Personal Access Token + +**Setup Steps:** + +1. **Create a Personal Access Token:** + - Go to GitLab → User Settings → Access Tokens + - Create token with scopes: `api`, `read_repository`, `write_repository` + +2. **Configure in mcp.json:** + ```json + { + "mcpServers": { + "gitlab": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-gitlab"], + "env": { + "GITLAB_PERSONAL_ACCESS_TOKEN": "glpat-your_token_here", + "GITLAB_API_URL": "https://gitlab.com/api/v4" + } + } + } + } + ``` + +3. **For Self-Hosted GitLab:** + Change `GITLAB_API_URL` to your instance: + ```json + "GITLAB_API_URL": "https://gitlab.yourcompany.com/api/v4" + ``` + +## Tips + +1. **Use scoped labels** - `priority::high`, `type::bug`, `workflow::in-review` +2. **Use CI/CD** - Check pipeline status before merging +3. **Draft MRs early** - Get feedback before code is complete +4. **Use MR templates** - Standardize descriptions across your team +5. **Cross-reference** - Link issues and MRs with GitLab references +6. **Monitor pipelines** - Catch failures early with job logs +7. **Squash on merge** - Keep main branch history clean +8. **Use weights** - Plan sprints with issue weights +9. **Review diffs** - Always check the full diff before approving +10. **Automate** - Use pipeline triggers for deployment automation + +## Disclaimer + +This power is provided as a **base template** for reference and as a starting point only. Each organization must perform their own due diligence before using it in production environments. You may need additional customization, security review, and configuration specific to your infrastructure, compliance requirements, and operational standards. + +--- + +**Package:** `@modelcontextprotocol/server-gitlab` +**Source:** Anthropic (Model Context Protocol) +**License:** MIT-0 +**Documentation:** https://github.com/modelcontextprotocol/servers/tree/main/src/gitlab diff --git a/gitlab/mcp.json b/gitlab/mcp.json new file mode 100644 index 0000000..101b8a5 --- /dev/null +++ b/gitlab/mcp.json @@ -0,0 +1,14 @@ +{ + "mcpServers": { + "gitlab": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-gitlab"], + "env": { + "GITLAB_PERSONAL_ACCESS_TOKEN": "YOUR_GITLAB_TOKEN", + "GITLAB_API_URL": "https://gitlab.com/api/v4" + }, + "disabled": false, + "autoApprove": [] + } + } +} diff --git a/gitlab/steering/steering.md b/gitlab/steering/steering.md new file mode 100644 index 0000000..b87c8af --- /dev/null +++ b/gitlab/steering/steering.md @@ -0,0 +1,563 @@ +# GitLab MCP Server Steering Guide + +This steering file covers the GitLab MCP server to manage projects, merge requests, issues, CI/CD pipelines, and code collaboration. + +## When to Use the GitLab MCP Server + +Use GitLab MCP tools when you need to: +- **Manage merge requests**: Create, review, approve, and merge MRs +- **Track issues**: Create, search, update, and manage issues with boards +- **Monitor pipelines**: Trigger, check status, and debug CI/CD jobs +- **Search code**: Find patterns across projects and groups +- **Manage branches**: Create branches and push code +- **Collaborate**: Add comments, manage labels, and track milestones + +## Core Principles + +### 1. Follow GitLab Flow +Use feature branches → merge requests → main → deploy. Never push directly to protected branches. + +### 2. Pipeline First +Always check pipeline status before merging. Failed pipelines indicate problems that need fixing. + +### 3. Use Scoped Labels +GitLab's scoped labels (e.g., `priority::high`) ensure mutual exclusivity within a scope. + +--- + +## Merge Request Best Practices + +### MR Title Format +Follow conventional commits: +``` +feat: add user authentication with OAuth2 +fix: handle race condition in order processing +docs: update deployment guide for Kubernetes +refactor: extract payment validation into service +test: add integration tests for notification system +chore: upgrade Rails to 7.1 +``` + +### MR Description Template +```markdown +## Summary +Brief description of what this MR does and why. + +## Changes +- Implemented OAuth2 login flow +- Added token refresh mechanism +- Created auth middleware + +## Testing +- [x] Unit tests pass (`bundle exec rspec`) +- [x] Integration tests pass +- [x] Manual testing completed + +## Screenshots (if applicable) +Before: ... +After: ... + +## Related Issues +Closes #123 +Related to #456 + +## Checklist +- [x] Code follows project style guidelines +- [x] Tests added for new functionality +- [x] Documentation updated +- [ ] Migration included (if DB changes) +``` + +### MR Workflow + +```javascript +// Step 1: Create branch +create_branch({ + "project_id": "mygroup/myproject", + "branch": "feature/oauth-login", + "ref": "main" +}) + +// Step 2: Push code +create_or_update_file({ + "project_id": "mygroup/myproject", + "file_path": "app/controllers/auth_controller.rb", + "content": "...", + "commit_message": "feat: add OAuth2 authentication controller", + "branch": "feature/oauth-login" +}) + +// Step 3: Create MR +create_merge_request({ + "project_id": "mygroup/myproject", + "title": "feat: add OAuth2 authentication", + "source_branch": "feature/oauth-login", + "target_branch": "main", + "description": "## Summary\nAdds OAuth2 login flow...", + "reviewer_ids": [42, 43], + "labels": "feature,auth,priority::high" +}) + +// Step 4: Check pipeline +list_pipelines({ + "project_id": "mygroup/myproject", + "ref": "feature/oauth-login" +}) + +// Step 5: Merge when ready +merge_merge_request({ + "project_id": "mygroup/myproject", + "merge_request_iid": 99, + "squash": true, + "should_remove_source_branch": true +}) +``` + +--- + +## CI/CD Pipeline Management + +### Checking Pipeline Status + +```javascript +// List recent pipelines +list_pipelines({ + "project_id": "mygroup/myproject", + "status": "failed" +}) + +// Get pipeline details +get_pipeline({ + "project_id": "mygroup/myproject", + "pipeline_id": 12345 +}) + +// List jobs in a pipeline +list_pipeline_jobs({ + "project_id": "mygroup/myproject", + "pipeline_id": 12345 +}) + +// Get failed job log +get_job_log({ + "project_id": "mygroup/myproject", + "job_id": 67890 +}) +``` + +### Pipeline States +| Status | Description | +|--------|-------------| +| `created` | Pipeline created, not yet started | +| `waiting_for_resource` | Waiting for runner | +| `preparing` | Being prepared | +| `pending` | Waiting to run | +| `running` | Currently executing | +| `success` | All jobs passed | +| `failed` | One or more jobs failed | +| `canceled` | Manually cancelled | +| `skipped` | Skipped due to rules | +| `manual` | Waiting for manual trigger | +| `scheduled` | Scheduled for later | + +### Debugging Failed Pipelines + +1. **List pipelines for the branch:** +```javascript +list_pipelines({ + "project_id": "mygroup/myproject", + "ref": "feature/my-branch", + "status": "failed" +}) +``` + +2. **Get pipeline jobs:** +```javascript +list_pipeline_jobs({ + "project_id": "mygroup/myproject", + "pipeline_id": 12345 +}) +``` + +3. **Find the failed job:** +Look for jobs with `status: "failed"` in the response. + +4. **Get job log:** +```javascript +get_job_log({ + "project_id": "mygroup/myproject", + "job_id": failedJobId +}) +``` + +5. **Common failure patterns:** +- Test failures → Check test output in log +- Lint errors → Look for style violations +- Build errors → Check compilation output +- Docker errors → Check Dockerfile and registry access +- Deploy errors → Check credentials and permissions + +--- + +## Issue Management + +### Creating Issues + +**Bug report:** +```javascript +create_issue({ + "project_id": "mygroup/myproject", + "title": "Bug: API returns 500 on concurrent checkout requests", + "description": "## Environment\n- Production (v2.3.1)\n- Affects: checkout-service\n\n## Steps to Reproduce\n1. Send 10 concurrent POST /checkout requests\n2. Observe intermittent 500 errors\n\n## Expected\nAll requests succeed (or graceful 429)\n\n## Actual\n3-4 requests fail with 500 Internal Server Error\n\n## Logs\n```\nActiveRecord::Deadlock: Mysql2::Error: Deadlock found\n```", + "labels": "bug,priority::critical,service::checkout", + "weight": 8 +}) +``` + +**Feature request:** +```javascript +create_issue({ + "project_id": "mygroup/myproject", + "title": "Feature: Add bulk order import via CSV", + "description": "## Problem\nCustomers with large orders must add items individually.\n\n## Proposal\nAdd CSV upload endpoint for bulk order creation.\n\n## Acceptance Criteria\n- [ ] CSV parsing with validation\n- [ ] Error reporting per row\n- [ ] Max 1000 items per upload\n- [ ] Background processing for large files", + "labels": "feature,priority::medium,service::orders", + "weight": 13 +}) +``` + +### Scoped Labels + +GitLab scoped labels use `::` separator. Only one label per scope can be applied: + +``` +priority::critical # Only one priority at a time +priority::high +priority::medium +priority::low + +workflow::backlog # Only one workflow state +workflow::ready +workflow::in-progress +workflow::review +workflow::done + +service::checkout # Can have multiple service labels +service::payment +service::inventory + +type::bug +type::feature +type::tech-debt +type::documentation +``` + +### Issue Boards + +Issues move through board columns based on scoped labels: +``` +Backlog → Ready → In Progress → Review → Done +(workflow::backlog → workflow::ready → workflow::in-progress → workflow::review → workflow::done) +``` + +--- + +## Code Search + +### Search Patterns + +```javascript +// Find function definitions +search_repositories({ "search": "def authenticate" }) + +// Find configuration +search_repositories({ "search": "DATABASE_URL" }) + +// Find specific file types +search_repositories({ "search": "Dockerfile" }) +``` + +### File Operations + +```javascript +// Read a file +get_file_contents({ + "project_id": "mygroup/myproject", + "file_path": "config/database.yml", + "ref": "main" +}) + +// Create/update a file +create_or_update_file({ + "project_id": "mygroup/myproject", + "file_path": "docs/API.md", + "content": "# API Documentation\n...", + "commit_message": "docs: add API documentation", + "branch": "docs/api-docs" +}) +``` + +--- + +## Project Organization + +### Group Structure +``` +mycompany/ +├── platform/ +│ ├── api-gateway +│ ├── auth-service +│ └── shared-libs +├── services/ +│ ├── checkout +│ ├── payment +│ └── inventory +└── infrastructure/ + ├── terraform + ├── helm-charts + └── monitoring +``` + +### Branch Protection +Protected branches (main, release/*) should require: +- Merge request approval (1-2 reviewers) +- Passing CI pipeline +- No force push +- Code owner approval (for critical paths) + +--- + +## Merge Strategies + +| Strategy | When to Use | Command | +|----------|-------------|---------| +| Merge commit | Preserve full history | `squash: false` | +| Squash | Clean up WIP commits | `squash: true` | +| Fast-forward | Linear history (if possible) | Configured in project settings | + +### Recommended: Squash Merge +```javascript +merge_merge_request({ + "project_id": "mygroup/myproject", + "merge_request_iid": 99, + "squash": true, + "should_remove_source_branch": true, + "merge_commit_message": "feat: add OAuth2 authentication (#99)" +}) +``` + +--- + +## Common Workflows + +### Workflow 1: Bug Fix + +```javascript +// 1. Create branch from main +create_branch({ + "project_id": "mygroup/myproject", + "branch": "fix/checkout-deadlock", + "ref": "main" +}) + +// 2. Push fix +create_or_update_file({ + "project_id": "mygroup/myproject", + "file_path": "app/services/checkout_service.rb", + "content": "...", + "commit_message": "fix: add row-level locking to prevent checkout deadlock", + "branch": "fix/checkout-deadlock" +}) + +// 3. Create MR linked to issue +create_merge_request({ + "project_id": "mygroup/myproject", + "title": "fix: add row-level locking to prevent checkout deadlock", + "source_branch": "fix/checkout-deadlock", + "target_branch": "main", + "description": "Closes #456\n\nAdds `FOR UPDATE` lock on inventory rows during checkout to prevent deadlocks under concurrent load.", + "labels": "bug,priority::critical" +}) + +// 4. Monitor pipeline +list_pipelines({ + "project_id": "mygroup/myproject", + "ref": "fix/checkout-deadlock" +}) + +// 5. After approval and green pipeline, merge +merge_merge_request({ + "project_id": "mygroup/myproject", + "merge_request_iid": 100, + "squash": true, + "should_remove_source_branch": true +}) +``` + +### Workflow 2: MR Review + +```javascript +// 1. Get MR details +get_merge_request({ + "project_id": "mygroup/myproject", + "merge_request_iid": 99 +}) + +// 2. Review the diff +get_merge_request_diffs({ + "project_id": "mygroup/myproject", + "merge_request_iid": 99 +}) + +// 3. Check pipeline status +list_pipelines({ + "project_id": "mygroup/myproject", + "ref": "feature/oauth-login" +}) + +// 4. If pipeline failed, check logs +list_pipeline_jobs({ + "project_id": "mygroup/myproject", + "pipeline_id": 12345 +}) + +// 5. Add review comment +create_note({ + "project_id": "mygroup/myproject", + "noteable_type": "MergeRequest", + "noteable_iid": 99, + "body": "Looks good! One suggestion: consider adding rate limiting to the token endpoint." +}) +``` + +--- + +## Troubleshooting + +### Pipeline Keeps Failing +1. Check job logs for specific error messages +2. Verify CI/CD variables are set correctly +3. Check if runner is available and has correct tags +4. Verify Docker images are accessible +5. Check for flaky tests (retry the pipeline) + +### MR Cannot Be Merged +1. Check for merge conflicts (rebase or merge main into branch) +2. Verify pipeline is passing +3. Check if required approvals are met +4. Verify branch protection rules +5. Check if there are unresolved threads + +### Permission Denied +1. Verify PAT has `api` scope +2. Check project membership and role +3. Verify group-level permissions +4. Check if project is archived + +--- + +## Summary Checklist + +For effective GitLab usage: +- ✅ Follow GitLab Flow (feature branch → MR → main) +- ✅ Use conventional commit format for MR titles +- ✅ Include descriptive MR descriptions +- ✅ Use scoped labels for structured categorization +- ✅ Check pipeline status before merging +- ✅ Use squash merge for clean history +- ✅ Delete source branches after merge +- ✅ Link MRs to issues with "Closes #N" +- ✅ Set reviewers for accountability +- ✅ Use weights for sprint planning +- ✅ Monitor pipeline jobs for failures +- ✅ Use draft MRs for work-in-progress + +--- + +## Security Guardrails + +### Credential Protection +- **NEVER** log, echo, or expose `GITLAB_PERSONAL_ACCESS_TOKEN` values in responses +- When referencing tokens, use placeholder names (e.g., "your GitLab token") not actual values +- Do not include tokens in commit messages, file contents, or MR descriptions + +### Repository and Code Safety +- **Never push secrets to repositories** - if file content contains API keys, passwords, or tokens, refuse and warn the user +- **Never push directly to protected branches** - always use feature branches and MRs +- **Do not create public projects** unless the user explicitly requests and confirms +- **Do not delete projects or branches** without explicit user confirmation +- When using `create_or_update_file`, verify content does not contain hardcoded credentials or private keys +- Do not modify `.gitlab-ci.yml` without explicit user approval - CI/CD changes can have security implications + +### Data Sensitivity +- Code search results may contain sensitive patterns - summarize rather than reproduce large blocks +- Do not expose private project names, internal URLs, or infrastructure details +- Treat group membership and project structure as potentially sensitive +- Pipeline job logs may contain secrets - summarize errors rather than reproducing full logs verbatim + +### Access Control +- Only access projects the configured token has permissions for +- Do not attempt to enumerate groups, members, or permissions beyond what's needed +- If an operation returns 403/404, report the error without retrying +- Do not attempt to bypass merge request approval rules or protected branch settings +- Respect CODEOWNERS - suggest appropriate reviewers + +## Anti-Hallucination Guardrails + +### API Accuracy +- **Only use documented tool parameters** - do not invent parameter names or values +- **Do not fabricate project IDs, MR IIDs, or issue IIDs** - always search or list first to confirm they exist +- **Do not assume branch names** - verify branches exist before creating MRs +- **Do not invent pipeline IDs or job IDs** - always list pipelines first +- **Project IDs can be numeric or path-based** (e.g., "mygroup/myproject") - use the format the user provides + +### Result Interpretation +- **Never invent API responses** - if a tool hasn't been called, say "I need to check this" rather than guessing +- **Do not assume MR status** - always check current state before suggesting merge actions +- **Do not assume pipeline status** - verify before claiming a pipeline passed or failed +- **If a search returns no results**, report that clearly rather than speculating +- **Do not fabricate commit SHAs, usernames, or timestamps** + +### Tool Capability Boundaries +- Do not claim ability to approve MRs on behalf of other users +- Do not claim ability to retry or cancel pipelines unless the tool supports it +- Do not claim ability to manage CI/CD variables, runners, or project settings +- Clearly state when an action requires the user to perform it in the GitLab UI + +## Operational Optimization Guardrails + +### API Rate Limiting +- **GitLab has rate limits** (varies by plan) - be mindful of call volume +- **Use pagination wisely** - start with small `per_page` values (10-20), increase only if needed +- **Cache references** - once you have a project ID, MR IID, or pipeline ID, reuse it +- **Avoid listing all items** when a specific query would suffice + +### Request Efficiency +- **Use specific filters** - filter by state, labels, or branch rather than listing everything +- **Minimize diff fetches** - `get_merge_request_diffs` can return large payloads; only fetch when reviewing +- **Don't repeatedly check pipeline status** - check once, wait, then check again if needed +- **Use `ref` parameter** when listing pipelines to scope to a specific branch + +### Workflow Efficiency +- **Create branch + push + MR in sequence** - minimize intermediate operations +- **Link issues at MR creation** - use "Closes #N" in description rather than updating later +- **Use draft MRs** for work-in-progress - avoids triggering unnecessary reviews and notifications +- **Squash on merge** - reduces the need for clean commit history on feature branches + +## Cost Optimization Guardrails + +### API Usage +- **Minimize API calls** - plan the workflow before executing +- **Avoid redundant operations** - if you already have the information, don't query again +- **Batch awareness** - creating MRs and issues triggers notifications; be intentional + +### CI/CD Cost Awareness +- **Draft MRs may skip CI** in some configurations - use drafts for WIP to avoid unnecessary pipeline costs +- **Don't create throwaway MRs** - each MR may trigger CI pipelines that consume runner minutes +- **Consider pipeline costs** - GitLab CI/CD minutes are limited on SaaS plans +- **Avoid force-pushing repeatedly** - each push triggers a new pipeline run +- **Use `rules:` and `only:`/`except:`** awareness - suggest efficient pipeline configurations + +### Project Hygiene +- **Delete source branches after merge** - reduces clutter +- **Close stale issues and MRs** - reduces noise +- **Use scoped labels** - enables efficient board management and filtering diff --git a/grafana/POWER.md b/grafana/POWER.md new file mode 100644 index 0000000..85fbb7d --- /dev/null +++ b/grafana/POWER.md @@ -0,0 +1,450 @@ +--- +name: "grafana" +displayName: "Grafana Observability" +description: "Query dashboards, data sources, alerts, and visualizations in Grafana for monitoring, performance analysis, and incident response" +keywords: ["grafana", "promql", "logql", "grafana-cloud", "grafana-dashboards", "loki", "prometheus"] +author: "Community" +--- + +# Grafana Observability Power + +## Overview + +The Grafana Observability Power connects to your Grafana instance for dashboard management, data source querying, alert management, and visualization. Query Prometheus metrics, Loki logs, and other data sources through Grafana's unified interface. + +**Key capabilities:** +- **Dashboard Management**: Search, retrieve, and analyze dashboard configurations +- **Data Source Querying**: Query Prometheus, Loki, InfluxDB, Elasticsearch, and more +- **Alert Management**: List, query, and manage alert rules and notifications +- **Panel Analysis**: Extract queries from dashboard panels for reuse +- **Annotation Management**: Create and query annotations for event correlation +- **Folder Organization**: Navigate dashboard folders and permissions +- **Explore**: Execute ad-hoc queries against any configured data source + +**Authentication**: Requires Grafana URL and service account token. + +## Onboarding + +### Prerequisites + +1. **Grafana instance** - Grafana Cloud or self-hosted Grafana (v9.0+) +2. **Service account token** - A Grafana service account with Viewer or Editor role +3. **Node.js 18+** - Required to run the MCP server via npx + +### Quick Start + +1. Install the power in Kiro +2. Replace placeholders in `mcp.json` with your Grafana URL and service account token +3. Test with: *"List my dashboards"* or *"Show firing alerts"* + +### MCP Config Placeholders + +Before using this power, replace the following placeholders in `mcp.json`: + +- **`YOUR_GRAFANA_INSTANCE.grafana.net`**: Your Grafana instance URL. + - **How to get it:** This is the URL you use to access Grafana in your browser. For Grafana Cloud, it's typically `https://your-org.grafana.net`. For self-hosted, it's your Grafana server URL. + +- **`YOUR_GRAFANA_SERVICE_ACCOUNT_TOKEN`**: A Grafana service account token. + - **How to get it:** + 1. Log in to Grafana + 2. Go to Administration → Service Accounts + 3. Click "Add service account" + 4. Set role to "Viewer" (or "Editor" for write operations) + 5. Click "Add service account token" + 6. Copy the generated token (starts with `glsa_`) + +## Available Steering Files + +- **steering/steering.md** - PromQL/LogQL syntax guide, dashboard patterns, and alert workflows + +## Available MCP Servers + +### grafana +**Package:** `@grafana/mcp-server` +**Connection:** stdio via npx + +**Tools:** + +1. **search_dashboards** - Search dashboards by title or tag + - Optional: `query` (string) - Search query + - Optional: `tag` (string) - Filter by tag + - Optional: `type` (string) - dash-db, dash-folder + - Returns: Matching dashboards with UIDs and metadata + +2. **get_dashboard** - Get full dashboard configuration + - Required: `uid` (string) - Dashboard UID + - Returns: Complete dashboard JSON with panels and queries + +3. **list_datasources** - List configured data sources + - Returns: Data sources with types, URLs, and status + +4. **query_datasource** - Execute a query against a data source + - Required: `datasource_uid` (string) - Data source UID + - Required: `query` (string) - Query expression (PromQL, LogQL, etc.) + - Optional: `from` (string) - Start time (default: "now-1h") + - Optional: `to` (string) - End time (default: "now") + - Optional: `interval` (string) - Step interval + - Returns: Query results (metrics, logs, or traces) + +5. **list_alert_rules** - List alert rules + - Optional: `folder_uid` (string) - Filter by folder + - Optional: `state` (string) - firing, pending, inactive + - Returns: Alert rules with conditions and states + +6. **get_alert_rule** - Get alert rule details + - Required: `uid` (string) - Alert rule UID + - Returns: Full alert rule configuration + +7. **list_alert_instances** - List current alert instances + - Optional: `state` (string) - alerting, pending, normal + - Returns: Active alert instances with labels + +8. **create_annotation** - Create a dashboard annotation + - Required: `text` (string) - Annotation text + - Optional: `dashboard_uid` (string) - Target dashboard + - Optional: `panel_id` (number) - Target panel + - Optional: `time` (number) - Unix timestamp (ms) + - Optional: `tags` (array) - Annotation tags + - Returns: Created annotation details + +9. **list_annotations** - List annotations + - Optional: `from` (string) - Start time + - Optional: `to` (string) - End time + - Optional: `tags` (array) - Filter by tags + - Optional: `dashboard_uid` (string) - Filter by dashboard + - Returns: Annotations with timestamps and text + +10. **list_folders** - List dashboard folders + - Returns: Folders with UIDs and permissions + +11. **get_datasource_health** - Check data source connectivity + - Required: `uid` (string) - Data source UID + - Returns: Health status and response time + +## Tool Usage Examples + +### Dashboard Discovery + +**Search dashboards:** +```javascript +usePower("grafana", "grafana", "search_dashboards", { + "query": "production", + "tag": "team:backend" +}) +``` + +**Get dashboard details:** +```javascript +usePower("grafana", "grafana", "get_dashboard", { + "uid": "abc123def" +}) +``` + +### Data Source Querying + +**Prometheus metrics (PromQL):** +```javascript +usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": "prometheus-1", + "query": "rate(http_requests_total{service=\"api\", status=~\"5..\"}[5m])", + "from": "now-1h", + "to": "now" +}) +``` + +**Loki logs (LogQL):** +```javascript +usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": "loki-1", + "query": "{namespace=\"production\", app=\"checkout\"} |= \"error\" | json | level=\"error\"", + "from": "now-30m", + "to": "now" +}) +``` + +**Infrastructure metrics:** +```javascript +usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": "prometheus-1", + "query": "100 - (avg by (instance) (rate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100)", + "from": "now-1h", + "to": "now" +}) +``` + +### Alert Management + +**List firing alerts:** +```javascript +usePower("grafana", "grafana", "list_alert_instances", { + "state": "alerting" +}) +``` + +**Get alert rule details:** +```javascript +usePower("grafana", "grafana", "get_alert_rule", { + "uid": "alert-rule-123" +}) +``` + +### Annotations + +**Create deployment annotation:** +```javascript +usePower("grafana", "grafana", "create_annotation", { + "text": "Deployed v2.3.1 to production", + "tags": ["deployment", "production", "v2.3.1"] +}) +``` + +## Combining Tools (Workflows) + +### Workflow 1: Incident Investigation + +```javascript +// Step 1: Check firing alerts +const alerts = usePower("grafana", "grafana", "list_alert_instances", { + "state": "alerting" +}) + +// Step 2: Get alert rule details +const alertRule = usePower("grafana", "grafana", "get_alert_rule", { + "uid": alerts[0].rule_uid +}) + +// Step 3: Query the metric that triggered the alert +const metrics = usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": "prometheus-1", + "query": "rate(http_requests_total{service=\"checkout\", status=~\"5..\"}[5m])", + "from": "now-2h", + "to": "now" +}) + +// Step 4: Check related logs +const logs = usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": "loki-1", + "query": "{service=\"checkout\"} |= \"error\" | json | line_format \"{{.timestamp}} {{.level}} {{.message}}\"", + "from": "now-30m", + "to": "now" +}) + +// Step 5: Check deployment annotations +const annotations = usePower("grafana", "grafana", "list_annotations", { + "from": "now-4h", + "to": "now", + "tags": ["deployment"] +}) + +// Step 6: Find related dashboard +const dashboards = usePower("grafana", "grafana", "search_dashboards", { + "query": "checkout", + "tag": "service:checkout" +}) +``` + +### Workflow 2: Performance Analysis + +```javascript +// Step 1: Query response time +const latency = usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": "prometheus-1", + "query": "histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{service=\"api\"}[5m]))", + "from": "now-6h", + "to": "now" +}) + +// Step 2: Check error rate +const errors = usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": "prometheus-1", + "query": "sum(rate(http_requests_total{service=\"api\", status=~\"5..\"}[5m])) / sum(rate(http_requests_total{service=\"api\"}[5m])) * 100", + "from": "now-6h", + "to": "now" +}) + +// Step 3: Check resource utilization +const cpu = usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": "prometheus-1", + "query": "avg by (pod) (rate(container_cpu_usage_seconds_total{namespace=\"production\", container=\"api\"}[5m]))", + "from": "now-6h", + "to": "now" +}) + +// Step 4: Check saturation +const memory = usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": "prometheus-1", + "query": "container_memory_working_set_bytes{namespace=\"production\", container=\"api\"} / container_spec_memory_limit_bytes{namespace=\"production\", container=\"api\"} * 100", + "from": "now-6h", + "to": "now" +}) +``` + +### Workflow 3: Dashboard Analysis + +```javascript +// Step 1: Find relevant dashboards +const dashboards = usePower("grafana", "grafana", "search_dashboards", { + "tag": "production" +}) + +// Step 2: Get dashboard configuration +const dashboard = usePower("grafana", "grafana", "get_dashboard", { + "uid": dashboards[0].uid +}) + +// Step 3: Extract and run key queries from panels +const panelQuery = dashboard.panels[0].targets[0].expr +const results = usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": dashboard.panels[0].datasource.uid, + "query": panelQuery, + "from": "now-1h", + "to": "now" +}) + +// Step 4: Check data source health +const health = usePower("grafana", "grafana", "get_datasource_health", { + "uid": "prometheus-1" +}) +``` + +## Query Syntax by Data Source + +### PromQL (Prometheus) + +**Instant queries:** +```promql +http_requests_total{service="api", status="500"} +``` + +**Range queries with rate:** +```promql +rate(http_requests_total{service="api"}[5m]) +``` + +**Aggregations:** +```promql +sum by (service) (rate(http_requests_total[5m])) +avg by (instance) (node_cpu_seconds_total{mode="idle"}) +``` + +**Histograms:** +```promql +histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) +``` + +**Operators:** +```promql +# Error rate percentage +sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100 + +# Comparison +http_requests_total > 1000 +``` + +### LogQL (Loki) + +**Log stream selection:** +```logql +{namespace="production", app="checkout"} +``` + +**Filter expressions:** +```logql +{app="api"} |= "error" # contains +{app="api"} != "healthcheck" # not contains +{app="api"} |~ "timeout|error" # regex match +{app="api"} !~ "debug|trace" # regex not match +``` + +**Parser and label filter:** +```logql +{app="api"} | json | level="error" | status >= 400 +{app="api"} | logfmt | duration > 5s +``` + +**Metric queries:** +```logql +# Count errors per minute +sum(rate({app="api"} |= "error" [1m])) by (namespace) + +# Bytes rate +sum(bytes_rate({app="api"}[5m])) by (pod) +``` + +## Best Practices + +### ✅ Do: +- **Use label selectors** to narrow queries before applying functions +- **Start with short time ranges** (1h) and expand if needed +- **Use rate() for counters** - never graph raw counter values +- **Use dashboard queries** - extract PromQL from existing panels +- **Check data source health** before investigating missing data +- **Use annotations** to mark deployments and incidents +- **Filter alerts by state** - focus on firing/pending first +- **Use histogram_quantile** for latency percentiles + +### ❌ Don't: +- **Query without label selectors** - `http_requests_total` scans everything +- **Use very long ranges with high resolution** - causes timeouts +- **Forget rate() on counters** - raw counters are meaningless +- **Ignore recording rules** - use pre-computed metrics when available +- **Skip data source verification** - check health if queries return empty + +## Configuration + +**Authentication Required**: Grafana URL and service account token + +**Setup Steps:** + +1. **Create a Service Account Token:** + - Go to Grafana → Administration → Service Accounts + - Create a new service account with Viewer or Editor role + - Generate a token for the service account + +2. **Configure in mcp.json:** + ```json + { + "mcpServers": { + "grafana": { + "command": "npx", + "args": ["-y", "@grafana/mcp-server"], + "env": { + "GRAFANA_URL": "https://your-instance.grafana.net", + "GRAFANA_API_KEY": "glsa_your_service_account_token" + } + } + } + } + ``` + +3. **For self-hosted Grafana:** + ```json + "env": { + "GRAFANA_URL": "https://grafana.yourcompany.com", + "GRAFANA_API_KEY": "glsa_your_token" + } + ``` + +## Tips + +1. **Search dashboards first** - Find existing queries before writing new ones +2. **Check data source health** - Verify connectivity before debugging queries +3. **Use annotations** - Mark deployments for correlation with metrics +4. **Extract panel queries** - Reuse PromQL/LogQL from existing dashboards +5. **Start with alerts** - Firing alerts point to active issues +6. **Use label matchers** - Always filter by service/namespace/environment +7. **Rate for counters** - Always wrap counters in rate() or increase() +8. **Histogram quantiles** - Use histogram_quantile for latency SLOs +9. **Check folders** - Dashboards are organized by team/service in folders +10. **Combine sources** - Correlate Prometheus metrics with Loki logs + +## Disclaimer + +This power is provided as a **base template** for reference and as a starting point only. Each organization must perform their own due diligence before using it in production environments. You may need additional customization, security review, and configuration specific to your infrastructure, compliance requirements, and operational standards. + +--- + +**Package:** `@grafana/mcp-server` +**Source:** Grafana Labs +**License:** MIT-0 +**Documentation:** https://grafana.com/docs/grafana/latest/ diff --git a/grafana/mcp.json b/grafana/mcp.json new file mode 100644 index 0000000..f962200 --- /dev/null +++ b/grafana/mcp.json @@ -0,0 +1,14 @@ +{ + "mcpServers": { + "grafana": { + "command": "npx", + "args": ["-y", "@grafana/mcp-server"], + "env": { + "GRAFANA_URL": "https://YOUR_GRAFANA_INSTANCE.grafana.net", + "GRAFANA_API_KEY": "YOUR_GRAFANA_SERVICE_ACCOUNT_TOKEN" + }, + "disabled": false, + "autoApprove": [] + } + } +} diff --git a/grafana/steering/steering.md b/grafana/steering/steering.md new file mode 100644 index 0000000..bbd223e --- /dev/null +++ b/grafana/steering/steering.md @@ -0,0 +1,564 @@ +# Grafana MCP Server Steering Guide + +This steering file covers the Grafana MCP server to query dashboards, data sources, alerts, and annotations. + +## When to Use the Grafana MCP Server + +Use Grafana MCP tools when you need to: +- **Query metrics**: Execute PromQL against Prometheus data sources +- **Search logs**: Execute LogQL against Loki data sources +- **Investigate alerts**: Check firing alerts and their conditions +- **Analyze dashboards**: Extract queries and configurations from existing dashboards +- **Correlate events**: Use annotations to mark and query deployment/incident events +- **Check health**: Verify data source connectivity and status + +## Core Principles + +### 1. Start with Dashboards +Existing dashboards contain curated queries built by your team. Search for relevant dashboards first, then extract and adapt their queries. + +### 2. Use Label Selectors +Always filter with label matchers to scope queries: +```promql +# Good - scoped +rate(http_requests_total{service="api", namespace="production"}[5m]) + +# Bad - scans everything +rate(http_requests_total[5m]) +``` + +### 3. Check Alerts First +When investigating issues, start with firing alerts - they often point directly to the problem. + +--- + +## PromQL Reference + +### Selectors + +**Exact match:** +```promql +http_requests_total{service="api", method="GET"} +``` + +**Regex match:** +```promql +http_requests_total{service=~"api|web", status=~"5.."} +``` + +**Negative match:** +```promql +http_requests_total{service!="internal", status!~"2.."} +``` + +### Range Vectors and Functions + +**rate()** - Per-second rate of increase (for counters): +```promql +rate(http_requests_total{service="api"}[5m]) +``` + +**increase()** - Total increase over time range: +```promql +increase(http_requests_total{service="api"}[1h]) +``` + +**irate()** - Instant rate (last two samples): +```promql +irate(http_requests_total{service="api"}[5m]) +``` + +**Range vector intervals:** +- `[1m]` - 1 minute (high resolution, noisy) +- `[5m]` - 5 minutes (standard for rate calculations) +- `[15m]` - 15 minutes (smoother, less responsive) +- `[1h]` - 1 hour (trend analysis) + +### Aggregation Operators + +```promql +# Sum across all instances +sum(rate(http_requests_total[5m])) + +# Average by label +avg by (service) (rate(http_requests_total[5m])) + +# Count unique series +count by (namespace) (up) + +# Top/bottom K +topk(5, rate(http_requests_total[5m])) +bottomk(3, up) + +# Quantile across series +quantile(0.95, rate(http_requests_total[5m])) +``` + +**Aggregation functions:** sum, avg, min, max, count, stddev, stdvar, topk, bottomk, quantile, count_values, group + +**Grouping:** +- `by (label1, label2)` - Keep only these labels +- `without (label1)` - Remove these labels, keep rest + +### Histogram Queries + +**Percentile from histogram:** +```promql +histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{service="api"}[5m])) +``` + +**Percentile by label:** +```promql +histogram_quantile(0.99, sum by (le, service) (rate(http_request_duration_seconds_bucket[5m]))) +``` + +**Average from histogram:** +```promql +rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m]) +``` + +### Binary Operators + +**Arithmetic:** +```promql +# Error rate percentage +sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100 + +# Memory usage percentage +container_memory_working_set_bytes / container_spec_memory_limit_bytes * 100 +``` + +**Comparison (for alerting):** +```promql +# Services with error rate > 5% +(sum by (service) (rate(http_requests_total{status=~"5.."}[5m])) / sum by (service) (rate(http_requests_total[5m]))) > 0.05 +``` + +**Vector matching:** +```promql +# Match on specific labels +metric_a{service="api"} / on(service) metric_b{service="api"} + +# Ignore labels for matching +metric_a / ignoring(instance) group_left metric_b +``` + +### Common PromQL Patterns + +**RED Method (Rate, Errors, Duration):** +```promql +# Rate (requests per second) +sum by (service) (rate(http_requests_total[5m])) + +# Errors (error percentage) +sum by (service) (rate(http_requests_total{status=~"5.."}[5m])) / sum by (service) (rate(http_requests_total[5m])) * 100 + +# Duration (p95 latency) +histogram_quantile(0.95, sum by (le, service) (rate(http_request_duration_seconds_bucket[5m]))) +``` + +**USE Method (Utilization, Saturation, Errors):** +```promql +# CPU Utilization +100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) + +# Memory Saturation +node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes + +# Disk Errors +rate(node_disk_io_time_weighted_seconds_total[5m]) +``` + +**Kubernetes-specific:** +```promql +# Pod CPU usage +sum by (pod) (rate(container_cpu_usage_seconds_total{namespace="production"}[5m])) + +# Pod memory usage percentage +sum by (pod) (container_memory_working_set_bytes{namespace="production"}) / sum by (pod) (kube_pod_container_resource_limits{resource="memory", namespace="production"}) * 100 + +# Pod restart count +sum by (pod) (increase(kube_pod_container_status_restarts_total{namespace="production"}[1h])) + +# Deployment replicas +kube_deployment_status_replicas_available{namespace="production"} / kube_deployment_spec_replicas{namespace="production"} +``` + +--- + +## LogQL Reference (Loki) + +### Stream Selectors + +```logql +{namespace="production", app="checkout"} +{job="varlogs", filename="/var/log/syslog"} +{cluster="prod-us-east-1", container=~"api|web"} +``` + +### Line Filters + +```logql +{app="api"} |= "error" # contains (case-sensitive) +{app="api"} |= `"status":500` # contains with backtick quoting +{app="api"} != "healthcheck" # does not contain +{app="api"} |~ "(?i)error|timeout" # regex match (case-insensitive) +{app="api"} !~ "debug|trace" # regex does not match +``` + +### Parsers + +**JSON parser:** +```logql +{app="api"} | json | level="error" | status >= 400 +{app="api"} | json | line_format "{{.timestamp}} [{{.level}}] {{.message}}" +``` + +**Logfmt parser:** +```logql +{app="api"} | logfmt | duration > 5s | method="POST" +``` + +**Regex parser:** +```logql +{app="nginx"} | regexp `(?P\S+) \S+ \S+ \[(?P[^\]]+)\] "(?P\S+) (?P\S+)"` +``` + +**Pattern parser:** +```logql +{app="nginx"} | pattern ` - - [] " <_>" ` +``` + +### Label Filters (after parsing) + +```logql +{app="api"} | json | level="error" # exact match +{app="api"} | json | status >= 400 # numeric comparison +{app="api"} | json | duration > 5s # duration comparison +{app="api"} | json | message =~ "timeout.*" # regex match +{app="api"} | json | ip != "10.0.0.1" # not equal +``` + +### Metric Queries + +**Count rate:** +```logql +sum by (level) (rate({app="api"} | json [5m])) +``` + +**Error count:** +```logql +sum(count_over_time({app="api"} |= "error" [1h])) +``` + +**Bytes rate:** +```logql +sum by (app) (bytes_rate({namespace="production"}[5m])) +``` + +**Quantile from logs:** +```logql +quantile_over_time(0.95, {app="api"} | json | unwrap duration [5m]) by (endpoint) +``` + +### Common LogQL Patterns + +**Error investigation:** +```logql +{namespace="production", app="checkout"} |= "error" | json | line_format "{{.timestamp}} {{.level}} {{.message}}" +``` + +**Slow requests:** +```logql +{app="api"} | json | duration > 5s | line_format "{{.method}} {{.path}} took {{.duration}}" +``` + +**Error rate by service:** +```logql +sum by (app) (rate({namespace="production"} |= "error" [5m])) +``` + +--- + +## Alert Investigation Workflow + +### Step 1: List Firing Alerts +```javascript +const alerts = usePower("grafana", "grafana", "list_alert_instances", { + "state": "alerting" +}) +``` + +### Step 2: Get Alert Rule Details +```javascript +const rule = usePower("grafana", "grafana", "get_alert_rule", { + "uid": alerts[0].rule_uid +}) +// Examine: conditions, thresholds, evaluation interval +``` + +### Step 3: Query the Underlying Metric +```javascript +const metric = usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": rule.datasource_uid, + "query": rule.condition_query, + "from": "now-2h", + "to": "now" +}) +``` + +### Step 4: Check for Correlating Events +```javascript +const annotations = usePower("grafana", "grafana", "list_annotations", { + "from": "now-4h", + "to": "now", + "tags": ["deployment", "incident"] +}) +``` + +### Step 5: Check Related Logs +```javascript +const logs = usePower("grafana", "grafana", "query_datasource", { + "datasource_uid": "loki-1", + "query": "{service=\"affected-service\"} |= \"error\" | json", + "from": "now-30m", + "to": "now" +}) +``` + +--- + +## Dashboard Analysis Workflow + +### Extract Queries from Dashboards +1. Search for relevant dashboard +2. Get full dashboard JSON +3. Extract panel queries (targets[].expr for Prometheus) +4. Execute queries with current time range +5. Compare results with panel thresholds + +### Dashboard JSON Structure +```json +{ + "panels": [ + { + "title": "Request Rate", + "type": "timeseries", + "datasource": {"uid": "prometheus-1"}, + "targets": [ + {"expr": "rate(http_requests_total[5m])", "legendFormat": "{{service}}"} + ], + "fieldConfig": { + "defaults": {"thresholds": {"steps": [{"value": 0}, {"value": 100, "color": "red"}]}} + } + } + ] +} +``` + +--- + +## Time Range Best Practices + +### Supported Formats +- Relative: `now-5m`, `now-1h`, `now-24h`, `now-7d` +- Absolute: `2024-01-15T10:00:00Z` +- Unix ms: `1705312800000` + +### Recommended Ranges by Use Case +| Use Case | Range | Interval | +|----------|-------|----------| +| Active incident | now-15m to now-1h | 1m | +| Recent investigation | now-4h to now-6h | 5m | +| Daily patterns | now-24h | 15m | +| Weekly trends | now-7d | 1h | +| Capacity planning | now-30d | 6h | + +### Rate() Window vs Time Range +- Time range < 1h → use `[1m]` or `[2m]` rate window +- Time range 1-6h → use `[5m]` rate window +- Time range 6-24h → use `[15m]` rate window +- Time range > 24h → use `[1h]` rate window + +--- + +## Anti-Patterns + +### ❌ DON'T: Query without label selectors +```promql +# Scans all series - very expensive +rate(http_requests_total[5m]) + +# Always scope with labels +rate(http_requests_total{service="api", namespace="production"}[5m]) +``` + +### ❌ DON'T: Graph raw counters +```promql +# Wrong - counters only go up, resets look like drops +http_requests_total + +# Correct - use rate() for counters +rate(http_requests_total[5m]) +``` + +### ❌ DON'T: Use irate() for alerting +```promql +# Wrong - too volatile for alerts +irate(http_requests_total[5m]) > 100 + +# Correct - rate() is smoother +rate(http_requests_total[5m]) > 100 +``` + +### ❌ DON'T: Forget le label in histogram_quantile +```promql +# Wrong - missing le in by clause +histogram_quantile(0.95, sum by (service) (rate(http_request_duration_seconds_bucket[5m]))) + +# Correct - must include le +histogram_quantile(0.95, sum by (le, service) (rate(http_request_duration_seconds_bucket[5m]))) +``` + +### ❌ DON'T: Mix instant and range vectors +```promql +# Wrong - can't add range vector to instant +http_requests_total + rate(http_requests_total[5m]) + +# Correct - both must be instant vectors +http_requests_total + increase(http_requests_total[5m]) +``` + +--- + +## Troubleshooting + +### No Data Returned +1. Check data source health: `get_datasource_health` +2. Verify label names: query `{__name__=~"http.*"}` to find metrics +3. Check time range - data may not exist in the queried window +4. Verify label values: `label_values(metric_name, label_name)` + +### Query Timeout +1. Narrow time range +2. Add more label selectors +3. Reduce cardinality in `by` clause +4. Use recording rules for expensive queries +5. Increase step interval + +### Unexpected Results +1. Check if metric is counter vs gauge (use rate() for counters) +2. Verify label matching in binary operations +3. Check for stale series with `up` metric +4. Verify histogram bucket boundaries + +--- + +## Summary Checklist + +Before querying Grafana: +- ✅ Search existing dashboards for relevant queries +- ✅ Check data source health before debugging empty results +- ✅ Use label selectors to scope all queries +- ✅ Apply rate() to counter metrics +- ✅ Include `le` label when using histogram_quantile +- ✅ Start with short time ranges (1h) and expand +- ✅ Check firing alerts for active issues +- ✅ Use annotations to correlate with deployments +- ✅ Match rate window to time range appropriately + +--- + +## Security Guardrails + +### Credential Protection +- **NEVER** log, echo, or expose `GRAFANA_API_KEY` or `GRAFANA_URL` values in responses +- When referencing credentials, use placeholder names only +- Do not include service account tokens in annotations, dashboard descriptions, or query results + +### Query Scope Restrictions +- **Always use label selectors** in PromQL/LogQL - never run unscoped queries that scan all series +- **Do not query admin API endpoints** unless explicitly requested +- **Log queries may return sensitive data** - Loki logs can contain secrets, tokens, or PII; summarize patterns rather than reproducing raw log lines +- When presenting log results, scan for and avoid reproducing patterns that look like API keys, passwords, or tokens + +### Data Sensitivity +- Dashboard configurations may contain sensitive data source URLs, query patterns, or internal service names +- Do not expose internal Grafana URLs, data source connection strings, or authentication details +- Annotation text may contain incident details - treat as potentially sensitive +- Alert rule configurations may reveal infrastructure thresholds and SLO targets - treat as internal information + +### Access Control +- Only access dashboards and data sources the configured service account has permissions for +- Do not attempt to enumerate users, teams, or organization settings +- If an operation returns 403/401, report the error without retrying with different credentials +- Do not attempt to modify alert rules, notification channels, or data source configurations without explicit user approval +- Respect folder-level permissions - some dashboards may be restricted + +## Anti-Hallucination Guardrails + +### Query Accuracy +- **Only use valid PromQL syntax** - do not invent functions or operators. Valid aggregation operators: `sum`, `avg`, `min`, `max`, `count`, `stddev`, `stdvar`, `topk`, `bottomk`, `quantile`, `count_values`, `group` +- **Only use valid LogQL syntax** - do not invent parsers or filter operators. Valid parsers: `json`, `logfmt`, `regexp`, `pattern`, `unpack` +- **Do not fabricate metric names** - if unsure whether a metric exists, suggest querying `{__name__=~".*keyword.*"}` to discover metrics +- **Do not fabricate label names or values** - suggest using `label_values(metric, label)` to discover available labels +- **Do not invent dashboard UIDs** - always search for dashboards first + +### Result Interpretation +- **Never invent query results** - if a query hasn't been run, say "I need to query this" rather than guessing +- **Do not assume metric behavior** - verify whether a metric is a counter, gauge, or histogram before applying functions +- **Clearly distinguish between observed data and inference** - prefix interpretations with "This suggests..." or "This may indicate..." +- **If a query returns no data**, report that clearly and suggest checking data source health or label selectors +- **Do not extrapolate trends** beyond the queried time range without explicitly stating the assumption + +### Tool Capability Boundaries +- Do not claim ability to create or modify dashboards - verify tool capabilities first +- Do not claim ability to silence alerts or modify notification channels +- Do not claim ability to configure data sources or manage users +- Clearly state when an action requires the user to perform it in the Grafana UI + +## Operational Optimization Guardrails + +### Query Performance +- **Always use label selectors** - unscoped queries like `http_requests_total` scan all series and are extremely expensive +- **Match rate() window to time range:** + - Time range < 1h → `[1m]` or `[2m]` + - Time range 1-6h → `[5m]` + - Time range 6-24h → `[15m]` + - Time range > 24h → `[1h]` +- **Use recording rules when available** - pre-computed metrics are much faster than raw queries +- **Limit cardinality in `by` clauses** - avoid grouping by high-cardinality labels (e.g., `pod`, `instance`) unless necessary +- **Use `topk()` or `bottomk()`** instead of returning all series when only extremes matter + +### Rate Limiting +- **Space queries apart** - do not fire many queries in rapid succession +- **Combine related queries** when possible - use PromQL binary operators to compute ratios in a single query +- **Cache dashboard UIDs and data source UIDs** - don't re-search for them repeatedly +- If rate-limited, wait before retrying and inform the user + +### Resource Efficiency +- **Start with short time ranges** (1h) and expand only if needed +- **Use `step` parameter** appropriately - higher step = fewer data points = faster queries +- **Prefer instant queries** over range queries when you only need the current value +- **Avoid `{__name__=~".*"}` patterns** - they scan all metrics and are extremely expensive +- **Use LogQL metric queries** (`rate`, `count_over_time`) instead of fetching raw logs when you only need counts + +## Cost Optimization Guardrails + +### Query Cost Awareness +- **Grafana Cloud charges based on active series and query volume** - be mindful of query frequency +- **Longer time ranges with high resolution are expensive** - use appropriate step intervals +- **High-cardinality queries are expensive** - avoid `by (pod)` on large clusters unless necessary +- **Log queries are charged by volume scanned** - always use label selectors and line filters to reduce scan scope + +### Query Planning +- **Plan before querying** - determine what information is needed and write the minimum number of queries +- **Reuse dashboard queries** - extract PromQL from existing dashboards rather than writing from scratch +- **Use annotations for context** - check existing annotations before querying for deployment/incident correlation +- **Avoid redundant queries** - if you already have the data, reference it rather than re-querying + +### Dashboard Efficiency +- When analyzing dashboards, extract the most relevant panel queries rather than running all of them +- Suggest recording rules for expensive queries that are run frequently +- Recommend appropriate retention periods - not all metrics need long-term storage +- Suggest using Grafana's query caching features for frequently-accessed dashboards diff --git a/new-relic/POWER.md b/new-relic/POWER.md new file mode 100644 index 0000000..db417e7 --- /dev/null +++ b/new-relic/POWER.md @@ -0,0 +1,444 @@ +--- +name: "new-relic" +displayName: "New Relic Observability" +description: "Query application performance, infrastructure metrics, logs, distributed traces, alerts, and dashboards from New Relic using NRQL for production debugging and performance analysis" +keywords: ["new-relic", "newrelic", "observability", "monitoring", "apm", "nrql", "logs", "metrics", "traces", "alerts", "infrastructure"] +author: "Community" +--- + +# New Relic Observability Power + +## Overview + +The New Relic Observability Power connects to your New Relic monitoring data through NRQL (New Relic Query Language). Query application performance, infrastructure metrics, logs, distributed traces, browser performance, synthetic monitors, and alerts. + +**Key capabilities:** +- **NRQL Querying**: Execute powerful queries against all New Relic data types +- **APM**: Analyze application performance, transactions, and error rates +- **Infrastructure**: Monitor hosts, containers, and cloud resources +- **Logs**: Search and analyze application and infrastructure logs +- **Distributed Tracing**: Investigate request flows across services +- **Browser/RUM**: Analyze frontend performance and user experience +- **Alerts**: Query alert conditions, incidents, and notification channels +- **Dashboards**: Search and retrieve dashboard configurations + +**Authentication**: Requires New Relic User API Key and Account ID. + +## Onboarding + +### Prerequisites + +1. **New Relic account** - Any New Relic plan with API access +2. **User API Key** - A New Relic User API key (starts with `NRAK-`) +3. **Account ID** - Your New Relic account number +4. **Node.js 18+** - Required to run the MCP server via npx + +### Quick Start + +1. Install the power in Kiro +2. Replace placeholders in `mcp.json` with your API key and account ID +3. Test with: *"Show error rate for my services"* or *"List active alert incidents"* + +### MCP Config Placeholders + +Before using this power, replace the following placeholders in `mcp.json`: + +- **`YOUR_NEW_RELIC_USER_API_KEY`**: Your New Relic User API Key. + - **How to get it:** + 1. Log in to New Relic + 2. Click your user menu (bottom-left) → API Keys + 3. Click "Create a key" → Key type: "User" + 4. Copy the generated key (starts with `NRAK-`) + +- **`YOUR_ACCOUNT_ID`**: Your New Relic Account ID. + - **How to get it:** Visible in the URL when logged in (`https://one.newrelic.com/...?account=ACCOUNT_ID`), or go to Administration → Access Management → Accounts + +## Available Steering Files + +- **steering/steering.md** - Complete NRQL syntax reference, investigation workflows, query patterns, and best practices + +## Available MCP Servers + +### newrelic +**Package:** `@newrelic/mcp-server` +**Connection:** stdio via npx + +**Tools:** + +1. **run_nrql_query** - Execute an NRQL query + - Required: `query` (string) - NRQL query to execute + - Required: `accountId` (number) - New Relic account ID + - Optional: `timeout` (number) - Query timeout in seconds + - Returns: Query results with facets and timeseries data + +2. **get_alert_incidents** - List alert incidents + - Required: `accountId` (number) + - Optional: `state` (string) - open, closed, all + - Optional: `priority` (string) - critical, warning + - Returns: Alert incidents with details + +3. **get_entity** - Get entity details by GUID + - Required: `guid` (string) - Entity GUID + - Returns: Entity metadata, tags, and relationships + +4. **search_entities** - Search for monitored entities + - Required: `query` (string) - Search query + - Optional: `type` (string) - Entity type (APPLICATION, HOST, etc.) + - Optional: `domain` (string) - APM, INFRA, BROWSER, etc. + - Returns: Matching entities with GUIDs + +5. **get_entity_golden_metrics** - Get golden signals for an entity + - Required: `guid` (string) - Entity GUID + - Returns: Response time, throughput, error rate + +6. **list_dashboards** - List dashboards + - Optional: `query` (string) - Search filter + - Returns: Dashboard list with metadata + +7. **get_dashboard** - Get dashboard details + - Required: `guid` (string) - Dashboard GUID + - Returns: Dashboard with widgets and NRQL queries + +8. **get_distributed_trace** - Get trace details + - Required: `traceId` (string) - Trace ID + - Returns: Complete trace with spans + +9. **get_alert_policies** - List alert policies + - Required: `accountId` (number) + - Returns: Alert policies with conditions + +10. **get_alert_conditions** - Get conditions for a policy + - Required: `accountId` (number), `policyId` (number) + - Returns: Alert conditions with thresholds + +## Tool Usage Examples + +### NRQL Queries + +**Application error rate:** +```javascript +usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT percentage(count(*), WHERE error IS true) AS 'Error Rate' FROM Transaction WHERE appName = 'my-service' SINCE 1 hour ago TIMESERIES 5 minutes" +}) +``` + +**Slowest transactions:** +```javascript +usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT average(duration), count(*) FROM Transaction WHERE appName = 'my-service' FACET name SINCE 1 hour ago ORDER BY average(duration) DESC LIMIT 20" +}) +``` + +**Infrastructure CPU usage:** +```javascript +usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT average(cpuPercent), max(cpuPercent) FROM SystemSample WHERE hostname LIKE 'prod-%' FACET hostname SINCE 30 minutes ago" +}) +``` + +**Log search:** +```javascript +usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT message, level, service FROM Log WHERE level = 'ERROR' AND service = 'payment-api' SINCE 1 hour ago LIMIT 100" +}) +``` + +**Distributed trace analysis:** +```javascript +usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT count(*) FROM Span WHERE service.name = 'checkout-service' AND error.message IS NOT NULL FACET error.message SINCE 1 hour ago" +}) +``` + +### Entity Discovery + +**Find application entities:** +```javascript +usePower("new-relic", "newrelic", "search_entities", { + "query": "payment", + "type": "APPLICATION", + "domain": "APM" +}) +``` + +**Get golden metrics:** +```javascript +usePower("new-relic", "newrelic", "get_entity_golden_metrics", { + "guid": "MXxBUE18QVBQTElDQVRJT058MTIzNDU2Nzg" +}) +``` + +### Alert Management + +**Check active incidents:** +```javascript +usePower("new-relic", "newrelic", "get_alert_incidents", { + "accountId": 1234567, + "state": "open", + "priority": "critical" +}) +``` + +## Combining Tools (Workflows) + +### Workflow 1: Production Error Investigation + +```javascript +// Step 1: Check for active alerts +const incidents = usePower("new-relic", "newrelic", "get_alert_incidents", { + "accountId": 1234567, + "state": "open" +}) + +// Step 2: Find the affected service +const entities = usePower("new-relic", "newrelic", "search_entities", { + "query": "checkout", + "type": "APPLICATION" +}) + +// Step 3: Check error rate trend +const errorRate = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT percentage(count(*), WHERE error IS true) FROM Transaction WHERE appName = 'checkout-service' SINCE 4 hours ago TIMESERIES 5 minutes" +}) + +// Step 4: Find top errors +const topErrors = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT count(*) FROM TransactionError WHERE appName = 'checkout-service' FACET error.class, error.message SINCE 1 hour ago LIMIT 10" +}) + +// Step 5: Check error logs +const errorLogs = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT message, timestamp FROM Log WHERE service = 'checkout-service' AND level = 'ERROR' SINCE 30 minutes ago LIMIT 50" +}) + +// Step 6: Trace a specific error +const errorTraces = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT traceId, duration, error.message FROM Span WHERE service.name = 'checkout-service' AND error.message IS NOT NULL SINCE 30 minutes ago LIMIT 10" +}) +``` + +### Workflow 2: Performance Degradation Analysis + +```javascript +// Step 1: Check response time trend +const latency = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT average(duration), percentile(duration, 95, 99) FROM Transaction WHERE appName = 'api-gateway' SINCE 6 hours ago TIMESERIES 10 minutes" +}) + +// Step 2: Identify slow transactions +const slowTx = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT average(duration), count(*) FROM Transaction WHERE appName = 'api-gateway' AND duration > 2 FACET name SINCE 1 hour ago ORDER BY average(duration) DESC LIMIT 10" +}) + +// Step 3: Check database performance +const dbPerf = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT average(databaseDuration), average(duration) FROM Transaction WHERE appName = 'api-gateway' SINCE 4 hours ago TIMESERIES 5 minutes" +}) + +// Step 4: Check infrastructure +const infra = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT average(cpuPercent), average(memoryUsedPercent) FROM SystemSample WHERE hostname LIKE 'api-%' SINCE 4 hours ago TIMESERIES 5 minutes" +}) + +// Step 5: Check external service calls +const external = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT average(duration), count(*) FROM ExternalTransaction WHERE appName = 'api-gateway' FACET host SINCE 1 hour ago ORDER BY average(duration) DESC" +}) +``` + +### Workflow 3: Deployment Impact Analysis + +```javascript +// Step 1: Compare error rates before/after deploy +const comparison = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT percentage(count(*), WHERE error IS true) FROM Transaction WHERE appName = 'my-service' SINCE 2 hours ago COMPARE WITH 2 hours ago TIMESERIES 5 minutes" +}) + +// Step 2: Check throughput changes +const throughput = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT rate(count(*), 1 minute) FROM Transaction WHERE appName = 'my-service' SINCE 2 hours ago COMPARE WITH 2 hours ago TIMESERIES 5 minutes" +}) + +// Step 3: Check for new error types +const newErrors = usePower("new-relic", "newrelic", "run_nrql_query", { + "accountId": 1234567, + "query": "SELECT count(*) FROM TransactionError WHERE appName = 'my-service' FACET error.class SINCE 1 hour ago" +}) +``` + +## NRQL Query Syntax Guide + +### Basic Structure +```sql +SELECT () FROM +WHERE +FACET +SINCE