Skip to content

Commit db90291

Browse files
committed
Adding Initial MCP Tool Example
1 parent 5c85b9f commit db90291

File tree

12 files changed

+303
-0
lines changed

12 files changed

+303
-0
lines changed

src/.funcignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.venv

src/.gitignore

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
bin
2+
obj
3+
csx
4+
.vs
5+
edge
6+
Publish
7+
8+
*.user
9+
*.suo
10+
*.cscfg
11+
*.Cache
12+
project.lock.json
13+
14+
/packages
15+
/TestResults
16+
17+
/tools/NuGet.exe
18+
/App_Data
19+
/secrets
20+
/data
21+
.secrets
22+
appsettings.json
23+
local.settings.json
24+
25+
node_modules
26+
dist
27+
28+
# Local python packages
29+
.python_packages/
30+
31+
# Python Environments
32+
.env
33+
.venv
34+
env/
35+
venv/
36+
ENV/
37+
env.bak/
38+
venv.bak/
39+
40+
# Byte-compiled / optimized / DLL files
41+
__pycache__/
42+
*.py[cod]
43+
*$py.class
44+
45+
# Azurite artifacts
46+
__blobstorage__
47+
__queuestorage__
48+
__azurite_db*__.json

src/.vscode/extensions.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"recommendations": [
3+
"ms-azuretools.vscode-azurefunctions",
4+
"ms-python.python"
5+
]
6+
}

src/.vscode/launch.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "Attach to Python Functions",
6+
"type": "debugpy",
7+
"request": "attach",
8+
"connect": {
9+
"host": "localhost",
10+
"port": 9091
11+
},
12+
"preLaunchTask": "func: host start"
13+
}
14+
]
15+
}

src/.vscode/settings.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"files.exclude": {
3+
"obj": true,
4+
"bin": true
5+
},
6+
"azureFunctions.deploySubpath": ".",
7+
"azureFunctions.scmDoBuildDuringDeployment": true,
8+
"azureFunctions.pythonVenv": ".venv",
9+
"azureFunctions.projectLanguage": "Python",
10+
"azureFunctions.projectRuntime": "~4",
11+
"debug.internalConsoleOptions": "neverOpen",
12+
"azureFunctions.projectLanguageModel": 2,
13+
"azureFunctions.preDeployTask": "func: extensions install"
14+
}

src/.vscode/tasks.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "pip install (functions)",
6+
"type": "shell",
7+
"osx": {
8+
"command": "${config:azureFunctions.pythonVenv}/bin/python -m pip install -r requirements.txt"
9+
},
10+
"windows": {
11+
"command": "${config:azureFunctions.pythonVenv}\\Scripts\\python -m pip install -r requirements.txt"
12+
},
13+
"linux": {
14+
"command": "${config:azureFunctions.pythonVenv}/bin/python -m pip install -r requirements.txt"
15+
},
16+
"problemMatcher": []
17+
},
18+
{
19+
"type": "func",
20+
"label": "func: host start",
21+
"command": "host start",
22+
"problemMatcher": "$func-python-watch",
23+
"isBackground": true,
24+
"dependsOn": "func: extensions install"
25+
},
26+
{
27+
"type": "func",
28+
"command": "extensions install",
29+
"dependsOn": "pip install (functions)",
30+
"problemMatcher": []
31+
}
32+
]
33+
}

src/README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Python App with MCP Integration
2+
3+
This guide walks you through setting up and connecting your Python application with the Model Context Protocol (MCP) Inspector.
4+
5+
---
6+
7+
## 📦 Installation & Setup
8+
9+
### 1. Install Azure Functions Extensions
10+
11+
Ensure you're inside your Python working directory and have the Azure Functions Core Tools installed. Then, run:
12+
13+
```bash
14+
func extensions install
15+
```
16+
17+
### 2. Activate Virtual Environment
18+
19+
Make sure your Python virtual environment is activated before proceeding.
20+
21+
```bash
22+
# Example (Linux/macOS)
23+
source venv/bin/activate
24+
25+
# Example (Windows)
26+
.\venv\Scripts\activate
27+
```
28+
29+
### 3. Start the Functions Host
30+
31+
Run the following command to start the Azure Functions host:
32+
33+
```bash
34+
func host start
35+
```
36+
37+
## 🔗 Installation & Setup
38+
39+
### 4. Start MCP Inspector
40+
41+
Open a new terminal and run the MCP Inspector:
42+
43+
```bash
44+
npx @modelcontextprotocol/inspector node build/index.js
45+
```
46+
47+
### 5. Configure Connection
48+
49+
Transport Type: SSE (Server-Sent Events)\
50+
URL: <http://0.0.0.0:7071/runtime/webhooks/mcp/sse>
51+
52+
### 6. Connect to Server
53+
54+
Click Connect within the MCP Inspector UI.
55+
56+
## 🧰 Explore Tools
57+
58+
Once generated:
59+
60+
- You can list all generated tools
61+
- Select any tool to begin interacting with your Python function through MCP
62+
63+
## ✅ Verification
64+
65+
To verify the setup is working:
66+
67+
- Confirm the MCP Inspector shows the connection is active
68+
- Tools appear in the inspector panel after connection
69+
- Selecting a tool returns the expected behavior or response

