| name | Foundry Toolbox Ops |
| description | Operate the Foundry Toolbox and Foundry-hosted agents for the Fibey project: inspect, version, recreate, and smoke-test. |
| tags | ["azure","foundry","toolbox","mcp","hosted-agents","ops"] |
Foundry Toolbox Ops Skill
You are a specialist for operating the Foundry Toolbox and Foundry-hosted
agents this project depends on. You don't write new agent code โ that's
the Agent Developer skill. You focus on the runtime configuration:
toolbox versions, the connections inside them, the tools they expose, and
the hosted agent that consumes them.
Mental model
Foundry account (e.g. ai-fibey)
โโ Project (e.g. fibey-project-westus2)
โโ Connections/ (CognitiveSearch, OpenAPI, MCP, ...)
โ โโ fibey-search โ used by the knowledge_base tool
โ
โโ Toolboxes/ (logical container)
โ โโ fibey/
โ โโ versions/ immutable snapshots (v1, v2, ...)
โ โโ default_version: "1"
โ
โโ Agents/
โโ fibey-agent references a toolbox via MCP URL
The agent connects via a versioned MCP URL:
{FOUNDRY_PROJECT_ENDPOINT}/toolboxes/{name}/versions/{n}/mcp?api-version=v1
Critical: the unversioned URL โฆ/toolboxes/{name}/mcp always serves
v1 regardless of newer versions or what default_version says. Prefer
the versioned URL when pinning the agent to a specific version. The agent
auto-appends ?api-version=v1 if missing (see src/fibey/agent/agent.py).
Key facts
- Foundry data-plane API version:
v1.
- AAD scope for data-plane:
https://ai.azure.com/.default
(NOT cognitiveservices.azure.com โ that returns 401).
- Toolbox also accepts the Cognitive Services account key via the
api-key header โ Ocp-Apim-Subscription-Key returns 401. We use this
for the deployed agent-service to avoid RBAC quota churn (see
TOOLBOX_API_KEY env var and _ToolboxApiKeyAuth in agent.py).
- Toolbox creation:
POST /toolboxes/{name}/versions. POST /toolboxes
and PUT /toolboxes/{name} both return HTTP 405.
- Connection auth that works for AI Search:
CognitiveSearch + ApiKey
- Foundry tool type
azure_ai_search. The combination RemoteTool +
ProjectManagedIdentity pointing at a KB MCP endpoint returns HTTP 403.
- Subscription
921496dc-... has historically been near its
4000-role-assignment cap. Prefer API-key auth on the toolbox โ
CognitiveSearch connection over granting fresh RBAC where possible.
Required env
Read from .env (root) or .azure/<env>/.env (azd):
| Var | Used for |
|---|
FOUNDRY_PROJECT_ENDPOINT | Data-plane base, e.g. https://ai-fibey.services.ai.azure.com/api/projects/fibey-project-westus2 |
TOOLBOX_MCP_URL | What the agent connects to (versioned MCP URL) |
TOOLBOX_API_KEY | Optional: Cognitive Services account key for api-key auth to the toolbox |
HOSTED_AGENT_NAME | Hosted agent name (hosted mode only) |
HOSTED_AGENT_ENDPOINT | Hosted agent endpoint (gateway hosted mode) |
Get a token to use in curl calls:
TOK=$(az account get-access-token --scope https://ai.azure.com/.default --query accessToken -o tsv)
Inline operations
These replace previous wrapper scripts. Run them from the repo root with
.env already exported (set -a && . .env && set +a).
List toolboxes and inspect a version
TOK=$(az account get-access-token --scope https://ai.azure.com/.default --query accessToken -o tsv)
BASE="$FOUNDRY_PROJECT_ENDPOINT"
curl -fsS "$BASE/toolboxes?api-version=v1" -H "Authorization: Bearer $TOK" | jq
curl -fsS "$BASE/toolboxes/fibey/versions?api-version=v1" \
-H "Authorization: Bearer $TOK" | jq '.data[] | {version, tools: [.tools[].type]}'
curl -fsS "$BASE/toolboxes/fibey/versions/1?api-version=v1" \
-H "Authorization: Bearer $TOK" | jq
Smoke-test the toolbox MCP endpoint
URL="$TOOLBOX_MCP_URL"
TOK=$(az account get-access-token --scope https://ai.azure.com/.default --query accessToken -o tsv)
curl -fsS -X POST "$URL" \
-H "Authorization: Bearer $TOK" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"1"}}}'
Or with the account key (matches deployed agent-service):
KEY=$(az cognitiveservices account keys list -g <rg> -n <account> --query key1 -o tsv)
curl -fsS -X POST "$URL" -H "api-key: $KEY" -H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Recreate a toolbox in a different project
Use when a referenced connection is deleted or the project workspace is at
its 120-connection cap. Clone the source definition, prune fields the API
rejects on create, and POST to the new project.
TOK_OLD=$(az account get-access-token --scope https://ai.azure.com/.default --query accessToken -o tsv)
curl -fsS "$SOURCE_ENDPOINT/toolboxes/fibey/versions/9?api-version=v1" \
-H "Authorization: Bearer $TOK_OLD" > /tmp/source.json
TOK_NEW=$(az account get-access-token --scope https://ai.azure.com/.default --query accessToken -o tsv)
curl -fsS -X POST "$NEW_ENDPOINT/toolboxes/fibey/versions?api-version=v1" \
-H "Authorization: Bearer $TOK_NEW" \
-H "Content-Type: application/json" \
-d @/tmp/body.json | jq
Hosted agent inspection
TOK=$(az account get-access-token --scope https://ai.azure.com/.default --query accessToken -o tsv)
BASE="$FOUNDRY_PROJECT_ENDPOINT"
curl -fsS "$BASE/agents?api-version=2025-11-15-preview" -H "Authorization: Bearer $TOK" | jq
curl -fsS "$BASE/agents/$HOSTED_AGENT_NAME?api-version=2025-11-15-preview" \
-H "Authorization: Bearer $TOK" | jq
Update deployed services after a toolbox/version change
The gateway runs in containerapp mode and proxies to agent-service. The
actually-relevant env vars live on fibey-apps-agent-service:
NEW_EP="https://ai-fibey.services.ai.azure.com/api/projects/fibey-project-westus2"
NEW_TB="${NEW_EP}/toolboxes/fibey/mcp?api-version=v1"
KEY=$(az cognitiveservices account keys list -g rg-fibey-westus2 -n ai-fibey --query key1 -o tsv)
az containerapp secret set -n fibey-apps-agent-service -g rg-fibey-westus2 \
--secrets toolbox-api-key="$KEY"
az containerapp update -n fibey-apps-agent-service -g rg-fibey-westus2 \
--set-env-vars "FOUNDRY_PROJECT_ENDPOINT=$NEW_EP" \
"TOOLBOX_MCP_URL=$NEW_TB" \
"TOOLBOX_API_KEY=secretref:toolbox-api-key"
azd deploy <service> rebuilds the image but does not push env-var
changes for azd-managed container apps. Update env vars via az containerapp update (or azd env set + full azd up/redeploy through bicep wiring).
Standard playbooks
Adopt a new toolbox version
- List versions and confirm the new one exposes the expected tools.
- Update
TOOLBOX_MCP_URL in .env (and .azure/<env>/.env for deployed).
- For containerapp deployment, run the
az containerapp update block above.
- Restart the gateway / agent-service container revision.
- Smoke-test via the agent CLI or a
/api/chat request.
Diagnose "tool not found" / ARA 403 errors
- Check
TOOLBOX_MCP_URL includes /versions/<N>/ โ the unversioned URL is pinned at v1.
- Use the inspect commands above to verify the expected connection exists in that version.
- For Azure Search KB calls, confirm the connection is
CognitiveSearch + ApiKey + azure_ai_search.
- If running deployed: confirm the agent-service MSI has Cognitive Services User / OpenAI User / Azure AI User on the account (these inherit to projects).
Recreate the toolbox in a fresh project (cap or corruption)
- Confirm the new account / project exists (
az cognitiveservices account show, etc.).
- Verify model deployments are present.
- If using AAD: grant the agent-service MSI Cognitive Services User / Cognitive Services OpenAI User / Azure AI User (renamed from "Azure AI Developer") on the new account.
- Create connections in the new project (e.g.
fibey-search โ CognitiveSearch + ApiKey).
- POST the cleaned toolbox payload (see "Recreate" snippet above).
- Update
.env + .azure/<env>/.env + agent-service container app env vars.
Don'ts
- Don't commit
.env, .azure/<env>/.env, or agent.yaml.bak.
- Don't add a
latest alias for toolbox versions โ always be explicit.
- Don't redirect a Python heredoc's stdout to a JSON file;
print() pollutes the file. Open the file inside the script.
- Don't use the Cognitive Services scope (
https://cognitiveservices.azure.com/.default) for data-plane calls โ it 401s.
- Don't grant new RBAC on subscription
921496dc-987f-410f-bd57-426eb2611356 without first freeing existing slots; it hovers near the 4000 cap.