Remote MCP Servers using Azure Functions : Getting Started
Remote MCP Servers using Azure Functions : Getting Started
Project Overview
This project implements a Model Context Protocol (MCP) server using Azure Functions with .NET 10. The application exposes multiple tools through MCP that can be invoked by MCP-compatible clients for various operations including health checks, product information retrieval, and user profile management.
Table of Contents
- Architecture
- Technology Stack
- Project Structure
- MCP Tools
- Getting Started
- Configuration
- Testing with VS Code
- Development
- Deployment
- Dependencies
Architecture
The application follows a serverless architecture pattern using Azure Functions with the isolated worker model. It leverages the Model Context Protocol to expose tools that can be consumed by AI assistants and other MCP clients.
Key Components:
- Azure Functions Runtime: v4
- Worker Model: Isolated (.NET 10)
- Protocol: Model Context Protocol (MCP)
- Monitoring: Application Insights integration
- Logging: Console logging with configurable log levels
Technology Stack
- .NET: 10.0
- Azure Functions: v4
- Model Context Protocol: v0.5.0-preview.1
- Application Insights: v2.23.0
- Runtime: dotnet-isolated worker
Project Structure
src/
FunctionApp/
Functions/
PingFunction.cs
ProductInfoFunction.cs
UserProfileFunction.cs
Program.cs
FunctionApp.csproj
host.json
local.settings.json
Directory Layout
| Path | Description |
|---|---|
Functions/ |
Contains all MCP tool function implementations |
Program.cs |
Application entry point and service configuration |
FunctionApp.csproj |
Project file with dependencies and build configuration |
host.json |
Azure Functions host configuration |
local.settings.json |
Local development settings |
MCP Tools
The application exposes three MCP tools:
1. PingFunction
Purpose: Health check endpoint to verify the MCP server is running.
Trigger: McpToolTrigger
- Name:
PingFunction - Description: “Check if the MCP server is running.”
Parameters:
message(string, optional): Optional message to echo back
Response:
- Returns “? MCP server is alive.” if no message provided
- Echoes back the message if provided: “? MCP server received: {message}”
Example Usage:
{
"tool": "PingFunction",
"parameters": {
"message": "Hello"
}
}
2. ProductInfoFunction
Purpose: Retrieve product information by product code.
Trigger: McpToolTrigger
- Name:
ProductInfoFunction - Description: “Get product information by product code.”
Parameters:
productCode(string, required): The product code
Supported Product Codes:
P100: Laptop – $1200 – AvailableP200: Monitor – $300 – Out of stockP300: Keyboard – $80 – Available
Response:
Returns formatted product information including:
- Product name
- Price
- Stock availability
Example Usage:
{
"tool": "ProductInfoFunction",
"parameters": {
"productCode": "P100"
}
}
Response:
Product: Laptop
Price: $1200
Stock: Available
3. UserProfileFunction
Purpose: Retrieve basic user profile information.
Trigger: McpToolTrigger
- Name:
UserProfileFunction - Description: “Get basic user profile information.”
Parameters:
userId(string, required): The user identifier
Supported User IDs:
alice: Administrator – Activebob: Developer – Activecharlie: Viewer – Disabled
Response:
Returns formatted user profile including:
- Name
- Role
- Status
Example Usage:
{
"tool": "UserProfileFunction",
"parameters": {
"userId": "alice"
}
}
Response:
Name: Alice
Role: Administrator
Status: Active
Getting Started
Prerequisites
- .NET 10 SDK
- Azure Functions Core Tools (v4)
- Azure Storage Emulator or Azure Storage Account
- Visual Studio 2022 (or later) or VS Code with Azure Functions extension
- VS Code MCP extension (for testing)
Install Azure Functions Core Tools
winget install Microsoft.Azure.FunctionsCoreTools
Local Development Setup
-
Clone the repository:
git clone https://github.com/azurecorner/remote-MCP-servers-using-azure-functions cd remote-MCP-servers-using-azure-functions/src -
Restore dependencies:
dotnet restore -
Build the project:
dotnet build -
Configure local settings:
Ensurelocal.settings.jsonis properly configured (see Configuration) -
Run the application:
func startor
dotnet runExpected Output:
Azure Functions Core Tools Core Tools Version: 4.6.0+ab90faafcab539d63cd3d0ce5faf1bca4395fccc (64-bit) Function Runtime Version: 4.1045.200.25556 MCP server endpoint: http://localhost:7071/runtime/webhooks/mcp MCP server legacy SSE endpoint: http://localhost:7071/runtime/webhooks/mcp/sse Worker process started and initialized. Functions: PingFunction: mcpToolTrigger ProductInfoFunction: mcpToolTrigger UserProfileFunction: mcpToolTrigger Host lock lease acquired by instance ID '000000000000000000000000F243C912'.
Configuration
local.settings.json
Configuration for local development:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
}
}
Configuration Keys:
AzureWebJobsStorage: Storage connection string (use local emulator for development)FUNCTIONS_WORKER_RUNTIME: Worker runtime type (dotnet-isolated)
host.json
Azure Functions host configuration:
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
},
"enableLiveMetricsFilters": true
}
}
}
Features:
- Application Insights integration
- Telemetry sampling enabled
- Live metrics support
- Request logging excluded from sampling
Testing with VS Code
Starting the MCP Server
-
Using Command Palette:
- Press
Ctrl + Shift + Pin VS Code - Type and select: “Start MCP Server”
- Press
-
Using Terminal:
dotnet run
Configuring MCP Client
Add the following configuration to your MCP client settings:
{
"servers": {
"local-mcp-server": {
"url": "http://localhost:7071/runtime/webhooks/mcp",
"type": "http"
}
},
"inputs": [
{
"type": "promptString",
"id": "functions-mcp-extension-system-key",
"description": "Azure Functions MCP Extension System Key",
"password": true
},
{
"type": "promptString",
"id": "functionapp-name",
"description": "Azure Functions App Name"
}
]
}
Verifying Connection
When the server starts successfully, you should see the following in the logs:
[info] Starting server local-mcp-server
[info] Connection state: Starting
[info] Starting server from LocalProcess extension host
[info] Connection state: Running
[info] Discovered 3 tools
Testing the MCP Tools
Once connected, you can test each tool through your MCP client:
1. Test PingFunction
{
"tool": "PingFunction",
"parameters": {
"message": "Hello from VS Code"
}
}
Expected Response: ? MCP server received: Hello from VS Code
2. Test ProductInfoFunction
{
"tool": "ProductInfoFunction",
"parameters": {
"productCode": "P100"
}
}
Expected Response:
Product: Laptop
Price: $1200
Stock: Available
3. Test UserProfileFunction
{
"tool": "UserProfileFunction",
"parameters": {
"userId": "alice"
}
}
Expected Response:
Name: Alice
Role: Administrator
Status: Active
Connection States
Monitor the connection state in the VS Code output:
| State | Description |
|---|---|
Starting |
Server is initializing |
Running |
Server is active and ready to accept requests |
Stopped |
Server has been stopped |
Error |
An error occurred during connection |
Development
Adding New MCP Tools
- Create a new class in the
Functions/directory - Implement the function with
[Function]attribute - Add
[McpToolTrigger]to define the tool - Use
[McpToolProperty]for parameters - Return appropriate response types
Template:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Mcp;
using Microsoft.Extensions.Logging;
namespace FunctionApp.Functions;
public class YourNewFunction
{
private readonly ILogger<YourNewFunction> _logger;
public YourNewFunction(ILogger<YourNewFunction> logger)
{
_logger = logger;
}
[Function(nameof(YourNewFunction))]
public async Task<string> Run(
[McpToolTrigger(nameof(YourNewFunction), "Description of your tool")] ToolInvocationContext context,
[McpToolProperty("paramName", "Parameter description")] string paramName)
{
_logger.LogInformation($"YourNewFunction invoked with: {paramName}");
// Your implementation here
await Task.CompletedTask;
return "Your response";
}
}
Logging
The application uses structured logging through ILogger<T>:
_logger.LogInformation("Message with {Parameter}", paramValue);
_logger.LogWarning("Warning message");
_logger.LogError(exception, "Error message");
Console logging is configured with trace-level output to standard error.
Deployment
Deployment instructions to Azure will be added later.
Dependencies
NuGet Packages
| Package | Version | Purpose |
|---|---|---|
| Microsoft.Azure.Functions.Worker | 2.51.0 | Azure Functions isolated worker runtime |
| Microsoft.Azure.Functions.Worker.Sdk | 2.0.7 | SDK for building Azure Functions |
| Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore | 2.1.0 | ASP.NET Core integration for HTTP triggers |
| Microsoft.Azure.Functions.Worker.Extensions.Mcp | 1.1.0 | Model Context Protocol support |
| ModelContextProtocol.AspNetCore | 0.5.0-preview.1 | ASP.NET Core MCP implementation |
| Microsoft.ApplicationInsights.WorkerService | 2.23.0 | Application Insights telemetry |
| Microsoft.Azure.Functions.Worker.ApplicationInsights | 2.50.0 | Application Insights integration for Functions |
Framework References
- Microsoft.AspNetCore.App: ASP.NET Core shared framework
Features
Implemented
- MCP server implementation with Azure Functions
- Three sample MCP tools (Ping, ProductInfo, UserProfile)
- Application Insights telemetry
- Structured logging
- Isolated worker model for better performance
- Health check endpoint
- VS Code integration for testing
Potential Enhancements
- Database integration for dynamic data
- Authentication and authorization
- Rate limiting
- Caching layer
- Additional MCP tools
- Integration tests
- CI/CD pipeline
- API documentation
- Error handling middleware
- Retry policies
Troubleshooting
Common Issues
-
Storage Emulator Not Running:
- Start Azure Storage Emulator or update
AzureWebJobsStoragein local.settings.json
- Start Azure Storage Emulator or update
-
Function Not Triggering:
- Verify MCP client configuration
- Check function logs for errors
- Ensure all required parameters are provided
-
Build Errors:
- Clean and rebuild:
dotnet clean && dotnet build - Restore packages:
dotnet restore - Verify .NET 10 SDK is installed
- Clean and rebuild:
-
MCP Server Connection Issues:
- Ensure the server is running on
http://localhost:7071 - Verify the MCP endpoint URL in client configuration
- Check for port conflicts with other applications
- Review the VS Code output logs for connection errors
- Ensure the server is running on
-
Tools Not Discovered:
- Restart the MCP server
- Verify the function bindings are correct
- Check that all
[McpToolTrigger]attributes are properly configured
Additional Resources
- Azure Functions Documentation
- Model Context Protocol Specification
- .NET 10 Documentation
- Application Insights Documentation
License
Please refer to the repository’s LICENSE file for licensing information.
Contributing
Contributions are welcome! Please follow standard pull request procedures and ensure all tests pass before submitting.
Source Code
github repository: https://github.com/azurecorner/remote-MCP-servers-using-azure-functions