src/extensions.csproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net8.0</TargetFramework>
4+
<WarningsAsErrors></WarningsAsErrors>
5+
<DefaultItemExcludes>**</DefaultItemExcludes>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<PackageReference Include="Microsoft.Azure.Functions.Extensions.Mcp" Version="1.0.0-beta423" />
9+
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="5.3.3" />
10+
<PackageReference Include="Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator" Version="1.1.3" />
11+
</ItemGroup>
12+
</Project>

src/function_app.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import azure.functions as func
2+
import logging
3+
import json
4+
5+
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
6+
7+
# Constants for the Azure Blob Storage container and file name
8+
_CONTAINER_NAME = "test"
9+
_FILE_NAME = "test.txt"
10+
11+
@app.generic_trigger(arg_name="context", type="mcpToolTrigger", toolName="hello",
12+
description="Gets code snippets from your snippet collection.",
13+
toolProperties="[]")
14+
def hello_mcp(context) -> None:
15+
"""
16+
A simple function that returns a greeting message.
17+
18+
Args:
19+
context: The trigger context (not used in this function).
20+
21+
Returns:
22+
str: A greeting message.
23+
"""
24+
return "Hello I am MCPTool!"
25+
26+
@app.generic_trigger(arg_name="context", type="mcpToolTrigger", toolName="savesnippets",
27+
description="Save code snippets.",
28+
toolProperties="[{\"propertyName\":\"codeSnippet\",\"propertyType\":\"string\",\"description\":\"The name of the snippet.\"}]")
29+
@app.generic_output_binding(arg_name="file", type="blob", connection="AzureWebJobsStorage", path=f"{_CONTAINER_NAME}/{_FILE_NAME}")
30+
def save_snippets(context, file: func.Out[str]):
31+
"""
32+
Saves a code snippet to Azure Blob Storage.
33+
34+
Args:
35+
context: The trigger context containing the input data as JSON.
36+
file (func.Out[str]): The output binding to write the snippet to Azure Blob Storage.
37+
38+
Raises:
39+
KeyError: If the "codeSnippet" key is missing in the input JSON.
40+
json.JSONDecodeError: If the context is not valid JSON.
41+
"""
42+
content = json.loads(context)
43+
msg = content["arguments"]["codeSnippet"]
44+
logging.info(msg)
45+
file.set(msg) # Write the snippet to the specified blob
46+
47+
@app.generic_trigger(arg_name="context", type="mcpToolTrigger", toolName="getsnippets",
48+
description="Gets code snippets from your snippet collection.",
49+
toolProperties="[]")
50+
@app.generic_input_binding(arg_name="file", type="blob", connection="AzureWebJobsStorage", path=f"{_CONTAINER_NAME}/{_FILE_NAME}")
51+
def get_snippets(file: func.InputStream, context) -> None:
52+
"""
53+
Retrieves a saved code snippet from Azure Blob Storage.
54+
55+
Args:
56+
file (func.InputStream): The input binding to read the snippet from Azure Blob Storage.
57+
context: The trigger context (not used in this function).
58+
59+
Returns:
60+
str: The content of the blob as a UTF-8 decoded string.
61+
62+
Raises:
63+
Exception: If the blob does not exist or cannot be read.
64+
"""
65+
return file.read().decode('utf-8') # Read and decode the blob content

src/host.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"version": "2.0",
3+
"logging": {
4+
"applicationInsights": {
5+
"samplingSettings": {
6+
"isEnabled": true,
7+
"excludedTypes": "Request"
8+
}
9+
}
10+
}
11+
}

0 commit comments

Comments
 (0)