1. Conduid
  2. Science
  3. ApprovalWorkflow
MCP server · Science

ApprovalWorkflow

An enterprise-grade Model Context Protocol (MCP) server built on C# .NET 8 that surfaces approval workflow management directly inside Microsoft 365 Copilot. Approvers can query, approve, reject, and delegate requests using natural language — with a rich interactive widget rendered inline in the Copilot chat pane.

Unclaimed science
34Low

Scored 6 months ago · breakdown

About ApprovalWorkflow

ApprovalWorkflow is an MCP server in the Science category: an enterprise-grade Model Context Protocol (MCP) server built on C# .NET 8 that surfaces approval workflow management directly inside Microsoft 365 Copilot. Approvers can query, approve, reject, and delegate requests using natural language — with a rich interactive widget rendered inline in the Copilot chat pane.

Install

From source
git clone https://github.com/bonaniibm/ApprovalWorkflow

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Tools (6)

.NET SDK8.0+

Parameters not published.

Azure CLILatest

Parameters not published.

Azure subscription—

Parameters not published.

EF Core CLILatest

Parameters not published.

Microsoft 365E3/E5 + Copilot licence

Parameters not published.

SQL Server2019+

Parameters not published.

Ask AI

✦

Ask AI about ApprovalWorkflow

Powered by Claude · Grounded in docs

I know everything about ApprovalWorkflow. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

  • ✓README presentThe repository ships documentation.

5 checks have not been run yet.

README

Approval Workflow — MCP App for Microsoft 365 Copilot

An enterprise-grade Model Context Protocol (MCP) server built on C# .NET 8 that surfaces approval workflow management directly inside Microsoft 365 Copilot. Approvers can query, approve, reject, and delegate requests using natural language — with a rich interactive widget rendered inline in the Copilot chat pane.


Architecture

┌─────────────────────────────────────────────┐
│          Microsoft 365 Copilot              │
│  (BizChat / Teams / Copilot Studio)         │
└────────────────┬────────────────────────────┘
                 │ MCP over HTTPS (Streamable HTTP)
                 ▼
┌─────────────────────────────────────────────┐
│     ApprovalWorkflow.McpServer              │
│     ASP.NET Core 8  ·  Azure App Service    │
│                                             │
│  ┌─────────────────┐  ┌──────────────────┐  │
│  │  MCP Tools      │  │  MCP Resource    │  │
│  │  ─ QueryTool    │  │  ─ Widget HTML   │  │
│  │  ─ DecisionTool │  │    (ui://)       │  │
│  └────────┬────────┘  └──────────────────┘  │
│           │                                 │
│  ┌────────▼────────────────────────────┐    │
│  │  ApprovalWorkflow.Infrastructure    │    │
│  │  ─ ApprovalService (EF Core)        │    │
│  │  ─ GraphNotificationService         │    │
│  └────────┬────────────────────────────┘    │
└───────────┼─────────────────────────────────┘
            │
   ┌────────┴────────────┐
   │                     │
   ▼                     ▼
Azure SQL            Microsoft Graph
(Approval data)      (Teams + Email notifications)

Security: All MCP endpoints are protected by Entra ID (JWT bearer auth). The App Service uses Easy Auth as an additional layer. Secrets are stored exclusively in Azure Key Vault, accessed via the App Service Managed Identity.


Solution Structure

ApprovalWorkflow/
├── ApprovalWorkflow.sln
├── src/
│   ├── ApprovalWorkflow.McpServer/          # ASP.NET Core 8 — MCP host
│   │   ├── Tools/
│   │   │   ├── ApprovalQueryTool.cs         # GetPendingApprovals, GetApprovalDetails
│   │   │   └── ApprovalDecisionTool.cs      # ApproveRequest, RejectRequest, DelegateRequest
│   │   ├── Resources/
│   │   │   └── ApprovalWidgetResource.cs    # Serves widget HTML at ui://approval/widget.html
│   │   ├── wwwroot/widget/index.html        # Copilot-rendered approval widget
│   │   ├── Program.cs
│   │   └── appsettings.json
│   ├── ApprovalWorkflow.Core/               # Domain models & interfaces
│   │   ├── Models/
│   │   │   ├── ApprovalRequest.cs
│   │   │   ├── ApprovalDecision.cs
│   │   │   └── ApprovalStatus.cs
│   │   └── Interfaces/
│   │       ├── IApprovalService.cs
│   │       └── INotificationService.cs
│   └── ApprovalWorkflow.Infrastructure/     # EF Core + Microsoft Graph
│       ├── Data/AppDbContext.cs
│       └── Services/
│           ├── ApprovalService.cs
│           └── GraphNotificationService.cs
├── frontend/widget/index.html               # Source copy of the widget
├── infra/main.bicep                         # Azure infrastructure (IaC)
└── .vscode/
    ├── mcp.json                             # Local MCP client config
    ├── launch.json
    └── tasks.json

Prerequisites

Tool Version Notes
.NET SDK 8.0+ Download
EF Core CLI Latest dotnet tool install --global dotnet-ef
Azure CLI Latest Download
SQL Server 2019+ LocalDB or Express for local dev
Azure subscription — For Key Vault, App Service, Azure SQL
Microsoft 365 E3/E5 + Copilot licence For Copilot integration

Entra ID App Registration

A Global Administrator or Application Administrator must complete this section once.

  1. Open Entra admin centre → App registrations → New registration

  2. Name: ApprovalWorkflow-MCP

  3. Supported account types: Single tenant

  4. Redirect URI: https://<your-app>.azurewebsites.net/.auth/login/aad/callback

  5. Expose an API:

    • Set Application ID URI: api://<client-id>
    • Add scope: Approvals.ReadWrite (Admin + user consent)
  6. API permissions (Application permissions — grant admin consent):

    Permission Purpose
    User.ReadBasic.All Resolve approver email to Entra Object ID
    Chat.Create Create 1:1 Teams chats for notifications
    ChatMessage.Send Send Adaptive Cards via Teams
    Mail.Send Send decision email notifications
  7. Certificates & secrets → New client secret → copy value immediately

  8. Store the secret in Key Vault (see Key Vault Setup)

  9. Note your Tenant ID, Client ID, and Application ID URI for configuration


Key Vault Setup

# Create Key Vault (or use the Bicep deployment below)
az keyvault create \
  --name <vault-name> \
  --resource-group <rg> \
  --location <region>

# Store secrets — note the double-dash delimiter which maps to ':' in ASP.NET Core config
az keyvault secret set --vault-name <vault-name> \
  --name "AzureAd--ClientSecret" --value "<client-secret>"

az keyvault secret set --vault-name <vault-name> \
  --name "ConnectionStrings--AzureSql" \
  --value "Server=<server>.database.windows.net;Database=ApprovalWorkflow;Authentication=Active Directory Managed Identity;"

az keyvault secret set --vault-name <vault-name> \
  --name "ApplicationInsights--ConnectionString" --value "<ai-connection-string>"

Configuration

appsettings.json contains placeholder values. In production all secrets are resolved from Key Vault via Managed Identity. For local development use User Secrets.

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "<your-tenant-id>",
    "ClientId": "<your-client-id>",
    "ClientSecret": "<from-key-vault>",
    "Audience": "api://<your-client-id>"
  },
  "ConnectionStrings": {
    "AzureSql": "<from-key-vault>"
  },
  "KeyVault": {
    "Uri": "https://<vault-name>.vault.azure.net/"
  },
  "ApprovalWorkflow": {
    "AppUrl": "https://<app-service-name>.azurewebsites.net",
    "NotificationMailbox": "approvals@yourdomain.com"
  },
  "ApplicationInsights": {
    "ConnectionString": "<from-key-vault>"
  }
}

