Skip to main content
Glama
README.md
AgentBridge

A custom MCP (Model Context Protocol) server that exposes personal productivity data — Google Calendar, Gmail, and local notes — as agent-callable tools, paired with a LangGraph ReAct agent that decides when to use them, with Human-in-the-Loop approval, guardrails, and persistent memory — plus both a terminal and a web chat interface.

Built as a portfolio project to demonstrate practical multi-agent orchestration, tool-calling protocols, and hybrid RAG — not just a single chatbot wrapper.

Architecture
User query (terminal or Streamlit UI)
    │
    ▼
LangGraph ReAct agent (Groq / Anthropic Claude)
  · conversation persisted to SQLite — survives restarts
    │
    ├─ no tool needed → answers directly
    │
    └─ tool needed
            │
            ▼
      [Guardrails] blocked?  ──yes──▶ rejected automatically, agent told why
            │ no
            ▼
      [Human-in-the-Loop] "Approve this tool call? (y/n)"
            │  (only proceeds on approval)
            ▼
      MCP client ──HTTP──▶ MCP server (localhost:8765)
            │
      ┌─────┼─────────────┐
      ▼     ▼             ▼
  Calendar Gmail    Notes (local RAG:
  (Google  (Google   FAISS + sentence-
   API)     API)     transformer embeddings)
What's in this repo
File	Purpose
src/agentbridge/server.py	MCP server — exposes 3 tools over HTTP
src/agentbridge/rag.py	Local RAG layer: chunks + embeds notes/*.md, semantic search via FAISS
src/agentbridge/guardrails.py	Safety checks run before any tool call reaches approval
agent.py	LangGraph ReAct agent — terminal chat, Human-in-the-Loop, SQLite persistence
app.py	Streamlit web UI for the same agent, with approve/reject buttons
test_client.py	Standalone script to sanity-check the MCP server without the agent
notes/	Sample notes indexed by search_notes
Tools exposed by the MCP server
get_upcoming_events — reads Google Calendar (read-only scope)
search_emails — searches Gmail using Gmail's query syntax (read-only scope)
search_notes — semantic search over local .md notes using a local embedding model (no API key needed, runs offline after first download)
Safety features
Human-in-the-Loop: every tool call pauses for explicit approval before it runs (interrupt_before=["tools"] in LangGraph).
Guardrails (guardrails.py): blocks tool calls before they even reach approval if they request an unreasonable amount of data (possible runaway loop) or search for sensitive terms like passwords.
Persistent memory: conversation history is saved to agentbridge_memory.db (SQLite) via SqliteSaver, so context survives restarting the agent.
Setup
1. Install dependencies
bash
cd agentbridge
uv sync
2. Google Cloud setup (Calendar + Gmail)
Go to https://console.cloud.google.com/ → create/select project "AgentBridge"
APIs & Services → Library → enable Google Calendar API and Gmail API
APIs & Services → Credentials → Create Credentials → OAuth client ID
Application type: Desktop app
Download the JSON, rename it exactly credentials.json, place it in the agentbridge/ root folder (same level as pyproject.toml)
Google Auth Platform → Audience → Test users → add your own Google account email (required while the app is in "Testing" mode)

⚠️ Never commit credentials.json or token.json — both are already in .gitignore.

3. LLM provider

Default is Groq (free):

powershell
$env:GROQ_API_KEY = "your-groq-key"    # get one at console.groq.com/keys

To use Claude instead:

powershell
$env:LLM_PROVIDER = "anthropic"
$env:ANTHROPIC_API_KEY = "your-anthropic-key"
4. Run — Terminal

Terminal 1 — MCP server:

bash
uv run python -m agentbridge.server

Terminal 2 — Agent:

bash
uv run python agent.py
5. Run — Web UI (optional, instead of Terminal 2)
bash
uv run streamlit run app.py

Opens a browser chat window with clickable Approve/Reject buttons.

Try these queries
What are my upcoming meetings?
Do I have any unread emails?
What did we decide about the transport layer? (answered from notes/)
Multi-tool chaining: Do I have any meetings tomorrow, and are there any emails related to them? — the agent will call Calendar, then Gmail, asking for approval on each.
Guardrails demo: Search my emails for my password reset code — gets blocked automatically, before any approval prompt.
Resume bullet

Built AgentBridge, a custom MCP (Model Context Protocol) server exposing Google Calendar, Gmail, and local notes as agent-callable tools, integrated with a LangGraph ReAct agent featuring Human-in-the-Loop tool approval, rule-based guardrails, SQLite-backed persistent memory, a local FAISS RAG layer for semantic note search, and a Streamlit web interface.

Interview talking points
MCP transport tradeoffs: started with stdio, switched to streamable-http after hitting Windows-specific pipe issues.
Human-in-the-Loop: implemented via LangGraph's interrupt_before, pausing before the tools node and resuming with Command(resume=True) only on explicit approval.
Guardrails: a small rule-based layer that runs before approval — can discuss how this differs from (and could evolve into) a full framework like Guardrails AI or NeMo Guardrails.
Persistence: swapped InMemorySaver for SqliteSaver — can explain why production agents need durable state, not just in-memory.
RAG vs Vectorless RAG: search_notes uses real vector search (FAISS + sentence-transformer embeddings) because notes are numerous and stable; a vectorless approach suits smaller, fast-changing data like a single email thread better.