JouleOps MCP Server
by nilansh-07
README.md
# JouleOps @ NorthWind Manufacturing
> **Agentic AI Enterprise Assistant using SAP Joule, SAP HANA Cloud,
> Python FastAPI, and Model Context Protocol (MCP).**
JouleOps is a scenario-based enterprise assistant for NorthWind
Manufacturing. It provides a governed natural-language interface for
retrieving operational data from SAP HANA Cloud and performing
controlled business actions through Python FastAPI services and a custom
MCP server.
------------------------------------------------------------------------
## Table of Contents
- [Project Overview](#project-overview)
- [Problem Statement](#problem-statement)
- [Key Features](#key-features)
- [Architecture](#architecture)
- [Technology Stack](#technology-stack)
- [Project Structure](#project-structure)
- [Business Capabilities](#business-capabilities)
- [Database](#database)
- [REST API](#rest-api)
- [MCP Server](#mcp-server)
- [Environment Configuration](#environment-configuration)
- [Local Setup](#local-setup)
- [Running the Project](#running-the-project)
- [Testing](#testing)
- [SAP BTP and Joule Integration](#sap-btp-and-joule-integration)
- [Security and Guardrails](#security-and-guardrails)
- [Demo Scenarios](#demo-scenarios)
- [Troubleshooting](#troubleshooting)
- [Reproducibility Checklist](#reproducibility-checklist)
- [Future Improvements](#future-improvements)
- [License](#license)
------------------------------------------------------------------------
## Project Overview
NorthWind Manufacturing stores its operational data in SAP HANA Cloud.
JouleOps provides a single agentic interface for common plant, sales,
and finance operations.
The intended end-to-end flow is:
``` text
User
↓
SAP Joule / Joule Studio Agent
↓
Joule Skill OR MCP Tool
↓
Python FastAPI / MCP Server
↓
SAP HANA Cloud
↓
JSON Result
↓
Joule Agent
↓
Grounded Response
```
The project combines REST-based Joule Skills with MCP-based tool
exposure so the same backend capabilities can be consumed through
governed integration paths.
------------------------------------------------------------------------
## Problem Statement
The project addresses common operational tasks at NorthWind
Manufacturing:
- Check material stock and safety stock at a plant.
- Retrieve open sales orders for a region and date range.
- Review customer exposure and overdue invoices.
- Summarize overdue invoices and support collection decisions.
- Create maintenance tickets when operational action is required.
Instead of manually querying several systems, users can express these
requirements in natural language through SAP Joule.
------------------------------------------------------------------------
## Key Features
### Operational Data
- Material details by material and plant.
- Open sales orders by region and date range.
- Customer summaries.
- Overdue invoice summaries.
### Business Action
- Create maintenance tickets.
- Verify material/plant combinations before creating tickets.
- Write audit records for business actions.
### MCP
- Custom Python MCP server using FastMCP.
- Streamable HTTP transport.
- MCP tool discovery and execution through MCP Inspector.
- Reuse of backend business logic.
### Guardrails
- HANA credentials remain in the backend.
- Pydantic validation.
- Parameterized SQL.
- Audit logging.
- Role-aware write operations.
- No guessing of missing required business parameters.
------------------------------------------------------------------------
## Architecture
``` text
┌──────────────────────┐
│ User / Joule │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ SAP Joule Studio │
│ Agent │
└──────────┬───────────┘
│
┌──────────┴───────────┐
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Joule Skill │ │ MCP Server │
│ REST Action │ │ FastMCP │
└──────┬───────┘ └──────┬───────┘
│ │
└──────────┬──────────┘
▼
┌──────────────────────┐
│ Python Backend │
│ FastAPI + Services │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ SAP HANA Cloud │
│ NORTHWIND │
└──────────────────────┘
```
### Responsibilities
Component Responsibility
-------------------- ----------------------------------------------
SAP Joule Natural-language interaction
Joule Studio Agent Intent routing, planning, and tool selection
Joule Skills REST-based actions
MCP Server MCP tool exposure
FastAPI Backend action/API layer
Services Business logic and HANA queries
HANA Cloud Data persistence
AUDIT_LOG Write-operation auditing
------------------------------------------------------------------------
## Technology Stack
Technology Purpose
-------------------------- ------------------------
Python 3.11+ Backend and MCP
FastAPI REST API
Pydantic Validation and schemas
Uvicorn ASGI server
`hdbcli` SAP HANA connectivity
SAP HANA Cloud Database
FastMCP / `mcp` MCP server
SAP Joule / Joule Studio Agentic AI
SAP Build SAP-native integration
MCP Inspector MCP testing
Git / GitHub Version control
------------------------------------------------------------------------
## Project Structure
``` text
jouleops/
│
├── app/
│ ├── api/
│ │ └── routes.py
│ │
│ ├── db/
│ │ └── db.py
│ │
│ ├── models/
│ │ └── models.py
│ │
│ ├── services/
│ │ ├── customers.py
│ │ ├── invoices.py
│ │ ├── materials.py
│ │ ├── sales_orders.py
│ │ └── tickets.py
│ │
│ └── main.py
│
├── mcp/
│ └── server.py
│
├── sql/
│ ├── 01_schema.sql
│ ├── 02_seed.sql
│ └── generate_seed.py
│
├── tests/
│
├── .env
├── .gitignore
├── requirements.txt
└── README.md
```
The application separates HTTP routing, database connectivity, business
services, data models, and MCP integration.
------------------------------------------------------------------------
## Business Capabilities
### 1. Material Details
``` text
GET /materials/{material_id}/{plant_code}
```
Example:
``` text
GET /materials/MAT-1023/PLT-PUN
```
Retrieves material information for a specific plant.
### 2. Open Sales Orders
``` text
GET /sales-orders/open
```
Required parameters:
``` text
region
date_from
date_to
```
The service retrieves open orders and groups the returned orders by
customer.
### 3. Customer Summary
``` text
GET /customers/{customer_id}/summary
```
Example:
``` text
GET /customers/C-501/summary
```
Combines customer and invoice information for customer exposure
analysis.
### 4. Overdue Invoice Summary
``` text
GET /customers/{customer_id}/overdue-invoices
```
Example:
``` text
GET /customers/C-501/overdue-invoices
```
Provides overdue invoice information used by the agent for collection
recommendations.
### 5. Create Maintenance Ticket
``` text
POST /tickets
```
The service:
1. Validates the request.
2. Verifies the material exists at the requested plant.
3. Creates a ticket ID.
4. Inserts the ticket into HANA.
5. Inserts an audit record.
6. Commits the transaction.
7. Returns the created ticket.
------------------------------------------------------------------------
## Database
The application uses the `NORTHWIND` schema in SAP HANA Cloud.
### Tables
``` text
NORTHWIND.MATERIALS
NORTHWIND.SALES_ORDERS
NORTHWIND.CUSTOMERS
NORTHWIND.INVOICES
NORTHWIND.TICKETS
NORTHWIND.AUDIT_LOG
```
### MATERIALS
Stores material ID, description, category, unit price, stock quantity,
safety stock, and plant code.
### SALES_ORDERS
Stores order ID, customer ID, material ID, quantity, status, creation
date, and region.
### CUSTOMERS
Stores customer ID, name, region, credit limit, and outstanding amount.
### INVOICES
Stores invoice ID, customer ID, amount, due date, status, and days
overdue.
### TICKETS
Stores maintenance tickets created through JouleOps.
### AUDIT_LOG
Stores timestamp, user role, tool name, masked parameters, and outcome
for audited operations.
### Database Scripts
``` text
sql/01_schema.sql
```
Creates the database objects.
``` text
sql/02_seed.sql
```
Loads synthetic NorthWind data.
``` text
sql/generate_seed.py
```
Generates seed data when required.
------------------------------------------------------------------------
## REST API
Start the API from the project root:
``` powershell
uvicorn app.main:app --reload
```
Default local address:
``` text
http://127.0.0.1:8000
```
Swagger UI:
``` text
http://127.0.0.1:8000/docs
```
OpenAPI specification:
``` text
http://127.0.0.1:8000/openapi.json
```
The generated OpenAPI document can be used when registering the REST
actions in SAP Build.
------------------------------------------------------------------------
## MCP Server
The project exposes selected backend capabilities through a custom
FastMCP server.
Local MCP endpoint:
``` text
http://127.0.0.1:8001/mcp
```
Transport:
``` text
Streamable HTTP
```
The MCP server exposes tools for operations such as:
``` text
get_customer_summary_tool
get_material_details
get_open_sales_orders_tool
summarize_overdue_invoices
create_maintenance_ticket
```
The MCP tool signature must match the underlying business operation. For
example, open sales orders requires:
``` text
region
date_from
date_to
```
rather than a single `customer_id`.
------------------------------------------------------------------------
## Environment Configuration
Create a `.env` file in the project root:
``` env
HANA_HOST=your-hana-host
HANA_PORT=443
HANA_USER=your-hana-user
HANA_PASSWORD=your-hana-password
```
Do not commit `.env`.
Recommended `.gitignore` entries:
``` gitignore
.env
.venv/
__pycache__/
*.pyc
```
HANA credentials must remain server-side and must never be included in
Joule prompts, MCP descriptions, LLM context, or API responses.
------------------------------------------------------------------------
## Local Setup
### 1. Clone the repository
``` powershell
git clone <repository-url>
cd jouleops
```
### 2. Create a virtual environment
``` powershell
py -m venv .venv
```
Activate it:
``` powershell
.\.venv\Scripts\Activate.ps1
```
### 3. Install dependencies
``` powershell
pip install -r requirements.txt
```
### 4. Configure HANA
Create `.env` and provide the SAP HANA Cloud connection information.
### 5. Create the database
Execute:
``` text
sql/01_schema.sql
```
against the target HANA Cloud schema.
### 6. Load seed data
Execute:
``` text
sql/02_seed.sql
```
or generate the required data using:
``` text
sql/generate_seed.py
```
------------------------------------------------------------------------
## Running the Project
### FastAPI
``` powershell
uvicorn app.main:app --reload
```
Verify:
``` text
http://127.0.0.1:8000/docs
```
### MCP Server
Run the MCP server using the ASGI/application entry point defined in
`mcp/server.py`.
For an ASGI application exposed as `app`, the command is:
``` powershell
uvicorn mcp.server:app --host 127.0.0.1 --port 8001
```
The final command should match the object exported by the project's
`mcp/server.py`.
------------------------------------------------------------------------
## Testing
### REST API
Use Swagger UI:
``` text
http://127.0.0.1:8000/docs
```
Recommended checks:
``` text
GET /materials/MAT-1023/PLT-PUN
GET /customers/C-501/summary
GET /customers/C-501/overdue-invoices
GET /sales-orders/open
POST /tickets
```
For the ticket operation, verify both:
``` text
NORTHWIND.TICKETS
NORTHWIND.AUDIT_LOG
```
after a successful write.
### MCP Inspector
Use [MCP Inspector](https://github.com/modelcontextprotocol/inspector)
to inspect and execute the MCP server.
Configure:
``` text
Server ID: jouleops-mcp
Transport: Streamable HTTP
URL: http://127.0.0.1:8001/mcp
```
After connecting:
1. Open **Tools**.
2. Select a JouleOps tool.
3. Enter all required parameters.
4. Execute the tool.
5. Verify the JSON response.
6. Verify HANA data where appropriate.
7. For write operations, verify `AUDIT_LOG`.
------------------------------------------------------------------------
## SAP BTP and Joule Integration
The intended enterprise flow is:
``` text
SAP Joule
↓
Joule Studio Agent
↓
BTP Destination
↓
FastAPI / MCP
↓
SAP HANA Cloud
```
### FastAPI Action Destination
The REST API is exposed through a BTP Destination for Joule Studio
actions.
The destination should contain:
``` text
sap-joule-studio-action = true
```
### MCP Destination
The MCP server is exposed through an HTTP destination configured for
Joule Studio MCP discovery.
The destination should contain:
``` text
sap-joule-studio-mcp-server = true
```
For local demonstrations, a tunnel such as ngrok can expose the local
service.
HANA itself should never be exposed directly to Joule.
------------------------------------------------------------------------
## Security and Guardrails
### No HANA Credentials to the LLM
Only FastAPI/MCP holds HANA credentials.
``` text
Joule
↓
Tool parameters
↓
FastAPI / MCP
↓
HANA credentials
↓
SAP HANA Cloud
```
### Parameterized SQL
Queries use parameter binding:
``` python
cursor.execute(
"""
SELECT ...
WHERE MATERIAL_ID = ?
AND PLANT_CODE = ?
""",
(material_id, plant_code),
)
```
rather than string concatenation.
### Audit Logging
Write operations should record:
``` text
user role
tool name
masked parameters
outcome
timestamp
```
in `NORTHWIND.AUDIT_LOG`.
### Input Validation
FastAPI/Pydantic models validate structured inputs before business logic
executes.
### Role-Based Access
The intended roles are:
``` text
PLANT_SUPERVISOR
SALES_MANAGER
FINANCE
VIEWER
```
A `VIEWER` must not be allowed to create maintenance tickets.
### No Guessing
If a required parameter is missing, the agent should request the missing
information instead of guessing or sending null values to a write
operation.
------------------------------------------------------------------------
## Demo Scenarios
### Scenario 1 --- Stock Check + Auto Ticket
``` text
Is steel coil MAT-1023 below safety stock in Pune?
If yes, raise a HIGH-priority ticket for the Mechanical team.
```
Expected flow:
``` text
get_material_details
↓
Compare stock with safety stock
↓
create_ticket
↓
AUDIT_LOG
↓
Confirmation
```
### Scenario 2 --- Open Sales Orders
``` text
Show me last week's open sales orders for the South region,
grouped by customer, with totals.
```
Expected tool:
``` text
get_open_sales_orders
```
Expected parameters:
``` text
region
date_from
date_to
```
### Scenario 3 --- Customer Exposure
``` text
Summarize C-501's overdue invoices and tell me what to do next.
```
Expected tools:
``` text
get_customer_summary
summarize_overdue_invoices
```
### Scenario 4 --- MCP Architecture Demonstration
``` text
Give me an inventory snapshot for the Chennai plant.
```
This scenario is intended to demonstrate an equivalent business
capability through an MCP tool.
### Scenario 5 --- Escalation / Missing Parameters
``` text
Create a ticket.
```
The agent should request the required information instead of guessing.
For a `VIEWER`, the write operation must be rejected.
------------------------------------------------------------------------
## Troubleshooting
### `500 Internal Server Error`
Check:
1. `.env` values.
2. HANA host and port.
3. HANA Cloud network accessibility.
4. Schema/table names.
5. SQL parameters.
6. Uvicorn logs.
### HANA Table Not Found
Verify the schema and tables:
``` sql
SELECT SCHEMA_NAME, TABLE_NAME
FROM SYS.TABLES
ORDER BY SCHEMA_NAME, TABLE_NAME;
```
The project expects the NorthWind tables under:
``` text
NORTHWIND
```
### MCP Inspector Cannot Connect
Verify:
``` text
MCP server is running
Port = 8001
Path = /mcp
Transport = Streamable HTTP
```
Expected endpoint:
``` text
http://127.0.0.1:8001/mcp
```
### MCP Tool Reports Missing Arguments
Check that the MCP wrapper signature matches the service function.
For example:
``` python
def get_open_sales_orders(
region: str,
date_from: date,
date_to: date,
):
...
```
The MCP tool must expose all three parameters.
### SAP Build Action Returns `404 Not Found`
The SAP Build Action endpoint must exactly match the FastAPI route.
For example:
``` text
GET /customers/{customer_id}/overdue-invoices
```
must not be configured as:
``` text
/invoices/{customer_id}/overdue-summary
```
Use the current FastAPI OpenAPI specification:
``` text
http://127.0.0.1:8000/openapi.json
```
### Invalid OpenAPI File
Use the OpenAPI document generated by the current FastAPI application
rather than an outdated specification.
------------------------------------------------------------------------
## Reproducibility Checklist
### Backend
- [ ] Python environment created.
- [ ] Dependencies installed.
- [ ] `.env` configured.
- [ ] FastAPI starts successfully.
- [ ] Swagger UI loads.
- [ ] OpenAPI specification loads.
- [ ] All core REST operations work.
### HANA
- [ ] HANA Cloud instance available.
- [ ] `NORTHWIND` schema exists.
- [ ] Required tables exist.
- [ ] Seed data loaded.
- [ ] Ticket creation persists.
- [ ] Audit records are created.
### MCP
- [ ] MCP server starts.
- [ ] Streamable HTTP endpoint is reachable.
- [ ] MCP Inspector connects.
- [ ] Tools are discovered.
- [ ] All required parameters are exposed.
- [ ] Read tools return valid results.
- [ ] Write tools create audit records.
### Joule / SAP Build
- [ ] JouleOps agent configured.
- [ ] REST actions registered.
- [ ] MCP server connected.
- [ ] BTP Destinations configured.
- [ ] Required destination properties configured.
- [ ] Correct tools selected for representative prompts.
- [ ] Missing parameters handled correctly.
- [ ] RBAC behavior verified.
- [ ] Source transparency verified.
### Demo
- [ ] Stock + ticket scenario tested.
- [ ] Open sales order scenario tested.
- [ ] Customer/invoice scenario tested.
- [ ] MCP scenario tested.
- [ ] Escalation/RBAC scenario tested.
- [ ] Tool traces captured.
- [ ] HANA results verified.
------------------------------------------------------------------------
## Future Improvements
Potential extensions include:
- Deploy FastAPI and MCP to SAP BTP Cloud Foundry or Kyma.
- Add CI/CD using GitHub Actions.
- Add comprehensive automated tests.
- Build a Fiori/SAPUI5 audit dashboard.
- Add HANA Vector Engine capabilities.
- Add semantic search over historical tickets.
- Add document grounding for credit/collection policies.
- Add multi-agent orchestration.
- Add bilingual interaction.
- Add production-grade authentication and authorization.
- Add structured observability and performance monitoring.
------------------------------------------------------------------------
## License
This project was developed as an educational/capstone implementation
demonstrating SAP Joule, SAP HANA Cloud, Python FastAPI, and Model
Context Protocol integration.
Unless a separate license is added to the repository, the project should
be treated as project-specific educational work.
------------------------------------------------------------------------
## Acknowledgements
Built using:
- SAP Joule / Joule Studio
- SAP Build
- SAP HANA Cloud
- Python
- FastAPI
- Pydantic
- FastMCP / Model Context Protocol
- MCP Inspector
- Git / GitHub
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues