Inspiration

In Open Banking and multi-provider payments, a single customer intent — send money, pay a bill, or buy airtime — can be served by several providers, each with different capabilities, availability, and policies. A conversational assistant may understand the request, but understanding alone is not enough. The system must also determine whether the action is permitted, route it to an eligible provider, execute it safely, and establish what actually happened. In payments, an incorrect answer is not merely a bad response; it can mean a lost transaction or, worse, a duplicate charge.

Agentic Switcher was built on one principle: AI should make financial transactions easier to request without giving a model unrestricted control over money movement. The agent proposes. Deterministic services decide. The Switcher routes. The transaction engine records the truth.

This submission demonstrates that architecture end-to-end using Amazon's agentic stack, exposed through a self-hosted Model Context Protocol (MCP) server.

What it does

Agentic Switcher is a working prototype of the orchestration layer that Open Banking requires. It combines a conversational interface with deterministic policy enforcement, controlled multi-vendor routing, and durable transaction-state management. The current end-to-end demonstration focuses on one use case: MTN airtime.

A user states what they want in natural language. The system gathers missing details, presents a transaction summary, and requires explicit confirmation before execution. The confirmed request is validated against a capability registry, checked by a deterministic policy guard, routed by the Switcher to an eligible vendor, executed through a controlled MCP business tool, and recorded by the transaction state machine.

The explanation presented to the user is derived from the transaction record. The system does not invent success or failure.

A central design principle is that an uncertain outcome must remain uncertain. If a vendor timeout leaves a transaction unconfirmed, the system reports UNKNOWN rather than incorrectly claiming success or failure. It does not automatically retry the transaction, because doing so could create a duplicate purchase.

The current prototype uses simulated MTN airtime vendors. It does not execute real airtime purchases or move real money. Vendor adapters sit behind a stable interface, allowing a real provider to replace a simulator without changing the agent, policy, routing, or explanation layers.

How we built it

The backend uses Python 3.12, FastAPI, Pydantic, PostgreSQL, SQLAlchemy, and Alembic. Its architecture separates request handling, deterministic planning and routing, policy enforcement, vendor adapters, transaction persistence, and outcome reporting. Each layer has a defined responsibility.

The integration surface is a self-hosted MCP server over Streamable HTTP, providing the protocol boundary for the Alexa+ track. It exposes three business tools:

  • find_transaction_capabilities
  • execute_transaction
  • get_transaction_status — read-only

These tools expose controlled business capabilities rather than unrestricted access to vendor APIs. A policy-denied request returns a structured denial without performing a capability lookup or submitting a vendor transaction.

Every chat response carries the actual MCP tool calls made by the backend for that turn. The frontend displays this activity as a read-only trace, providing evidence of the operations performed rather than a scripted or scenario-derived list. Values are sanitized at the MCP boundary: credentials and idempotency keys are redacted, and personal identifiers are masked. The trace is populated from actual tool invocations, including relevant error paths.

The transaction engine is authoritative for execution state and outcomes. Confirmation and cancellation are submitted only through explicit, button-driven actions, mutually exclusive with free-text input. Typing "yes" or "cancel" alone cannot execute or cancel a transaction.

The frontend is presentation-only. It cannot supply vendor choices, idempotency keys, account balances, or fabricated transaction statuses.

The frontend uses React 19, TypeScript, and Vite. It provides an interactive demonstration in which judges can explore transaction scenarios and inspect MCP activity.

The current demonstration uses deterministic planning. A Bedrock Converse provider has been implemented and unit-tested behind the existing LLMProvider contract, but connecting a language model to the live execution path remains future work.

Challenges we ran into

The hardest problem was separating interpretation from decision-making. A conversational request may include a preferred vendor, and a language model may suggest where the transaction should go. However, the Switcher must remain the authority that determines where execution occurs.

We enforced this separation structurally: the planner's vendor suggestion is advisory, the Switcher routes independently, and the MCP boundary rejects inputs that would allow the caller to control routing.

The second challenge was handling uncertainty honestly. A timeout does not necessarily mean a transaction failed; a vendor may have processed the request without returning a usable response. Reporting FAILED would be misleading, while retrying could be dangerous. We introduced an explicit UNKNOWN state (ADR-003), which is neither reported as success nor automatically retried. This principle shapes the transaction lifecycle and outcome reporting.

