👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
Automate NuGet Upgrades with GitHub Copilot AI Skills and Live Documentation Lookup

Automate NuGet Upgrades with GitHub Copilot AI Skills and Live Documentation Lookup

Author - Abdul Rahman (Bhai)

AI

7 Articles

Improve

Table of Contents

  1. What we gonna do?
  2. Why we gonna do?
  3. How we gonna do?
  4. Summary

What we gonna do?

Managing NuGet package versions across .NET solutions is a maintenance nightmare—especially when breaking changes lurk in every minor version bump. GitHub Copilot Skills combined with Model Context Protocol (MCP) transform this tedious process into an intelligent, automated workflow that not only upgrades packages but also fetches live documentation to understand and fix breaking changes on the fly.

A GitHub Copilot Skill is a reusable capability stored in your repository's .github/skills directory. Unlike agents (which are conversational workflows), skills are contextual tools that Copilot can invoke when referenced via #file:SKILL.md syntax. Think of skills as specialized knowledge modules that teach Copilot domain-specific expertise—like enforcing strict NuGet management rules, version verification protocols, and restoration workflows.

In this article, you'll learn how to build a NuGet upgrade skill that combines three powerful capabilities: automated package discovery, intelligent version updates with safety checks, and live documentation lookup via MCP to resolve breaking changes automatically. Instead of spending hours debugging cryptic errors after a package upgrade, you'll type one command and let the skill handle everything—from verifying versions exist on NuGet.org to reading official migration guides and applying the necessary code fixes.

How Skills Differ from Agents

While agents are conversational workflows designed for multi-step tasks (like the .NET upgrade agent we covered previously), skills are reusable knowledge modules that:

  • Enforce rules and constraints: "NEVER add packages by editing .csproj, always use dotnet CLI"
  • Provide verification workflows: "Check if version exists before updating"
  • Offer domain expertise: "Understand Central Package Management vs per-project versioning"
  • Can be composed: Skills can reference other skills and integrate with MCP tools

Skills are invoked differently too—you reference them directly in prompts using #file:.github/skills/name/SKILL.md, making them immediately available without needing to select an agent mode first.

Why we gonna do?

NuGet package upgrades fail spectacularly in production because traditional approaches ignore the context needed to make safe changes. Here's what goes wrong and why GitHub Copilot Skills with MCP solve these problems definitively.

Problem 1: Package Version Chaos Without Verification

Developers commonly update package versions by directly editing .csproj files or Directory.Packages.props, leading to catastrophic failures:


<!-- Developer manually edits Directory.Packages.props -->
<ItemGroup>
  <!-- Typo: 8.0.2 doesn't exist, should be 8.0.1 -->
  <PackageVersion Include="Microsoft.AspNetCore.OpenApi" 
                  Version="8.0.2" />
  <!-- Wrong major version for compatibility -->
  <PackageVersion Include="Newtonsoft.Json" 
                  Version="14.0.0" />
</ItemGroup>

What happens next:


dotnet restore

# Output:
error NU1102: Unable to find package Microsoft.AspNetCore.OpenApi 
             with version (= 8.0.2)