Local Development

1. Clone and restore

git clone <repo-url>
cd ApprovalWorkflow
dotnet restore

2. Set User Secrets

cd src/ApprovalWorkflow.McpServer

dotnet user-secrets set "AzureAd:TenantId"     "<your-tenant-id>"
dotnet user-secrets set "AzureAd:ClientId"     "<your-client-id>"
dotnet user-secrets set "AzureAd:ClientSecret" "<your-client-secret>"
dotnet user-secrets set "ConnectionStrings:AzureSql" "Server=localhost;Database=ApprovalWorkflow;Trusted_Connection=True;TrustServerCertificate=True;"
dotnet user-secrets set "ApprovalWorkflow:NotificationMailbox" "approvals@yourdomain.com"
dotnet user-secrets set "ApprovalWorkflow:AppUrl" "https://localhost:7001"

3. Apply EF Core migrations

# From solution root
dotnet ef migrations add InitialCreate `
  --project src/ApprovalWorkflow.Infrastructure `
  --startup-project src/ApprovalWorkflow.McpServer

dotnet ef database update `
  --project src/ApprovalWorkflow.Infrastructure `
  --startup-project src/ApprovalWorkflow.McpServer

4. Run

dotnet run --project src/ApprovalWorkflow.McpServer
# Listening on https://localhost:7001

5. Verify the MCP handshake

POST https://localhost:7001/mcp
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {},
    "clientInfo": { "name": "test", "version": "1.0" }
  }
}

Expected: a JSON response listing ApprovalWorkflow.McpServer with tools and resources capabilities.

6. Expose locally for Copilot testing

# Azure Dev Tunnels CLI (recommended — Microsoft-hosted, no auth challenge)
devtunnel user login
devtunnel host -p 7001 --allow-anonymous

Or use the VS Code Ports panel: forward port 7001 and set visibility to Public.


MCP Tools Reference

Tool Description
GetPendingApprovals Returns paginated pending approvals for the authenticated user, ordered by priority then due date. Optional category and pageSize parameters.
GetApprovalDetails Returns full detail and complete decision history for a single request by GUID.
ApproveRequest Approves a request with an optional comment. Notifies the requestor via email.
RejectRequest Rejects a request with a mandatory reason. Notifies the requestor via email.
DelegateRequest Reassigns a request to another user by email. Notifies the delegate via Teams Adaptive Card.