The third challenge was demonstrating the architecture within the hackathon's constraints. Real vendor integrations were outside the scope of the prototype, and a full Alexa+ device integration was not available to participants. We chose the self-hosted MCP server approach permitted by the track, built a presentation-only web demo that exposes the real MCP activity trace, and identified direct Alexa+ integration as future work.

We also had to be precise about the guarantees provided. The conversational path generates a new idempotency key for each request, so repeating the same intent is not universally deduplicated across requests. The equivalent-unresolved-operation guard prevents duplicate submissions while an equivalent operation remains unresolved. We do not claim a universal exactly-once execution guarantee.

Documenting the limitations and protocol issues encountered with the MCP Python SDK also helped us describe the implementation accurately rather than making unsupported claims about protocol behavior.

Accomplishments that we're proud of

We built a working transaction pipeline and an interactive web demo that make key architectural claims verifiable through the application rather than relying only on documentation.

  • Multi-turn transaction flow: The system gathers missing details, presents a transaction summary, and requires explicit confirmation before execution.
  • Deterministic policy enforcement: Disallowed actions are denied before vendor execution. The MCP activity trace makes the denial visible.
  • Controlled multi-vendor routing: When Vendor A is unavailable, the Switcher can select an eligible alternative, such as Vendor B.
  • Independent routing decisions: The planner's suggested vendor remains advisory; the Switcher determines the actual execution route.
  • Honest outcome handling: Unconfirmed transactions remain UNKNOWN instead of being incorrectly reported as successful or failed, and they are not automatically retried.
  • Persistent transaction records: Transaction state and simulator operation ledgers are persisted in PostgreSQL through SQLAlchemy and Alembic.
  • Evidence-backed MCP tracing: The frontend displays actual tool calls with sensitive values sanitized at the protocol boundary, including when an operation encounters an error.
  • Backend-authoritative execution: The frontend cannot supply vendor choices, idempotency keys, balances, or transaction statuses. The MCP boundary enforces controlled access to business operations.
  • Regression-tested safety: The project includes 495 backend tests and 169 frontend tests across 13 frontend test files, covering transaction behavior, policy enforcement, reconciliation, and important integration boundaries.

Together, these capabilities demonstrate how an agentic transaction system can combine conversational convenience with deterministic controls and auditable outcomes.

What we learned

We learned that a useful transaction agent requires much more than natural-language understanding. It needs explicit business policies, controlled tool access, deterministic routing, durable transaction state, and truthful handling of uncertain outcomes.

Language models can help interpret user intent, but they should not independently decide whether a transaction is permitted, which provider executes it, or whether an ambiguous vendor response means the transaction succeeded.

We also learned to maintain a firm boundary between the conversational interface and the transaction system behind it. The interface can evolve into a web application, voice assistant, or future Alexa+ experience, but transaction authorization, execution, and outcome determination must remain under deterministic backend control.

Finally, we learned that documenting integration friction is valuable engineering work. Recording the MCP SDK issues encountered and the approaches used to resolve them helped us make implementation decisions explicit and communicate the system's actual capabilities and limitations.

What's next for Agentic Switcher

The next milestone is real provider integration. Vendor adapters already sit behind a stable interface, allowing a licensed API consumer — such as a bank, fintech, or Open Banking aggregator — to replace a simulator without changing the agent, policy, routing, or explanation layers.

Three capabilities would help close the gap between this prototype and a production orchestration layer:

  1. Customer consent management: Capture and enforce consent scoped to the specific data and transaction being authorized.
  2. Tenant usage metering: Measure API usage per tenant to support billing and reconciliation across settlement windows.
  3. Regulatory sandbox participation: Apply for an appropriate regulatory sandbox to evaluate the system under supervision and, where authorized, with real customers.

We also plan to evaluate how language-model reasoning and additional AWS agent capabilities can improve request interpretation through the existing LLMProvider contract without compromising deterministic execution controls.

Our longer-term goal is to build an orchestration layer for Open Banking in Nigeria: one capable of routing across heterogeneous bank and payment APIs, enforcing policy and consent before execution, explaining transaction outcomes truthfully, and metering usage for billing and settlement.

That is the problem Agentic Switcher is designed to address.

Built With

Share this project:

Updates

Submission history