Azure / Azure/azure-sdk-for-python

Structured inputs: MCP server_url template ({{server_url}}) rejected at agent create — 'not a valid URI'

Open
#47,684 6 comments 0 reactions 1 assignee Claimed by @dargilco View on GitHub
AI Projects customer-reported needs-team-attention question Service Attention
Dominant language
Python
Stars
5.6k
Forks
3.4k
Avg merge
1d 21h
Merged PRs (30d)
193

Description

# 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*](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/structured-inputs?pivots=python#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)

```python
# 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://.services.ai.azure.com/api/projects/",
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//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:

```jsonc
// POST .../agents?api-version=v1 -> 200 OK; GET shows the stored definition:
"tools": [{
"type": "mcp",
"server_label": "{{server_label}}", // <- stored literally (OK)
"server_url": "https://gitmcp.io/org/repo", // <- must be a real URI
"headers": { "Authorization": "{{auth_token}}" } // <- stored literally (OK)
}]
```

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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.