MAIN MENU
Devolutions Blog

Ankündigungen, Aktualisierungen und Einsichten von Devolutions

Devolutions PowerShell Universal and GitHub Copilot illustration for the blog.

PowerShell Universal als MCP-Server für die GitHub Copilot-Integration bereitstellen

Dokumentieren Sie PSU-Endpunkte mit New-PSUEndpointDocumentation, erzeugen Sie einen MCP-Proxy mit openapi-mcp-generator, fügen Sie die SSE-URL in VS Code hinzu und bitten Sie Copilot dann, Prozesse aufzulisten oder zu starten.

GitHub Copilot ist ein KI-Helfer, der in einem Editor wie Visual Studio Code laufen kann. Er bietet Codevervollständigung sowie Chatfunktionen, um Code zu analysieren und zu erzeugen. GitHub Copilot unterstützt außerdem den Agent-Modus, der die Kommunikation mit zusätzlichen Tools erlaubt, damit Aktionen in Ihrem Namen ausgeführt werden. In diesem Beitrag zeigen wir, wie Sie PowerShell Universal als Tool für GitHub Copilot bereitstellen, damit Copilot Aktionen ausführen kann.

Model Context Protocol (MCP)

Das Model Context Protocol, oder MCP, ist ein Standard, um Tools für KI-Agenten wie Copilot bereitzustellen. Ähnlich wie Standards wie OpenAPI oder das Language Server Protocol in Visual Studio Code nutzt dieser Standard JSON-Objekte und Endpunkte, um einem KI-Agenten Details zu einem Tool zu liefern. Durch erwartete Ein- und Ausgaben sowie Beschreibungen des Tools können KI-Modelle entscheiden, ob und wie sie ein Tool nutzen.

MCP-Server werden in Software-Stacks zunehmend üblich, damit KI einfach mit ihnen interagieren kann. PowerShell Universal unterstützt MCP noch nicht direkt, aber wir können die vorhandene OpenAPI-Implementierung und ein Open-Source-Projekt nutzen, um einen MCP-Proxyserver zu hosten. Dieser Server übersetzt die OpenAPI-Spezifikation in die MCP-Spezifikation und leitet MCP-Anfragen dann an die zugehörigen APIs weiter.

PowerShell Universal und OpenAPI

Zuerst müssen wir eine API und eine API-Dokumentation definieren, die der MCP-Proxy konsumieren kann. In PowerShell Universal erstellen wir ein paar APIs, um Prozesse zurückzugeben und zu starten. Diese APIs sind in der Implementierung einfach, nutzen aber ein paar PSU-Techniken, um der OpenAPI-Dokumentationsengine der Plattform Informationen zu liefern. Wir geben Informationen zu den Ausgabetypen der Endpunkte sowie eine Beschreibung für jeden an, die das LLM parsen kann.

New-PSUEndpoint -Url "/process" -Description "Gets a list of processes running on the PowerShell Universal server." -Method @('GET') -Endpoint {
    <#
.OUTPUTS
200:
  Description: An array of process information.
  Content:
      application/json: ProcessInfo[]

400:
  Description: Invalid input
#>
    param()

    Get-Process | Select-Object Name, Id
} -Documentation "Agent Docs"

New-PSUEndpoint -Url "/process/:name" -Description "Starts a process on the PowerShell Universal server." -Endpoint {
    param(
        [Parameter(Mandatory, HelpMessage = "The file name of the process to start.")]
        $Name
    )

    Start-Process $Name -PassThru | Select-Object Name, Id
} -Documentation "Agent Docs"

Wir müssen außerdem ein API-Dokument für diese Endpunkte anlegen, das auch eine Klasse mit der Struktur unserer Ausgabe definiert.

New-PSUEndpointDocumentation -Name "Agent Docs" -Definition {
    [Documentation()]
    class ProcessInfo {
        [string]$Name
        [string]$Id
    }
} -Url "/agent-docs" -ContactName "Adam Driscoll" -Version "1.0.0" -LicenseName "MIT"

Nach dem Definieren der Endpunkte und des Dokuments können wir die Dokumentation unter http://localhost:5000/swagger/index.html?urls.primaryName=Agent%20Docs ansehen.

Zusätzlich wird eine JSON-OpenAPI-Spezifikation erzeugt.

