Build a Pro-Code A2A Agent for SAP S/4HANA Cloud with the CAP Agent Plugin (Node.js)
Share

[[{“value”:”

Overview

 

The CAP Agent Plugin (`@cap-js/agents`) is currently in Alpha (experimental). This tutorial shows how to use it to build a pro-code Agent-to-Agent (A2A) agent that exposes the SAP S/4HANA Cloud Outbound Delivery OData v2 API as an AI-callable endpoint.

 

By the end, you will have:
  • A CAP Node.js service that proxies the S/4HANA `API_OUTBOUND_DELIVERY_SRV` OData v2 API
  • A pro-code A2A Agent endpoint ready to be integrated with Joule or any MCP-compatible AI tool (such as Claude)

 

Prerequisites
  • SAP BTP account with a Cloud Foundry environment
  • SAP S/4HANA Cloud system with access to the Outbound Delivery API
  • SAP CAP (`@sap/cds`) installed globally
  • Node.js 20+
  • Cloud Foundry CLI (`cf`)
  • SAP AI Core service instance on BTP

 

Procedure

 

Step 1 — Generate a Sample CAP Project
Scaffold a new CAP Node.js project and open it in VS Code:

cds init capagents4 –nodejs
cd capagents4
code .

Jacky_Liu1_0-1787220816089.png

 

Step 2 — Download the OData API Metadata
Go to the SAP API Business Hub — Outbound Delivery API and download the EDMX metadata file.

 

Step 3 — Import the EDMX Metadata into CAP
Use the `cds import` command to generate a CDS definition from the downloaded EDMX file:

cds import <path-to-edmx-file> –as cds –out srv/external/API_OUTBOUND_DELIVERY_SRV_0002.cds

Jacky_Liu1_1-1787220853105.png

 

Step 4 — Configure `package.json`
Update `package.json` to configure the S/4HANA connection credentials for hybrid (local) and production (Cloud Foundry) profiles.

 

Before:

Jacky_Liu1_2-1787220872703.png

 

“cds”: {
“requires”: {
“API_OUTBOUND_DELIVERY_SRV_0002”: {
“kind”: “odata-v2”,
“model”: “srv/external/API_OUTBOUND_DELIVERY_SRV_0002”
}
}
}

 
After:

“cds”: {
“requires”: {
“API_OUTBOUND_DELIVERY_SRV_0002”: {
“kind”: “odata-v2”,
“model”: “srv/external/API_OUTBOUND_DELIVERY_SRV_0002”,
“[hybrid]”: {
“csrf”: true,
“csrfInBatch”: true,
“credentials”: {
“url”: “https://<S4-instance>-api.s4hana.ondemand.com/sap/opu/odata/sap/API_OUTBOUND_DELIVERY_SRV;v=0002”,
“authentication”: “BasicAuthentication”,
“username”: “<S4-communication-user>”,
“password”: “<S4-communication-password>”
}
},
“[production]”: {
“credentials”: {
“destination”: “<S4-destination-name>”,
“path”: “/sap/opu/odata/sap/API_OUTBOUND_DELIVERY_SRV;v=0002”
}
}
}
}
}

 

Jacky_Liu1_3-1787220888177.png

 
> Replace `<S4-instance>`, `<S4-communication-user>`, `<S4-communication-password>`, and `<S4-destination-name>` with your actual values.

 

Step 5 — Define the CAP Service (`srv/dnsrv.cds`)
Create `srv/dnsrv.cds` to expose the delivery entities and a `createDelivery` action. The `@agent` annotation registers the service as an A2A agent endpoint:

using {API_OUTBOUND_DELIVERY_SRV_0002 as s4h} from ‘./external/API_OUTBOUND_DELIVERY_SRV_0002’;

service dnsservices {

entity DeliveryDocument as projection on s4h.A_OutbDeliveryHeader;

entity DeliveryDocumentItem as projection on s4h.A_OutbDeliveryItem;

type DeliveryItemInput {
ReferenceSDDocument : String;
ReferenceSDDocumentItem : String;
}

action createDelivery(ShippingPoint: String,
items: many DeliveryItemInput) returns DeliveryDocument;
}

annotate dnsservices with @AGent;

 

Jacky_Liu1_4-1787220901247.png

 

Step 6 — Implement the Service Handler (`srv/dnsrv.js`)
Create `srv/dnsrv.js` to delegate CRUD operations to S/4HANA and handle the `createDelivery` action:

const cds = require(“@sap/cds”);

module.exports = class dnsservices extends cds.ApplicationService {
async init() {
const s4h = await cds.connect.to(“API_OUTBOUND_DELIVERY_SRV_0002”);

const { DeliveryDocument, DeliveryDocumentItem } = this.entities;

this.on(“READ”, DeliveryDocument, (req) => s4h.run(req.query));
this.on(“READ”, DeliveryDocumentItem, (req) => s4h.run(req.query));

this.on(“createDelivery”, async (req) => {
const { ShippingPoint, items } = req.data;
const result = await s4h.post(“/A_OutbDeliveryHeader”, {
ShippingPoint,
to_DeliveryDocumentItem: items.map((i) => ({
ReferenceSDDocument: i.ReferenceSDDocument,
ReferenceSDDocumentItem: i.ReferenceSDDocumentItem,
})),
});
return result;
});

return super.init();
}
};

Jacky_Liu1_6-1787220923458.png

 

Step 7 — Add LLM Configuration in `package.json`
Under `cds.requires`, add the AI Core LLM binding so the agent plugin can invoke the language model:

“llm”: {
“kind”: “aicore”,
“model”: “anthropic–claude-4.6-sonnet”
},

 

Jacky_Liu1_7-1787220934739.png

 

Step 8 — Add Agent Plugin, XSUAA, and MTA Support
Install the agent plugin and scaffold the required BTP service configurations:

npm add @cap-js/agents
cds add xsuaa
cds add mta

 

Jacky_Liu1_8-1787220944931.png

 

Step 9 — Add AI Core Resource to the MTA File
Open `mta.yaml` and add a resource entry for the SAP AI Core service instance so it is bound during deployment.
 

Jacky_Liu1_9-1787220956636.png

 

Jacky_Liu1_10-1787220964404.png

 

Step 10 — Run the Application Locally (Hybrid Mode)
Bind to your BTP services and start the CAP server using the hybrid profile to connect to the real S/4HANA system:

cf login -a <Cloud Foundry API Endpoint> –sso
cds bind -2 <AI Core instance>
npm i
cds watch –profile hybrid

Jacky_Liu1_11-1787221001629.pngJacky_Liu1_12-1787221015599.pngJacky_Liu1_14-1787221041631.pngJacky_Liu1_15-1787221055537.png

 

> Note: If you are using Node.js 24, run the following command before starting:

npm install-scripts approve better-sqlite3 && npm rebuild better-sqlite3

 

 

 

Step 11 — Test the Agent Endpoint Locally
Use an MCP-compatible client (such as Claude Desktop or the CAP MCP client) to invoke the agent and verify it can query and create outbound deliveries.
 

Jacky_Liu1_0-1787221158192.png

Jacky_Liu1_1-1787221165090.pngJacky_Liu1_2-1787221172619.png

Jacky_Liu1_3-1787221189589.png

 

Step 12 — Deploy to SAP BTP Cloud Foundry
Log in to Cloud Foundry and deploy the application using `cds up`:

cds up

Jacky_Liu1_4-1787221215910.png

 

Step 13 — Verify the Deployed A2A Agent
Confirm the agent endpoint is running and accessible in the BTP environment.
 
Jacky_Liu1_5-1787221228549.png

 

 

The End! Thanks for your time! Jacky Liu

“}]] 

 [[{“value”:”Overview The CAP Agent Plugin (`@cap-js/agents`) is currently in Alpha (experimental). This tutorial shows how to use it to build a pro-code Agent-to-Agent (A2A) agent that exposes the SAP S/4HANA Cloud Outbound Delivery OData v2 API as an AI-callable endpoint. By the end, you will have:A CAP Node.js service that proxies the S/4HANA `API_OUTBOUND_DELIVERY_SRV` OData v2 APIA pro-code A2A Agent endpoint ready to be integrated with Joule or any MCP-compatible AI tool (such as Claude) PrerequisitesSAP BTP account with a Cloud Foundry environmentSAP S/4HANA Cloud system with access to the Outbound Delivery APISAP CAP (`@sap/cds`) installed globallyNode.js 20+Cloud Foundry CLI (`cf`)SAP AI Core service instance on BTP Procedure Step 1 — Generate a Sample CAP ProjectScaffold a new CAP Node.js project and open it in VS Code:cds init capagents4 –nodejs
cd capagents4
code . Step 2 — Download the OData API MetadataGo to the SAP API Business Hub — Outbound Delivery API and download the EDMX metadata file. Step 3 — Import the EDMX Metadata into CAPUse the `cds import` command to generate a CDS definition from the downloaded EDMX file:cds import <path-to-edmx-file> –as cds –out srv/external/API_OUTBOUND_DELIVERY_SRV_0002.cds Step 4 — Configure `package.json`Update `package.json` to configure the S/4HANA connection credentials for hybrid (local) and production (Cloud Foundry) profiles. Before: “cds”: {
“requires”: {
“API_OUTBOUND_DELIVERY_SRV_0002”: {
“kind”: “odata-v2”,
“model”: “srv/external/API_OUTBOUND_DELIVERY_SRV_0002”
}
}
} After:”cds”: {
“requires”: {
“API_OUTBOUND_DELIVERY_SRV_0002”: {
“kind”: “odata-v2”,
“model”: “srv/external/API_OUTBOUND_DELIVERY_SRV_0002”,
“[hybrid]”: {
“csrf”: true,
“csrfInBatch”: true,
“credentials”: {
“url”: “https://<S4-instance>-api.s4hana.ondemand.com/sap/opu/odata/sap/API_OUTBOUND_DELIVERY_SRV;v=0002”,
“authentication”: “BasicAuthentication”,
“username”: “<S4-communication-user>”,
“password”: “<S4-communication-password>”
}
},
“[production]”: {
“credentials”: {
“destination”: “<S4-destination-name>”,
“path”: “/sap/opu/odata/sap/API_OUTBOUND_DELIVERY_SRV;v=0002”
}
}
}
}
}  > Replace `<S4-instance>`, `<S4-communication-user>`, `<S4-communication-password>`, and `<S4-destination-name>` with your actual values. Step 5 — Define the CAP Service (`srv/dnsrv.cds`)Create `srv/dnsrv.cds` to expose the delivery entities and a `createDelivery` action. The `@agent` annotation registers the service as an A2A agent endpoint:using {API_OUTBOUND_DELIVERY_SRV_0002 as s4h} from ‘./external/API_OUTBOUND_DELIVERY_SRV_0002’;

service dnsservices {

entity DeliveryDocument as projection on s4h.A_OutbDeliveryHeader;

entity DeliveryDocumentItem as projection on s4h.A_OutbDeliveryItem;

type DeliveryItemInput {
ReferenceSDDocument : String;
ReferenceSDDocumentItem : String;
}

action createDelivery(ShippingPoint: String,
items: many DeliveryItemInput) returns DeliveryDocument;
}

annotate dnsservices with @AGent;  Step 6 — Implement the Service Handler (`srv/dnsrv.js`)Create `srv/dnsrv.js` to delegate CRUD operations to S/4HANA and handle the `createDelivery` action:const cds = require(“@sap/cds”);

module.exports = class dnsservices extends cds.ApplicationService {
async init() {
const s4h = await cds.connect.to(“API_OUTBOUND_DELIVERY_SRV_0002”);

const { DeliveryDocument, DeliveryDocumentItem } = this.entities;

this.on(“READ”, DeliveryDocument, (req) => s4h.run(req.query));
this.on(“READ”, DeliveryDocumentItem, (req) => s4h.run(req.query));

this.on(“createDelivery”, async (req) => {
const { ShippingPoint, items } = req.data;
const result = await s4h.post(“/A_OutbDeliveryHeader”, {
ShippingPoint,
to_DeliveryDocumentItem: items.map((i) => ({
ReferenceSDDocument: i.ReferenceSDDocument,
ReferenceSDDocumentItem: i.ReferenceSDDocumentItem,
})),
});
return result;
});

return super.init();
}
}; Step 7 — Add LLM Configuration in `package.json`Under `cds.requires`, add the AI Core LLM binding so the agent plugin can invoke the language model:”llm”: {
“kind”: “aicore”,
“model”: “anthropic–claude-4.6-sonnet”
},  Step 8 — Add Agent Plugin, XSUAA, and MTA SupportInstall the agent plugin and scaffold the required BTP service configurations:npm add @cap-js/agents
cds add xsuaa
cds add mta  Step 9 — Add AI Core Resource to the MTA FileOpen `mta.yaml` and add a resource entry for the SAP AI Core service instance so it is bound during deployment.   Step 10 — Run the Application Locally (Hybrid Mode)Bind to your BTP services and start the CAP server using the hybrid profile to connect to the real S/4HANA system:cf login -a <Cloud Foundry API Endpoint> –sso
cds bind -2 <AI Core instance>
npm i
cds watch –profile hybrid > Note: If you are using Node.js 24, run the following command before starting:npm install-scripts approve better-sqlite3 && npm rebuild better-sqlite3   Step 11 — Test the Agent Endpoint LocallyUse an MCP-compatible client (such as Claude Desktop or the CAP MCP client) to invoke the agent and verify it can query and create outbound deliveries.  Step 12 — Deploy to SAP BTP Cloud FoundryLog in to Cloud Foundry and deploy the application using `cds up`:cds up Step 13 — Verify the Deployed A2A AgentConfirm the agent endpoint is running and accessible in the BTP environment.   The End! Thanks for your time! Jacky Liu”}]] Read More Technology Blog Posts by SAP articles 

#SAPCHANNEL

By ali

Leave a Reply