Skip to main content
Glama
aryansiddhantsap-ctrl

CAP V2 Case MCP

README.md
# CAP V2 Case MCP β€” SAP Sales Cloud V2 Case Integration

A **SAP CAP (Cloud Application Programming Model)** project that exposes SAP Sales Cloud V2 (C4C) case management operations as an **OData V4 + MCP dual-protocol service**.

---

## πŸ“ Architecture Overview

```
Client (OData V4 / MCP)
        β”‚
        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   CaseServices (CAP)    β”‚  ← srv/services.cds + srv/services.js
β”‚  /odata/v4/case-servicesβ”‚
β”‚                         β”‚
β”‚  listCases()            β”‚
β”‚  getCaseById()          β”‚
β”‚  createCase()           β”‚
β”‚  patchCase()            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚ c4c.send() β€” HTTP REST
             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  SAP Sales Cloud V2     β”‚  ← REST API
β”‚  /sap/c4c/api/v1/       β”‚
β”‚    case-service/cases   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

---

## πŸ—‚οΈ Project Structure

| File / Folder | Purpose |
|---|---|
| `srv/services.cds` | CAP service definition β€” public API contract |
| `srv/services.js` | CAP service implementation β€” handler logic |
| `srv/external/SalesSvcCloudV2_case.cds` | Auto-generated CDS model from `cds import` β€” describes the remote REST API |
| `srv/external/SalesSvcCloudV2_case.json` | Original OpenAPI spec from SAP Sales Cloud V2 |
| `package.json` β†’ `cds.requires` | Remote service binding β€” credentials & kind |

---

## πŸ”‘ Key Concepts

### 1. Dual Protocol β€” OData V4 + MCP
The service is annotated with both protocols:
```cds
annotate CaseServices with @protocol: ['odata-v4', 'mcp'];
```
This means the same service is reachable as an OData V4 endpoint **and** as an MCP (Model Context Protocol) tool β€” usable by AI agents.

---

### 2. External Service Import
The remote SAP Sales Cloud V2 API was imported using:
```bash
cds import SalesSvcCloudV2_case.json --as cds
```
This generates `SalesSvcCloudV2_case.cds` β€” a CDS description of the remote REST API. It is used as **documentation/metadata only**, not invoked by name.

---

### 3. `kind: "rest"` β€” Not OData
The remote service is bound as a plain REST adapter in `package.json`:
```json
"SalesSvcCloudV2_case": {
  "kind": "rest",
  "model": "srv/external/SalesSvcCloudV2_case",
  "service": "Case.Service"
}
```
- `kind: "rest"` β†’ CAP uses an HTTP client, not an OData client
- `service: "Case.Service"` β†’ maps the requires key to the actual service definition inside the CDS model (`namespace ![Case]; service Service {}`)
- Because it is REST (not OData), there are **no entities** β€” `c4c.entities` is empty

---

### 4. `c4c.send()` β€” Why Not `SELECT.from()`

| Method | Use when |
|---|---|
| `SELECT.from(c4c.entities.X)` | Remote service has **OData entities** |
| `c4c.send({ method, path, data })` | Remote service is **REST** with functions/actions only |

Since `SalesSvcCloudV2_case.cds` defines only **functions** (no entities), `c4c.send()` is used to make a direct HTTP call to the remote path annotated with `@openapi.path`.

---

### 5. Handler Registration & Service Name Matching

CAP wires the JS class to the CDS service via the **export key** β€” it must match the CDS service name exactly:

```js
// services.js
module.exports = { CaseServices: CaseService };
//                  ↑ must match service name in services.cds
```

Handlers are registered inside `init()` using the **exact function/action name** from `services.cds`:
```js
this.on("listCases", async (req) => { ... });
//       ↑ must match function name in services.cds
```

---

## πŸš€ Operations

| Operation | Type | HTTP | Remote Path |
|---|---|---|---|
| `listCases` | function | `GET` | `/sap/c4c/api/v1/case-service/cases` |
| `getCaseById` | function | `GET` | `/sap/c4c/api/v1/case-service/cases/{id}` |
| `createCase` | action | `POST` | `/sap/c4c/api/v1/case-service/cases` |
| `patchCase` | action | `PATCH` | `/sap/c4c/api/v1/case-service/cases/{id}` |

---

## ▢️ Running Locally

```bash
npm install
cds watch
```

Service available at: `http://localhost:4004/odata/v4/case-services`

---

## πŸ”— References
- [SAP CAP Documentation](https://cap.cloud.sap)
- [CAP External Services](https://cap.cloud.sap/docs/guides/using-services)
- [SAP Sales Cloud V2 API](https://api.sap.com)