error NU1605: Detected package downgrade: Newtonsoft.Json from 13.0.3 
             to 14.0.0 (doesn't exist!)

Consequence: The build breaks, CI/CD pipelines fail, and developers waste 30+ minutes debugging version typos and compatibility issues that shouldn't exist in the first place.

Problem 2: Breaking Changes Discovered Too Late

Version upgrades often introduce breaking changes that only surface at runtime. Consider upgrading System.Text.Json from 6.0 to 8.0:


// This worked in System.Text.Json 6.0
public class ApiResponse
{
    public DateTime Timestamp { get; set; }
}

var options = new JsonSerializerOptions
{
    // PropertyNameCaseInsensitive changed behavior in 8.0
    PropertyNameCaseInsensitive = true
};

var json = "{\"timestamp\":\"2024-01-15T10:30:00\"}";
var response = JsonSerializer.Deserialize<ApiResponse>(json, options);

// Runtime Exception in 8.0:
// System.Text.Json.JsonException: The JSON value could not be converted

Consequence: The upgrade passes all unit tests (because they don't cover this edge case), deploys to production, and crashes when processing real API responses. The team scrambles to roll back, losing hours of productivity and damaging user trust.

Problem 3: No Guidance on Fixing Breaking Changes

When breaking changes occur, developers have to manually:

  1. Google for migration guides
  2. Read through 50-page changelog documents
  3. Guess which APIs changed and how
  4. Trial-and-error code modifications

For example, upgrading Entity Framework Core from 6.0 to 8.0 requires understanding:

  • Changes to DbContext configuration patterns
  • New required using statements
  • Modified query execution behavior
  • Deprecated overload replacements

Consequence: What should be a 10-minute upgrade turns into a 3-day research project, with multiple failed attempts and code modifications that may or may not align with best practices.

Why GitHub Copilot Skills + MCP Are the Solution

GitHub Copilot Skills combined with Model Context Protocol eliminate these problems through intelligent automation with context-aware guidance:

  • Version verification before updates: Skills enforce checking NuGet.org via dotnet package search to confirm versions exist before making any file changes
  • Centralized version management detection: Skills automatically determine if your solution uses Directory.Packages.props or per-project versioning, updating the correct files
  • Live documentation lookup via MCP: When breaking changes occur, skills use MCP tools (like context7 or microsoft-docs) to fetch official migration guides, changelogs, and API documentation in real-time
  • Automated fix application: Skills parse documentation, identify required code changes, and apply them systematically across your codebase
  • Safety through workflows: Skills enforce dotnet restore after every change to immediately catch compatibility issues

Instead of 3 days of manual work plus debugging, a skill-based upgrade completes in 15 minutes—with higher accuracy, better documentation, and zero guesswork about breaking changes.

How we gonna do?

Step 1: Create the Skills Directory Structure

Start by setting up the skills directory in your repository:


mkdir -p .github/skills/nuget-manager
cd .github/skills/nuget-manager

Step 2: Create the NuGet Manager Skill File

Create SKILL.md in the .github/skills/nuget-manager directory with comprehensive rules and workflows:


---
name: nuget-manager
description: 'Manage NuGet packages in .NET projects/solutions. Use this skill when adding, removing, or updating NuGet package versions. It enforces using `dotnet` CLI for package management and provides strict procedures for direct file edits only when updating versions.'
---

# NuGet Manager

## Overview

This skill ensures consistent and safe management of NuGet packages across .NET projects. It prioritizes using the `dotnet` CLI to maintain project integrity and enforces a strict verification and restoration workflow for version updates.

## Prerequisites

- .NET SDK installed (typically .NET 10.0 SDK or later, or a version compatible with the target solution).
- `dotnet` CLI available on your `PATH`.
- `jq` (JSON processor) OR PowerShell (for version verification using `dotnet package search`).

## Core Rules

1.  **NEVER** directly edit `.csproj`, `.props`, or `Directory.Packages.props` files to **add** or **remove** packages. Always use `dotnet add package` and `dotnet remove package` commands.
2.  **DIRECT EDITING** is ONLY permitted for **changing versions** of existing packages.
3.  **VERSION UPDATES** must follow the mandatory workflow:
    - Verify the target version exists on NuGet.
    - Determine if versions are managed per-project (`.csproj`) or centrally (`Directory.Packages.props`).
    - Update the version string in the appropriate file.
    - Immediately run `dotnet restore` to verify compatibility.

## Workflows

### Adding a Package
Use `dotnet add [<PROJECT>] package <PACKAGE_NAME> [--version <VERSION>]`.
Example: `dotnet add src/MyProject/MyProject.csproj package Newtonsoft.Json`

### Removing a Package
Use `dotnet remove [<PROJECT>] package <PACKAGE_NAME>`.
Example: `dotnet remove src/MyProject/MyProject.csproj package Newtonsoft.Json`

### Updating Package Versions
When updating a version, follow these steps:

1.  **Verify Version Existence**:
    Check if the version exists using the `dotnet package search` command with exact match and JSON formatting. 
    Using `jq`:
    `dotnet package search <PACKAGE_NAME> --exact-match --format json | jq -e '.searchResult[].packages[] | select(.version == "<VERSION>")'`
    Using PowerShell:
    `(dotnet package search <PACKAGE_NAME> --exact-match --format json | ConvertFrom-Json).searchResult.packages | Where-Object { $_.version -eq "<VERSION>" }`
    
2.  **Determine Version Management**:
    - Search for `Directory.Packages.props` in the solution root. If present, versions should be managed there via `<PackageVersion Include="Package.Name" Version="1.2.3" />`.
    - If absent, check individual `.csproj` files for `<PackageReference Include="Package.Name" Version="1.2.3" />`.

3.  **Apply Changes**:
    Modify the identified file with the new version string.

4.  **Verify Stability**:
    Run `dotnet restore` on the project or solution. If errors occur, revert the change and investigate.

## Examples

### User: "Add Serilog to the PublicAPI project"
**Action**: Execute `dotnet add src/PublicAPI/PublicAPI.csproj package Serilog`.

### User: "Update System.Text.Json to 10.0.2 in the whole solution"
**Action**:
1. Verify 10.0.2 exists: `dotnet package search System.Text.Json --exact-match --format json` (and parse output to confirm "10.0.2" is present).
2. Find where it's defined (e.g., `Directory.Packages.props`).
3. Edit the file to update the version.
4. Run `dotnet restore`.

Step 3: Enable MCP Tools in Your Environment

GitHub Copilot automatically integrates with MCP servers when configured. Verify MCP tools are available:


# Check available MCP tools in Copilot Chat
# You should see tools like:
# - mcp_context7_resolve-library-id
# - mcp_context7_get-library-docs
# - mcp_microsoft-doc_microsoft_docs_search
# - mcp_microsoft-doc_microsoft_docs_fetch

These tools allow Copilot to fetch documentation from:

  • Context7: Up-to-date documentation for popular libraries (MongoDB, Supabase, Next.js, etc.)
  • Microsoft Docs: Official .NET, Azure, and Microsoft 365 documentation

Step 4: Use the Skill with a Simple Prompt

Once your skill is created, upgrading packages becomes trivial. Open GitHub Copilot Chat and use:


Use #file:.github/skills/nuget-manager/SKILL.md and upgrade the following 
packages to their latest versions:
- Microsoft.AspNetCore.OpenApi to 8.0.1
- System.Text.Json to 8.0.5
- Entity Framework Core to 8.0.10

If breaking changes occur, use MCP to read official migration guides and 
apply necessary fixes.

Or for a complete solution upgrade:


Use #file:.github/skills/nuget-manager/SKILL.md and upgrade all outdated 
packages in the solution. For each package with breaking changes, fetch 
documentation using MCP and fix the code accordingly.

Step 5: What the Skill Does Automatically

When you execute the prompt, the skill orchestrates an intelligent upgrade workflow:

Phase 1: Package Discovery and Planning


# Skill executes automatically
dotnet list package --outdated

# Output:
Project `MyApi` has the following updates to its packages
   [net8.0]: 
   Top-level Package                      Requested   Resolved   Latest
   > Microsoft.AspNetCore.OpenApi        8.0.0       8.0.0      8.0.1
   > System.Text.Json                    6.0.0       6.0.0      8.0.5
   > Microsoft.EntityFrameworkCore       7.0.0       7.0.0      8.0.10

# Skill creates upgrade plan prioritizing:
# 1. Packages with no dependencies first
# 2. Packages with compatible version jumps (minor/patch)
# 3. Packages with major version changes last (higher risk)

Phase 2: Version Verification

For each package upgrade, the skill verifies the version exists:


# Skill executes for System.Text.Json
dotnet package search System.Text.Json --exact-match --format json

# Parses JSON response to confirm 8.0.5 exists:
{
  "searchResult": [{
    "packages": [{
      "id": "System.Text.Json",
      "version": "8.0.5",
      "description": "Provides high-performance JSON APIs...",
      "totalDownloads": 500000000
    }]
  }]
}

# ✅ Version verified - proceed with update

Phase 3: Centralized vs Per-Project Detection

The skill automatically detects your solution's package management strategy:


<!-- Scenario 1: Central Package Management Found -->
<!-- Directory.Packages.props exists in solution root -->

<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <!-- Skill updates versions here -->
    <PackageVersion Include="System.Text.Json" Version="6.0.0" />
    <PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
  </ItemGroup>
</Project>

<!-- Scenario 2: Per-Project Versioning -->
<!-- No Directory.Packages.props, skill updates individual .csproj files -->

<Project Sdk="Microsoft.NET.Sdk.Web">
  <ItemGroup>
    <!-- Skill updates versions here -->
    <PackageReference Include="System.Text.Json" Version="6.0.0" />
  </ItemGroup>
</Project>

Phase 4: Version Update with Safety Checks

The skill updates versions and immediately validates:


<!-- Before: Directory.Packages.props -->
<PackageVersion Include="System.Text.Json" Version="6.0.0" />

<!-- After: Skill updates to -->
<PackageVersion Include="System.Text.Json" Version="8.0.5" />

# Skill runs immediately after update
dotnet restore

# If successful:
Restore succeeded.

# If breaking changes detected:
error CS0619: 'JsonSerializerOptions.IgnoreNullValues' is obsolete: 
             'Use DefaultIgnoreCondition instead'
warning CS8618: Non-nullable property 'Name' must contain a non-null value

Phase 5: MCP Documentation Lookup and Auto-Fix

When breaking changes are detected, the skill uses MCP to fetch documentation:


# Skill detects breaking change in System.Text.Json
# Automatically invokes MCP tool:

mcp_microsoft-doc_microsoft_docs_search 
  --query "System.Text.Json 8.0 breaking changes migration guide"

# Returns documentation snippets:
{
  "results": [
    {
      "title": "What's new in System.Text.Json 8.0",
      "url": "https://learn.microsoft.com/dotnet/core/whats-new/...",
      "excerpt": "...IgnoreNullValues property is obsolete. Use 
                 DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull..."
    }
  ]
}

# Skill then fetches full documentation:
mcp_microsoft-doc_microsoft_docs_fetch 
  --url "https://learn.microsoft.com/dotnet/core/whats-new/dotnet-8"

The skill parses the documentation and applies fixes automatically:


// Before: System.Text.Json 6.0 code
var options = new JsonSerializerOptions
{
    IgnoreNullValues = true  // Obsolete in 8.0
};

// After: Skill applies fix from documentation
var options = new JsonSerializerOptions
{
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

Phase 6: Comprehensive Validation Report

After all upgrades and fixes, the skill generates a detailed report:


## NuGet Upgrade Summary

**Packages Updated:** 3
**Breaking Changes Fixed:** 2
**Documentation Sources Used:** 2 (Microsoft Docs, Context7)

### Successful Upgrades

1. ✅ **Microsoft.AspNetCore.OpenApi** 8.0.0 → 8.0.1
   - No breaking changes
   - Restore successful

2. ✅ **System.Text.Json** 6.0.0 → 8.0.5
   - Breaking change detected: `IgnoreNullValues` obsolete
   - Auto-fixed using Microsoft Docs migration guide
   - Updated 3 files: ApiController.cs, JsonConfig.cs, Startup.cs
   - Restore successful

3. ✅ **Microsoft.EntityFrameworkCore** 7.0.0 → 8.0.10
   - Breaking change detected: DbContext configuration pattern changed
   - Auto-fixed using MCP documentation lookup
   - Updated: Program.cs, ApplicationDbContext.cs
   - Restore successful

### Changes Applied

**System.Text.Json Migration:**
- Replaced `IgnoreNullValues` with `DefaultIgnoreCondition`
- Added `JsonIgnoreCondition.WhenWritingNull` where needed
- Updated null handling in API responses

**Entity Framework Core Migration:**
- Migrated from `ConfigureWarnings` to new pattern
- Updated `DbContext` registration in Program.cs
- Applied new query splitting behavior

### Next Steps
- Review changes in feature branch `nuget-upgrade/batch-2024-02`
- Run full test suite
- Deploy to staging for validation

Step 6: Advanced Scenario - Custom Package Sources

For organizations using private NuGet feeds, extend the skill:


## Custom Package Source Verification

```bash
# Add to SKILL.md for private NuGet feeds
dotnet package search <PACKAGE_NAME> \
  --source https://pkgs.dev.azure.com/yourorg/_packaging/yourfeed/nuget/v3/index.json \
  --exact-match --format json
```

## Authentication

Ensure NuGet.config is configured:
```xml
<configuration>
  <packageSources>
    <add key="CompanyFeed" value="https://pkgs.dev.azure.com/..." />
  </packageSources>
</configuration>
```

Step 7: Handling Major Version Upgrades

For major version jumps (e.g., EF Core 6 → 8), the skill can request more context:


Use #file:.github/skills/nuget-manager/SKILL.md and upgrade 
Entity Framework Core from 6.0 to 8.0. 

Use MCP to:
1. Fetch the official EF Core 7.0 breaking changes guide
2. Fetch the official EF Core 8.0 breaking changes guide
3. Create a migration checklist
4. Apply changes incrementally, testing after each step

The skill will fetch comprehensive documentation and create a step-by-step migration plan:


## EF Core 6 → 8 Migration Plan

### Phase 1: Update to 7.0 (Intermediate)
- [ ] Update package version to 7.0.20
- [ ] Apply 7.0 breaking changes (from MCP docs)
- [ ] Test and validate

### Phase 2: Update to 8.0 (Final)
- [ ] Update package version to 8.0.10
- [ ] Apply 8.0 breaking changes (from MCP docs)
- [ ] Update query patterns for new defaults
- [ ] Test and validate

### Breaking Changes Identified (via MCP):

**EF Core 7.0:**
- `DbContext.Database.EnsureCreated()` behavior changed
- Temporal tables require explicit configuration
- JSON column support changes

**EF Core 8.0:**
- Query splitting behavior defaults changed
- HierarchyId requires new package
- Complex types formerly owned types syntax updated

Tips for Effective Skill Usage

  • Be specific in prompts: Reference the skill file explicitly using #file:.github/skills/nuget-manager/SKILL.md
  • Include MCP instructions: Tell the skill to use MCP for documentation when breaking changes occur
  • Review before committing: Always verify auto-applied fixes make sense in your context
  • Test incrementally: For multiple package upgrades, validate each one before proceeding
  • Update skills based on learnings: Add new patterns to SKILL.md as you encounter edge cases

Extending the Skill for Team Workflows

Add team-specific rules to the skill for consistency:


## Team-Specific Rules

### Package Version Policies
- Always use LTS versions for production dependencies
- Preview packages allowed only in development branches
- Security patches must be applied within 48 hours

### Documentation Requirements
- Document breaking changes in CHANGELOG.md
- Update package upgrade history in docs/package-upgrades.md
- Create GitHub issue for each major version upgrade

### Testing Requirements
- Run full integration test suite after upgrades
- Performance test critical paths if major version changes
- Require manual QA approval for database-related packages

Summary

Key Takeaways

  • GitHub Copilot Skills are reusable knowledge modules stored in .github/skills that teach Copilot domain-specific expertise—different from agents, which are conversational workflows
  • The NuGet Manager skill enforces strict safety rules: verify versions exist before updating, detect centralized vs per-project package management, and always run dotnet restore after changes
  • Model Context Protocol (MCP) integration allows skills to fetch live documentation from official sources (Microsoft Docs, Context7) when breaking changes occur, eliminating manual research
  • Skills automatically parse migration guides and apply code fixes systematically, transforming 3-day manual upgrades into 15-minute automated workflows with higher accuracy
  • Skills are invoked via #file:SKILL.md syntax in prompts, making them immediately available without selecting agent modes
  • For major version upgrades (e.g., EF Core 6 → 8), skills can fetch documentation for intermediate versions and create incremental migration plans tested at each step
  • Skills are team knowledge assets—check them into source control, add organization-specific rules, and improve them over time as your team encounters new upgrade patterns

Start by creating your NuGet Manager skill today. The initial setup takes 20 minutes, but you'll save hours on every package upgrade and eliminate entire classes of breaking-change bugs. As your skill evolves with team-specific rules and MCP integrations, it becomes an invaluable automation asset that makes package management effortless and safe.

👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
  • AI
  • Copilot
  • GitHub
  • AI Skill
  • NuGet
  • Package Management
  • MCP
  • Breaking Changes