TravelService
Exposes SAP CAP-based services via MCP, enabling AI agents to describe and query entities in CQL/CQN, call unbound actions, and access security-controlled projections of the travel service.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@TravelServiceshow me rejected travels over $10k"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
GenAI & MCP Integration in SAP CAP
Companion repository for the live session "GenAI & MCP Integration in SAP CAP".
main holds the base CAP application. Every demo is its own branch, and the
branches form a linear chain — each builds on the previous one, so
git diff main..<branch> shows exactly what that step added.
All facts, versions and annotations in this repo were verified against plugin source code and integration tests on 2026-09-07 — not against READMEs. Where the official docs and the code disagree, the code wins and the branch README says so.
The base app
A deliberately small travel domain: Travels (draft-enabled) with Bookings,
TravelAgencies, Customers and a TravelStatus code list.
300 travels · 752 bookings · 20 agencies · 60 customersThe seed data is generated deterministically and carries two learnable patterns, so AI recommendations have something real to find:
Pattern | Strength |
an agency always bills in its country's currency | 100% (1 currency per agency) |
customers rebook with their "home" agency | 78.7% |
expensive travels get rejected more often | correlated with |
All three status codes are populated (168 Open / 100 Accepted / 32 Rejected), so
no filter demo returns an empty list. The database deploys with
assert_integrity: "DB", which proves every foreign key resolves.
Related MCP server: Bookshop MCP Example
Branches
Each branch carries its own docs/<branch-name>.md with the exact commands, the
verify: checks, and what the official docs get wrong.
Track A — GenAI
Branch | Demo | Runs offline? |
| SAP-RPT-1 field recommendations via | yes (mock) |
|
| yes (mock) |
|
| yes (predictions) |
| a real generative call via SAP Cloud SDK for AI, behind a mockable CAP service | yes (local impl) |
|
| yes |
Track B — MCP
Branch | Demo | Runs offline? |
| expose the service via | yes |
|
| yes |
| writes via unbound actions, the | yes |
|
| yes |
| autowiring into Claude Code; manual VS Code / Copilot config | yes |
| one service, two consumers — an agent invoking CAP's own RAG | yes |
No BTP entitlement is required for any demo. Every branch runs offline; the cloud paths are documented and, where possible, wired so that switching to them is a profile change rather than a code change.
What the upstream exercises get wrong
This repo started as a verification of SAP's recap2026 exercises 08 and 09.
The corrections are load-bearing, not cosmetic:
Claim | Reality |
MCP tools are |
|
| Default is |
| Removed in 1.4.2. TOON is unconditional; JSON only via |
MCP Inspector: "Transport Type" → "Via Proxy" → "Connect" | That is the v1 UI. |
| It is dropped as a prediction target but still sent to SAP AI Core |
"You should see a message indicating that the AI plugin is active" | The plugin logs nothing — not on startup, not on mock fallback |
| Opens an interactive session and never exits. Use |
|
|
Two problems are ours to report upstream, found by building this repo:
@cds.api.ignoreon an element is not access control in MCP's defaultcqlmode — hidden fromdescribe, still returned byquery, while OData andcqnmode both refuse it. Seedocs/09-mcp-security.md.Querying AI Core admin entities with no binding terminates the CAP process — an uncaught
TypeErrorinAICoreService._getToken(), not a 500. Seedocs/03-aicore-service.md.
Quick start
npm ci
npm run watchThen open:
What | URL |
Service index | |
Fiori preview (list report) | |
OData | |
MCP (full service) |
|
MCP (curated agent surface) |
|
Local auth uses CAP's mocked users — alice (role admin) with an empty
password, i.e. Authorization: Basic YWxpY2U6.
No UI5 application is generated: CAP 10's built-in $fiori-preview serves a
full Fiori elements list report and object page straight from the annotations
in app/. That keeps the UI out of the branch diffs entirely.
Maintaining the chain
The branches form a linear chain, so a change to main needs re-stacking:
./rebase-chain.shIt rebases each branch onto its predecessor, using each branch's own first parent as the base.
Two invariants it relies on, both learned the hard way:
One commit per branch. The script uses
<branch>^as the rebase base, so a second commit on a branch makes it silently drop the first. Amend instead of adding commits, and squash if you slip:git reset --soft <branch>~2 && git commit.Do not substitute
git merge-base. Once the parent branch has been rewritten, the merge base moves backwards and the parent's commit is replayed a second time — which conflicts onpackage.json.
Check the invariant before running it:
git log --oneline main..11-genai-mcp-together | wc -l # must equal the branch countPrerequisites
node >= 22.19.0 (MCP Inspector v2 needs this; @sap/cds 10 needs >= 22)
@sap/cds 10.0.6 pinned
@cap-js/sqlite 3.0.2 pinned
@sap/cds-dk 10.x global (npm i -g @sap/cds-dk)Versions are pinned exactly, not floated. Between @cap-js/mcp 1.2.0 and
1.4.3 — about six weeks — a tool was renamed, the default query input format
changed, and a config flag was deleted. Floating those ranges breaks demos.
Layout
db/schema.cds domain model
db/data/*.csv deterministic seed data (generated, committed)
srv/travel-service.cds the service
app/annotations.cds draft + value helps <- gates the AI recommendations feature
app/fiori.cds Fiori elements UI annotations
docs/<branch>.md one per branch: commands, verify checks, doc corrections
mcp-rpc.sh minimal MCP client (branch 06+) -- no Inspector neededVerifying MCP without the Inspector
mcp-rpc.sh posts one JSON-RPC call and unwraps the SSE frame. No download, no
Node version floor, fully deterministic — the safest thing to run on stage:
./mcp-rpc.sh '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | jq -r '.result.tools[].name'
MCP_USER=viewer ./mcp-rpc.sh '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
MCP_URL=http://localhost:4004/mcp/travel-agent ./mcp-rpc.sh '…'This server cannot be deployed
Maintenance
Related MCP Connectors
Let AI agents query data and act across all your business apps via MCP.
Agent-native travel platform: read-only flight, hotel, and brand tools over MCP. OAuth sign-in.
Corporate travel booking and expense management for TripGain, exposed as an MCP server.
Travel tools for AI agents: plan and edit real trips, search stays and tours, import travel videos.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceExposes SAP SuccessFactors HR data as MCP tools for AI agents, enabling natural language queries about employees, jobs, performance, and organizational structure.-
- AlicenseNot gradedqualityCmaintenanceExposes a CAP bookshop service via MCP, enabling AI agents to query books, authors, and genres using natural language.5 npmMIT
- FlicenseNot gradedqualityCmaintenanceEnables natural language querying of SAP business partner data by exposing OData APIs as MCP tools for LLM agents.-
- AlicenseNot gradedqualityCmaintenanceExposes tools for retrieving member profiles and personalized travel recommendations with multi-tenant partner rule enforcement, enabling AI agents to respect business constraints like caps and exclusions.MIT