com.google.code.gson
gson
diff --git a/samples/FunctionsMcpTool/src/main/java/com/function/PromptExamples.java b/samples/FunctionsMcpTool/src/main/java/com/function/PromptExamples.java
new file mode 100644
index 0000000..095d4dc
--- /dev/null
+++ b/samples/FunctionsMcpTool/src/main/java/com/function/PromptExamples.java
@@ -0,0 +1,88 @@
+package com.function;
+
+import com.microsoft.azure.functions.ExecutionContext;
+import com.microsoft.azure.functions.annotation.FunctionName;
+import com.microsoft.azure.functions.annotation.McpPromptArgument;
+import com.microsoft.azure.functions.annotation.McpPromptTrigger;
+
+/**
+ * Demonstrates MCP Prompt functions that expose prompt templates to MCP clients.
+ * Clients discover prompts via prompts/list and invoke them via prompts/get.
+ *
+ * Return a plain string (auto-wrapped into a single user message by the host)
+ * or a JSON-serialized GetPromptResult for multi-message / rich content responses.
+ */
+public class PromptExamples {
+
+ /**
+ * A code review prompt with multiple arguments (1 required, 1 optional).
+ * Uses McpPromptArgument annotations to define arguments in a strongly-typed way.
+ */
+ @FunctionName("CodeReviewPrompt")
+ public String codeReviewPrompt(
+ @McpPromptTrigger(
+ name = "code_review",
+ description = "Generates a code review prompt for the given code snippet",
+ title = "Code Review")
+ String context,
+ @McpPromptArgument(
+ name = "code",
+ description = "The code to review",
+ isRequired = true)
+ String code,
+ @McpPromptArgument(
+ name = "language",
+ description = "The programming language")
+ String language,
+ final ExecutionContext executionContext) {
+
+ executionContext.getLogger().info("Generating code review prompt");
+
+ String lang = (language != null && !language.isEmpty()) ? language : "unknown";
+ String snippet = (code != null && !code.isEmpty()) ? code : "// no code provided";
+
+ return "Please review the following " + lang + " code and suggest improvements:\n\n```"
+ + lang + "\n" + snippet + "\n```";
+ }
+
+ /**
+ * A summarize prompt with a single required argument and plain string return.
+ * The host auto-wraps the returned string into a PromptMessage with role "user".
+ */
+ @FunctionName("SummarizePrompt")
+ public String summarizePrompt(
+ @McpPromptTrigger(
+ name = "summarize",
+ description = "Summarizes the provided text",
+ title = "Summarize Text")
+ String context,
+ @McpPromptArgument(
+ name = "text",
+ description = "The text to summarize",
+ isRequired = true)
+ String text,
+ final ExecutionContext executionContext) {
+
+ executionContext.getLogger().info("Generating summarize prompt");
+
+ String input = (text != null && !text.isEmpty()) ? text : "No text provided";
+ return "Please provide a concise summary of the following text:\n\n" + input;
+ }
+
+ /**
+ * A prompt with no arguments. Tests the edge case of a prompt
+ * that takes no user input.
+ */
+ @FunctionName("NoArgsPrompt")
+ public String noArgsPrompt(
+ @McpPromptTrigger(
+ name = "no_args_prompt",
+ description = "A prompt that requires no arguments",
+ title = "No Arguments Prompt")
+ String context,
+ final ExecutionContext executionContext) {
+
+ executionContext.getLogger().info("Generating no-args prompt");
+ return "This prompt requires no arguments. Please provide general guidance.";
+ }
+}
diff --git a/samples/FunctionsMcpTool/src/main/java/com/function/StructuredContentExamples.java b/samples/FunctionsMcpTool/src/main/java/com/function/StructuredContentExamples.java
new file mode 100644
index 0000000..5bc5b53
--- /dev/null
+++ b/samples/FunctionsMcpTool/src/main/java/com/function/StructuredContentExamples.java
@@ -0,0 +1,159 @@
+package com.function;
+
+import com.microsoft.azure.functions.ExecutionContext;
+import com.microsoft.azure.functions.annotation.FunctionName;
+import com.microsoft.azure.functions.annotation.McpToolProperty;
+import com.microsoft.azure.functions.annotation.McpToolTrigger;
+import com.microsoft.azure.functions.mcp.McpContent;
+import com.microsoft.azure.functions.mcp.McpToolResult;
+import io.modelcontextprotocol.spec.McpSchema.Content;
+import io.modelcontextprotocol.spec.McpSchema.ImageContent;
+import io.modelcontextprotocol.spec.McpSchema.TextContent;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Demonstrates structured content support in Azure Functions MCP tools.
+ *
+ * These examples show three approaches for returning rich content from MCP tools:
+ *
+ * - {@link #getSnippetStructured} — {@code @McpContent}-annotated POJO (automatic text + structured content)
+ * - {@link #renderImage} — Single content block (ImageContentBlock)
+ * - {@link #getMultiContent} — Multiple content blocks (List of ContentBlock)
+ *
+ *
+ * Note: These functions require the {@code azure-functions-java-mcp} dependency which provides
+ * the middleware that wraps return values into the MCP result envelope.
+ */
+public class StructuredContentExamples {
+
+ // ========================================================================
+ // Example 1: @McpContent-annotated POJO
+ // The middleware automatically creates both text content (for backwards
+ // compatibility) and structured content (for clients that support it).
+ // ========================================================================
+
+ /**
+ * A snippet POJO decorated with @McpContent. When returned from an MCP tool function,
+ * this will be serialized as both text content (JSON text) and structured content
+ * (JSON object), enabling MCP clients to parse the result programmatically.
+ */
+ @McpContent
+ public static class SnippetResult {
+ private String name;
+ private String content;
+ private String language;
+
+ public SnippetResult() {
+ }
+
+ public SnippetResult(String name, String content, String language) {
+ this.name = name;
+ this.content = content;
+ this.language = language;
+ }
+
+ public String getName() { return name; }
+ public void setName(String name) { this.name = name; }
+ public String getContent() { return content; }
+ public void setContent(String content) { this.content = content; }
+ public String getLanguage() { return language; }
+ public void setLanguage(String language) { this.language = language; }
+ }
+
+ /**
+ * Returns a code snippet as structured content. The {@code @McpContent} annotation
+ * on {@code SnippetResult} tells the middleware to serialize the return value as both
+ * text content and structured content.
+ *
+ * MCP clients that support structured content can parse the JSON object directly.
+ * Older clients will see the JSON as a text string.
+ */
+ @FunctionName("GetSnippetStructured")
+ public SnippetResult getSnippetStructured(
+ @McpToolTrigger(
+ name = "getSnippetStructured",
+ description = "Gets a code snippet with structured content support.")
+ String context,
+ @McpToolProperty(
+ name = "snippetName",
+ propertyType = "string",
+ description = "The name of the snippet to retrieve.",
+ isRequired = true)
+ String snippetName,
+ final ExecutionContext executionContext) {
+
+ executionContext.getLogger().info("Getting structured snippet: " + snippetName);
+
+ return new SnippetResult(
+ snippetName,
+ "public class HelloWorld { public static void main(String[] args) { System.out.println(\"Hello!\"); } }",
+ "java"
+ );
+ }
+
+ // ========================================================================
+ // Example 2: Single content block (ImageContentBlock)
+ // For returning rich content types like images.
+ // ========================================================================
+
+ /**
+ * Returns an image as a single content block. The middleware wraps this
+ * in an MCP result envelope automatically.
+ */
+ @FunctionName("RenderImage")
+ public ImageContent renderImage(
+ @McpToolTrigger(
+ name = "renderImage",
+ description = "Returns a base64-encoded image.")
+ String context,
+ @McpToolProperty(
+ name = "data",
+ propertyType = "string",
+ description = "Base64-encoded image data.",
+ isRequired = true)
+ String data,
+ @McpToolProperty(
+ name = "mimeType",
+ propertyType = "string",
+ description = "MIME type of the image (e.g., image/png).")
+ String mimeType,
+ final ExecutionContext executionContext) {
+
+ executionContext.getLogger().info("Rendering image with MIME type: " + mimeType);
+
+ return new ImageContent(null, data, mimeType != null ? mimeType : "image/png");
+ }
+
+ // ========================================================================
+ // Example 3: Multiple content blocks
+ // For returning a list of mixed content types in a single response.
+ // ========================================================================
+
+ /**
+ * Returns multiple content blocks — a text description followed by an image.
+ * The middleware wraps this as a multi-content result.
+ */
+ @FunctionName("GetMultiContent")
+ public List getMultiContent(
+ @McpToolTrigger(
+ name = "getMultiContent",
+ description = "Returns multiple content blocks including text and an image.")
+ String context,
+ @McpToolProperty(
+ name = "imageData",
+ propertyType = "string",
+ description = "Base64-encoded image data.",
+ isRequired = true)
+ String imageData,
+ final ExecutionContext executionContext) {
+
+ executionContext.getLogger().info("Generating multi-content response");
+
+ return Arrays.asList(
+ new TextContent("Here is the requested image:"),
+ new ImageContent(null, imageData, "image/png")
+ );
+ }
+}
diff --git a/samples/McpWeatherApp/pom.xml b/samples/McpWeatherApp/pom.xml
index 570b46d..59e6e99 100644
--- a/samples/McpWeatherApp/pom.xml
+++ b/samples/McpWeatherApp/pom.xml
@@ -13,7 +13,7 @@
UTF-8
17
1.41.0
- 3.2.4
+ 3.3.0
McpWeatherApp