Hello, I am Prathyusha. When I decided to build a fraud detection agent, I did not just read about it. I built it from scratch.
This is the story of building FraudGuard AI — an agent that monitors every credit card transaction in real time, detects fraud using Claude AI, and blocks your card while you sleep.
What I Built
An AI agent that monitors all your bank accounts and credit cards in real time — using Claude AI as the fraud detection brain and a custom MCP server as the backbone.
One scan does everything:
http://localhost:3000/scan-all
Output:
Step 1: Fetching transactions... ✓ 10 transactions loaded
Step 2: Running rule checks... ✓ 5 flags raised
Step 3: Analyzing with Claude AI... ✓ Risk scores assigned
Step 4: Handling fraud... ✓ 1 card blocked, 2 emails sent
Step 5: Dashboard updated... ✓ Live feed refreshed
Scan complete in seconds.
Full action log written to memory.
The Problem It Solves
Most fraud alerts arrive after the damage is done:
→ Bank flags a transaction after it goes through
→ You get a notification too late
→ Attacker already has what they need
→ You spend hours disputing and waiting
That is the reality for millions of people every day. This agent catches fraud the moment it happens — and acts on it immediately.
What is MCP?
MCP stands for Model Context Protocol. It is an open standard that lets AI agents connect to external tools in a structured way.
Without MCP:
Agent → custom code → Plaid
Agent → different code → Gmail
Agent → another code → Block API
With a custom MCP server:
Agent → ONE MCP server → Plaid
→ Claude AI
→ Gmail
→ Block handler
One server. All tools. Clean architecture.
The Architecture
Browser / API call
↓
mcp-server.js — exposes all 11 tools
↓
plaid-client.js — fetches transactions
↓
claude-agent.js — fraud analysis
↓ ↓
Rule checks Claude AI (Anthropic API)
↓
block-handler.js — 2AM rule engine
↓ ↓
Auto-block Email approval (Gmail API)
↓
dashboard — live HTML/CSS/JS UI
Built in Node.js. 5 server files. Clean structure.
Tech Stack**
→ Language → Node.js + JavaScript
→ AI Brain → Claude AI (Anthropic API)
→ Bank Data → Plaid API
→ Agent Backbone → Custom MCP Server
→ Notifications → Gmail API
→ Dashboard → HTML + CSS + JS
→ Data → Mock data (safe for GitHub)
The 2AM Rule — My Favourite Feature
The biggest problem with fraud alerts is bad timing. They interrupt you at 3AM and you end up ignoring them. So I built a time-aware rule:
─────────────────────────────────────────
Before 2AM
A fraud alert email is sent with one-click YES / NO buttons.
Click YES → transaction approved, card stays active.
Click NO → card blocked instantly.
─────────────────────────────────────────
After 2AM
Agent auto-blocks the card immediately. No interruptions.
A full morning report arrives when you wake up.
─────────────────────────────────────────
No midnight interruptions. No missed fraud. The agent handles it either way.
3 Real Errors I Hit
These taught me the most about building AI agents.
─────────────────────────────────────────
Error 1 — Gmail OAuth redirect_uri_mismatch
Error 400: redirect_uri_mismatch
Access blocked: This app's request is invalid
Why: Created OAuth credentials as Desktop App type. Desktop Apps do not support redirect URIs, so the OAuth Playground rejected the request.
Fix: Delete the Desktop App credential. Create a new one as Web Application type. Add this exact URI to Authorized Redirect URIs:
https://developers.google.com/oauthplayground
─────────────────────────────────────────
Error 2 — Claude model deprecated
404: model claude-sonnet-4-20250514 not found
The model is deprecated and will reach end-of-life
Why: Used an outdated model string that had been deprecated by Anthropic.
Fix: One line change in claude-agent.js. Updated to the current model:
claude-sonnet-4-6
─────────────────────────────────────────
Error 3 — Gmail not configured fallback
[Gmail] Not configured — logging email to console instead
Why: The .env file still had placeholder values for Gmail credentials. The system silently fell back to console logging instead of throwing an error.
Fix: Complete the full OAuth Playground flow. Make sure all three Gmail values are real in .env:
GMAIL_CLIENT_ID=real_value
GMAIL_CLIENT_SECRET=real_value
GMAIL_REFRESH_TOKEN=1//real_value
Pro tip: Check your terminal for [Gmail] CONFIGURED ✅ on startup. That confirms Gmail is live before you test anything.
─────────────────────────────────────────
What I Learned About Building AI Agents
✓ Always check model names against current Anthropic docs — they deprecate fast
✓ OAuth credentials type matters — Web Application not Desktop App for redirect flows
✓ Use placeholder detection in code — fail loudly when keys are missing
✓ Mock data is not just for testing — it makes your repo safe and instantly runnable
✓ Time-aware logic makes agents feel genuinely intelligent, not just automated
✓ Hybrid detection (rules + AI) is stronger than either approach alone
Results
✓ Plaid connected → 10 mock transactions loaded across 3 accounts
✓ Claude AI running → 82% confidence on Frankfurt fraud detection
✓ Gmail live → Fraud alert email sent with YES / NO buttons
✓ Card blocked → One click in email blocks card instantly
✓ Dashboard live → Real-time feed, alerts, and card controls
✓ GitHub ready → Mock data, .env.example, full README
Final Thought
Building this agent taught me that AI is most powerful when it understands context — not just data. Claude AI did not just flag the Frankfurt transaction because it was foreign. It understood the combination of foreign location, unknown merchant, and 2AM timing together.
That kind of contextual reasoning is what separates an AI agent from a simple rule engine.
And the 2AM rule? That is just good product thinking. The best automation knows when to act and when to ask.
Running With Mock Data vs Your Real Cards
The project ships with mock data by default. This means you can clone it, run it, and see the full fraud detection working instantly — no bank account needed.
What mock data includes
✓ 10 realistic fake transactions across 3 accounts
✓ 2 high-risk scenarios — Frankfurt foreign transaction, CryptoExchange at 3AM
✓ 3 medium-risk scenarios — velocity attack, $1.00 test charge, luxury jewelry store
✓ 5 normal transactions — Starbucks, Shell, Netflix, Whole Foods, Texas Roadhouse
✓ Pre-assigned risk levels and fraud reasons for instant testing
If you want to connect your real cards
You need to replace 3 things in the project:
Step 1 — Get a Plaid account
→ Go to dashboard.plaid.com and create a free developer account
→ Get your PLAID_CLIENT_ID and PLAID_SECRET
→ Add both to your .env file
Step 2 — Replace mock data with live Plaid data
In server/plaid-client.js, the switch is already built in. The file automatically detects whether your Plaid keys are real or placeholders:
→ Placeholder keys → runs on mock data automatically
→ Real Plaid keys → fetches live transactions from your bank
No code changes needed. Just add your real keys to .env and restart.
Step 3 — Connect your bank via Plaid Link
→ Plaid uses OAuth — your bank password is entered directly on your bank's website
→ The app never sees your actual login credentials
→ Plaid never shares raw card numbers — only transaction metadata
→ Start with Plaid Sandbox mode to test with fake bank data first
Important — what Plaid shares vs what stays private
✓ Transaction amounts → shared
✓ Merchant names → shared
✓ Transaction timestamps → shared
✓ Tokenized account IDs → shared
✗ Your actual card number → never shared
✗ Your bank login credentials → never shared
✗ Your CVV or PIN → never shared
This is why Plaid is trusted by apps like Venmo, Robinhood, and thousands of others. Your sensitive details never leave your bank.
Full Code on GitHub
https://github.com/prathyushak828/FraudGuard-AI-AI-powered-fraud-detection-agent
If you are building AI agents that work with real-world APIs and need intelligent decision-making — Claude AI and a custom MCP server is worth your time.
Top comments (2)
The architecture choice that stands out is the right one: rule checks first, then Claude on what's left. That's the pattern most people skip, they throw every transaction at the model and pay for it in latency, cost, and false confidence. Cheap deterministic rules catch the obvious fraud and obvious-legit instantly, and you reserve the expensive LLM reasoning for the genuinely ambiguous middle, which is exactly where its judgment earns its price. The hard part in fraud specifically is the asymmetry of errors: a false negative is a stolen card, a false positive is blocking someone's groceries at checkout, and those failures cost completely differently. So the question that decides whether FraudGuard is usable is the confidence threshold for auto-block versus flag-for-review, because auto-blocking on a shaky Claude call trades one bad experience for another. I'd want the agent to abstain to human review when it's not sure rather than act, the verify-or-escalate line. That's core to how I think about agent actions in Moonshift. Where did you set the auto-block bar, and how often did Claude disagree with the rule layer?
This is exactly the kind of feedback that makes you rethink your own assumptions — thank you.
You're right about the asymmetry. A false negative is a stolen card. A false positive is someone's groceries getting declined at checkout. Those are not equivalent failures and I didn't treat them that way in v1.
On the auto-block threshold — I set it conservatively. Claude only triggers auto-block when it returns high risk with confidence above 80% AND at least one high-severity rule flag already fired. Medium risk never auto-blocks. It always goes to email approval. So the rule layer acts as a gate, not just a pre-filter — Claude can only act autonomously when the rules already agreed with it first.
On the disagreement question — in my mock data tests Claude disagreed with the rule layer on 2 out of 10 transactions. Both were medium-risk edge cases where the rules fired but Claude came back with low confidence (76% and 78%). In both cases the system defaulted to flag-for-review rather than auto-block, which felt like the right call.
But your verify-or-escalate point exposes the gap I haven't closed yet. Right now "not sure" still sends an email. It doesn't explicitly abstain to a human review queue with context attached. That's the next thing I want to build — a proper confidence band where high confidence acts, low confidence abstains with a reason, and the middle band always escalates to human review with Claude's full reasoning attached so the reviewer isn't starting blind.
Would love to understand how Moonshift handles that threshold in practice — specifically whether you let the model set its own confidence or whether you impose an external bar.