Skip to content

How to connect CrewAI to SAP ECC via RFC using Python

How to Connect CrewAI to SAP ECC via RFC (Python)

Section titled “How to Connect CrewAI to SAP ECC via RFC (Python)”

Connecting modern AI agents to SAP ECC (Enterprise Central Component) is a classic “Big Iron” problem. While agents speak REST and JSON, SAP ECC natively communicates via the RFC (Remote Function Call) protocol, a proprietary binary interface optimized for the internal networks of the 1990s.

This guide provides a production-ready Model Context Protocol (MCP) server that acts as a bridge. It translates your agent’s natural language requests (e.g., “Check the stock level for material 1045”) into compliant SAP RFC calls using the pyrfc library.

We will build a FastMCP server in Python that exposes SAP BAPIs (Business Application Programming Interfaces) as tools. Your CrewAI agent connects to this server via SSE (Server-Sent Events).

  1. SAP NW RFC SDK: You cannot simply pip install the connectivity layer. You must download the SAP NetWeaver RFC SDK 7.50 (Linux x86_64) from the SAP ONE Support Launchpad (requires an S-User ID).
  2. VPN Access: If your SAP instance is behind a corporate firewall, your Docker container needs a tunnel.

This server exposes two tools:

  • get_user_details: A safe, read-only wrapper around BAPI_USER_GET_DETAIL.
  • execute_generic_rfc: A flexible tool that allows the agent to call any RFC (use with caution).
import os
import sys
from fastmcp import FastMCP
from pyrfc import Connection, ABAPApplicationError, ABAPRuntimeError, LogonError, CommunicationError
# Initialize FastMCP
mcp = FastMCP("SAP-ECC-RFC-Gateway")
def get_sap_connection():
"""
Establishes a connection to SAP ECC.
Parameters should be loaded from secure environment variables.
"""
# Ensure your container has network access (e.g. via NordLayer)
try:
conn = Connection(
ashost=os.getenv("SAP_ASHOST", "10.0.0.1"),
sysnr=os.getenv("SAP_SYSNR", "00"),
client=os.getenv("SAP_CLIENT", "100"),
user=os.getenv("SAP_USER", "DEVELOPER"),
passwd=os.getenv("SAP_PASSWORD", "password123"),
lang=os.getenv("SAP_LANG", "EN")
)
return conn
except LogonError as e:
print(f"SAP Logon Error: {e}", file=sys.stderr)
raise
except CommunicationError as e:
print(f"SAP Network/Communication Error: {e}", file=sys.stderr)
raise
@mcp.tool()
def get_user_details(username: str) -> dict:
"""
Retrieves detailed information about an SAP user using BAPI_USER_GET_DETAIL.
Args:
username: The SAP User ID (e.g., 'JSMITH').
"""
conn = None
try:
conn = get_sap_connection()
result = conn.call("BAPI_USER_GET_DETAIL", USERNAME=username)
# Clean up the return structure for the agent
return {
"address": result.get("ADDRESS", {}),
"defaults": result.get("DEFAULTS", {}),
"status": "success"
}
except (ABAPApplicationError, ABAPRuntimeError) as e:
return {"status": "error", "message": str(e)}
except Exception as e:
return {"status": "error", "message": f"System error: {str(e)}"}
finally:
if conn and conn.alive:
conn.close()
@mcp.tool()
def execute_generic_rfc(function_name: str, parameters: dict) -> dict:
"""
Executes a generic SAP Remote Function Call (RFC).
Useful for ad-hoc queries if the agent knows the BAPI signature.
Args:
function_name: Name of the RFC/BAPI (e.g., 'STFC_CONNECTION').
parameters: Dictionary of import parameters.
"""
conn = None
try:
conn = get_sap_connection()
# **SECURITY WARNING**: In production, validate function_name against an allowlist.
result = conn.call(function_name, **parameters)
return result
except Exception as e:
return {"error": str(e)}
finally:
if conn and conn.alive:
conn.close()
if __name__ == "__main__":
# Binds to 0.0.0.0 to allow access from other Docker containers or host
mcp.run(transport='sse', host='0.0.0.0', port=8000)

Because pyrfc depends on C++ libraries provided by SAP, the Docker build is more complex than a standard Python app.

Structure:

  • You must place the unzipped SAP SDK in a folder named nwrfcsdk next to your Dockerfile.
  • The nwrfcsdk folder should contain the lib directory with .so files.
FROM python:3.11-slim
# Install system dependencies required by SAP SDK
# libaio1 is often required for SAP's asynchronous I/O
RUN apt-get update && apt-get install -y \
libaio1 \
&& rm -rf /var/lib/apt/lists/*
# --- SAP SDK SETUP ---
# Create directory for SAP SDK
WORKDIR /usr/local/sap
# Copy the SDK from your local machine into the image
# NOTE: You must download 'nwrfc750P_X-xxxxxx.zip' from SAP and extract it here
COPY nwrfcsdk ./nwrfcsdk
# Setup environment variables so Python can find the C++ libs
ENV SAPNWRFC_HOME=/usr/local/sap/nwrfcsdk
ENV LD_LIBRARY_PATH=$SAPNWRFC_HOME/lib
# Setup app directory
WORKDIR /app
# Install Python dependencies
# 'pyrfc' will look for the headers/libs defined in ENV vars above
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy server code
COPY server.py .
# Expose port 8000 for Railway/Docker networking
EXPOSE 8000
# Start the server
CMD ["python", "server.py"]
fastmcp
pyrfc
uvicorn

Once your Docker container is running (e.g., mapped to localhost:8000), you configure your CrewAI agent to use the SSE endpoint.

from crewai import Agent, Task, Crew
from crewai_tools import BaseTool
# Define the connection to your custom SAP MCP Server
sap_mcp_source = {
"url": "http://localhost:8000/sse",
"type": "sse"
}
# Create the Agent
sap_specialist = Agent(
role='SAP ERP Specialist',
goal='Retrieve user data from the legacy SAP ECC system',
backstory="You are an expert in SAP BAPIs. You help the HR team verify user details in the legacy system.",
verbose=True,
# The 'mcps' configuration attaches the tools served by your server
mcps=[sap_mcp_source]
)
# Define a Task
verify_user_task = Task(
description="Find the address and default settings for SAP user 'DEVELOPER'.",
expected_output="A summary of the user's address and format settings.",
agent=sap_specialist
)
# Run the Crew
crew = Crew(
agents=[sap_specialist],
tasks=[verify_user_task]
)
result = crew.kickoff()
print(result)

ImportError: libsapnwrfc.so: cannot open shared object file

Section titled “ImportError: libsapnwrfc.so: cannot open shared object file”
  • Cause: The Docker container cannot find the SAP C++ libraries.
  • Fix: Ensure LD_LIBRARY_PATH is correctly set in the Dockerfile and points to the folder containing .so files.
  • Cause: Incorrect credentials or Client ID (e.g., client 000 vs 100).
  • Fix: Verify the SAP_CLIENT environment variable. RFC requires specific client numbers.

CommunicationError: RFC_COMMUNICATION_FAILURE

Section titled “CommunicationError: RFC_COMMUNICATION_FAILURE”
  • Cause: The container cannot reach the SAP Host IP.
  • Fix: Ensure you are not blocking the RFC ports (usually 3300 + instance number, e.g., 3300 for instance 00). If using a VPN (e.g., NordLayer), ensure the tunnel is active inside the container context.

  • Status: ✅ Verified
  • Environment: Python 3.11
  • Auditor: AgentRetrofit CI/CD

Transparency: This page may contain affiliate links.