JouleOps MCP Server
Exposes SAP HANA Cloud operational data and controlled business actions as MCP tools for natural-language enterprise assistants.
README
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
- Problem Statement
- Key Features
- Architecture
- Technology Stack
- Project Structure
- Business Capabilities
- Database
- REST API
- MCP Server
- Environment Configuration
- Local Setup
- Running the Project
- Testing
- SAP BTP and Joule Integration
- Security and Guardrails
- Demo Scenarios
- Troubleshooting
- Reproducibility Checklist
- Future Improvements
- 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:
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
┌──────────────────────┐
│ 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
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
GET /materials/{material_id}/{plant_code}
Example:
GET /materials/MAT-1023/PLT-PUN
Retrieves material information for a specific plant.
2. Open Sales Orders
GET /sales-orders/open
Required parameters:
region
date_from
date_to
The service retrieves open orders and groups the returned orders by customer.
3. Customer Summary
GET /customers/{customer_id}/summary
Example:
GET /customers/C-501/summary
Combines customer and invoice information for customer exposure analysis.
4. Overdue Invoice Summary
GET /customers/{customer_id}/overdue-invoices
Example:
GET /customers/C-501/overdue-invoices
Provides overdue invoice information used by the agent for collection recommendations.
5. Create Maintenance Ticket
POST /tickets
The service:
- Validates the request.
- Verifies the material exists at the requested plant.
- Creates a ticket ID.
- Inserts the ticket into HANA.
- Inserts an audit record.
- Commits the transaction.
- Returns the created ticket.
Database
The application uses the NORTHWIND schema in SAP HANA Cloud.
Tables
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
sql/01_schema.sql
Creates the database objects.
sql/02_seed.sql
Loads synthetic NorthWind data.
sql/generate_seed.py
Generates seed data when required.
REST API
Start the API from the project root:
uvicorn app.main:app --reload
Default local address:
http://127.0.0.1:8000
Swagger UI:
http://127.0.0.1:8000/docs
OpenAPI specification:
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:
http://127.0.0.1:8001/mcp
Transport:
Streamable HTTP
The MCP server exposes tools for operations such as:
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:
region
date_from
date_to
rather than a single customer_id.
Environment Configuration
Create a .env file in the project root:
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:
.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
git clone <repository-url>
cd jouleops
2. Create a virtual environment
py -m venv .venv
Activate it:
.\.venv\Scripts\Activate.ps1
3. Install dependencies
pip install -r requirements.txt
4. Configure HANA
Create .env and provide the SAP HANA Cloud connection information.
5. Create the database
Execute:
sql/01_schema.sql
against the target HANA Cloud schema.
6. Load seed data
Execute:
sql/02_seed.sql
or generate the required data using:
sql/generate_seed.py
Running the Project
FastAPI
uvicorn app.main:app --reload
Verify:
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:
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:
http://127.0.0.1:8000/docs
Recommended checks:
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:
NORTHWIND.TICKETS
NORTHWIND.AUDIT_LOG
after a successful write.
MCP Inspector
Use MCP Inspector to inspect and execute the MCP server.
Configure:
Server ID: jouleops-mcp
Transport: Streamable HTTP
URL: http://127.0.0.1:8001/mcp
After connecting:
- Open Tools.
- Select a JouleOps tool.
- Enter all required parameters.
- Execute the tool.
- Verify the JSON response.
- Verify HANA data where appropriate.
- For write operations, verify
AUDIT_LOG.
SAP BTP and Joule Integration
The intended enterprise flow is:
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:
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:
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.
Joule
↓
Tool parameters
↓
FastAPI / MCP
↓
HANA credentials
↓
SAP HANA Cloud
Parameterized SQL
Queries use parameter binding:
cursor.execute(
"""
SELECT ...
WHERE MATERIAL_ID = ?
AND PLANT_CODE = ?
""",
(material_id, plant_code),
)
rather than string concatenation.
Audit Logging
Write operations should record:
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:
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
Is steel coil MAT-1023 below safety stock in Pune?
If yes, raise a HIGH-priority ticket for the Mechanical team.
Expected flow:
get_material_details
↓
Compare stock with safety stock
↓
create_ticket
↓
AUDIT_LOG
↓
Confirmation
Scenario 2 --- Open Sales Orders
Show me last week's open sales orders for the South region,
grouped by customer, with totals.
Expected tool:
get_open_sales_orders
Expected parameters:
region
date_from
date_to
Scenario 3 --- Customer Exposure
Summarize C-501's overdue invoices and tell me what to do next.
Expected tools:
get_customer_summary
summarize_overdue_invoices
Scenario 4 --- MCP Architecture Demonstration
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
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:
.envvalues.- HANA host and port.
- HANA Cloud network accessibility.
- Schema/table names.
- SQL parameters.
- Uvicorn logs.
HANA Table Not Found
Verify the schema and tables:
SELECT SCHEMA_NAME, TABLE_NAME
FROM SYS.TABLES
ORDER BY SCHEMA_NAME, TABLE_NAME;
The project expects the NorthWind tables under:
NORTHWIND
MCP Inspector Cannot Connect
Verify:
MCP server is running
Port = 8001
Path = /mcp
Transport = Streamable HTTP
Expected endpoint:
http://127.0.0.1:8001/mcp
MCP Tool Reports Missing Arguments
Check that the MCP wrapper signature matches the service function.
For example:
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:
GET /customers/{customer_id}/overdue-invoices
must not be configured as:
/invoices/{customer_id}/overdue-summary
Use the current FastAPI OpenAPI specification:
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.
- [ ]
.envconfigured. - [ ] FastAPI starts successfully.
- [ ] Swagger UI loads.
- [ ] OpenAPI specification loads.
- [ ] All core REST operations work.
HANA
- [ ] HANA Cloud instance available.
- [ ]
NORTHWINDschema 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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。