Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
42 changes: 42 additions & 0 deletions src/FunctionsMcpTool/function_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import logging

import azure.functions as func

app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)

# Constants for the Azure Blob Storage container, file, and blob path
_SNIPPET_NAME_PROPERTY_NAME = "snippetname"
_BLOB_PATH = "snippets/{mcptoolargs." + _SNIPPET_NAME_PROPERTY_NAME + "}.json"


@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."""
snippet_content = file.read().decode("utf-8")
logging.info(f"Retrieved snippet: {snippet_content}")
return snippet_content


@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."""
if not snippetname:
return "No snippet name provided"

if not snippet:
return "No snippet content provided"

file.set(snippet)
logging.info(f"Saved snippet: {snippet}")
return f"Snippet '{snippet}' saved successfully"
4 changes: 2 additions & 2 deletions src/host.json → src/FunctionsMcpTool/host.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
"version": "[4.32.0, 5.0.0)"
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
# The Python Worker is managed by the Azure Functions platform
# Manually managing azure-functions-worker may cause unexpected issues

azure-functions==1.25.0b3
azure-functions>=1.25.0b3
1 change: 1 addition & 0 deletions src/McpWeatherApp/.funcignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.venv
47 changes: 47 additions & 0 deletions src/McpWeatherApp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
bin
obj
csx
.vs
edge
Publish

*.user
*.suo
*.cscfg
*.Cache
project.lock.json

/packages
/TestResults

/tools/NuGet.exe
/App_Data
/secrets
/data
.secrets
appsettings.json

node_modules
dist

# Local python packages
.python_packages/

# Python Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# Azurite artifacts
__blobstorage__
__queuestorage__
__azurite_db*__.json
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
42 changes: 2 additions & 40 deletions src/function_app.py → src/McpWeatherApp/function_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,48 +18,10 @@
WEATHER_WIDGET_MIME_TYPE = "text/html;profile=mcp-app"

# Metadata for the tool (as valid JSON string)
TOOL_METADATA = '{"ui": {"resourceUri": "ui://weather/index.html"}}'
TOOL_METADATA = json.dumps({"ui": {"resourceUri": "ui://weather/index.html"}})

# Metadata for the resource (as valid JSON string)
RESOURCE_METADATA = '{"ui": {"prefersBorder": true}}'

# Constants for the Azure Blob Storage container, file, and blob path
_SNIPPET_NAME_PROPERTY_NAME = "snippetname"
_BLOB_PATH = "snippets/{mcptoolargs." + _SNIPPET_NAME_PROPERTY_NAME + "}.json"


@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."""
snippet_content = file.read().decode("utf-8")
logging.info(f"Retrieved snippet: {snippet_content}")
return snippet_content


@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."""
if not snippetname:
return "No snippet name provided"

if not snippet:
return "No snippet content provided"

file.set(snippet)
logging.info(f"Saved snippet: {snippet}")
return f"Snippet '{snippet}' saved successfully"

RESOURCE_METADATA = json.dumps({"ui": {"prefersBorder": True}})

# Weather Widget Resource - returns HTML content for the weather widget
@app.mcp_resource_trigger(
Expand Down
15 changes: 15 additions & 0 deletions src/McpWeatherApp/host.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
8 changes: 8 additions & 0 deletions src/McpWeatherApp/local.settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"PYTHON_ISOLATE_WORKER_DEPENDENCIES": "1"
}
}
5 changes: 5 additions & 0 deletions src/McpWeatherApp/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Do not include azure-functions-worker in this file
# The Python Worker is managed by the Azure Functions platform
# Manually managing azure-functions-worker may cause unexpected issues

azure-functions>=1.25.0b3
File renamed without changes.
Loading