PowerShell MCP Azure Function Server

Recently under the experimental Azure Functions build Microsoft Developer Advocates have shown enabling Azure Functions as MCP Servers. I wondered if it was possible to use this to MCP enable a number of my PowerShell Identity Tools Modules. Yes, yes it is possible. This post details how to build your own PowerShell MCP Azure Function Server.

Overview

Initially I saw the Python MCP Azure Function example. I wrote a Python wrapper to then call MCP enabled PowerShell Modules. It worked expertly locally. Deploy to Azure and FAIL. Fail because the Python Azure runtime is only supported on Linux nodes. Linux nodes don’t have PowerShell. Some searching and I found the .NET MCP Azure Function example. Perfect, as it supports Windows and PowerShell is then available and even better under the Consumption Plan model.

This post demonstrates how to expose PowerShell modules through Azure Functions (.NET) as MCP tools and in my example I’m exposing my JWTDetails and X509Details PowerShell modules. However, the possibilities are endless and the approach is scalable. I have many ideas for empowering AI with my PowerShell tools.

How (The Details)

So how does it actually work? Below are the components, the flow and a deployed example. Jump to the end for the Repo and deployment steps.

Core Components

  • Azure Functions (.NET 8): hosting platform running on Windows Consumption Plan
  • MCP Server Integration: Uses Microsoft.Azure.Functions.Worker.Extensions.Mcp for native MCP protocol support
  • PowerShell Automation: Native PowerShell execution via System.Management.Automation library
  • PowerShell Modules: My PowerShell Modules (JWTDetails, X509Details) packaged with the Function Application

Data Flow

  • MCP Client (VSCode with GitHub Copilot, Claude etc) → Sends tool requests to Azure Function MCP endpoint (/runtime/webhooks/mcp)
  • Azure Function → Receives requests via [McpToolTrigger] attributes
  • PowerShell Executor → Executes PowerShell cmdlets natively within .NET process
  • JSON Response → Returns structured data back to MCP client

Technical Summary – Request Processing Flow

  1. MCP Request Reception: Azure Function receives MCP tool invocation via [McpToolTrigger]
  2. Parameter Extraction: Extracts and validates parameters from ToolInvocationContext
  3. PowerShell Module Loading: Dynamically imports required PowerShell modules
  4. Cmdlet Execution: Runs PowerShell cmdlets with sanitized parameters
  5. JSON Serialization: Converts PowerShell objects to JSON using ConvertTo-Json
  6. Response Return: Returns structured JSON response to MCP client

The Function App below shows the JwtDetails and X509Details mcpToolTrigger endpoints from the deployed Azure Function. The health endpoint serves as the “heartbeat” of the MCP server, providing service status information.

Under API Keys you will see the mcp_extension system key. This is effectively your key to using the Azure Function. This is an example prototype. As the MCP Server Protocol matures I’ll be replacing this with oAuth.

Testing your PowerShell Module enabled MCP Server

The quickest way to test your MCP prior to using an MCP Client is to use MCP Inspector.

Select SSE and provide the URL with the key https://<functionapp>.azurewebsites.net/runtime/webhooks/mcp/sse?code=<yourMCPKey> then Connect. You will then be able to list the tools exposed via the MCP Server and provide input and run a tool. In the example above I’ve provided a self-signed certificate in pem format for the X509Details PowerShell Module cmdlet which returns the self-signed cert details including time to expiry.

MCP Client Configuration

In your MCP Client (e.g. VSCode or Claude) you provide the Azure Function URL and the MCP System Key retrieved from the deployment shown above.

In VSCode using the AI Toolkit via preferences you can add a new MCP Server and provide the path and key URL https://<functionapp>.azurewebsites.net/runtime/webhooks/mcp/sse?code=<yourMCPKey>. The type is SSE.

In Claude in Settings Add a Custom Connector. Provide the Azure Function URL and System Key URL https://<functionapp>.azurewebsites.net/runtime/webhooks/mcp/sse?code=<yourMCPKey>

