Enterprise Support MCP Server
by pbpeter
README.md
# Enterprise Support MCP Server
A lightweight **Enterprise AI integration prototype** demonstrating how business capabilities can be exposed to Large Language Models through the **Model Context Protocol (MCP)**.
The project provides customer and order information through a Python-based MCP server. A **Mistral-powered AI assistant** dynamically discovers the available MCP tools and decides which tools to call based on natural-language support requests.
For more complex requests, the assistant can execute multiple tool calls iteratively until enough information is available to generate a final response.
> All customer and order records used in this project are synthetic demo data.
---
## Key Features
- Model Context Protocol (MCP) server and client
- Dynamic MCP tool discovery
- LLM-driven tool selection using Mistral AI
- Multi-step tool-calling workflow
- Natural-language interaction with enterprise data
- Customer and order lookup
- Pydantic data models
- SQLite persistence
- Structured error handling
- Separation of MCP, persistence and AI integration layers
---
## Architecture
```mermaid
flowchart TD
U[User] --> L[Mistral LLM]
L --> C[MCP Client]
C --> S[Enterprise Support MCP Server]
S --> D[(SQLite Customer / Order Database)]
D --> S
S --> C
C --> L
L --> U
```
The LLM does not access the database directly.
Instead, enterprise capabilities are exposed through standardized MCP tools. The MCP client discovers these tools dynamically and makes their schemas available to the LLM.
The LLM then decides which tool is required for a given user request.
---
## Example Workflow
A user enters:
```text
Show me customer 1001.
```
The application performs the following workflow:
```text
User request
↓
Mistral LLM
↓
Selects get_customer
↓
MCP Client
↓
Enterprise Support MCP Server
↓
SQLite
↓
Customer data
↓
MCP Client
↓
Mistral LLM
↓
Natural-language response
```
Example result:
```text
Here is the information for customer 1001:
- Name: Anna Schmidt
- Email: anna@example.com
- Status: ACTIVE
```
The application code does not hard-code the selection of `get_customer`.
The LLM selects the appropriate MCP tool based on the user's natural-language request.
---
## Available MCP Tools
### `get_customer`
Retrieves customer information by customer ID.
Example input:
```json
{
"customer_id": 1001
}
```
### `get_customer_orders`
Retrieves all orders belonging to a customer.
Example input:
```json
{
"customer_id": 1001
}
```
### `get_order_status`
Retrieves the current status and tracking information for an order.
Example input:
```json
{
"order_id": 5002
}
```
---
## Technology Stack
- Python
- Model Context Protocol (MCP) Python SDK
- Mistral AI
- Pydantic
- SQLite
- asyncio
- python-dotenv
- uv
---
# Getting Started
## Prerequisites
The project requires:
- Python 3.11+
- `pip`
- `uv`
- a Mistral API key
Verify your Python installation:
```bash
python --version
```
Verify `uv`:
```bash
uv --version
```
---
## 1. Clone the Repository
```bash
git clone https://github.com/YOUR-USERNAME/enterprise-support-mcp-server.git
cd enterprise-support-mcp-server
```
Replace `YOUR-USERNAME` with your GitHub username.
---
## 2. Create a Virtual Environment
```bash
python -m venv .venv
```
### Windows PowerShell
```powershell
.venv\Scripts\Activate.ps1
```
### Linux / macOS
```bash
source .venv/bin/activate
```
---
## 3. Install Dependencies
```bash
pip install -r requirements.txt
```
The main dependencies include:
```text
mcp[cli]
mistralai
pydantic
python-dotenv
```
---
## 4. Configure the Mistral API Key
Create a `.env` file in the project root.
You can use `.env.example` as a template:
```text
MISTRAL_API_KEY=your_mistral_api_key
```
Never commit the actual `.env` file or an API key to Git.
---
## 5. Initialize the Demo Database
Run:
```bash
python init_db.py
```
This creates the local SQLite database containing synthetic customer and order records used by the MCP tools.
---
# Testing
The project can be tested at several levels.
## Test 1 – Database Access
The database functions can be tested independently before MCP is involved.
Verify that the demo database has been initialized:
```bash
python init_db.py
```
The database layer provides operations for:
```text
get_customer
get_customer_orders
get_order_status
```
This verifies the persistence layer independently from MCP and the LLM.
---
## Test 2 – Start the MCP Server
Run:
```bash
python server.py
```
For a `stdio`-based MCP server, no HTTP port or browser is opened.
The process waits for an MCP client to communicate through standard input/output.
Stop the server with:
```text
Ctrl+C
```
---
## Test 3 – MCP Client without an LLM
Run:
```bash
python client.py
```
The client connects to the MCP server and discovers the available tools.
Expected tool discovery:
```text
Available tools:
- get_customer
- get_customer_orders
- get_order_status
```
The client can then invoke the MCP tools directly.
This test verifies:
```text
MCP Client
↓
MCP protocol
↓
MCP Server
↓
SQLite
↓
MCP result
```
No Large Language Model is required for this test.
---
## Test 4 – LLM-driven MCP Tool Selection
Run:
```bash
python llm_client.py
```
The application should first display the MCP tools discovered from the server:
```text
Available MCP tools:
- get_customer
- get_customer_orders
- get_order_status
```
You can then enter a natural-language request.
### Customer lookup
```text
Show me customer 1001.
```
Expected behavior:
```text
Mistral
↓
get_customer
↓
customer_id = 1001
```
The final response should contain the information for customer `1001`.
---
### Customer orders
Try:
```text
Show me all orders for customer 1001.
```
Expected tool:
```text
get_customer_orders
```
---
### Order status
Try:
```text
What is the status of order 5002?
```
Expected tool:
```text
get_order_status
```
---
### Request without Enterprise Data
Try:
```text
What can you help me with?
```
The LLM should be able to answer this request without accessing customer or order data.
This demonstrates that tool execution is selected dynamically rather than being executed for every request.
---
## Test 5 – Multi-Step Tool Calling
The LLM client supports iterative tool execution.
Try a more complex request such as:
```text
Customer 1001 says that one of her orders has not arrived.
Can you investigate?
```
For complex requests, the assistant can use multiple MCP tools before generating the final response.
Conceptually:
```text
User
↓
Mistral
↓
MCP Tool
↓
Tool Result
↓
Mistral
↓
Another tool required?
├── Yes → MCP Tool → Result → Mistral
└── No → Final Response
```
The tool-calling loop has a maximum number of iterations to prevent accidental infinite execution.
---
## Error Handling Tests
The MCP server also handles unknown business entities.
For example:
```text
Show me customer 9999.
```
The corresponding MCP tool returns an error result instead of inventing customer information.
This is particularly important for AI-based enterprise integrations: factual customer and order information must originate from the connected enterprise system rather than from the LLM.
---
# Project Structure
```text
enterprise-support-mcp-server/
│
├── server.py
│ └── MCP server and tool definitions
│
├── client.py
│ └── MCP client for direct tool testing
│
├── llm_client.py
│ └── Mistral integration and agentic tool-calling workflow
│
├── database.py
│ └── Database access layer
│
├── models.py
│ └── Pydantic domain models
│
├── init_db.py
│ └── Creates synthetic demo data
│
├── requirements.txt
├── .env.example
├── .gitignore
└── README.md
```
---
# Why MCP?
An LLM can also call application-specific functions directly.
MCP introduces a standardized interface between AI applications and external capabilities.
In this project:
```text
Mistral
↓
Tool Calling
↓
MCP Client
↓
Standardized MCP interface
↓
Enterprise Support MCP Server
↓
Enterprise capabilities
```
The LLM is responsible for deciding **which capability is required**.
MCP is responsible for exposing those capabilities through a **standardized protocol**.
This separation means that the enterprise backend does not need to be designed specifically for one LLM provider.
---
# Project Purpose
The project is intentionally small and focuses on one architectural question:
> How can existing enterprise capabilities be made available to AI assistants through a standardized integration layer?
It demonstrates the combination of:
- Enterprise system integration
- Model Context Protocol
- LLM tool calling
- Agentic workflows
- Structured business data
- Separation of concerns
The project serves as a practical prototype for integrating AI assistants with existing enterprise applications.
---
## Security Notice
This repository contains only synthetic demo data.
Do not expose API keys, credentials, customer data or other sensitive information through source code or committed `.env` files.This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues