Customer Service MCP Server
README.md
# Customer Service MCP Server
Minimal FastMCP server for the DataFlow Solutions e-commerce customer-service scenario: secure read access to customers, orders, and tickets, plus write tools with audit logging and basic monitoring.
For full technical documentation (architecture, data models, security, request flows, source map), see [CODEBASE.md](./CODEBASE.md).
## What's included
| Area | Implementation |
|------|----------------|
| **Resources** | `commerce://customers`, `commerce://orders`, `commerce://support-tickets` |
| **Read tools** | `get_customers`, `get_orders`, `get_support_tickets` (auth + cache) |
| **Write tools** | `create_support_ticket`, `update_order_status` (validation + rollback) |
| **Auth** | API key → role (`admin`, `agent`, `readonly`) |
| **RBAC** | Permission checks on every call |
| **Audit** | JSON audit lines on stderr |
| **Monitoring** | `health_check`, `get_metrics` |
| **Resilience** | Rate limiting, TTL cache, circuit breaker, safe errors |
## Project layout
```text
customer-service-mcp/
├── server.py # MCP server (single file)
├── requirements.txt
├── Dockerfile
└── README.md
```
## Setup
```bash
cd customer-service-mcp
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
## Configuration
Set via environment (or `.env`):
```env
# key:role pairs (comma-separated)
API_KEYS=dev-admin-key:admin,dev-agent-key:agent,dev-readonly-key:readonly
LOG_LEVEL=INFO
RATE_LIMIT_PER_MIN=60
CACHE_TTL_SEC=30
MCP_TRANSPORT=stdio
```
### Default API keys (dev only)
| Key | Role | Can |
|-----|------|-----|
| `dev-admin-key` | admin | read + write + metrics |
| `dev-agent-key` | agent | read + write tickets/orders |
| `dev-readonly-key` | readonly | read only |
## Run locally
```bash
python server.py
```
Uses **stdio** transport — start from Claude Desktop / Cursor MCP config, not as a standalone interactive process.
### Claude Desktop example
```json
{
"mcpServers": {
"customer_service": {
"command": "/Users/amardeepganguly/building ai agents coursera/mcp-module-3/customer-service-mcp/.venv/bin/python",
"args": [
"/Users/amardeepganguly/building ai agents coursera/mcp-module-3/customer-service-mcp/server.py"
],
"cwd": "/Users/amardeepganguly/building ai agents coursera/mcp-module-3/customer-service-mcp",
"env": {
"API_KEYS": "dev-admin-key:admin,dev-agent-key:agent,dev-readonly-key:readonly"
}
}
}
}
```
Restart the host app after editing config.
## Post–Claude Desktop integration test cases
After adding the server to Claude Desktop, fully quit (`Cmd+Q`) and reopen. Confirm **customer_service** shows as connected and lists the tools below.
### Pre-flight
| Check | How | Pass if |
|-------|-----|---------|
| Server connects | Claude → Settings → Developer → MCP | `customer_service` is green / no error |
| Tools visible | Ask: “What MCP tools does customer_service expose?” | Lists `get_customers`, `get_orders`, `get_support_tickets`, `create_support_ticket`, `update_order_status`, `health_check`, `get_metrics` |
| Logs | `tail -f ~/Library/Logs/Claude/mcp-server-customer_service.log` | `Customer Service MCP server initialized` on startup |
### Test 1 — Read customers (agent key)
**Prompt:**
```text
Use the customer_service MCP tool get_customers with api_key dev-agent-key.
Show me the customer list.
```
**Expected:** 3 customers (`cust-001` Jane Johnson, `cust-002` Acme Corp, `cust-003` Sam Lee). No `error` field.
---
### Test 2 — Orders for one customer
**Prompt:**
```text
Call get_orders with api_key dev-agent-key and customer_id cust-001.
```
**Expected:** 2 orders (`ord-1001`, `ord-1002`). Statuses `shipped` and `processing`.
---
### Test 3 — Create support ticket (write)
**Prompt:**
```text
Use create_support_ticket with:
- api_key: dev-agent-key
- customer_id: cust-001
- subject: "Test ticket from Claude"
- priority: high
```
**Expected:** New ticket with `id` like `tkt-xxxxxx`, `status: open`. Then run Test 4 to confirm it appears.
---
### Test 4 — Verify ticket in list
**Prompt:**
```text
Call get_support_tickets with api_key dev-agent-key and customer_id cust-001.
```
**Expected:** Includes the ticket from Test 3 plus the original `tkt-501`.
---
### Test 5 — Update order status (write + rollback path)
**Prompt:**
```text
Call update_order_status with api_key dev-agent-key, order_id ord-1002, status shipped.
Then get_orders for cust-001 and confirm ord-1002 is shipped.
```
**Expected:** `update_order_status` returns `order` with `status: shipped`. `get_orders` reflects the change.
---
### Test 6 — Health check (any authenticated role)
**Prompt:**
```text
Run health_check with api_key dev-readonly-key.
```
**Expected:** `status: healthy`, `circuit_open: false`, timestamp present.
---
### Test 7 — Metrics (admin only)
**Prompt:**
```text
Call get_metrics with api_key dev-admin-key.
```
**Expected:** Counters include `resource_reads`, `tool_calls`, `started_at`. Values should be > 0 after Tests 1–6.
---
### Test 8 — RBAC: readonly cannot write
**Prompt:**
```text
Try create_support_ticket with api_key dev-readonly-key, customer_id cust-001, subject "Should fail", priority low.
```
**Expected:** `error` mentioning role cannot perform `tickets:write` (or permission denied). No new ticket created.
---
### Test 9 — RBAC: agent cannot read metrics
**Prompt:**
```text
Call get_metrics with api_key dev-agent-key.
```
**Expected:** `error` — role cannot perform `metrics:read`.
---
### Test 10 — Invalid API key
**Prompt:**
```text
Call get_customers with api_key bad-key-123.
```
**Expected:** `error`: invalid or missing API key. Check log: `auth_failures` increments (visible via Test 7 after using admin key).
---
### Test 11 — Validation error (safe message, no stack trace)
**Prompt:**
```text
Call update_order_status with api_key dev-agent-key, order_id ord-9999, status shipped.
```
**Expected:** `error`: unknown order_id. No internal exception text leaked to Claude.
---
### Audit log spot-check
While running tests, watch:
```bash
tail -f ~/Library/Logs/Claude/mcp-server-customer_service.log
```
You should see `AUDIT` JSON lines for reads and writes, e.g. `resource.read`, `tool.create_support_ticket`, `tool.update_order_status`.
### Quick smoke prompt (all-in-one)
```text
Using customer_service MCP and api_key dev-agent-key:
1) get_customers
2) get_orders for cust-001
3) create_support_ticket for cust-001 — subject "Claude integration test" priority medium
4) health_check with dev-readonly-key
5) get_metrics with dev-admin-key
Summarize results and flag any errors.
```
## Example prompts
```text
Use customer_service MCP with api_key dev-agent-key:
- get_orders for customer cust-001
- create_support_ticket for cust-001 subject "Where is my order?" priority high
```
```text
health_check with dev-readonly-key
get_metrics with dev-admin-key
```
## Docker
```bash
docker build -t customer-service-mcp .
docker run --rm -i \
-e API_KEYS=dev-admin-key:admin,dev-agent-key:agent,dev-readonly-key:readonly \
customer-service-mcp
```
For production, terminate **TLS at a reverse proxy** if you expose HTTP/SSE transport; stdio MCP inside the container stays unencrypted (host manages the pipe).
## Security notes
- Never commit real API keys.
- Errors returned to the client are sanitized (no stack traces).
- Tool inputs are validated and length-limited.
- Audit logs go to stderr — ship to your log aggregator in prod.
- Rotate keys and use distinct keys per role/tenant.
## Assignment mapping
Covers the course checklist in a minimal form: server class, API key auth, RBAC, 3 resource types, 2 write tools, audit logging, health/metrics, rate limit, cache, circuit breaker, graceful errors, Docker.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues