This Azure Functions app implements an MCP server that demonstrates various tool patterns. It includes sample tools for connectivity testing, code snippet management with Azure Blob Storage, and more. Additional tools will be added over time to showcase different MCP capabilities.
This MCP server currently provides the following tools:
- hello_mcp: A simple hello world tool for testing connectivity
- get_snippet: Retrieve a saved code snippet by name from Azure Blob Storage
- save_snippet: Save a code snippet with a name to Azure Blob Storage
More tools will be added to demonstrate additional MCP patterns and Azure Functions bindings.
- Python version 3.13 or higher
- Azure Functions Core Tools >=
4.8.0 - Azure Storage Emulator (Azurite) for local development
An Azure Storage Emulator is needed to store snippets locally:
docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 \
mcr.microsoft.com/azure-storage/azuriteNote: If using the Azurite VS Code extension, run
Azurite: Startfrom the command palette.
From the src/FunctionsMcpTool directory, create and activate a virtual environment, then install dependencies:
python3 -m venv .venv
# macOS/Linux
source .venv/bin/activate
# Windows
.venv\Scripts\activate
pip install -r requirements.txtfunc start- Open .vscode/mcp.json
- Find the server called
local-mcp-functionand click Start. The server uses the endpoint:http://localhost:7071/runtime/webhooks/mcp - In Copilot chat agent mode, try these prompts:
- "Say Hello"
- "Save this snippet as snippet1" (with code selected)
- "Retrieve snippet1 and apply to newFile.py"
- Install and run MCP Inspector:
npx @modelcontextprotocol/inspector
- Open the URL displayed (e.g., http://0.0.0.0:5173/#resources)
- Set transport type to
Streamable HTTP - Set URL to
http://0.0.0.0:7071/runtime/webhooks/mcpand Connect - List Tools, select a tool, and Run Tool
After saving snippets, verify they're stored in Azurite:
- Open Azure Storage Explorer
- Navigate to Emulator & Attached → Storage Accounts → (Emulator - Default Ports) (Key)
- Go to Blob Containers → snippets
- View your saved snippet blobs
# List blobs in the snippets container
az storage blob list --container-name snippets --connection-string "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;"The function uses Azure Functions' first-class MCP decorators to expose tools:
@app.mcp_tool()
def hello_mcp() -> str:
"""Hello world."""
return "Hello I am MCPTool!"
@app.mcp_tool()
@app.mcp_tool_property(arg_name="snippetname", description="The name of the snippet.")
@app.blob_input(arg_name="file", connection="AzureWebJobsStorage", path=_BLOB_PATH)
def get_snippet(file: func.InputStream, snippetname: str) -> str:
"""Retrieve a snippet by name from Azure Blob Storage."""
# ... implementation
@app.mcp_tool()
@app.mcp_tool_property(arg_name="snippetname", description="The name of the snippet.")
@app.mcp_tool_property(arg_name="snippet", description="The content of the snippet.")
@app.blob_output(arg_name="file", connection="AzureWebJobsStorage", path=_BLOB_PATH)
def save_snippet(file: func.Out[str], snippetname: str, snippet: str) -> str:
"""Save a snippet with a name to Azure Blob Storage."""
# ... implementationThe MCP decorators automatically:
- Infer tool properties from function signatures and type hints
- Handle JSON serialization
- Expose the functions as MCP tools without manual configuration
See Deploy to Azure for Remote MCP for deployment instructions.
| Error | Solution |
|---|---|
AttributeError: 'FunctionApp' object has no attribute 'mcp_resource_trigger' |
Python 3.13 is required. Verify with python3 --version. Install via brew install python@3.13 (macOS) or from python.org. Recreate your virtual environment with Python 3.13 after installing. |
| Connection refused | Ensure Azurite is running (docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 mcr.microsoft.com/azure-storage/azurite) |
| API version not supported by Azurite | Pull the latest Azurite image (docker pull mcr.microsoft.com/azure-storage/azurite) then restart Azurite and the app |
| Blob not found | Verify the snippet was saved successfully and the name matches exactly |