Description
The CAP MCP Plugin currently lacks support for creating and managing draft entities in SAP CAP (Cloud Application Programming) applications. This prevents AI assistants and MCP clients from interacting with draft-enabled entities in a way that matches OData behavior, leading to critical issues:
Key Problems Solved:
- Invisible Drafts: Draft entities created via MCP tools don't appear in Fiori UI because the critical
DraftAdministrativeData record wasn't being created
- Composition Child Failures: Creating composition children (e.g., attachments, line items) under draft parents failed with service resolution errors
- Lifecycle Bypass: Direct INSERT operations bypassed CAP's draft lifecycle handlers, missing essential metadata population
Use Cases:
- AI-assisted data entry: Allow AI assistants to create and edit draft documents (e.g., purchase orders, consumption requests) that users can review before activation
- Multi-step workflows: Support complex business processes where AI helps populate draft records that require human approval
- Attachment handling: Enable AI to add attachments and related items to draft parent entities
- Draft management: Allow AI to query, update, and delete draft entities with proper user context
Benefits:
- Fiori Integration: Drafts created via MCP are fully visible and manageable in Fiori UIs
- CAP Compliance: Uses CAP's official draft lifecycle (
svc.send('NEW')) instead of bypassing it
- User Context: Properly links drafts to the authenticated user via
DraftAdministrativeData
- Consistency: MCP-created drafts are structurally identical to OData-created drafts
- Composition Support: Handles nested composition children that inherit draft behavior from parents
Suggested Solution
Implement comprehensive draft support through three components, each addressing a specific gap:
1. Root Draft Entity Creation
Before:
- Used direct INSERT operations:
svc.run(INSERT.into(entity.drafts).entries(data))
- Bypassed CAP's draft lifecycle handlers
- Created draft record but NO
DraftAdministrativeData
- ❌ Drafts invisible in Fiori UI
After:
- Use CAP's official draft API:
svc.send('NEW', draftEntityDef, data)
- Triggers CAP's
onNew() handler which creates BOTH draft record AND DraftAdministrativeData
- ✅ Drafts appear in Fiori UI
- ✅ User context properly tracked (
InProcessByUser, DraftIsCreatedByMe)
- ✅ Structurally identical to OData-created drafts
2. Draft Composition Child Support
Before:
- Composition children (e.g., attachments under draft documents) routed to regular INSERT path
- ❌ Error:
Service not found: ConsumptionService.ConsumptionRequests
- ❌ Error:
table has no column named hash (@Core.Computed fields included in SQL)
- ❌ Error:
NOT NULL constraint on DraftAdministrativeData_DraftUUID
After:
- Runtime detection of draft composition children (they inherit
.drafts from parent)
- Use explicit
.columns().values() INSERT to exclude computed fields
- Auto-resolve parent's
DraftAdministrativeData_DraftUUID via lookup
- ✅ Composition children successfully created under draft parents
- ✅ Correctly reference same DraftAdministrativeData as parent
- ✅ No computed field errors
3. Improved Entity Name Parsing
Before:
- Naive split on last dot:
"Service.Entity.SubEntity" → service: "Service.Entity" ❌
- ❌ Service resolution fails for nested entities
After:
- Longest-prefix matching against known service names
"ConsumptionService.ConsumptionRequests.chargeSheets" → service: "ConsumptionService" ✅
- ✅ Correct service resolution for all entity depths
Result Summary
| Metric |
Before |
After |
| Root drafts in Fiori |
❌ Invisible |
✅ Visible |
| DraftAdministrativeData |
❌ Missing |
✅ Created |
| Composition children |
❌ Failed |
✅ Working |
| Nested entity parsing |
❌ Incorrect |
✅ Correct |
| Test coverage |
❌ No draft tests |
✅ 787 tests passing |
Alternatives
Alternative 1: Direct .drafts INSERT (Rejected)
svc.run(INSERT.into(entity.drafts).entries(data));
Issues:
- Bypasses CAP's draft lifecycle
- No
DraftAdministrativeData created
- Drafts invisible in Fiori UI
Alternative 2: Use svc.post() (Rejected)
svc.post(`${entity}.drafts`, data);
Issues:
- Still bypasses
onNew() handler
- Missing draft metadata
- Not the official CAP draft API
Alternative 3: Manual DraftAdministrativeData Creation (Rejected)
// Manually insert draft record
await INSERT.into(entity.drafts).entries(data);
// Manually insert administrative data
await INSERT.into('DraftAdministrativeData').entries({...});
Issues:
- Fragile and error-prone
- Doesn't match CAP's internal implementation
- May break with CAP version updates
- Doesn't respect draft validation rules
Additional Context
References
SAP CAP Documentation
- Draft Support - Official CAP documentation on implementing draft-enabled entities
Related CAP Concepts
Description
The CAP MCP Plugin currently lacks support for creating and managing draft entities in SAP CAP (Cloud Application Programming) applications. This prevents AI assistants and MCP clients from interacting with draft-enabled entities in a way that matches OData behavior, leading to critical issues:
Key Problems Solved:
DraftAdministrativeDatarecord wasn't being createdUse Cases:
Benefits:
svc.send('NEW')) instead of bypassing itDraftAdministrativeDataSuggested Solution
Implement comprehensive draft support through three components, each addressing a specific gap:
1. Root Draft Entity Creation
Before:
svc.run(INSERT.into(entity.drafts).entries(data))DraftAdministrativeDataAfter:
svc.send('NEW', draftEntityDef, data)onNew()handler which creates BOTH draft record ANDDraftAdministrativeDataInProcessByUser,DraftIsCreatedByMe)2. Draft Composition Child Support
Before:
Service not found: ConsumptionService.ConsumptionRequeststable has no column named hash(@Core.Computed fields included in SQL)NOT NULL constraint on DraftAdministrativeData_DraftUUIDAfter:
.draftsfrom parent).columns().values()INSERT to exclude computed fieldsDraftAdministrativeData_DraftUUIDvia lookup3. Improved Entity Name Parsing
Before:
"Service.Entity.SubEntity"→ service:"Service.Entity"❌After:
"ConsumptionService.ConsumptionRequests.chargeSheets"→ service:"ConsumptionService"✅Result Summary
Alternatives
Alternative 1: Direct
.draftsINSERT (Rejected)Issues:
DraftAdministrativeDatacreatedAlternative 2: Use
svc.post()(Rejected)Issues:
onNew()handlerAlternative 3: Manual
DraftAdministrativeDataCreation (Rejected)Issues:
Additional Context
References
SAP CAP Documentation
Related CAP Concepts