-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathStructuredContentExamples.java
More file actions
159 lines (140 loc) · 6.51 KB
/
StructuredContentExamples.java
File metadata and controls
159 lines (140 loc) · 6.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
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.
*
* <p>These examples show three approaches for returning rich content from MCP tools:</p>
* <ol>
* <li>{@link #getSnippetStructured} — {@code @McpContent}-annotated POJO (automatic text + structured content)</li>
* <li>{@link #renderImage} — Single content block (ImageContentBlock)</li>
* <li>{@link #getMultiContent} — Multiple content blocks (List of ContentBlock)</li>
* </ol>
*
* <p>Note: These functions require the {@code azure-functions-java-mcp} dependency which provides
* the middleware that wraps return values into the MCP result envelope.</p>
*/
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.
*
* <p>MCP clients that support structured content can parse the JSON object directly.
* Older clients will see the JSON as a text string.</p>
*/
@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<Content> 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")
);
}
}