Inspiration

Haruspex scores every US stock 0–100 across AI-analyzed signals: earnings, sentiment, institutional flows, options flow, short interest, technicals and more. Until now you had to be at a keyboard to use it, in a chat app, an IDE, or our site. But the questions people ask about stocks are quick and spoken: "How's Nvidia looking today?", "Anything moving on my watchlist?". Alexa+ taking MCP servers as add-ons meant we could put Haruspex where those questions actually get asked: at the kitchen counter, on the way out the door.

What it does

Haruspex for Alexa+ lets you ask about any US-listed stock by voice and get a short spoken briefing: the Haruspex Score, the outlook, how it changed since yesterday, and which signals are driving it. On an Echo Show you also see the dimension breakdown. You can ask follow-ups ("why did it drop?") and hear the recent news behind the move.

Each user links their own Haruspex account once in the Alexa app, so scores, plans and usage credits stay per user. Haruspex provides quantitative signals for information only, not investment advice, and the briefings say so.

How we built it

  • Remote MCP server. We already had an open-source MCP server (haruspex-skills) that ran locally over stdio. We split it into a shared core with two entry points: the original stdio mode and a new Streamable HTTP endpoint implementing MCP spec 2025-11-25, which Alexa+ requires. It's stateless (a fresh server and transport per request), so it scales horizontally with no session affinity.
  • Hosting. It runs as a container on Google Cloud Run, built from its own Dockerfile through a Cloud Build pipeline.
  • Account linking. We built an OAuth 2.1 authorization server into the same service: authorization code with mandatory PKCE S256, rotating refresh tokens, and a discovery document at /.well-known/oauth-authorization-server. On the link page the user signs in with Google and confirms their Haruspex API key once. We check the key against Haruspex before storing it, encrypted with AES-256-GCM, in Firestore. Tokens and codes are stored only as SHA-256 hashes, and a Firestore TTL policy cleans up expired ones.
  • Tools Alexa sees: get_stock_score, get_stock_score_history, get_batch_scores, search_stocks and get_stock_news, all backed by the live Haruspex API.
  • Tests. An end-to-end suite covers the whole linking flow over real HTTP against a stub Haruspex API: PKCE enforcement, single-use codes, client authentication, refresh rotation, and MCP calls reaching the API with the right user's key.

Challenges we ran into

  • Protocol generation gap. Our server was on an early MCP SDK that predates Streamable HTTP entirely. The upgrade meant restructuring the server around a factory, so the same tools could serve stdio clients and per-request HTTP clients.
  • Identity on Google Cloud. We wanted to stay on Google Cloud, but Firebase Auth / Identity Platform can't act as an OAuth authorization server for a third party like Alexa. We built a small, focused authorization server ourselves and used Google only for sign-in.
  • Cloud Run surprises. Our /healthz endpoint returned Google's own 404: Cloud Run's front end reserves URL paths ending in z. And gcloud run deploy --source only builds a file named Dockerfile, so we moved to an explicit Cloud Build config.
  • Chat output isn't voice output. Our responses were Markdown tables built for chat. Read aloud, lines like "competitors: 68/100 (=0)" sound robotic, so we're redesigning responses for speech.
  • Being careful with financial content. Everything is framed as quantitative signals, never "buy" or "sell" instructions, and the disclaimer carries into the spoken briefings.

Accomplishments that we're proud of

  • An existing product went from local-only to a production remote MCP server with secure per-user account linking, in days.
  • A live end-to-end path: Alexa-style request → Cloud Run → MCP 2025-11-25 → Haruspex API → a real score.
  • The same codebase still powers Claude Code, Cursor and other MCP clients. Nothing forked.

What we learned

  • MCP's value really is "build once, reach many hosts": most of the work was transport and auth, not new tools.
  • OAuth 2.1 with PKCE is small enough to implement correctly yourself when you have exactly one client, and a thorough test suite makes that safe.
  • Voice needs its own design pass. Fewer numbers, one clear takeaway, and the detail left for follow-ups.

What's next for Haruspex for Alexa+

  • Voice-first briefings (in progress): a get_stock_briefing tool that returns a 2–3 sentence spoken summary and accepts company names ("Nvidia", "Apple") instead of tickers.
  • Personal watchlists: "Alexa, add Tesla to my watchlist" and "How's my watchlist?", stored per linked user.
  • Echo Show visuals through the MCP Apps extension: a score gauge with dimension bars.
  • Proactive alerts when a watched stock's score moves sharply.

Built With

  • alexa
  • alexa-plus
  • amazon-alexa
  • artifact-registry
  • docker
  • google-cloud-build
  • google-cloud-firestore
  • google-cloud-run
  • google-identity-services
  • google-secret-manager
  • haruspex-api
  • mcp
  • model-context-protocol
  • node.js
  • oauth2
  • pkce
  • rest-api
  • typescript
Share this project:

Updates

Submission history