Inspiration

Voice shopping dies in the gap between "yes" and a receipt. A model can pick a product. It cannot safely reserve stock, capture a card, and undo itself when the capture fails, unless something behind the tool call keeps a ledger. I wanted that something to be a small open-source gateway an Alexa+ agent can call, with the same shape a PayPal sandbox can plug into later.

What it does

Ledgerlane exposes commerce tools over MCP: search a catalog, compare options, build a cart, price a checkout, place an order, track it, and refund it. Place and refund are sagas. If a step fails, completed steps compensate in reverse, so a failed card capture voids the authorization and puts the stock back. Every tool call is written to Postgres with who, what, and why, and a turn can be replayed from that log. Idempotency keys stop a retry from capturing twice.

The page at / is the Alexa+ simulation. Suggested lines run a full order and a failed capture with no API key.

How we built it

The gateway is one Python service. FastMCP serves Streamable HTTP on /mcp and negotiates protocol 2025-11-25. Tools call a commerce service. The saga runner and the audit log are plain code over Postgres, covered by tests that do not need a model. The simulator's agent loop is an MCP client: it lists tools and calls them over HTTP, it does not import the checkout functions directly. The planner is mock by default. LLM_PROVIDER=openai or gemini switches the HTTP client; keys come from the environment.

Alexa+ discovery is sketched for later account linking: unauthenticated /mcp returns 401 without WWW-Authenticate, and the well-known OAuth documents advertise PKCE S256. The demo token is a local stand-in, not Login with Amazon.

The catalog is fictional on purpose, so the demo video does not depend on someone else's trademarks.

Challenges we ran into

  • Alexa+ production onboarding (Alexa AI CLI, a public HTTPS URL, icons, privacy policy, certification) is a different path from the hackathon's web-simulation path. The MCP server is real; it is not yet an Alexa+ add-on, because that needs the entrant's developer account.
  • The MCP Python SDK's built-in bearer middleware emits WWW-Authenticate. Current Alexa+ docs say that header is not supported yet and that a bare 401 is required. The gateway uses its own gate so the header is absent.
  • A single process must accept the simulator's HTTP call and, inside that call, accept the MCP callback. The agent uses an async client so the event loop can serve both.
  • Idempotency has to be decided before the saga, and a refund replay has to win over the "already refunded" check, or a retry looks like a second business error instead of the original receipt.

Accomplishments that we're proud of

  • A checkout that rolls back on a failed capture, with the compensating actions in the audit log in reverse order.
  • The same idempotency key returns the same order and does not authorize the card again.
  • The demo, including that failure, runs from Docker Compose with no model key and no payment key.
  • Tool results are stable ids, so search, compare, cart, quote, and order chain the way Alexa+'s tool guidance asks.

What we learned

An agent that can spend money needs a workflow engine more than it needs a longer prompt. The model should choose the next tool. The server should own confirmation, idempotency, and undo. The audit log is the only way to explain a charge after the conversation is gone.

The hackathon's simulation path is enough to show the interaction. Connecting the same server to Alexa+ still means OAuth, a public URL, and the add-on package. Those are deployment steps, not a reason to skip the protocol.

What's next for Ledgerlane: an agentic commerce MCP gateway

  • Register the MCP server as an Alexa+ add-on once an Alexa developer account and a public HTTPS endpoint are available. Add the privacy policy and terms URLs the manifest requires.
  • Implement PayPalSandboxProvider against the sandbox Orders v2 API for the PayPal AI Hackathon (authorize, capture, void, refund).
  • Point LLM_PROVIDER at Gemini when the lablab agents hackathon dates are real.
  • Chinese docs, a maintenance roadmap, and CI for the Beijing open-source track. Apache-2.0 stays the license.
  • Resume an in_progress saga after a crash, instead of only refusing a second capture.

Testing instructions

docker compose up --build Open http://localhost:4317. Click "Play a full order," then "Play a failed capture." No account and no API key. The MCP endpoint is http://localhost:4317/mcp. Unauthenticated calls return 401. The demo bearer token is demo-shopper-token, documented in .env.example and the README. It is a local demo credential, not a secret from a real user.

Built With

Share this project:

Updates

Submission history