AWS Harness — AgentCore Harness deployment¶
Warning
Status: Preview. AgentCore Harness is a managed agent layer announced at AWS re:Invent 2025 — currently in preview with limited regional coverage. This integration tracks the preview API surface; expect breaking changes before GA.
This guide covers the deployment of the Zscaler MCP Server as an AgentCore Harness tool. For the existing AgentCore Runtime deployment (Direct Runtime + experimental Gateway), see Amazon Bedrock AgentCore Deployment.
Pick a topology¶
The script supports two end-to-end deployment shapes. Pass --topology (or set TOPOLOGY in .env); omit both and the script prompts interactively.
Topology |
Tool type |
MCP server runs on |
IdP |
When to pick |
|---|---|---|---|---|
|
|
ECS Express Mode service (Fargate + auto-ALB) |
n/a (Basic auth from Token Vault) |
Simplest path; fewest moving parts; no Cognito to manage. |
|
|
AgentCore Runtime (managed) |
Amazon Cognito |
No ALB / ECS / Fargate. Same Gateway can later front other MCP clients (Cursor/Claude/Strands) with a real OIDC login. |
ecs topology gateway topology
───────────────────── ─────────────────────────
User ──SigV4──► Harness User ──SigV4──► Harness
│ │
│ remote_mcp │ agentcore_gateway
│ (Token Vault Basic) │ (Token Vault OAuth)
▼ ▼
ECS Express AgentCore Gateway
(ALB+HTTPS) (CUSTOM_JWT Cognito)
│ │
▼ │ OAuth2 outbound
MCP container ▼
AgentCore Runtime
(jwt Cognito)
│
▼
MCP container
What is AgentCore Harness?¶
Harness is a managed agent. You declare model, systemPrompt, tools, memory, and limits once via bedrock-agentcore-control:CreateHarness; AWS runs the agent loop. Under the hood it is Strands Agents on AgentCore Runtime — both still exist; Harness is just the higher-level surface AWS now markets as the go-to-production path.
Property |
Detail |
|---|---|
Service |
Amazon Bedrock AgentCore — |
API |
|
boto3 |
≥ 1.43.0 (earlier versions don’t expose the API) |
Tools |
|
Auth |
Static |
Memory |
Optional (AgentCore Memory). Opt-in per harness. |
Observability |
Auto-emitted to CloudWatch under |
The Zscaler MCP Server fits exclusively as a ``remote_mcp`` tool — a URL Harness will call over HTTPS with whatever headers we configure.
Critical constraint — remote_mcp headers are static¶
Harness’s remote_mcp tool can only send static ``Authorization`` headers. It has no SigV4 signer. That means:
A SigV4-protected AgentCore Runtime URL will not work as a
remote_mcptarget. Pointing Harness athttps://bedrock-agentcore.<region>.amazonaws.com/runtimes/...produces HTTP 403 on every invocation.Recommended: let this script deploy the MCP server to ECS Express Mode (default path — auto-managed ALB + HTTPS). Or stand it up yourself behind any other non-SigV4 endpoint and pass the URL via
MCP_URL=….Alternative (now shipped): AgentCore Gateway between Harness and a SigV4 Runtime URL — the Gateway does the OAuth → SigV4 protocol switch for you. Set
--topology gateway(orTOPOLOGY=gateway).
Prerequisites¶
Requirement |
Notes |
|---|---|
AWS account with AgentCore Harness preview access |
Currently limited to a subset of regions. Confirm via |
AWS CLI / boto3 credentials |
The script uses the default credential chain. |
Python 3.10+ |
One runtime dependency ( |
Bedrock model access |
At minimum the Claude Sonnet 4.6 inference profile (or whichever model you pick). Anthropic models additionally require a one-time use-case form in the Bedrock console. |
Permission to call |
Granted by |
Default VPC in the target region |
ECS Express auto-selects subnets + security groups from the default VPC. |
AWS Marketplace subscription to Zscaler MCP Server |
Free (BYOL). Required if you let the script use the default Marketplace image. |
|
The Marketplace image is multi-arch; dev builds must include ``linux/amd64``. |
Zscaler OneAPI credentials |
|
Install¶
cd integrations/aws/harness
uv venv .harness-venv --python 3.11
source .harness-venv/bin/activate
uv pip install -r requirements.txt
Configure¶
Copy the template and fill in your Zscaler credentials:
cp env.properties .env
${EDITOR:-vim} .env
You can also pass values as CLI flags or let the script prompt you interactively — env.properties is for convenience.
Deploy¶
python harness_mcp_operations.py deploy --region us-east-1
The script walks the full stack in one run (≈4-5 minutes — most of it is the ECS Express ALB + target group health-check warm-up). The deploy creates:
ECS task execution + infrastructure roles — for cross-account ECR pull, CloudWatch Logs, and the auto-ALB provisioning.
ECS cluster (
zscaler-mcp) — created if missing; preserved on destroy if it pre-existed.CloudWatch log group (
/ecs/zscaler-mcp).ECS Express service (
zscaler-mcp-server) — singleCreateExpressGatewayServicecall provisions ALB + target group + security groups + auto-scaling. Returns a stable public HTTPS endpoint of the formxxxxx.ecs.<region>.on.aws.AgentCore Identity Token Vault credential provider (
zscaler-mcp-creds) — storesBasic base64(client_id:client_secret).AWS IAM Harness execution role (
zscaler-mcp-harness-execution-role) — mirrors the AWS-published harness execution role policy.AgentCore Harness (
zscaler-mcp-harness) — wired to a model + system prompt + theremote_mcptool block pointing at the ECS Express URL with the Token Vault credential provider as theAuthorizationsubstitution target.
State persisted to .aws-harness-state.json (gitignored).
What success looks like¶
── Deployment summary ─────────────────────────────────────────────────────────
HarnessId = zscaler-mcp-harness-AbCdEfGhIj
HarnessArn = arn:aws:bedrock-agentcore:us-east-1:111122223333:harness/zscaler-mcp-harness-AbCdEfGhIj
Model = us.anthropic.claude-sonnet-4-5-20250929-v1:0
MCP URL = https://abc123.ecs.us-east-1.on.aws/mcp
MCP Host = ECS Express — zscaler-mcp-server (cluster: zscaler-mcp)
Execution Role = arn:aws:iam::111122223333:role/zscaler-mcp-harness-execution-role
Credential Provider = arn:aws:bedrock-agentcore:us-east-1:111122223333:token-vault/default/apikeycredentialprovider/zscaler-mcp-creds
Lifecycle commands¶
python harness_mcp_operations.py status --region us-east-1
python harness_mcp_operations.py logs --region us-east-1
python harness_mcp_operations.py invoke "list my zpa segment groups" --region us-east-1
python harness_mcp_operations.py destroy --region us-east-1 [--yes] [--keep-role] [--keep-ecs]
Command |
Description |
|---|---|
|
End-to-end walk-through. Idempotent on re-deploy — reuses existing ECS cluster, ECS Express service, IAM roles, log group, and credential provider when they already exist by name. |
|
|
|
Tails the auto-managed AgentCore runtime log group under |
|
One-shot smoke test: opens an |
|
Reverse-order tear-down. Use |
Authentication design¶
The Zscaler MCP Server has five auth modes (OIDCProxy, JWT, API Key, Zscaler, None). Harness’s remote_mcp tool pairs with them as follows:
MCP auth mode |
Harness header config |
Recommended? |
|---|---|---|
Zscaler |
|
Yes — this script’s default. Rotation handled by Token Vault. |
API Key |
|
Yes, if you’d rather use a static bearer instead of OneAPI. |
JWT |
|
Less common. JWT is usually short-lived. |
OIDCProxy |
Use |
Topology C. The OIDC flow can’t run from inside |
None |
No |
Dev / testing only. Do not deploy without auth. |
Secrets Manager — where Zscaler credentials live¶
By default this script does not put ZSCALER_CLIENT_SECRET in the ECS task definition as plaintext env vars. The five-key credential bundle goes to AWS Secrets Manager and the container fetches it at boot.
Mode |
How to activate |
Lifecycle |
|---|---|---|
Default — script-managed secret |
Leave |
|
Bring-your-own secret |
Set |
The script verifies the secret exists, scopes the IAM policy to its ARN, but never overwrites the value or deletes the secret — even on |
Plaintext opt-out (dev/debug only) |
Pass |
Restores the legacy behaviour where the 5 credential keys go straight into the ECS task definition. Production deploys should never use this. |
Troubleshooting (highlights)¶
Symptom |
Cause / Fix |
|---|---|
Harness playground returns |
Harness execution role is missing one of the AWS-mandated grants — most commonly |
|
AgentCore Identity does multiple distinct IAM authz checks per |
|
No AWS creds resolved. |
|
Harness preview not available in that region. Pick a region from the AWS preview list. As of writing, |
|
Invalid characters in |
First |
FastMCP’s DNS-rebinding guard rejects every request whose |
|
The image at |
The full Harness troubleshooting matrix lives in integrations/aws/harness/README.md.
Where to go next¶
Amazon Bedrock AgentCore Deployment — the AgentCore Runtime deployment path (the URL we co-deploy from here, or the alternative if you don’t need Harness at all).
Strands Agent client for AgentCore Runtime — local terminal client for the AgentCore Runtime path; the equivalent for the Harness path is the
invokesubcommand of the Harness script.