Add McpPromptTrigger and McpPromptArgument annotations#235
Add McpPromptTrigger and McpPromptArgument annotations#235ahmedmuhsin wants to merge 2 commits intoAzure:devfrom
Conversation
Implements annotation definitions for MCP prompt support (issue #861). - McpPromptTrigger: trigger annotation for prompt functions with name, description, title, promptArguments, metadata, and icons properties - McpPromptArgument: input binding annotation for individual prompt arguments with argumentName, description, and isRequired properties The name() property serves as both the binding parameter name and the unique prompt identifier (same convention as McpToolTrigger).
TsuyoshiUshio
left a comment
There was a problem hiding this comment.
Review: Add McpPromptTrigger and McpPromptArgument annotations
Thanks for this PR — it's well-structured and follows the existing McpToolTrigger/McpToolProperty pattern closely. The Javadoc quality is excellent. A few items to address before merge:
Block: Missing promptName field — host contract mismatch
The host extension contract (per issue #861) specifies separate fields in the binding JSON:
{
"name": "<paramName>",
"promptName": "<unique-prompt-name>"
}The Python library implements this correctly with name and prompt_name as independent parameters:
class MCPPromptTrigger(Trigger):
def __init__(self, name: str, prompt_name: str, ...):
self.promptName = prompt_nameHowever, this Java PR merges both into a single name() method. Without a separate promptName field, the Maven plugin cannot emit the correct function.json structure unless it duplicates name() into both fields.
Question: Does the companion Maven plugin PR (#2554) handle this by copying name() into both name and promptName? If so, this works but should be documented in the Javadoc. If not, a promptName() attribute is needed.
Note: The same issue exists on McpToolTrigger (no toolName), so this may be an intentional Java-specific convention — but it diverges from both the Python SDK and the host contract spec.
Block: Dangling @see McpMetadata reference
McpPromptTrigger.java line 58 references @see McpMetadata, but no McpMetadata class exists in the codebase. This will produce a Javadoc warning/error at build time.
Fix: Either remove @see McpMetadata or introduce the McpMetadata class in this PR.
Concern: argumentName() pattern differs from McpToolProperty
McpPromptArgument introduces argumentName() as a separate field from name(), allowing the MCP protocol argument name to differ from the binding parameter name. McpToolProperty does not have an equivalent propertyName() accessor.
This is arguably an improvement (more flexible), but creates an asymmetry across the two MCP annotation families. Please confirm the Maven plugin companion PR handles the argumentName default (falls back to name() when empty).
Concern: No tests included
The Python library includes tests in test_mcp.py for their prompt trigger implementation. While the existing McpToolTrigger/McpToolProperty also lack tests in this repo, new public API (@since 3.3.0) would benefit from basic annotation contract tests — verify RUNTIME retention, PARAMETER target, default values, and that name() is required.
Suggestion: Consider adding title/metadata/icons to McpToolTrigger for parity
McpPromptTrigger has title(), metadata(), and icons() which are absent from McpToolTrigger. The MCP spec supports annotations/metadata for tools as well. If these will eventually be added to McpToolTrigger, consider doing it in a coordinated PR to keep the two annotation families consistent.
Nit: Example prompt name in McpPromptArgument Javadoc
In the McpPromptArgument example (line 26), the trigger uses name = "context". Since name doubles as the prompt identifier, "context" reads like a generic binding name rather than a prompt identifier. Using "code_review" would be clearer and consistent with the McpPromptTrigger summarize example.
Praise
- Excellent Javadoc with two usage examples (inline JSON args vs annotation-based) — makes the API very learnable
- Clean
@see/@sincecross-referencing isRequired() default falseis consistent withMcpToolProperty- Follows the established
McpToolTrigger/McpToolPropertypattern faithfully
| * {@literal @}McpPromptTrigger(name = "context", description = "Code review prompt") String context, | ||
| * {@literal @}McpPromptArgument( | ||
| * name = "code", | ||
| * argumentName = "code", |
There was a problem hiding this comment.
Why is there both a name and argumentName property for McpPromptArgument?
The spec shows only name, description, and required properties:
[
{
"name": "code",
"description": "The code to review",
"required": true
},
{
"name": "language",
"description": "The programming language",
"required": false
}
]
There was a problem hiding this comment.
Good question. Removed argumentName() in the latest push. name() now serves as both the binding parameter name and the MCP argument identifier. The Maven plugin patches it into argumentName in function.json, same pattern as McpToolProperty where name() is patched into propertyName.
| * | ||
| * @return The prompt name / parameter binding name | ||
| */ | ||
| String name(); |
There was a problem hiding this comment.
Is name different from promptName?
Per the spec from Lilian:
"name": "<paramName>",
"promptName": "<unique-prompt-name>",
There was a problem hiding this comment.
name() serves as both the binding parameter name and the unique prompt identifier. The Maven plugin PR (#2554) patches it into promptName in function.json. This is the same convention as McpToolTrigger where name() is patched into toolName. Added Javadoc clarifying this.
- Remove argumentName() from McpPromptArgument: name() serves as both the binding parameter name and the MCP argument identifier, matching the McpToolProperty pattern where name() maps to propertyName - Fix Javadoc example in McpPromptArgument: use code_review as prompt name instead of context - Remove argumentName from McpPromptTrigger Javadoc example - Add Javadoc notes explaining the name/argumentName patching convention
|
Thanks for the thorough review! Addressed all items in the latest push: 1. Missing 2. Dangling 3. 4. No tests: 5. Add 6. Example uses |
| * | ||
| * @return JSON array of argument definitions, or empty string | ||
| */ | ||
| String promptArguments() default ""; |
There was a problem hiding this comment.
Instead of string, can you have more fluent api to define the prompt arguments?
Current implementation require customer to manage the JSON string.
Summary
Adds annotation definitions for MCP prompt support (issue #861).
New annotations
McpPromptTrigger
Trigger annotation for MCP prompt functions. Properties:
name()— binding parameter name and unique prompt identifier (same convention as McpToolTrigger)description()— human-readable descriptiontitle()— optional display titlepromptArguments()— inline JSON array of argument definitions (alternative to McpPromptArgument annotations)metadata()— optional JSON metadataicons()— optional JSON icons arraydataType()— serialization hintMcpPromptArgument
Input binding annotation for individual prompt arguments. Properties:
name()— binding parameter nameargumentName()— argument name exposed in MCP protocoldescription()— argument descriptionisRequired()— whether the argument is requiredUsage
Related PRs