{
  "openapi": "3.0.4",
  "info": {
    "title": "Agent Docs",
    "contact": {
      "name": "Adam Driscoll"
    },
    "license": {
      "name": "MIT"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "http://localhost:5000"
    }
  ],
  "paths": {
    "/process": {
      "get": {
        "summary": "",
        "description": "Gets a list of processes running on the PowerShell Universal server.",
        "requestBody": {
          "description": "Error processing input types. Cannot perform runtime binding on a null reference",
          "content": { }
        },
        "responses": {
          "200": {
            "description": "An array of process information.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProcessInfo"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          }
        }
      }
    },
    "/process/{name}": { }
  },
  "components": {
    "schemas": {
      "ProcessInfo": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "id": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "Bearer": {
        "type": "http",
        "description": "App Token for accessing the API",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "security": [
    {
      "Bearer": [ ]
    }
  ],
  "tags": [
    {
      "name": "default"
    }
  ]
}

LLMs sind sehr gut darin, solche Schemas zu parsen, aber wir können es noch einfacher machen, indem wir einen MCP-Proxy vor die API-Dokumentation setzen, damit Tools wie GitHub Copilot Tools leicht entdecken können.

MCP-Proxy

Wir nutzen das npm-Paket openapi-mcp-generator, um einen MCP-Proxyserver für unsere API zu erzeugen. Dafür muss Node.js installiert sein. Installieren Sie das Paket mit dem folgenden Befehl.

npm install -g openapi-mcp-generator

Als Nächstes müssen wir den MCP-Server-Proxy auf Basis unserer API erzeugen. Das erzeugt TypeScript-Dateien, die anschließend transpiliert und in Node.js ausgeführt werden können. Der folgende Ablauf liest die OpenAPI-Dokumentation und kompiliert und startet dann den MCP-Server.

openapi-mcp-generator --input http://localhost:5000/agent-docs --output .\mcp --base-url http://localhost:5000 --transport web
cd .\mcp
npm i
npm run build
npm run start:web

GitHub Copilot

Nachdem unsere PowerShell Universal-APIs definiert sind und unser MCP-Proxyserver läuft, können wir GitHub Copilot konfigurieren. Die Erweiterung muss installiert sein, bevor Sie fortfahren. Drücken Sie in VS Code Ctrl+Shift+P und suchen Sie nach MCP: Add Server....

Wählen Sie die HTTP-Option und geben Sie die URL zum MCP-Server ein. Sie benötigen die Route /sse. Die vollständige URL lautet standardmäßig http://localhost:3000/sse. Benennen Sie den Server, wie Sie möchten.

Der resultierende Inhalt von settings.json sieht etwa so aus.

"mcp": {
    "servers": {
        "PSU": {
            "url": "http://localhost:3000/sse"
        }
    }
}

Das PowerShell Universal-KI-Agent-Tool nutzen

Wenn alles konfiguriert ist, können wir unser KI-Agent-Tool nutzen. Klicken Sie auf das Copilot-Symbol und öffnen Sie einen neuen Chat.

Visual Studio Code Copilot chat panel ready for a new conversation.
Copilot-Chat in VS Code

Im Chatfenster können Sie Copilot zum Beispiel so fragen: Can you please list all the processes as an array of strings in a new PowerShell script? Copilot ruft unser PSU-Tool auf, holt die Prozessliste und erzeugt dann ein PowerShell-Skript in VS Code.

GitHub Copilot generating a PowerShell script from PowerShell Universal process data.
Copilot listet Prozesse über das PowerShell Universal-Tool auf

Weil wir auch einen Endpunkt zum Starten von Prozessen haben, können Sie Copilot das ebenfalls mit einer Aussage wie dieser auftragen: Can you start a new process in PowerShell Universal named calc? Das startet den Prozess calc.exe, weil der PSU-Endpunkt mit diesem Argument aufgerufen wird.

Fazit

In diesem Beitrag haben wir gezeigt, wie Sie einen MCP-Proxyserver für PowerShell Universal anlegen, um ihn aus GitHub Copilot aufzurufen. Weil MCP ein Standardprotokoll ist, können Sie den PSU-Server auch in andere LLM-Agenten integrieren.

Bereit zum Bauen? PowerShell Universal herunterladen.