Below is an example of Claude using the PowerShell MCP X509Details PowerShell Module tool and the LLM narrative around the result.

Azure Function App Details

Example Wrapper Implementation

The codeblock below shows the wrapper to expose the Get-JWTDetails cmdlet as an MCP Server Tool and execute it using PowerShell converting the response to JSON and returning the result. The X509Details tool in the repo has some post-processing to manage the conversion from a deeper nested PSObject to JSON before returning the response.

[Function(nameof(JwtDetails))]
public async Task JwtDetails(
[McpToolTrigger(JwtDetailsToolName, JwtDetailsToolDescription)]
ToolInvocationContext context,
[McpToolProperty(TokenPropertyName, PropertyType, TokenPropertyDescription)]
string token)
{
try
{
_logger.LogInformation("Processing JWT Details request");
    if (string.IsNullOrWhiteSpace(token))
    {
        return JsonSerializer.Serialize(new { error = "Token parameter is required" });
    }

    // Execute PowerShell command
    var psCommand = $"Import-Module JWTDetails; Get-JWTDetails -token '{token}' | ConvertTo-Json -Depth 10";
    var result = await _powerShellExecutor.ExecuteAsync(psCommand);

    return result;
}
catch (Exception ex)
{
    _logger.LogError(ex, "JWT Details error");
    return JsonSerializer.Serialize(new { error = $"Processing error: {ex.Message}" });
}
}

Building and Testing Locally and Deploying to Azure

I built the solution locally in VSCode and validated everything was working locally and then used azd to deploy to Azure. Just as the examples had done. I did try using VSCode to publish to Azure Functions, but I just couldn’t get the project to publish. Sometime spent learning Bicep and azd had me successfully deploying and updating my MCP Azure Functions.

The simplified steps are:

# Azure Login
azd auth login

# List all subscriptions you have access to
az account list --output table

# Set the subscription using Azure CLI
az account set --subscription "Your-Subscription-Name-or-ID"

# Initialise the environment
azd init --environment <name for your environment>

# Deploy - it will use the configured subscription
azd deploy

More about Azure Developer CLI (azd)

Azure Developer CLI (azd) is a developer-centric command-line interface that simplifies the entire Azure application lifecycle from local development to cloud deployment. It provides:

  • Infrastructure as Code: Manages Azure resources using Bicep templates
  • Application Deployment: Handles both infrastructure provisioning and application code deployment
  • Environment Management: Supports multiple deployment environments (dev, staging, prod)
  • Template-Based: Uses standardized project templates for consistent deployments
  • Integrated Workflow: Single command to deploy entire solutions

To get started and up and running for yourself, start here.

Full Project

Here is my repo with the full implementation. What will you MCP enable from your PowerShell library?

Darren Robinson

Bespoke learnings from a Microsoft Identity and Access Management Architect using lots of Microsoft Identity Manager, Azure Active Directory, PowerShell, SailPoint IdentityNow and Lithnet products and services.

Recent Posts

EntraPulse – Your AI-Powered Gateway to Microsoft Graph & Docs

Today, I’m super excited to finally announce the Beta release of EntraPulse Lite – a…

2 months ago

Lokka MCP Authentication Enhancements

I'm excited to share some significant authentication enhancements I've contributed to the Lokka MCP Server…

3 months ago

AI Inception: Building AI Solutions with AI for AI

Last month I had the pleasure of speaking at the Sydney event for Global Azure.…

3 months ago

A Have I Been Pwned MCP Server for Claude

Model Context Protocol (MCP) is a powerful framework that extends AI clients like Claude and…

6 months ago

Azure AI Developer Hackathon

I've just completed participating in the Azure AI Developer Hackathon that was looking to provide…

6 months ago

Dynamics 365 CE (Sales, CRM) IAM PowerShell Module

Updated: July 2025 v1.0.2 Fixes issue setting D365SalesGlobals enabling session management for D365 Sales API…

6 months ago

This website uses cookies.