Autonomous fraud investigation, with a human in command.
When a bank's monitoring system flags a suspicious transaction, a level-one fraud analyst spends 45-90 minutes investigating it by hand: pulling the customer's transaction history, KYC documents, device logs, sanctions screens, and prior cases, then writing a disposition that recommends closing the alert, escalating it, or filing a Suspicious Activity Report (SAR). One alert at a time.
Sentinel is an AI agent that does that same investigation autonomously, in about a minute. It produces the analyst's complete case file - a written narrative, a full evidence trail, citations to similar historical cases, and a recommendation with a confidence score - and then stops. A human reviewer makes the final call.
Live demo: https://sentinel-eight-kappa.vercel.app
- A transaction is flagged (in the demo, you fire one from the dashboard).
- Sentinel picks it up and investigates autonomously:
- Pulls the customer, accounts, and flagged transactions from MongoDB Atlas.
- Traces the money across the transaction graph with aggregation pipelines.
- Checks KYC records, device fingerprints, and sanctions screens.
- Runs Atlas Vector Search over thousands of historical case narratives to retrieve precedent - a past case with the same signature.
- It writes a SAR-style narrative, records every tool call as an auditable evidence trail, and produces a recommendation (close / escalate / file SAR) with a confidence score.
- A human reviewer approves, escalates, or rejects. Sentinel never files on its own.
A manual investigation takes ~55 minutes; Sentinel completes one in roughly 60-90 seconds.
Everything runs in production - the app on Vercel, the agent and the MongoDB MCP server on Google Cloud Run, orchestrated through Inngest.
Browser
|
v
Next.js app (Vercel) --- fire alert ---> Inngest Cloud
^ |
| poll liveProgress | invokes investigate-alert
| v
| /api/inngest (Vercel)
| |
| | POST /investigate
| v
| Sentinel Agent (Cloud Run)
| - Google ADK + Gemini on Vertex AI
| |
| | MCP tools over authenticated HTTP
| v
| MongoDB MCP Server (Cloud Run)
| |
+--------------------------------------------+
|
v
MongoDB Atlas
- operational data (customers, transactions, KYC, devices)
- case files + historical SAR narratives
- Atlas Vector Search (Voyage AI embeddings)
The agent reasons with Gemini, decides which queries to run, executes them through the MongoDB MCP Server, and grounds its conclusion in the institution's own history via vector search. The same Atlas cluster holds both the operational data the agent queries and the precedent it reasons from.
| Layer | Technology |
|---|---|
| Agent | Google Agent Development Kit (ADK), Gemini on Vertex AI |
| Agent tools | MongoDB MCP Server (HTTP transport) |
| Data + memory | MongoDB Atlas (operational + Atlas Vector Search) |
| Embeddings | Voyage AI (voyage-3-large, 1024-dim) |
| Agent hosting | Google Cloud Run (FastAPI wrapper, containerized) |
| Orchestration | Inngest (durable event-driven trigger) |
| App | Next.js, tRPC, Tailwind, shadcn/ui |
| App data | Prisma + MongoDB Atlas |
| Auth | better-auth (email/password) |
| App hosting | Vercel |
| Runtime | Bun |
- The user fires an alert on the dashboard. A tRPC mutation resets the target case and sends a
sentinel/alert.createdevent to Inngest Cloud. - Inngest invokes the
investigate-alertfunction (served at/api/inngeston Vercel), which calls the agent's/investigateendpoint on Cloud Run. - The agent service resolves the case, seeds session state, and runs the ADK agent to completion. As it works, before/after callbacks persist each tool call, the final narrative (with a vector embedding), and the case status to MongoDB.
- The UI polls
cases.liveProgressand streams the investigation into the case view in real time - tool calls appearing, stages advancing, the narrative landing - ending on a completed case awaiting human review.
src/ Next.js app (App Router)
app/ routes: landing, auth, dashboard, cases, alerts, settings
features/ feature modules (cases, alerts, dashboard, landing, ...)
inngest/ Inngest client + investigate-alert function
trpc/ tRPC routers
db/ Prisma client + seed
sentinel-agent/ the Python agent (deployed to Cloud Run)
sentinel_agent/ agent.py (root_agent), tools, persistence, prompt
server.py FastAPI wrapper exposing /investigate
Dockerfile container for Cloud Run
run_case.py headless single-case runner (local)
prisma/schema.prisma data model
# 1. Install app dependencies
bun install
# 2. Set up the agent (Python 3.12)
cd sentinel-agent
python3.12 -m venv .venv
./.venv/bin/pip install -e .
cd ..
# 3. Configure environment
cp .env.example .env
cp sentinel-agent/.env.example sentinel-agent/.env
# fill in: MongoDB Atlas URI, Voyage API key, Google Cloud / Vertex settings
# 4. Seed the database
bun run src/db/seed/index.ts
# 5. Run everything (Next.js + Inngest dev + agent)
bun run dev:allThe agent talks to a local MongoDB MCP server over stdio by default. Set MDB_MCP_HTTP_URL to point it at a hosted MCP service instead.
To run a single investigation headlessly:
cd sentinel-agent
./.venv/bin/python run_case.py <alert_object_id>Two services, both in us-central1.
gcloud run deploy sentinel-mcp \
--image=docker.io/mongodb/mongodb-mcp-server:latest \
--region=us-central1 \
--no-allow-unauthenticated \
--port=8080 \
--args='--transport=http,--httpHost=0.0.0.0,--httpPort=8080' \
--set-env-vars="MDB_MCP_CONNECTION_STRING=<atlas-connection-string>" \
--set-env-vars="MDB_MCP_READ_ONLY=true"The agent is wrapped in a small FastAPI app (server.py) that imports root_agent directly and exposes /investigate, then deployed with a plain Dockerfile:
cd sentinel-agent
gcloud run deploy sentinel-agent \
--source . \
--region=us-central1 \
--allow-unauthenticated \
--service-account=<compute-sa> \
--memory=1Gi \
--timeout=3600 \
--env-vars-file=agent.env.yamlEnvironment (in agent.env.yaml, gitignored): GOOGLE_GENAI_USE_VERTEXAI, GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_LOCATION, SENTINEL_MODEL, MDB_MCP_HTTP_URL, MONGODB_URI, MONGODB_DB, VOYAGE_API_KEY.
Set DATABASE_URL, BETTER_AUTH_SECRET, BETTER_AUTH_URL, NEXT_PUBLIC_APP_URL, VOYAGE_API_KEY, INNGEST_EVENT_KEY, INNGEST_SIGNING_KEY, and SENTINEL_AGENT_URL (the agent's Cloud Run URL). Sync the app to Inngest Cloud at <app-url>/api/inngest.
- Secrets are passed via environment variables for this demo; production should use Secret Manager.
- The Atlas IP allowlist is open for the demo so Cloud Run and Vercel can reach the cluster; production should use a VPC connector with a fixed egress range.
Sentinel produces a recommendation, never a filing. Financial-crime decisions carry legal weight, so the agent stops at "file a SAR" and a human reviewer reads the case and makes the call - approve, escalate, or reject. The agent compresses the investigation; the judgment stays human.
MIT - see LICENSE.