Inspiration

I've always been frustrated by how black-box fraud systems are. You get declined at a grocery store at 7pm on a Tuesday and there's zero explanation. I wanted to build something that reasons about fraud the way an experienced analyst would, not just pattern matching, but actually investigating context before making a call.

The financial services angle also felt underexplored for this hackathon. Most builders would go for something flashy. Fraud detection is unglamorous but the stakes are real, $485 billion lost globally every year, and a lot of that hits people who can least afford it.

What it does

FraudShield analyzes incoming transactions through a three-step agent loop:

Step 1 - Merchant history check. The agent calls the MongoDB MCP server to pull recent transactions at the same merchant. It looks for prior fraud incidents, volume spikes, and whether the current amount is out of character.

Step 2 - Vector similarity search. Using 384-dimensional embeddings stored in Atlas, the agent finds the most similar historical transactions and checks their outcomes. If 4 out of 5 similar transactions were fraudulent, that's a strong signal.

Step 3 - Verdict with reasoning. The agent writes its decision back to MongoDB, APPROVED, FLAGGED, or BLOCKED, along with a confidence score and a plain-English explanation a human analyst could actually act on.

The whole reasoning chain streams live to the dashboard so you can watch the agent think in real time.

How I built it

Started with MongoDB Atlas, loaded 10,000 synthetic transactions, generated vector embeddings with sentence-transformers, and built a Vector Search index. That became the agent's long-term memory.

The agent itself runs on Gemini 2.5 Flash through Google's ADK. I defined three tools: get_user_history, search_similar_fraud, and flag_transaction, and wired them to MongoDB through the official MCP server. The MCP integration was the architectural centerpiece: every tool call the agent makes is a real database operation, not a simulated one.

FastAPI handles the backend with an SSE streaming endpoint so the frontend can show tool calls appearing in real time. The React dashboard has a dark terminal-style reasoning panel that makes the agent's thought process visible. Deployed on Google Cloud Run with the model baked into the Docker image to avoid cold start delays.

Challenges I ran into

The MCP integration on Windows was the biggest headache. The MCP server requires config through environment variables rather than inline arguments, not documented clearly anywhere — and the subprocess handling between the .cmd wrapper and the actual Node script behaved differently than expected. Switching from subprocess.run to subprocess.Popen for proper stdio streaming was the fix, but it took most of a day to figure out.

The other interesting challenge was what to do when the agent disagrees with the ground-truth labels in the dataset. Early on I thought this was a bug. It's not, the agent is applying contextual reasoning that a binary label can't capture. A transaction flagged as fraud in the dataset might look legitimate given the merchant's history and similar cases. I kept the disagreement in and treated it as a feature.

Accomplishments that I'm proud of

The streaming reasoning panel, watching three sequential MCP tool calls fire and resolve in real time, ending in a structured verdict with a confidence bar, is exactly what "meaningful agentic behavior" should look like. It's not a chatbot with tool-shaped decorations. The agent actually investigates.

Also proud of the architectural decision to use a single Cloud Run service serving both the FastAPI backend and the React frontend. Keeping deployment simple as a solo builder meant I could actually finish.

What I learned

MCP is genuinely powerful but the developer experience for non-standard environments (Windows, stdio-based servers) still has rough edges. The mental model shift from "LLM that can call functions" to "agent with real tool access to live systems" took a day to fully internalize but it changes how you design everything, the tools, the prompts, the data model.

Vector search and function calling are a natural pairing for this kind of problem. The vector search doesn't just retrieve data, it gives the agent episodic memory of what similar situations looked like and how they resolved.

What's next for FraudShield

The obvious next step is real-time transaction streaming, hooking into a Kafka or Pub/Sub feed rather than manual submission. Multi-merchant network analysis would be powerful too: right now the agent looks at one merchant in isolation, but fraud rings operate across merchants simultaneously.

On the model side, fine-tuning Gemini on labeled fraud reasoning traces could tighten the confidence calibration significantly. And replacing the synthetic dataset with a production-grade one would make the vector search results meaningfully more accurate.

Built With

  • docker
  • fastapi
  • google-adk
  • google-artifact-registry
  • google-cloud-run
  • google-gemini
  • javascript
  • mongodb-atlas
  • mongodb-mcp-server
  • pydantic
  • pymongo
  • python
  • react
  • sentence-transformers
  • sse-streaming
  • tailwind-css
  • uvicorn
  • vector-search
  • vite
Share this project:

Updates