Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Create and synchronize prompt-based AI agents directly within Azure AI Foundry via REST API, from a local JSON manifest. Unlike scaffolding skills that only generate local code, this skill registers agents in the Foundry service itself — making them immediately available for invocation. Use when the user asks to create agents in Foundry, sync, deploy, register, or push agents to Foundry, update agent instructions, or scaffold the manifest and sync script for a new repository. Triggers: 'create a
.claude/skills/foundry-agent-sync/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-19 | ✗→✓ | ▲ Improved | — | — |
| case-23 | ✗→✓ | ▲ Improved | — | — |
| case-09 | ✗→✓ | ▲ Improved | — | — |
| case-15 | ✗→✓ | ▲ Improved | — | — |
| case-14 | ✗→✓ | ▲ Improved | — | — |
Create and synchronize prompt-based AI agents directly within Azure AI Foundry via the Agent Service REST API. This skill registers agents in the Foundry service itself — making them immediately available for invocation, evaluation, and management through the Foundry portal or API. Each agent is created or updated idempotently via a named POST call, using definitions from a local JSON manifest file.
> Key distinction: This skill creates agents inside AI Foundry (server-side). It does not scaffold local agent code or container images — for that, use the microsoft-foundry skill's create sub-skill.
The user must have:
gpt-5-4)az) authenticated with access to the Foundry projectCollect these values before proceeding:
| Value | How to get it | |---|---| | Foundry project endpoint | Azure Portal → AI Foundry project → Overview → Endpoint, or az resource show | | Subscription ID | az account show --query id -o tsv | | Model deployment name | The model name deployed in the Foundry project (e.g. gpt-5-4) |
The manifest is a JSON array where each entry defines one agent. Look for it at common paths: infra/foundry-agents.json, foundry-agents.json, or .foundry/agents.json. If none exists, scaffold one.
json[ { "useCaseId": "alert-triage", "description": "Short description of what this agent does.", "baseInstruction": "You are an assistant that... <system prompt for the agent>" } ]
| Field | Required | Description | |---|---|---| | useCaseId | Yes | Kebab-case identifier; used to build the agent name ({prefix}-{useCaseId}) | | description | Yes | Human-readable description stored as agent metadata | | baseInstruction | Yes | System prompt / base instructions for the agent |
Create or locate the sync script. The canonical path is infra/scripts/sync-foundry-agents.ps1 but adapt to the repo layout.
powershellparam( [Parameter(Mandatory)] [string]$SubscriptionId, [Parameter(Mandatory)] [string]$ProjectEndpoint, [string]$ManifestPath = (Join-Path $PSScriptRoot '..\foundry-agents.json'), [string]$ModelName = 'gpt-5-4', [string]$AgentNamePrefix = 'myproject', [string]$ApiVersion = '2025-11-15-preview' ) $ErrorActionPreference = 'Stop' # Optional: append a common instruction suffix to every agent $commonSuffix = '' az account set --subscription $SubscriptionId | Out-Null $accessToken = az account get-access-token --resource https://ai.azure.com/ --query accessToken -o tsv if (-not $accessToken) { throw 'Failed to acquire Foundry access token.' } $definitions = Get-Content -Raw -Path $ManifestPath | ConvertFrom-Json $headers = @{ Authorization = "Bearer $accessToken" } $results = @() foreach ($def in $definitions) { $agentName = "$AgentNamePrefix-$($def.useCaseId)" $instructions = if ($commonSuffix) { "$($def.baseInstruction)`n`n$commonSuffix" } else { $def.baseInstruction } $body = @{ definition = @{ kind = 'prompt'; model = $ModelName; instructions = $instructions } description = $def.description metadata = @{ useCaseId = $def.useCaseId; managedBy = 'foundry-agent-sync' } } | ConvertTo-Json -Depth 8 $uri = "$($ProjectEndpoint.TrimEnd('/'))/agents/$agentName`?api-version=$ApiVersion" $resp = Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -ContentType 'application/json' -Body $body $version = $resp.version ?? $resp.latest_version ?? $resp.id ?? 'unknown' Write-Host "Synced $agentName ($version)" $results += [pscustomobject]@{ name = $agentName; version = $version } } $results | Format-Table -AutoSize
For automated deployment via Microsoft.Resources/deploymentScripts, use a bash script that:
az login --identity --username "$CLIENT_ID"az account get-access-token --resource https://ai.azure.com/FOUNDRY_AGENT_DEFINITIONS environment variable (JSON string){endpoint}/agents/{name}?api-version=2025-11-15-previewTo run the sync automatically during infrastructure deployment:
bicep var agentDefinitions = loadJsonContent('foundry-agents.json')
Microsoft.Resources/deploymentScripts resource (kind AzureCLI) that:loadTextContentGate behind a deployFoundryAgents parameter so teams can opt in/out.
Search the repo for foundry-agents.json. If it doesn't exist, ask the user what agents they need and create the manifest.
Search for sync-foundry-agents.ps1 or foundry-agent-sync.sh. If missing, create the PowerShell script using the template above, adapting:
$AgentNamePrefix to match the project name$ModelName to the user's deployed model$ManifestPath to the actual manifest locationAsk the user for:
gpt-5-4)Execute the PowerShell script with the collected parameters:
powershell.\infra\scripts\sync-foundry-agents.ps1 ` -SubscriptionId '<sub-id>' ` -ProjectEndpoint '<endpoint>' ` -ModelName '<model>' ` -AgentNamePrefix '<prefix>'
Confirm synced agents by listing them:
powershell$token = az account get-access-token --resource https://ai.azure.com/ --query accessToken -o tsv $endpoint = '<project-endpoint>' Invoke-RestMethod -Uri "$endpoint/agents?api-version=2025-11-15-preview" ` -Headers @{ Authorization = "Bearer $token" }
| Operation | Method | URL | |---|---|---| | Create/update agent | POST | {projectEndpoint}/agents/{agentName}?api-version=2025-11-15-preview | | List agents | GET | {projectEndpoint}/agents?api-version=2025-11-15-preview | | Get agent | GET | {projectEndpoint}/agents/{agentName}?api-version=2025-11-15-preview | | Delete agent | DELETE | {projectEndpoint}/agents/{agentName}?api-version=2025-11-15-preview |
json{ "definition": { "kind": "prompt", "model": "<deployed-model-name>", "instructions": "<system prompt>" }, "description": "<agent description>", "metadata": { "useCaseId": "<use-case-id>", "managedBy": "foundry-agent-sync" } }
| Symptom | Cause | Fix | |---|---|---| | 401 Unauthorized | Token expired or wrong audience | Re-run az account get-access-token --resource https://ai.azure.com/ | | 403 Forbidden | Missing Azure AI User role | Assign the role on the Foundry project scope | | 404 Not Found | Wrong project endpoint | Verify endpoint includes /api/projects/{projectName} | | Model not found | Model not deployed in project | Deploy the model in AI Foundry portal first | | Empty definitions | Manifest path wrong | Check -ManifestPath points to the JSON file |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-23 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +70 percentage points is the difference between those two pass rates over the 23 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.