Skip to main content
A voice quality alarm fires at 3am. Rather than paging an engineer to open Operata and start querying, a Lambda hands the incident to a Claude model on Amazon Bedrock. The model queries your live Operata data and comes back with the cause: 130 calls averaging a mean opinion score (MOS) of 2.93, jitter at three times the fleet baseline, and round-trip time near half a second — all of it on one internet service provider in one city. That model reaches Operata through Amazon Bedrock AgentCore Gateway, a managed tool-access layer that holds your Operata credential and exposes the Operata MCP tools to the model. This page is for engineers running an AWS Lambda function that already orchestrates incident response. The job is to stand up the gateway, then call Operata tools from a Bedrock tool-calling loop.

operata/operata-mcp-recipes

The runnable version of everything on this page: the deploy scripts, the Lambda code, and a teardown. Fork it, set six values, run three scripts.

Use cases

The shape is the same wherever something automated needs evidence from Operata:
  • A monitoring alarm fires. The Lambda passes the alarm detail to the model, which queries traces and agent reports, and posts a diagnosis to the incident channel before anyone opens a dashboard.
  • A support ticket arrives naming a bad call. The Lambda passes the contact ID, and the model returns that call’s media quality, the agent’s device and network conditions, and what the agent reported.
  • A scheduled run each morning. The model compares yesterday against the fleet baseline and writes up the sites, carriers, or agents that moved.
Each one is the same gateway and the same tool-calling loop, with a different trigger and prompt.

How it works

Your Lambda keeps owning the workflow. The gateway sits between it and Operata, and the Operata API key lives in the gateway rather than in your function. The gateway authenticates on both sides. Inbound is AWS_IAM, so the Lambda execution role signs each request with SigV4 — no Amazon Cognito user pool, no client secret, and no token cache to run. Outbound is the Operata API key, which the gateway reads from the credential provider and sends as a bearer token.

Before you start

  • An AWS account with Bedrock model access for Claude, in a region where AgentCore Gateway is available. This recipe was deployed and verified in us-west-2.
  • Permission to create IAM roles, AgentCore gateways and targets, and a Lambda function.
  • git, AWS CLI v2, curl 7.75 or later, jq, and zip. The scripts sign gateway calls with curl --aws-sigv4.
  • An Operata API key, created in the Operata console at app.operata.io under Group Settings → API Management → Create New Key.
Use that key against the API-key MCP endpoint, https://api.operata.io/v1/mcp.

Why this recipe uses an API key

Operata’s authorization server advertises the authorization_code and refresh_token grant types. Every OAuth token it issues is bound to a person who consented in a browser, which does not suit a Lambda that a monitoring alarm triggers with nobody present. The API-key endpoint is the path for unattended callers. For a Lambda, that trade is narrow: the key is fixed to one Operata group, and all activity is attributed to the key rather than to an individual. See Choose how to connect for how the two paths differ across clients.

Quickstart

deploy-gateway.sh checks your key against Operata before it creates anything in AWS, so a rejected key fails in the first few seconds rather than part-way through. Both deploy scripts are re-runnable: they reuse what exists and update it in place. ./scripts/teardown.sh removes everything they made. The rest of this page explains what those scripts build, so you can read the result or rebuild it yourself.

What the deploy creates

Four AWS resources, in order. Each one exists for a reason worth knowing before you run it.

A gateway service role

The gateway assumes this role to fetch your Operata key at call time. Trust bedrock-agentcore.amazonaws.com, and condition that trust on your own account so no other account can assume it:
The role’s policy grants three things: bedrock-agentcore:GetWorkloadAccessToken and GetResourceApiKey to fetch the credential, secretsmanager:GetSecretValue on arn:aws:secretsmanager:<region>:<account-id>:secret:bedrock-agentcore* to read where AgentCore stored it, and SynchronizeGatewayTargets to re-index the tool catalogue.

A credential provider holding the Operata key

AgentCore Identity takes the key and writes it to AWS Secrets Manager under a bedrock-agentcore prefix, which is what that secret ARN pattern above matches. The key never reaches your Lambda, your deployment package, or the model. Only the gateway reads it.

The gateway

Two parameters carry the design. --authorizer-type AWS_IAM is what removes the token plumbing: callers prove who they are with SigV4, using credentials they already hold. searchType: SEMANTIC adds a tool the model can use to search the tool catalogue, so it carries fewer schemas in context. The scripts also set exceptionLevel: DEBUG, which returns readable target errors while you build. Remove it before production, because it exposes upstream detail in responses.

A target pointing at Operata

The target names the Operata endpoint and says where the credential goes. Operata authenticates with Authorization: Bearer <api key>, so the key goes in the standard header with a Bearer prefix:
Creating the target makes the gateway call tools/list upstream and index what it finds, so the target reaching READY confirms the key and the endpoint agree. The target name becomes a prefix on every tool it exposes. With the target named operata, the traces_query tool arrives as operata___traces_query — three underscores. Full scripts, including the polling and the re-run handling: scripts/deploy-gateway.sh.

Verify

The gateway returns 13 tools. Twelve are Operata’s, each carrying the target name as a prefix:
MCP tool reference documents what each one takes and returns. The thirteenth, x_amz_bedrock_agentcore_search, comes from the gateway because searchType is SEMANTIC. It lets the model search the tool catalogue instead of carrying every schema in context. To exercise the credential against a single tool, call one directly:

Use it in your own Lambda

Three files in lambda/ are the whole integration:
  • mcp_gateway_client.py — an MCP client that signs each request with SigV4 and negotiates the protocol version from what the gateway advertises. Standard library and botocore only, both already in the Lambda Python runtime, so the deployment package needs no vendored dependencies.
  • incident_agent.py — the Bedrock Converse tool-calling loop.
  • handler.py — turns an incident event into a prompt and returns the diagnosis with a trace of every tool call.
Copy the first two into an existing function and set GATEWAY_URL and MODEL_ID. The loop itself is short — hand the gateway’s tools to converse, run whatever the model asks for, and send the results back until it stops asking:
Return a tool failure to the model as a toolResult with status: "error" rather than raising. The model reads the message and adjusts its next call. Beyond writing logs, the execution role needs two statements: bedrock:InvokeModel, and bedrock-agentcore:InvokeGateway on the gateway ARN. That second one is the inbound half of AWS_IAM auth — the role itself is what authorizes the call.

What you get

run-incident.sh prints each tool call the model makes, then its diagnosis. One run against the sample incident took 9 turns and 12 tool calls. The model chose the sequence itself, starting with get_schema so the fields in its later queries would exist. Its conclusion: 130 calls averaging MOS 2.93 against a fleet baseline of 3.90, with jitter at 37.8 ms against 11.3 ms and round-trip time at 458 ms against 95 ms — all on one internet service provider in one city, which is narrow enough to raise with that provider.
These figures, and the ones in the opening, come from a single account on one day. Your turn count, token count, and numbers will differ.

Limits

  • An API key is fixed to the group it was created in. Calling switch_group for a different group returns 403 "API key access is restricted to its own group". Switching to the key’s own group succeeds.
  • 100 requests per minute per key, shared across every caller of the gateway. See Rate limits.
  • The gateway indexes the tool list when you create the target. After Operata changes a tool, re-run deploy-gateway.sh or call SynchronizeGatewayTargets to pick up the new schema.
  • Remove exceptionLevel: DEBUG before production.

Troubleshooting

More failure modes in MCP troubleshooting.