When an assistant places an order for a user, where should money, identity and customer data live?
Put simply: you need a clear, auditable boundary between the AI client and your ecommerce systems, a small, well-defined MCP (Model Context Protocol) server that exposes tool endpoints (search, order, returns, reviews), enforces auth, and calls your backend systems. This pattern uses FastMCP/Python for the application, Amazon Bedrock AgentCore (AgentCore Runtime) to host it, DynamoDB for data, and Cognito (OAuth2/OIDC) for identity so Mistral Vibe or any MCP-compatible client can discover and call your tools.
Why MCP + AgentCore?
MCP standardizes capability discovery (list_tools) and invocation (/mcp), so you avoid brittle point-to-point connectors for every UI. AgentCore Runtime provides a managed host for MCP workloads. It gives session isolation, long-request support and infrastructure-level checks, letting your code focus on business rules and data access instead of container plumbing and auth middleware.
Architecture at a glance
- User authenticates via OAuth/OIDC (the sample uses Amazon Cognito). The client (Mistral Vibe) stores tokens and discovers server tools via list_tools.
- Vibe issues an MCP /mcp call to a tool endpoint with a Bearer token.
- AgentCore Runtime performs infrastructure-level validation (JWT shape, expiry, allowedClients) and routes the request to your container implementing /invocations on port 8080.
- Your FastMCP app maps the validated identity to a customer record (the sample reads a custom:customer_id attribute from Cognito) and executes the requested tool against DynamoDB or downstream services.
The sample implements product search, order placement, review submission and returns processing backed by five DynamoDB tables named Products, Customers, Orders, Reviews and Returns. A DataLoaderStack seeds the dev environment (50 products, 10 customers, 50 orders plus associated reviews and returns).
First 5 minutes checklist
- Clone the sample repo: https://github.com/aws-samples/mistral-on-aws/tree/main/MCP/Ecommerce_MCP_Server
- Install prerequisites: Python 3.10+, Node.js 18+, then npm install -g aws-cdk and pip install bedrock-agentcore.
- Bootstrap and deploy the CDK stacks: cdk deploy –all. The sample deploys four stacks and the authors observed ≈5 minutes in the dev environment.
- Create your test users (Cognito) and seed data using the DataLoaderStack.
- Use the AgentCore CLI to configure and deploy the MCP runtime. Copy the exact agentcore commands from the repo to avoid shell-escaping errors.
Reproducible facts and useful caveats
- Local Docker is optional: AgentCore’s sample workflow uses cloud builds (AWS CodeBuild) to produce ARM64 images and push them to ECR, so you can avoid local cross-architecture builds. Alternatively, use Docker buildx for local ARM64 images.
- AgentCore Runtime containers in this pattern are ARM64 and must expose port 8080 and implement
/invocations. Failing to meet that contract yields exec-format or invocation failures (see AWS runtime docs). - Observed cold-start in the sample dev environment was roughly 10-20 seconds for the first invocation while the container initializes. Treat that as a measured example, not a guaranteed SLA.
- Sample deployment used cdk deploy –all to provision four CDK stacks; the sample authors reported ~5 minutes in their environment.
- Recommended operational sizing in the sample: keep each MCP server focused, with 5-8 well-defined tools, and avoid exposing dozens of overlapping functions to reduce complexity and surface area.
- Cloud and troubleshooting docs to keep handy: the AWS AgentCore runtime troubleshooting page and Mistral Vibe CLI configuration page are the reference points for runtime requirements and client configuration respectively (links in References).
Auth design: why two layers and the trade-offs
Two-layer auth balances security and application needs. AgentCore Runtime can validate JWTs at the infrastructure layer (signature, expiry, audience and allowedClients) so your container does not need to re-check signatures. But access tokens frequently do not include application-specific attributes like a database primary key, so your app still needs to map the validated identity to customer data.
The sample does that mapping by calling Cognito’s admin_get_user or get_user to read a custom attribute (custom:customer_id). Important trade-offs:
- Privilege scope: admin_get_user requires elevated permissions. Grant it sparingly to runtime roles and prefer alternatives where possible.
- Performance vs privilege: an extra Cognito API call per session adds latency and IAM surface. If you can reliably forward a verified claim (customer_id) into the container via AgentCore claim forwarding or include it in the ID token, you can avoid the admin call and reduce privileges.
- Provider compatibility: the admin_get_user fallback works for Cognito; with third-party OIDC providers you’ll need to verify whether the userinfo endpoint or tokens include the attributes you need or implement your own attribute lookup.
Call flow – end to end (compact)
- User logs in via OIDC/OAuth and Vibe receives tokens.
- Vibe calls list_tools on the MCP discovery endpoint to learn available tool schemas.
- User asks “Show me my recent orders”. Vibe calls the order-list tool at /mcp with the access token.
- AgentCore validates the token at the infra layer and routes the request to your /invocations endpoint.
- Your app resolves the customer (Cognito lookup or forwarded claim), queries DynamoDB, formats a natural-language response and returns it to Vibe.
Operational must-dos and gotchas
- MMDSv2 is required by deadline: per AWS docs, runtimes must use MMDSv2 starting June 30, 2026, call UpdateAgentRuntime with requireMMDSV2=true during runtime updates to avoid blocked invocations.
- /invocations on port 8080: the runtime contract requires your container to listen on port 8080 and implement the /invocations path; missing either causes 504s or timeouts.
- ARM64 images: exec-format errors are common if you ship x86 images. Use buildx locally or the cloud-build path (CodeBuild) to produce ARM64 images.
- Public ECR auth: 403s pulling public ECR base images are a frequent build failure, authenticate to ECR Public or choose alternate base images.
- Long-running work and /ping: AgentCore supports long requests but enforces idle timeouts (the sample behavior observed ~15 minutes). Return {“status”:”HealthyBusy”} from your /ping while background work runs and manage the runtime heartbeat (time_of_last_update) carefully so you don’t leak sessions or keep them alive indefinitely.
- AgentCore CLI and config: CLI flags and JSON arguments are easy to copy/paste wrong. Use the exact agentcore configure/deploy commands from the sample repository to avoid shell-escaping issues.
Practical hardening checklist
- Enable MMDSv2 on runtimes (UpdateAgentRuntime requireMMDSV2=true), operationally critical by the 2026 deadline.
- Place AWS WAF or equivalent in front of your AgentCore Gateway and start with IP rate limits, JSON payload size limits and basic bot protections.
- Apply least-privilege IAM: scope runtime roles to only the specific DynamoDB tables, SSM parameters and ECR repositories required; avoid broad Cognito admin rights if you can forward claims instead.
- Limit tools per server (5-8) and connectors per server (5-6) to reduce complexity and attack surface, this is a recommended operational heuristic born from small-scale testing, not a hard limit.
- Validate tool inputs at the infra/policy layer (AgentCore Policy) to guard against parameter abuse and simple prompt injection; use strict schemas and parameter whitelists.
- Instrument CloudWatch for session counts, invocation 5xx/504 rates, CodeBuild failures and DynamoDB throttling; use EventBridge to react to important order events and alerts.
Troubleshooting quick hits
- Exec-format error → rebuild for ARM64 (buildx) or use CodeBuild cloud builds.
- 403 pulling public ECR base images → authenticate to ECR public or switch base images.
- “Unknown service” when calling AgentCore APIs via boto3 → upgrade boto3/botocore to the versions listed in the runtime troubleshooting docs.
- Sessions terminating mid-work → implement /ping that returns HealthyBusy while progress continues and avoid resetting time_of_last_update on every heartbeat.
- Missing customer_id in tokens → fallback to admin_get_user/get_user or configure claim forwarding so the token or userinfo endpoint contains the attribute.
What the sample intentionally leaves for you to decide
- Cost and performance sizing, cold-starts, session quotas, sustained AgentCore runtime costs and DynamoDB capacity will depend on your traffic profile; run load tests and consult AWS pricing.
- Complete least-privilege IAM JSON and production dashboards, the sample provides a development-focused setup; craft stricter policies for production.
- AgentCore Policy rules for parameter enforcement, the sample describes the capability but does not ship a full rule set; add checks tailored to your domain.
- Multi-tenant scaling and data isolation at high scale, design partition keys and GSIs for your query patterns and plan throttling/limits accordingly.
- Prompt-injection mitigation beyond strict schemas, consider response sanitization and result redaction for any PII or payment-related outputs.
References
- AWS, AgentCore Runtime troubleshooting and runtime requirements: https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-troubleshooting.html
- Mistral, Vibe Code CLI configuration (mcp_servers, tool permissions): https://docs.mistral.ai/vibe/code/cli/configuration
- Sample project and full code: github.com/aws-samples/mistral-on-aws/MCP/Ecommerce_MCP_Server
Key questions (and short answers)
- How does AgentCore handle authentication?
AgentCore Runtime can be configured to validate JWT/OIDC tokens at the infrastructure layer (signature, expiry and allowedClients), but your application typically still maps that verified identity to internal records (the sample reads custom:customer_id from Cognito). Verify claim-forwarding options in your AgentCore control-plane configuration if you want to avoid extra user lookups.
- Do I need Docker locally to build the MCP image?
No, the sample uses cloud builds (AWS CodeBuild) to create ARM64 images and push them to ECR, removing the need for local Docker cross-builds. If you prefer local builds, use Docker buildx and target ARM64.
- What are the most common deployment failures?
Typical traps: shipping x86 images (exec-format errors), failing to expose /invocations on port 8080, public ECR 403 errors during base-image pulls, and not enabling MMDSv2 when updating runtimes (see the AWS runtime docs for the MMDSv2 deadline).
- How many tools should an MCP server expose?
Keep it focused: the sample recommends 5-8 well-defined tools per server and 5-6 active connectors to limit complexity. This reduces policy surface and simplifies input validation and rate limiting.
- What are the critical production hardening steps?
Enable MMDSv2 for runtimes, apply least-privilege IAM, front the gateway with W