All tools resolve the caller's identity from the oid JWT claim set by Entra ID. Unauthenticated requests return 401 Unauthorized.

Category Filter Values

The category parameter on GetPendingApprovals is a free-form string. Recommended conventions:

Value Description
PurchaseOrder Procurement and purchase approvals
Expense Expense claim approvals
LeaveRequest Annual, personal, or sick leave
ContractExtension Contractor or vendor extensions
ChangeRequest IT change management requests

Azure Deployment

Option A — Bicep (recommended)

# Create resource group
az group create --name rg-approval-workflow --location uksouth

# Deploy all infrastructure
az deployment group create \
  --resource-group rg-approval-workflow \
  --template-file infra/main.bicep \
  --parameters appName=approval-workflow \
               sqlAdminPassword='<secure-password>'

The Bicep template provisions:

Resource SKU / Config
App Service Plan B2 Linux
App Service System-Assigned Managed Identity, Easy Auth (Entra ID), HTTPS only
Azure SQL Server Public network access disabled
Azure SQL Database Serverless Gen5, auto-pauses after 60 min
Key Vault Standard, soft delete enabled, 90-day retention
Log Analytics Workspace PerGB2018
Application Insights Workspace-based

Option B — VS Code Azure App Service extension

  1. Install the Azure App Service extension
  2. Ctrl+Shift+P → "Azure App Service: Deploy to Web App"
  3. Select Create new Web App → .NET 8 → Linux
  4. After deployment, add KeyVault__Uri to App Settings in the Azure portal

Post-deployment checklist

  • Grant App Service Managed Identity get + list on Key Vault secrets
  • Add all three secrets to Key Vault (ClientSecret, AzureSql connection string, App Insights connection string)
  • Configure Easy Auth with your Entra App Registration Tenant ID and Client ID
  • Set ApprovalWorkflow:AppUrl App Setting to the live App Service hostname
  • EF migrations run automatically at first startup via MigrateAsync()

Connecting to Microsoft 365 Copilot

Via Copilot Studio

  1. Go to copilotstudio.microsoft.com
  2. Create → New agent → Configure tab
  3. Scroll to Tools → Add a tool → Model Context Protocol
  4. Fill in:
    • Server name: ApprovalWorkflow
    • Server description: Manages pending approval requests for the authenticated user
    • Server URL: https://<your-app>.azurewebsites.net/mcp
    • Authentication: OAuth 2.0 (configure with your Entra App Registration)
  5. Publish → Channels → Microsoft Teams and Microsoft 365 Copilot

Via .vscode/mcp.json (local development only)

{
  "servers": {
    "approval-workflow": {
      "type": "http",
      "url": "https://localhost:7001/mcp"
    }
  }
}

Notifications

The GraphNotificationService sends notifications via Microsoft Graph:

Event Channel Recipient
New request created Teams Adaptive Card (1:1 chat) Assigned approver
Request approved or rejected Email (shared mailbox) Original requestor
Request delegated Teams Adaptive Card (1:1 chat) Delegate approver

Notifications are fire-and-forget — failures are logged to Application Insights but do not affect the decision response.


Database Migrations

Migrations apply automatically at startup and are idempotent — safe for Blue/Green or slot deployments. To generate a migration after a model change:

dotnet ef migrations add <MigrationName> `
  --project src/ApprovalWorkflow.Infrastructure `
  --startup-project src/ApprovalWorkflow.McpServer

Security Considerations

  • Never commit secrets — use User Secrets locally and Key Vault in production
  • The /mcp endpoint requires a valid Entra ID bearer token at all times
  • CORS is restricted to known Copilot origins only
  • Azure SQL has public network access disabled in the Bicep template — use Private Endpoint or App Service VNet Integration for production workloads
  • Key Vault soft delete is enabled with 90-day retention to protect against accidental deletion

Contributing

  1. Fork the repository and create a feature branch: git checkout -b feature/your-feature
  2. Follow the existing namespace and layering conventions (Core → Infrastructure → McpServer)
  3. All new MCP tools must include [Description] attributes — these are surfaced directly to Copilot as tool documentation
  4. Test locally against the .vscode/mcp.json configuration before raising a PR
  5. Open a pull request against main with a clear description of the change and any configuration impacts

License

This project is licensed under the MIT License. See LICENSE for details.

README copy captured when this server was indexed; it may lag the repository. The original is authoritative.

Questions

About ApprovalWorkflow

How do I install ApprovalWorkflow?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is ApprovalWorkflow safe to use with an AI agent?

Its trust score is 34 out of 100 (low). It passes 1 of the 1 static security checks run so far. It has no ConduID identity yet, so agent calls to it are not receipted.

Is ApprovalWorkflow still maintained?

Conduid hasn't recorded a commit date for this repository yet. Check the repository directly for recent activity.