Skip to main content
Glama
sohaggain

AI Business MCP Server

by sohaggain
README.md
# AI Business MCP Server

![Python](https://img.shields.io/badge/Python-3.12-blue)
![FastAPI](https://img.shields.io/badge/MCP-FastMCP-green)
![Docker](https://img.shields.io/badge/Docker-Ready-2496ED)
![License](https://img.shields.io/badge/License-MIT-lightgrey)

A production-style **Model Context Protocol (MCP) server** that exposes six real business tools — **web search, database, CRM, email, calendar, and analytics** — to any MCP-compatible AI client (Claude Desktop, a custom AI agent, or an internal automation) through one secured, standardized interface.

Includes a working **reference AI agent client** (Claude or OpenAI, switchable) that connects to the server, discovers its tools, and performs multi-tool business tasks.

> Built by [Sohag Gain](https://sohaggain.com) — AI Automation Engineer — as part of a numbered portfolio of production-oriented AI automation projects.

---

## Table of Contents

- [Project Overview](#project-overview)
- [Business Problem](#business-problem)
- [Solution](#solution)
- [Key Features](#key-features)
- [Use Cases](#use-cases)
- [System Architecture](#system-architecture)
- [Tech Stack](#tech-stack)
- [Project Structure](#project-structure)
- [Installation](#installation)
- [Environment Variables](#environment-variables)
- [MCP Tools Reference](#mcp-tools-reference)
- [AI Architecture](#ai-architecture)
- [Testing](#testing)
- [Security](#security)
- [Deployment](#deployment)
- [Limitations](#limitations)
- [Future Improvements](#future-improvements)
- [Author](#author)
- [License](#license)

## Project Overview

AI agents are only as useful as the tools they can call. Today, every AI application that needs CRM access, database access, or email-sending capability re-implements that integration from scratch. **MCP (Model Context Protocol)** solves this by standardizing how AI clients discover and call external tools — but most teams still don't have a real, secured MCP server exposing their actual business systems.

This project is that server: a single, authenticated MCP endpoint that any AI agent can connect to and immediately gain the ability to search the web, query a database, manage CRM contacts, send email, manage a calendar, and track usage analytics.

## Business Problem

- AI agent projects repeatedly rebuild the same CRM/email/calendar/database glue code.
- Exposing internal business systems to an LLM without authentication or scoping is a real security risk (prompt injection → unauthorized data access).
- Teams need one governed integration surface, not N different one-off connectors per AI tool.

## Solution

A FastMCP-based server that:
1. Exposes 6 typed, schema-validated tools over Streamable HTTP.
2. Requires API-key authentication + per-key rate limiting on every call.
3. Restricts database access to an explicit table allow-list (guards against "excessive agency").
4. Runs fully in **mock mode** with realistic sample data when no credentials are configured — so it's demoable and testable with zero setup.
5. Ships a reference agent client showing the full loop: connect → discover tools → LLM decides which tool to call → execute → respond.

## Key Features

- 🔌 **6 production-style MCP tools**: search, database, CRM, email, calendar, analytics
- 🔐 **API-key authentication** with constant-time comparison + per-key rate limiting
- 🧱 **Vendor-agnostic providers** — swap HubSpot → Salesforce, SMTP → SendGrid, Tavily → SerpAPI without touching tool logic
- 🧪 **Offline-safe test suite** — every provider has a mock mode; CI runs with zero API keys
- 🔁 **Retry with exponential backoff** on all outbound provider calls (Tenacity)
- 🛡️ **Guardrails** — table allow-lists, mandatory filters on update/delete, Pydantic validation on every input
- 🤖 **Reference AI agent** — vendor-agnostic Claude/OpenAI client that performs real multi-tool tasks against the server
- 🐳 **Dockerized** with non-root user + health checks
- ⚙️ **GitHub Actions CI** — lint, test, build on every push

## Use Cases

- An internal ops AI agent that looks up a lead in the CRM, checks calendar availability, and sends a follow-up email — all through one MCP connection.
- Claude Desktop connected to your company's business systems for ad-hoc queries ("What's our latest lead from Acme Corp?").
- A foundation for a multi-tenant "AI tools API" product, where each client organization gets its own API key and provider credentials.

## System Architecture

```mermaid
flowchart TD
    Client[AI Client<br/>Claude Desktop / Agent] -->|Streamable HTTP + X-API-Key| Auth[Auth & Rate Limit Middleware]
    Auth --> MCP[FastMCP Server]
    MCP --> SearchTool[Search Tool]
    MCP --> DBTool[Database Tool]
    MCP --> CRMTool[CRM Tool]
    MCP --> EmailTool[Email Tool]
    MCP --> CalTool[Calendar Tool]
    MCP --> AnalyticsTool[Analytics Tool]

    SearchTool --> SearchProvider[Search Provider<br/>Tavily / Mock]
    DBTool --> DBProvider[PostgreSQL / Mock]
    CRMTool --> CRMProvider[HubSpot / Mock]
    EmailTool --> EmailProvider[SMTP / SendGrid / Mock]
    CalTool --> CalProvider[Google Calendar / Mock]
    AnalyticsTool --> AnalyticsDB[(SQLite)]
```

### Agent-to-server flow

```mermaid
sequenceDiagram
    participant Agent as AI Agent Client
    participant LLM as Claude / OpenAI
    participant MCP as MCP Server

    Agent->>MCP: initialize + list_tools (with X-API-Key)
    MCP-->>Agent: tool schemas (6 tools)
    Agent->>LLM: user request + tool schemas
    LLM-->>Agent: tool_use: crm_action(get_contact, email=...)
    Agent->>MCP: call_tool("crm_action", {...})
    MCP->>MCP: authenticate -> validate -> execute -> retry-on-failure
    MCP-->>Agent: tool result (JSON)
    Agent->>LLM: tool result
    LLM-->>Agent: final answer
```

## Tech Stack

| Category | Technology |
|---|---|
| Language | Python 3.12 |
| Protocol | Model Context Protocol (MCP) — FastMCP, Streamable HTTP |
| Backend | Starlette / Uvicorn (via FastMCP) |
| Validation | Pydantic v2 |
| Database | PostgreSQL (SQLAlchemy Core), SQLite (analytics) |
| AI | Anthropic Claude, OpenAI (vendor-agnostic) |
| Integrations | HubSpot (CRM), SMTP/SendGrid (Email), Google Calendar, Tavily (Search) |
| Reliability | Tenacity (retry/backoff) |
| Observability | structlog (structured logging) |
| DevOps | Docker, Docker Compose, GitHub Actions |
| Testing | pytest, pytest-cov, respx |

## Project Structure

```text
ai-business-mcp-server/
├── src/
│   ├── server.py            # MCP server entrypoint (tool registration + auth wiring)
│   ├── auth.py               # API key auth + rate limiting
│   ├── config.py             # Centralized settings (env-driven)
│   ├── exceptions.py         # Typed exceptions
│   ├── retry.py              # Shared retry policy
│   ├── logging_config.py     # structlog setup
│   ├── models/schemas.py     # Pydantic I/O contracts for every tool
│   ├── tools/                # Tool logic (validates + calls provider)
│   └── providers/            # External integration clients (mock + live)
├── agent_client/
│   ├── agent.py               # Reference AI agent (MCP client + LLM tool-calling loop)
│   └── llm_provider.py        # Vendor-agnostic Claude/OpenAI abstraction
├── tests/
│   ├── unit/                  # Per-tool unit tests (all mocked)
│   └── integration/           # Multi-tool workflow tests
├── docs/                      # Architecture, API, setup, security, testing, deployment docs
├── docker/                    # Dockerfile + docker-compose.yml
├── .github/workflows/ci.yml   # Lint + test + build pipeline
└── prompts/                   # Agent system prompt
```

## Installation

### Prerequisites
- Python 3.12+
- Docker (optional, for containerized run)
- API credentials for any integrations you want live (all optional — everything works mocked)

### Local setup

```bash
git clone <YOUR_GITHUB_URL>/ai-business-mcp-server.git
cd ai-business-mcp-server

python -m venv venv
source venv/bin/activate   # Windows: venv\Scripts\activate

pip install -r requirements.txt

cp .env.example .env
# Edit .env — leave everything blank to run fully in mock mode

python -m src.server
# Server starts on http://localhost:8000 (MCP endpoint: /mcp)
```

### Try the reference agent

```bash
export ANTHROPIC_API_KEY=sk-...   # only the LLM key is required — tools stay mocked
python -m agent_client.agent "Look up our contact jane@example.com and email her a quick follow-up"
```

### Docker

```bash
cd docker
docker compose up --build
curl http://localhost:8000/health
```

## Environment Variables

See [`.env.example`](.env.example) for the full list. Every integration variable is optional — leaving it blank keeps that specific tool in mock mode even if `MOCK_MODE=false`, so you can go live incrementally (e.g., real CRM, mocked calendar).

Key variables:

| Variable | Purpose |
|---|---|
| `MCP_API_KEYS` | Comma-separated keys allowed to call the server |
| `MOCK_MODE` | Global mock switch (default `true`) |
| `DATABASE_URL` | PostgreSQL connection string |
| `HUBSPOT_ACCESS_TOKEN` | Live CRM access |
| `SMTP_HOST` / `SENDGRID_API_KEY` | Live email sending |
| `GOOGLE_CALENDAR_CREDENTIALS_JSON` | Live calendar access |
| `TAVILY_API_KEY` | Live web search |
| `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` | Reference agent client's LLM |

## MCP Tools Reference

Full parameter/response documentation: [`docs/api.md`](docs/api.md)

| Tool | Actions | Purpose |
|---|---|---|
| `web_search` | — | Search the web for grounding information |
| `database_query` | select / insert / update / delete | Scoped CRUD on allow-listed tables |
| `crm_action` | create_contact / get_contact / list_contacts / add_note | Manage CRM contacts |
| `send_email` | — | Send transactional/business email |
| `calendar_action` | create_event / list_events / delete_event | Manage calendar events |
| `analytics_action` | track_event / get_summary | Usage tracking |

## AI Architecture

- **Tool-calling model**: the MCP server itself is model-agnostic — it just exposes tools. The bundled agent client demonstrates tool selection using Claude's native tool-use or OpenAI's function-calling, switchable via `LLM_PROVIDER`.
- **Guardrails**: table allow-list on the database tool, mandatory filters on destructive operations, strict Pydantic schemas rejecting malformed input before it reaches any provider.
- **Human-in-the-loop**: not built into this reference server (it's a tools layer, not a decision layer) — documented as a required addition for any tool with financial or irreversible real-world effect (see [Limitations](#limitations)).

## Testing

```bash
pytest tests/ -v --cov=src --cov-report=term-missing
```

- **Unit tests** — one file per tool, covering success paths, validation errors, and guardrails (e.g., disallowed tables, missing filters on update/delete).
- **Integration test** — a realistic multi-tool sequence (search → CRM → database) exercising the same dispatch path the live server uses.
- All tests run against mock providers — **no API keys or network access required**, matching this project series' offline-safe testing standard.

Run locally before every push: `pytest` (all 38 source files pass `py_compile` syntax validation as a first gate; full unit/integration suite requires installing `requirements.txt`).

## Security

Full checklist: [`docs/security.md`](docs/security.md)

- API-key authentication on every tool call, constant-time comparison
- Per-key sliding-window rate limiting
- Table allow-list prevents the LLM from reaching arbitrary database tables
- Mandatory filters on `update`/`delete` prevent unscoped writes
- SQL values always bound-parameterized — never string-interpolated
- No secrets in code, logs, or documentation — `.env` gitignored, `.env.example` provided
- API key fingerprints (not raw keys) appear in logs

## Deployment

See [`docs/deployment.md`](docs/deployment.md) for Docker, docker-compose, and AWS (ECS/RDS) deployment guidance.

- Live demo: **Not publicly deployed yet.**
- Demo video: **Will be added after recording.**

## Limitations

- Rate limiter is in-memory — for multi-instance production deployment, back it with Redis (interface designed to support this swap).
- No human-in-the-loop approval step for destructive actions — appropriate for a portfolio/reference server, but a real deployment sending real emails or deleting real CRM records should add an approval gate.
- Single-turn tool loop in the reference agent — extend to a `while` loop for multi-step chained tool use.
- OAuth-based per-client scoping is not implemented (static API keys only) — documented as a future improvement.

## Future Improvements

- Redis-backed rate limiting for multi-instance deployments
- Per-API-key tool scoping (e.g., a read-only key)
- OAuth 2.1 support (MCP spec now supports it) instead of static API keys
- Streaming tool results for long-running operations
- Human-approval workflow for destructive actions

## Author

**Sohag Gain**
AI Automation Engineer | Founder, AI Smart Galaxy

- Website: https://sohaggain.com
- GitHub: [YOUR_GITHUB_URL — add your GitHub profile link]
- LinkedIn: [YOUR_LINKEDIN_URL — add your LinkedIn profile link]
- Email: sohaggain650@gmail.com

## License

MIT License — see [LICENSE](LICENSE).