Inspiration

We started with Albugent, a data-governance engine we'd already built — it scores datasets for risk (PII exposure, pipeline centrality, freshness) and halts anything above a threshold pending human review. When Amazon opened an Alexa+ track for autonomous-agent commerce, the parallel was immediate: an AI agent completing purchases on someone's behalf has the exact same shape of risk as a pipeline touching sensitive data — except the "dataset" is now real money. We didn't want to build a purchase assistant. We wanted to build the thing that watches the purchase assistant.

What it does

Alguard sits between Alexa+ and any purchase, booking, or subscription it tries to complete on a customer's behalf. Every attempt is scored on category risk (gift cards, crypto, and wire transfers score higher than groceries), behavioral anomalies (a brand-new merchant, an amount that's a statistical outlier for that category, a duplicate attempt within a short window), and the agent's own accumulated trust score. Ordinary purchases complete instantly. Risky ones are halted — not silently, but with an explanation — and can only be approved or denied through a separate, account-linked channel the voice assistant itself has no access to. The rule we built the whole system around: the system that requests a risky action can never approve it itself.

How we built it

The MCP server (Streamable HTTP, spec 2025-11-25+) exposes exactly three tools to Alexa+: attempt a purchase, check a session's status, and read an audit trail. Nothing resembling "approve" exists in that tool list — approval lives in a completely separate FastAPI service (Tier 2), reachable only through what would be an authenticated end-user channel in production. Caller identity comes from a real OAuth 2.1 resource-server implementation we wrote (JWT + JWKS verification via PyJWT), not from a parameter the model could fill in itself. Every completed purchase writes a real receipt to a durable ledger. The risk engine itself — category severity, anomaly detection, an owner-scoped circuit breaker that holds further non-low purchases until the human resolves the halt — is a direct architectural port of Albugent's dataset-risk logic.

Challenges we ran into

We hit real, external friction, not just code bugs. The mcp Python SDK went through a breaking major-version change mid-project (1.x → 2.0.0, renaming FastMCP to MCPServer and changing the Streamable HTTP client's signature) with no compatibility shim, which silently broke our first working demo. We also tried to get real Alexa+ MCP Toolkit access to test against the actual client — that's gated behind a Private Preview partners program, and Amazon's own hackathon organizers confirmed publicly that participants aren't expected to have it. We adjusted by building a faithful client-side simulator instead. On re-reading Amazon's own Functional Requirements checklist, we also caught a real bug in our own code: our purchase category was free text matched by substring, so "gift card" (a space) versus "gift_card" (an underscore) would have silently missed a high-risk category. Fixed by making category a closed enum in the tool schema.

Accomplishments that we're proud of

The whole flow runs end to end, for real: a low-risk purchase completes automatically, a high-risk one halts with a real explanation, a later purchase correctly inherits the open circuit state, and approval only ever happens through the separate Tier 2 service — never through the assistant, even if you ask it directly. We also built and tested a real OAuth 2.1 token verifier (not a stub) that validates actual signed JWTs against a JWKS endpoint, ready to point at any real authorization server the moment account linking is configured.

What we learned

MCP's "declare only what you honor" principle cuts deeper than it first sounds — we initially had the calling agent supply its own identity as a tool argument, which would have let any caller impersonate any other agent and quietly defeat our own trust-score logic. The fix wasn't a bigger prompt; it was removing the parameter from the schema entirely and reading identity off the authenticated request context instead. Security boundaries that live in what an LLM is told are advisory. Security boundaries that live in what tools don't exist are real.

What's next for Alguard

Connecting to a real authorization system for account-linked approval, wiring up real purchase receipts by email, and — if access opens up — testing this against the real Alexa+ client instead of our own simulator.

We also red-teamed our own design. High-severity categories are already a hard rule (they halt regardless of trust), and repeat behavior is tracked per authenticated caller across sessions — so two of the early red-team gaps are closed. One gap remains and needs more than a parameter change: our amount check catches sudden spikes but not a slow, deliberate drift upward, because the historical mean it compares against shifts along with the drift itself. Catching that needs trend detection against transaction order (a regression slope or an exponentially-weighted moving average), not just a point-wise outlier check — and it needs real transaction volume per customer to be statistically reliable, which we don't have yet with a handful of test purchases.

What's next for Alguard

Built With

  • 2.1
  • addon
  • alexa-ai-cli
  • amazon-web-services
  • fastapi
  • fastmcp
  • httpx
  • item
  • json
  • jwks
  • jwt
  • mcp
  • mcp-spec-2025-11-25
  • model-context-protocol
  • oauth-2.1
  • pyjwt
  • python
  • python-3.11
  • streamable-http
  • uvicorn
Share this project:

Updates

Submission history