cds-kb-mcp
Provides tools for searching and retrieving SAP CDS view definitions and metadata from a knowledge base, supporting local and remote data sources.
Click on "Install 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., "@cds-kb-mcpFind CDS view for material master"
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.
cds-kb-mcp
A dataless MCP server that gives AI agents instant, ranked access to 7,355 SAP S/4HANA released CDS views via semantic search, business taxonomy, and on-demand definition retrieval.
TL;DR — fastest path: install Node ≥ 18, point your MCP client at
node /path/to/cds-kb-mcp.mjs, and you're done. No data download, no config. The server fetches what it needs from GitHub on first use, caches it, and revalidates in the background. See Quick Start.
Benchmark vs. raw file access: ~830× faster, ~94× cheaper in tokens, better top-3 relevance — full numbers in BENCHMARK.md.
Table of Contents
Quick Start — under 60 seconds
Running modes — online (recommended) vs offline
Client Registration — Claude Code, Claude Desktop, Antigravity, generic
Configuration — env vars & flags
Related MCP server: SAP ADT MCP Server
What you get
Coverage | 7,355 released CDS views for S/4HANA Cloud Public Edition |
Enrichment | 7,160 / 7,355 views have a semantic description + synonyms |
Taxonomy | 12 Lines of Business → 829 Business Objects → keyword map |
Search ranking | Field-boosted MiniSearch ( |
Module aliasing | Filter by |
Tools | 5 MCP tools: |
Bundle | Single 784 KB |
Data isolation | The server ships no view data. Data lives in a separate repo, served over GitHub or via a local clone. |
Quick Start
The recommended path is online mode — no clone of the data repo, no config, no path to set. The MCP fetches the search index on first start (~800 KB on the wire), caches it for 24 h, and then operates locally.
1. Install
git clone https://github.com/truongdva2/cds-kb-mcp.git
cd cds-kb-mcp
# The pre-built bundle is committed at dist/cds-kb-mcp.mjs — no build step needed.2. Smoke test
node dist/cds-kb-mcp.mjs --help 2>&1 || true # the server exits without input; that's expectedStderr should read something like:
[cds-kb-mcp] ready. remote:https://raw.githubusercontent.com/truongdva2/cds-kb-data/main (cache ~/.cache/cds-kb/<hash>) | views=7355 enriched=7160 modules=313. Register with your MCP client
See Client Registration below. The shortest version, for Claude Code:
claude mcp add cds-kb -- node /absolute/path/to/cds-kb-mcp/dist/cds-kb-mcp.mjsThen in any project ask the agent something like "find me CDS views for vendor open items" and watch the tool fire.
Installation
Option A — pre-built bundle (recommended)
dist/cds-kb-mcp.mjs is committed to the repo. Clone it, that's it. No npm install, no build step.
git clone https://github.com/truongdva2/cds-kb-mcp.git
node cds-kb-mcp/dist/cds-kb-mcp.mjs # ready to useOption B — build from source
git clone https://github.com/truongdva2/cds-kb-mcp.git
cd cds-kb-mcp
npm install
npm run build # → dist/cds-kb-mcp.mjs (~784 KB)Option C — npm (when published)
npm install -g cds-kb-mcp
cds-kb-mcp # binary on PATHPrerequisites
Node.js ≥ 18 — uses native
fetch, ES modules,AbortController.No external services to provision.
No SAP system access needed — the KB describes the released CDS views, not your tenant data.
Running modes
The MCP supports two data-source modes. Use online unless you have a specific reason not to.
🟢 Online mode (default, recommended)
node dist/cds-kb-mcp.mjsThe server lazily fetches the search index + views from the upstream GitHub data repo, caches everything under ~/.cache/cds-kb/<sha1-of-url>/, and revalidates against upstream via ETag. No flags needed.
Why this is the recommended default:
Online (default) | Offline ( | |
Setup | Zero — just run the bundle | Must clone |
Data freshness | Auto-syncs with upstream on TTL expiry | Stays at whatever commit you cloned; manual |
Disk usage | 6 MB cache + on-demand views (~30 KB each) | Full 80 MB clone |
Cold-start latency | ~3 s on first run; ~150 ms afterwards | ~100 ms always |
Network requirement | First run + revalidations only | None |
Custom Z-namespace views | Not supported | Fork the data repo |
The on-the-wire cost is much lower than the file sizes suggest — Node fetch() auto-negotiates gzip, so the 5.7 MB index transfers as ~820 KB.
Override the default URL (e.g. to point at your own fork):
node dist/cds-kb-mcp.mjs --remote https://raw.githubusercontent.com/<you>/cds-kb-data/mainOr via env:
CDS_KB_REMOTE=https://raw.githubusercontent.com/<you>/cds-kb-data/main \
node dist/cds-kb-mcp.mjs🟡 Offline mode (--data)
Use only when you have a clear reason:
Air-gapped or strict-firewall environments
You maintain a custom data repo with Z-namespace views and want sub-second cold-start
CI runs where you've already checked out the data repo
Reproducibility: pin to a specific data commit
git clone https://github.com/truongdva2/cds-kb-data.git
node dist/cds-kb-mcp.mjs --data ./cds-kb-dataOr via env:
CDS_KB_DATA=./cds-kb-data node dist/cds-kb-mcp.mjsResolution order
CLI flags → environment variables → online default. Specifically:
Priority | Source | Mode |
1 |
| Offline |
2 |
| Offline |
3 |
| Online (custom URL) |
4 |
| Online (custom URL) |
5 | none | Online (upstream default) ← you land here normally |
Client Registration
Claude Code
The fastest way:
claude mcp add cds-kb -- node /absolute/path/to/cds-kb-mcp/dist/cds-kb-mcp.mjsVerify:
claude mcp listYou should see cds-kb in the list. Inside any project the model now has access to mcp__cds-kb__search_cds, mcp__cds-kb__get_cds_view, and the rest.
To scope to one project, add --scope project. To remove: claude mcp remove cds-kb.
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent on your OS:
{
"mcpServers": {
"cds-kb": {
"command": "node",
"args": ["/absolute/path/to/cds-kb-mcp/dist/cds-kb-mcp.mjs"]
}
}
}Restart Claude Desktop. The wrench icon should list five new tools under "cds-kb".
Antigravity IDE
{
"mcpServers": {
"cds-kb": {
"command": "node",
"args": ["/absolute/path/to/cds-kb-mcp/dist/cds-kb-mcp.mjs"]
}
}
}Cursor / generic MCP clients
The same JSON config works for any MCP-compatible client — point them at the bundle. The server speaks MCP over stdio.
Optional: offline-mode config
If you've cloned the data repo and want the client to launch in offline mode, add the --data flag:
{
"mcpServers": {
"cds-kb": {
"command": "node",
"args": [
"/absolute/path/to/cds-kb-mcp/dist/cds-kb-mcp.mjs",
"--data",
"/absolute/path/to/cds-kb-data"
]
}
}
}Tools Reference
The server exposes five tools. They are designed so an AI agent can go from a vague business question to a complete CDS view definition in two or three calls.
1. search_cds
Find CDS views by business meaning, name, tag, or classic SAP keyword (VBAK, BSEG, etc.). Returns a ranked shortlist.
Parameter | Type | Required | Description |
| string | ✓ | Natural language or keyword (e.g. |
| string | optional | Module filter — code ( |
| string | optional | Line-of-business filter (partial match) |
| string | optional | Business object filter (partial match, e.g. |
| int 1-50 | optional | Max results (default 10) |
Returns: ranked list with name, score, module, short description, and path.
1. **I_CAOPENITEMLIST** [FI-FIO-AR-2CL] (score 14.2)
List of open items across customer and vendor accounts.
path: views/I_CAOPENITEMLIST.md
2. **I_PARKEDOPLACCTGDOCRBLSITEM** ...2. get_cds_view
Fetch one view's definition by exact name. Default: full markdown (metadata + fields + associations + source). Use sections to slim down the response.
Parameter | Type | Required | Description |
| string | ✓ | Exact view name (case-insensitive), e.g. |
| string[] | optional | Subset of |
Typical pattern: search_cds → pick a hit → get_cds_view(name, sections=["metadata", "fields"]) to confirm the field list without pulling 5-10 KB of DDL source.
3. get_views_by_tag
Deterministic listing by tag. Use when search_cds is too fuzzy.
Parameter | Type | Required | Description |
| string | ✓ | Exact tag, e.g. |
| int 1-200 | optional | Default 50 |
Discover valid tags with get_taxonomy first.
4. get_taxonomy
Returns the semantic map: 12 Lines of Business → 829 Business Objects, each with keywords and synonyms. Useful for the agent to orient itself before issuing a search, or to discover valid tags for get_views_by_tag.
No parameters.
5. kb_info
Report the active data source, view count, enrichment coverage, and index build timestamp. Use this to verify which version of the KB you're talking to.
source: remote:https://raw.githubusercontent.com/truongdva2/cds-kb-data/main (cache ~/.cache/cds-kb/...)
views: 7355
enriched: 7160
modules: 31
builtAt: 2026-06-25T09:13:52.301ZConfiguration
Everything is optional. The defaults are what you want unless you're operating offline or behind a strict proxy.
CLI flags
Flag | Value | Effect |
| absolute or relative path | Run in offline mode against a local data clone |
| base URL | Run in online mode against a custom data URL |
Environment variables
Variable | Default | Description |
| — | Path to local data repo (alternative to |
|
| Base URL for online mode |
|
| Set to |
|
| Legacy TTL — only used when upstream lacks |
|
| Per-request HTTP timeout (online mode) |
|
| Max attempts on network errors / 5xx / 408 / 429 |
|
| Honoured for cache directory location |
Cache location
Online mode stores everything under ${XDG_CACHE_HOME:-~/.cache}/cds-kb/<sha1-of-base-url>/:
~/.cache/cds-kb/59f498ee5cf8/
├── search_index.json # 5.7 MB MiniSearch index
├── taxonomy.json # 231 KB business taxonomy
├── version.json # ~200 B — {commit, builtAt, viewCount, ...}; checked on every startup
├── etags.json # ETag map for conditional GETs
└── views/
├── I_BUSINESSPARTNER.md
└── ... # fetched on demandTo wipe and re-fetch:
rm -rf ~/.cache/cds-kb/
# or
CDS_KB_REFRESH=1 node dist/cds-kb-mcp.mjsNetwork Resilience
The remote backend is designed to survive ordinary network conditions:
Feature | Behaviour | Tunable |
Version manifest probe | On every startup, fetch | Automatic |
Per-request timeout | Each HTTP GET aborts after 20 s |
|
Retry with exponential backoff | Up to 3 attempts on network errors and 5xx/408/429 (500 ms → 1 s → 2 s) |
|
Conditional GET via ETag | Subsequent requests send | Automatic |
Atomic cache writes | Writes via | Automatic |
JSON integrity check | Index and taxonomy parsed before being persisted; corrupt downloads never overwrite a good cache | Automatic |
Stale-while-revalidate | TTL-expired cache served immediately; refresh happens in background (legacy fallback when upstream lacks | Automatic |
Terminal 4xx fast-fail | 404 / 403 fail on first attempt — no wasted retries on permanent errors | Automatic |
Net effect: when the data repo publishes a new commit, the next MCP session picks it up automatically — the startup probe sees the commit mismatch and refreshes. A brief GitHub outage can't break an active session; warm-cache restarts skip the 800 KB index re-download.
How updates propagate
cds-kb-data push → GitHub Action rebuilds index + stamps version.json → push back to main
│
▼ (no work needed by users) │
Next MCP startup: GET /index/version.json (~200B) │
compare commit vs cached │
mismatch → re-download index (800 KB on the wire) ◀──────────────┘
match → reuse cached index, regardless of TTLEnd-to-end latency from a data push to clients seeing the new data: the time of one MCP restart — typically a few seconds the next time a client opens a new session.
Architecture
┌──────────────────────────────────────────────────────────────────┐
│ AI Client (Claude) │
│ search_cds("vendor open items", "FI") │
└──────────────────────────┬───────────────────────────────────────┘
│ MCP / JSON-RPC over stdio
┌──────────────────────────▼───────────────────────────────────────┐
│ cds-kb-mcp (this server) │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ search_cds│ │ get_view │ │ taxonomy │ │ kb_info │ ... │
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
│ └─────────────┴─────────────┴─────────────┘ │
│ │ │
│ ┌────────────────────▼───────────────────┐ │
│ │ MiniSearch (in-memory, 5.7 MB index) │ │
│ └────────────────────┬───────────────────┘ │
│ │ │
│ ┌────────────────────▼───────────────────┐ │
│ │ DataSource (Local | Remote) │ │
│ │ • ETag-validated cache │ │
│ │ • Atomic writes, SWR, retry │ │
│ └─────────┬───────────────────┬──────────┘ │
└────────────┼───────────────────┼─────────────────────────────────┘
│ │
┌─────▼────┐ ┌────▼──────────────┐
│ Local FS │ │ GitHub Raw / CDN │
│ cds-kb- │ │ raw.github... │
│ data/ │ └───────────────────┘
└──────────┘Key design decisions
Dataless server. The 80 MB data repo is never bundled — the server is just code (784 KB). Data updates ship independently as commits to
cds-kb-data.Self-describing index.
search_index.jsoncarries its own MiniSearch options. The server has zero schema knowledge of how the index was built, so the data repo can evolve without breaking deployed servers.Online-first. Cold-start cost is paid once per machine, then amortised across every session via ETag-validated cache. No clone step in the happy path.
No AI-context bloat. All 5.7 MB of index lives inside the MCP process. The model only ever sees ranked, short text responses — typically 80–400 tokens per call.
Stdio transport. The server speaks JSON-RPC over stdio. It runs anywhere Node ≥ 18 runs; no HTTP server, no port to expose, no auth to configure.
Troubleshooting
"Module not found" or fails to start
Check Node version:
node --version # must be >= 18Confirm the bundle exists:
ls -l dist/cds-kb-mcp.mjsSearch returns poor results
Run kb_info and check the enriched count. If it's 0 or much lower than viewCount, the index was built without enrichment. The fix is on the data-repo side:
cd cds-kb-data
node enrich_index.mjsIf you're on online mode and seeing this, file an issue on cds-kb-data — the upstream index needs a rebuild.
Cache feels stale
Two options:
# A) Force a one-time refresh
CDS_KB_REFRESH=1 node dist/cds-kb-mcp.mjs
# B) Wipe cache entirely
rm -rf ~/.cache/cds-kb/Normal operation does not require either — the 24 h TTL + ETag revalidation handle drift automatically.
Behind a corporate proxy / firewall
If raw.githubusercontent.com is blocked:
Switch to offline mode — clone the data repo behind the firewall and use
--data.Or set
HTTPS_PROXY/HTTP_PROXYenv vars; Nodefetch()honours them via undici.
View not found
The exact view name might differ. Always call search_cds first to get the canonical name, then get_cds_view with that name. Names are case-insensitive.
"Failed to fetch view ...: data source may be temporarily unreachable"
This is a transient error message (added in v1.2 to distinguish from "view not found"). The server already retried 3× with backoff. Wait a few seconds and call again — the cache and SWR will usually paper over upstream blips.
Project Structure
cds-kb-mcp/
├── dist/
│ └── cds-kb-mcp.mjs # Self-contained bundle — what you ship to users
├── src/
│ ├── server.mjs # MCP server + 5 tool registrations
│ └── datasource.mjs # Local + Remote backends, ETag, SWR, retry
├── build.mjs # esbuild config
├── enrich_index.mjs # Helper script (run against cds-kb-data repo)
├── test_tools.mjs # Smoke test against a live server
├── package.json
├── README.md # ← you are here
├── BENCHMARK.md # Detailed performance & quality comparison
└── cds-kb-data/ # Git submodule pointer (optional clone)Development
Run from source
npm install
node src/server.mjs # online mode
node src/server.mjs --data ./cds-kb-data # offline modeRebuild the bundle
npm run buildThis regenerates dist/cds-kb-mcp.mjs via esbuild. Commit the rebuilt file so end-users don't need a build step.
Run smoke tests
# Against a local data clone
node test_tools.mjs ./cds-kb-data
# Against the default online source
node test_tools.mjsThe script exercises all five tools and prints sample output.
Updating the search index
The MCP itself never builds the index — that happens in cds-kb-data via a GitHub Action that auto-triggers on every data change. Contributors edit .md view files or index/taxonomy.json, push, and the bot regenerates search_index.json + version.json on main.
Full contributor guide lives in the data repo: see
cds-kb-data/README.md— pipeline diagram, the 5-step dev checklist, and 6 common-scenario fixes.
Short version (data side)
edit views/X.md → git push → Action rebuilds → bot commits index/* back to main
│
▼
Next MCP session sees commit
mismatch via version.json probe
→ cache invalidated → fresh dataThe workflow file is cds-kb-data/.github/workflows/rebuild-on-push.yml. It checks out cds-kb-mcp@main to get enrich_index.mjs, installs only minisearch (the script's one dep), and uses $GITHUB_SHA to stamp the version manifest. Concurrency-guarded: two quick pushes won't race.
Manual rebuild (rare — for iterating on enrich_index.mjs itself, or air-gapped use)
cd cds-kb-mcp
node enrich_index.mjs ../cds-kb-data
cd ../cds-kb-data
git add index/search_index.json index/version.json
git commit -m "data: <what changed>"
git pushIf you change enrich_index.mjs in this repo, trigger the data-repo workflow manually afterwards so it rebuilds with your new logic: data-repo → Actions tab → "Rebuild search index on data change" → Run workflow button.
What clients see
On every MCP startup the server fetches <base>/index/version.json (~200 B, bypasses TTL). When the upstream commit differs from what was cached on the previous run, the cache is invalidated and the index is re-downloaded. Result: every new data push is visible to every client on their next session — usually within seconds. The server logs the transition explicitly:
[cds-kb-mcp] upstream commit a1b2c3d4 ≠ cached deadbeef — refreshing indexClient-side troubleshooting
Symptom | Fix |
| Restart the MCP host (Claude Code / Desktop). Cache probe only runs at startup. |
Cache feels stuck |
|
Need an immediate refresh in this session |
|
| The data source is an older snapshot without |
License
MIT. See LICENSE if present, or the repo metadata.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/truongdva2/cds-kb-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server