Skip to content

BUG - fiori-mcp download_odata_service_metadata: clarify appPath pre-condition to prevent LLMs from passing a non-existent folder #4981

Description

@cfg74

Related Feature

Feature request: N/A — this is a bug report on the existing download_odata_service_metadata tool exposed by @sap-ux/fiori-mcp-server.

Description

The MCP tool download_odata_service_metadata (exposed by @sap-ux/fiori-mcp-server) requires its appPath parameter to point to an already-existing directory into which metadata.xml will be written. This pre-condition is not documented in the tool's input schema description, so LLMs consuming the MCP server routinely pass a folder that has not been created yet — for example, the target folder of a Fiori application they are about to scaffold. When that happens the metadata download fails and the whole "download metadata → generate app" chain breaks in a way that is hard for the LLM to recover from.

The problem is not the runtime behaviour per se (writing a file into a non-existent folder is a legitimate error) — the problem is that the tool's description gives the LLM no signal that this pre-condition exists.

Current parameter description (from the tool's JSON Schema):

appPath (required, string): "Absolute path to the folder where metadata.xml will be saved. Typically the project target folder."

Why this misleads the LLM:

  1. "folder where metadata.xml will be saved" describes the folder's purpose, not its lifecycle. Many filesystem primitives the LLM has been trained on (mkdir -p && …, various generator CLIs, some fs.writeFile variants) auto-create parent directories, so absent a rule to the contrary the LLM defaults to that convention.
  2. "Typically the project target folder" reinforces the wrong intuition: for a new project, "the project target folder" is exactly the thing the LLM is about to create. So the LLM concludes it is safe to pass a path that does not exist yet.
  3. The description contains no pre-condition line, no failure-mode hint, no post-condition line.
  4. The parameter name appPath is semantically loaded ("the app's path"), which further hides the fact that this is just "an existing directory to drop a file into".

Steps to Reproduce

  1. From an MCP client (e.g. Claude Code, GitHub Copilot with fiori-mcp installed), start a conversation like:

    "Create a Fiori elements List Report for the OData service at https://…/sap/opu/odata/sap/<SERVICE>/ and put it under C:\dev\my-new-fiori-app."

  2. The LLM chains the recommended workflow:
    a. Calls download_odata_service_metadata with appPath: "C:/dev/my-new-fiori-app" (a path that does not exist yet).
    b. Intends to follow up with generate_fiori_app_odata.
  3. The metadata download step fails because the folder does not exist. Depending on the client, the LLM sees either a raw filesystem error or a truncated failure and cannot recover automatically.

Expected results

Either:

  • (a) The tool description makes the pre-condition explicit ("this folder MUST exist; this tool does not create directories; create it with mkdir -p <appPath> first"), so the LLM plans a preparatory mkdir step; or
  • (b) The server-side handler creates the directory recursively (fs.mkdirSync(appPath, { recursive: true })) and the description states this behaviour, so the current LLM planning is correct-by-default; or
  • (c) The server-side handler validates and returns a precise, actionable error message ("appPath does not exist. Create the directory before calling this tool: mkdir -p <appPath>. This tool does not create directories."), so the LLM can self-correct on the next turn.

Recommended combination: (a) + (c) — clarify the contract in the description and fail fast with a specific error string. Both are cheap and give defence in depth against LLMs that skim the schema.

Proposed replacement description for appPath:

Absolute path to an existing folder where metadata.xml will be written. The folder MUST exist before this tool is invoked — this tool does not create directories. If the caller is about to scaffold a new Fiori project, create the target folder first (e.g. mkdir -p <appPath>) and only then call this tool. Typically this is the same folder that will later be passed as the project target to generate_fiori_app_odata.

Proposed fail-fast guard at the top of the handler:

if (!fs.existsSync(appPath)) {
  throw new Error(
    `appPath does not exist: ${appPath}. Create the directory before calling this tool ` +
    `(e.g. \`mkdir -p ${appPath}\`). This tool does not create directories.`
  );
}

Actual results

The tool description does not state the pre-condition; the handler does not create the directory; and (based on the observed demo) the resulting error is not verbose enough for the LLM to recognise the root cause and self-correct.

Screenshots

N/A — text-based tool invocation. Trace/log excerpt can be added if useful.

Version/Components/Environment

OS:

  • Mac OS

  • Windows

  • Other

  • Component: @sap-ux/fiori-mcp-server

  • Tool: download_odata_service_metadata

  • MCP client: GitHub Copilot (VS Code) — model: Claude 4.7 Opus (AI Core)

  • fiori-mcp-server version: 1.9.1 (as currently on npm, dist-tags.latest)

Root Cause Analysis

Problem

{describe the problem}

Fix

{describe the fix}

Why was it missed

{Some explanation why this issue might have been missed during normal development/testing cycle}

How can we avoid this

{if we don't want to see this type of issues anymore what we should do to prevent}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfiori-mcp@sap-ux/fiori-mcp

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions