Atlas / MCP servers / kalyanjanumpally / SAP Joule — S/4HANA Cloud Procurement & Finance Copilot

SAP Joule — S/4HANA Cloud Procurement & Finance CopilotBLOCK

mcp/kalyanjanumpally/sap-joule-ai-plugin

Reference implementation: SAP Joule procurement copilot backed by a CAP AI service and an LLM-agnostic plugin (Anthropic / Ollama / SAP Generative AI Hub).

Verdict
BLOCK
Grade
F
Trust score
28 /100
Exposed tools
70 66r · 2w · 2d
Transport
streamable-http
License
—
Stars
2
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

A real SAP Joule project targeting S/4HANA Cloud for Finance, Procurement, and Supply Chain. Includes deployable Joule Studio artifacts (skills, agent, actions, destinations) and a customer-facing pitch site.

Use this repo to:

  1. Spin up a free SAP BTP trial with Joule Studio enabled (see docs/01-setup-btp-trial.md).
  2. Import the skills and agent from joule-project/ into Joule Studio.
  3. Run the live demo using docs/04-demo-script.md.
  4. Show the pitch site (pitch-site/) as the visual companion during the customer meeting.

What's inside

The five skills

The agent

procurement-copilot is a Joule Agent that composes the skills into multi-step conversations, e.g.:

"Check MAT-1001 stock in plant
Read from source at commit eac8e60fd788OBSERVED · 2026-10-12
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add joule-pitch-site --env AICORE_AUTH_URL=${AICORE_AUTH_URL} --env AICORE_CLIENT_SECRET=${AICORE_CLIENT_SECRET} --env ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} --env GEMINI_API_KEY=${GEMINI_API_KEY} -- npx -y [email protected]
claude-desktop
{
  "mcpServers": {
    "joule-pitch-site": {
      "command": "npx",
      "args": [
        "-y",
        "[email protected]"
      ],
      "env": {
        "AICORE_AUTH_URL": "${AICORE_AUTH_URL}",
        "AICORE_CLIENT_SECRET": "${AICORE_CLIENT_SECRET}",
        "ANTHROPIC_API_KEY": "${ANTHROPIC_API_KEY}",
        "GEMINI_API_KEY": "${GEMINI_API_KEY}"
      }
    }
  }
}
03

Exposed tools (70)

66 read · 2 write · 2 destructive. Blast radius: 2 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
Areadfirst
AcmereadGlobal widgets.
Breadbeta
Creadgamma
Doomedreadx
Keptreadx
Onereada
Originalreadtext
Paperreadsheets
ShippingreadFree over 50 EUR.
Steelreadcoils
Testreadx
Threereadc
Tworeadb
Updatedreadtext
Xready
areadx
accuracyreadfacts match source
addwriteadd two numbers
bread
badreadalways throws
boomreadalways fails
boom-agentreadx
brevityread2 sentences max
cread
classifywriteClassify input into one of a fixed set of labels.
compliancereadCompliance checker.
compliance-checkerreadFlags compliance concerns (REACH, RoHS, GDPR, sanctions, green claims) in a contract or scenario.
consultread
contract-lookupreadAnswers questions about supplier contracts.
defaultreadanswer must cite a source
echoreadecho the input
echo-agentreadEchoes the question back.
extract_jsonreadExtract structured JSON from unstructured text against a given JSON schema.
get_weatherreadget w
greetread
greet_from_filereadfile-based prompt
groundingreadcites specific IDs
labelsreadArray of allowed labels
list_providersreadList every provider kind this plugin supports, the active default, and any configured aliases. Aliases are pickable via the
lookupreadlook up
lsread
my_custom_from_diskreadloaded via --prompts-dir
my_promptreada demo
pread
p1readdemo prompt
peekread
plainreadplain agent
pricereadPrice analyst.
price-analystreadprices
procurement_risk_scorerreadScore procurement / contract text for risk (SAP-flavored built-in prompt for demos).
reload_budgetreadRe-read LlmBudget rows into the costBudget middleware. Call after editing rows via OData.
reset_cachedestructiveClear both the exact-match cache and the semantic index. Use to force cache warmup after a data change.
reset_injection_statsdestructiveReset the promptInjectionGuard counters (scanned/blocked/sanitized/warned + per-detector). Cadence: after ops reviews the pattern of hits.
schemareadJSON schema (object) for the output
searchreadsearch things
search_contractsreadSemantic + keyword search over supplier contracts. Returns the top matching contracts as JSON.
sentencesreadTarget length
slowreadreports progress
sql-workerreadRuns SQL against the analytics warehouse.
summarizereadSummarize input text in a target number of sentences.
tread
targetLanguagereadTarget language (e.g.
testreadtest
textreadText to summarize
translatereadTranslate text into a target language.
unused_toolreadA tool the model should not call for this prompt.
verifyreadSanity-check a configured provider by sending a tiny probe.
with-toolsreadx
xreadx
04

Trust audit

BLOCKgrade F · trust 28/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)FAIL
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (6 observation(s))
Network
declared (10 observation(s))
Shell
declared (3 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (25)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
cds-plugin-llm/lib/index.d.ts:1008
eval(script: string, numKeys: number, ...args: (string | number)[]): Promise<unknown>;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
cds-plugin-llm/lib/middleware/redisRateLimit.js:67
throw new Error('redisRateLimit: options.redis is required and must expose an eval() method');
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHObfuscation / stealth · obf.rtl_override · CWE-506, CWE-94
cds-plugin-llm/lib/middleware/promptInjectionGuard.js:73
const ZERO_WIDTH_RE = /[---]/g;
HIGHPrompt injection · prompt.override · CWE-94, CWE-1427
cds-plugin-llm/CHANGELOG.md:2298
- **Injection pattern detection** (`DEFAULT_INJECTION_PATTERNS`) catches the common jailbreak seeds accidentally left in prompts:
Why it matters. asks the agent to drop prior instructions or safety
Fix. remove the instruction
HIGHPrompt injection · prompt.override · CWE-94, CWE-1427
cds-plugin-llm/CHANGELOG.md:2400
| `promptInjectionGuard` (1.31) | Blocks jailbreak / role-marker patterns |
Why it matters. asks the agent to drop prior instructions or safety
Fix. remove the instruction
HIGHPrompt injection · prompt.override · CWE-94, CWE-1427
cds-plugin-llm/CHANGELOG.md:2915
- `skipMethods: ['embed']` — bypass for methods where safety doesn't apply
Why it matters. asks the agent to drop prior instructions or safety
Fix. remove the instruction
MEDIUMInventory / provenance · inv.binary · CWE-1104
pitch-deck/cds-plugin-llm-and-vector-hana.pptx
cds-plugin-llm-and-vector-hana.pptx
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
scripts/stream-demo.js:85
console.log(`\n\n\x1b[2mfirst token: ${first}ms · total: ${total}ms · ${chunk.usage?.output_tokens ?? '?'} output tokens\x1b[0m`);
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
cds-plugin-llm/lib/cli/commands/verify.js:47
saptarishi-llm verify --provider ollama --base-url http://192.168.5.13:11434
MEDIUMObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
cds-plugin-llm/lib/middleware/promptInjectionGuard.js:73
const ZERO_WIDTH_RE = /[---]/g;
MEDIUMHard-coded secrets · secret.anthropic · CWE-798, CWE-321
cds-plugin-llm/test/doctorCmd.test.js:88
ANTHROPIC_API_KEY: 'sk-ant-api03-abcdefghijklmnop-secret',
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
cds-plugin-llm/test/batch.test.js:81
credentials: { apiKey: 'sk-ant-fake-for-init-only' },
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
cds-plugin-llm/test/responseSigning.test.js:27
const SECRET = 'test-response-signing-key';
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
reset_cache, reset_injection_stats
Why it matters. 2 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
joule-project-api/.cfignore
.cfignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
cds-plugin-llm/lib/util.js:125
return crypto.createHash('sha1').update(stable).digest('hex');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
cds-plugin-llm/lib/cli/commands/batch.js:20
const { waitForBatch } = require('../../batchHelpers');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
cds-plugin-llm/lib/cli/commands/chainDiff.js:6
const { chainDiff, formatChainDiff } = require('../../chainDiff');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
cds-plugin-llm/lib/cli/commands/chainValidate.js:7
const { validateMiddlewareOrder } = require('../../validateMiddlewareOrder');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
cds-plugin-llm/lib/cli/commands/costPredict.js:3
const { DEFAULT_PRICING } = require('../../pricing');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
cds-plugin-llm/lib/cli/commands/costPredict.js:4
const { getTokenizer, charsPerTokenFor } = require('../../tokenizer');
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
cds-plugin-llm/README.md:702
OLLAMA_URL=http://192.168.5.13:11434 saptarishi-llm chat --provider ollama -p "hello"
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
cds-plugin-llm/README.md:917
# → MCP HTTP+SSE listening on http://0.0.0.0:3333/sse
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
cds-plugin-llm/test/audio.test.js:120
credentials: { apiKey: 'sk-fake', baseUrl: 'http://127.0.0.1:65535/v1' },
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
cds-plugin-llm/test/audio.test.js:162
credentials: { apiKey: 'sk-fake', baseUrl: 'http://127.0.0.1:65535/v1' },

Gates applied: instruction_override, no_behavioural_pass.

Audited 2026-10-12 · audit v0.4.1 · source sha eac8e60fd788full audit observations/trust-audit/mcp-server/kalyanjanumpally__sap-joule-ai-plugin.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-12eac8e60fd788BLOCKF28first audit
06

Questions

What is the @saptarishi/cds-plugin-llm MCP server?

Reference implementation: SAP Joule procurement copilot backed by a CAP AI service and an LLM-agnostic plugin (Anthropic / Ollama / SAP Generative AI Hub).

What tools does @saptarishi/cds-plugin-llm expose?

70 in total: 66 read-only, 2 that write, and 2 that can delete or overwrite (reset_cache, reset_injection_stats). Every one is listed on this page with its risk.

Is @saptarishi/cds-plugin-llm safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (28/100) and found 6 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 2 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does @saptarishi/cds-plugin-llm need?

It reads AICORE_AUTH_URL, AICORE_CLIENT_SECRET, ANTHROPIC_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY, GROQ_API_KEY, LLM_HMAC_KEY, LLM_RESPONSE_HMAC_KEY, MCP_OBS_TOKEN, OPENAI_API_KEY, OPENAI_KEY_A and OPENAI_KEY_B from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does @saptarishi/cds-plugin-llm run?

It speaks streamable-http, so it runs as a service you connect to over the network. It is published on npm as joule-pitch-site at 1.0.0.

How current is this page?

The grade is for one exact copy of the source (eac8e60fd788), read on 2026-10-12. The repository is watched and re-audited when it changes.

Advertisement