Structured inputs: MCP server_url template ({{server_url}}) rejected at agent create — format: '{{server_url}}' is not a valid URI
Description
Following Customize agent behavior at runtime with structured inputs → Use structured inputs with MCP servers, creating a prompt agent whose MCP tool puts a handlebar template in server_url is rejected at create-version time. The server_url is validated as a strict URI before structured-input substitution, so the documented placeholder can never be stored.
Repro (the doc's example)
# azure-ai-projects==2.2.0, openai==2.44.0
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import MCPTool, PromptAgentDefinition, StructuredInputDefinition
from azure.identity import DefaultAzureCredential
project = AIProjectClient(
endpoint="https://<resource>.services.ai.azure.com/api/projects/<project>",
credential=DefaultAzureCredential(),
)
tool = MCPTool(server_label="{{server_label}}", server_url="{{server_url}}", require_approval="never")
project.agents.create_version(
agent_name="mcp-dynamic-agent",
definition=PromptAgentDefinition(
model="gpt-4o-mini",
instructions="You are a helpful assistant.",
tools=[tool],
structured_inputs={
"server_label": StructuredInputDefinition(description="MCP server label", required=True, schema={"type": "string"}),
"server_url": StructuredInputDefinition(description="MCP server URL", required=True, schema={"type": "string"}),
},
),
)
Result:
azure.core.exceptions.HttpResponseError: (invalid_payload)
format: '{{server_url}}' is not a valid URI
param: /definition/tools/0/server_url
Equivalent raw REST (POST {endpoint}/agents/<name>/versions?api-version=v1, body {"definition": {...}}) returns the same 400.
The failure is specific to server_url
Templating works for the other MCP fields in the same example — only server_url is URI-validated. With a static server_url, the identical definition creates successfully and the templates are stored verbatim:
So the substitution engine accepts templates in server_label and headers; the issue is isolated to the URI-format validation on server_url.
If the template is instead embedded in an otherwise-valid path ("https://host/{{segment}}"), create succeeds but the braces are percent-encoded at store time → the stored value becomes https://host/%7B%7Bsegment%7D%7D, so runtime substitution never matches and the MCP client connects to the literal encoded URL.
Expected
server_url should accept a handlebar template (skipping URI-format validation/normalization when the value is a template), consistent with server_label/headers and with the documentation, and substitute it from the request-body structured_inputs at POST /openai/v1/responses.
Environment
azure-ai-projects==2.2.0, openai==2.44.0, api-version=v1 (also reproduced on 2025-11-15-preview).
- Reproduced via the Python SDK and raw REST, on multiple Foundry resources across different regions/tenants.
Ask
Relax server_url (and confirm server_label) URI-format validation for handlebar templates so the documented MCP structured-input pattern works — or, if the feature is not yet enabled in these regions, please annotate the docs and advise how to opt in.
Structured inputs: MCP
server_urltemplate ({{server_url}}) rejected at agent create —format: '{{server_url}}' is not a valid URIDescription
Following Customize agent behavior at runtime with structured inputs → Use structured inputs with MCP servers, creating a prompt agent whose MCP tool puts a handlebar template in
server_urlis rejected at create-version time. Theserver_urlis validated as a strict URI before structured-input substitution, so the documented placeholder can never be stored.Repro (the doc's example)
Result:
Equivalent raw REST (
POST {endpoint}/agents/<name>/versions?api-version=v1, body{"definition": {...}}) returns the same400.The failure is specific to
server_urlTemplating works for the other MCP fields in the same example — only
server_urlis URI-validated. With a staticserver_url, the identical definition creates successfully and the templates are stored verbatim:So the substitution engine accepts templates in
server_labelandheaders; the issue is isolated to the URI-format validation onserver_url.If the template is instead embedded in an otherwise-valid path (
"https://host/{{segment}}"), create succeeds but the braces are percent-encoded at store time → the stored value becomeshttps://host/%7B%7Bsegment%7D%7D, so runtime substitution never matches and the MCP client connects to the literal encoded URL.Expected
server_urlshould accept a handlebar template (skipping URI-format validation/normalization when the value is a template), consistent withserver_label/headersand with the documentation, and substitute it from the request-bodystructured_inputsatPOST /openai/v1/responses.Environment
azure-ai-projects==2.2.0,openai==2.44.0,api-version=v1(also reproduced on2025-11-15-preview).Ask
Relax
server_url(and confirmserver_label) URI-format validation for handlebar templates so the documented MCP structured-input pattern works — or, if the feature is not yet enabled in these regions, please annotate the docs and advise how to opt in.