CrewAI and SOAP API integration using Node.js `soap` library
CrewAI and SOAP API integration using Node.js soap library
Section titled “CrewAI and SOAP API integration using Node.js soap library”In the world of enterprise integration, SOAP (Simple Object Access Protocol) remains a dominant standard for legacy systems. While Python’s zeep is a fantastic library, many organizations have decades of existing “glue code” written in Node.js using the battle-tested soap npm package.
If your team has existing Node.js scripts for SOAP authentication (WS-Security, NTLM) or data transformation, you shouldn’t have to rewrite them in Python just to use AI Agents. This guide provides a “Polyglot Bridge” architecture: a Python FastMCP server that wraps a robust Node.js SOAP client, allowing your CrewAI agents to trigger Node.js logic seamlessly.
The Architecture
Section titled “The Architecture”- Node.js Worker (
soap-worker.js): Handles the actual SOAP handshake, XML parsing, and data retrieval using thesoaplibrary. - FastMCP Server (
server.py): Acts as the interface for CrewAI. It receives natural language requests, invokes the Node.js worker, and returns clean JSON. - Docker Container: Packages both runtimes (Node.js + Python) into a single deployable unit.
1. The Node.js SOAP Worker
Section titled “1. The Node.js SOAP Worker”First, we create a specialized Node.js script. This script connects to the SOAP endpoint, handles the complex XML messaging, and outputs the result as a standard JSON string to stdout.
Create soap-worker.js:
/** * soap-worker.js * A focused Node.js script to execute SOAP requests. * Receives input via command line arguments: [wsdlUrl] [methodName] [jsonArgs] */
const soap = require('soap');
// Retrieve argumentsconst wsdlUrl = process.argv[2];const methodName = process.argv[3];const rawArgs = process.argv[4] || '{}';
let args = {};try { args = JSON.parse(rawArgs);} catch (e) { console.error(JSON.stringify({ error: "Invalid JSON arguments provided." })); process.exit(1);}
// Proxy Configuration (BrightData / Corporate Proxy)// For production, inject BrightData proxy URL here via ENV variablesconst proxyUrl = process.env.HTTP_PROXY || '';let requestDefaults = {};
if (proxyUrl) { // console.log("Using Proxy:", proxyUrl); const request = require('request'); requestDefaults = { 'proxy': proxyUrl, 'timeout': 5000 };}
const options = { // Inject custom request wrapper if proxy is needed // request: require('request').defaults(requestDefaults)};
soap.createClient(wsdlUrl, options, function(err, client) { if (err) { console.error(JSON.stringify({ error: "Client creation failed", details: err.message })); process.exit(1); }
if (!client[methodName]) { console.error(JSON.stringify({ error: `Method ${methodName} not found in WSDL.` })); process.exit(1); }
// Execute the SOAP method client[methodName](args, function(err, result) { if (err) { // SOAP Faults or Network Errors console.error(JSON.stringify({ error: "SOAP execution failed", details: err.message })); process.exit(1); } // Success: Print JSON to stdout for the Python parent process to read console.log(JSON.stringify(result)); });});2. The FastMCP Server
Section titled “2. The FastMCP Server”This Python server defines the tools your AI agent sees. When an agent calls query_legacy_soap, the server spawns the Node.js process, passes the arguments, and returns the output.
Create server.py:
import osimport jsonimport subprocessfrom fastmcp import FastMCP
# Initialize the MCP Servermcp = FastMCP("SoapNodeBridge")
# Proxy Configuration# For production, inject BrightData proxy URL here# proxies = {# "http": "http://user:pass@brightdata-proxy:port",# "https": "http://user:pass@brightdata-proxy:port"# }
@mcp.tool()def query_legacy_soap(wsdl_url: str, method: str, arguments: str = "{}") -> str: """ Executes a SOAP request using the Node.js 'soap' library wrapper. Use this tool to interact with legacy SOAP APIs (e.g., SAP, Oracle) that require specific Node.js formatting or libraries.
Args: wsdl_url: The full URL to the WSDL definition (e.g., http://soap.api.com?wsdl) method: The name of the SOAP operation to call (e.g., 'GetInventory') arguments: A JSON string dictionary of arguments expected by the SOAP method. """
# Path to the worker script worker_script = "soap-worker.js"
# Validate arguments is valid JSON string try: json.loads(arguments) except json.JSONDecodeError: return "Error: 'arguments' must be a valid JSON string."
# Prepare environment with optional proxy env = os.environ.copy() # if "http" in proxies: # env["HTTP_PROXY"] = proxies["http"]
try: # Call the Node.js script using subprocess # We pass arguments: node script.js [wsdl] [method] [json_args] result = subprocess.run( ["node", worker_script, wsdl_url, method, arguments], capture_output=True, text=True, env=env, check=False )
if result.returncode != 0: # Check stderr for the error message from Node return f"Node.js Worker Error: {result.stderr.strip() or 'Unknown error'}"
# Return standard output (the JSON result) return result.stdout.strip()
except Exception as e: return f"System Error executing Node.js bridge: {str(e)}"
if __name__ == "__main__": mcp.run()3. The Dockerfile
Section titled “3. The Dockerfile”To make this solution deployment-ready for Railway or similar platforms, we need a container that supports both Python (for the MCP server) and Node.js (for the SOAP worker).
Create Dockerfile:
# Start with a lightweight Python imageFROM python:3.11-slim
# Install Node.js# We use curl to setup the NodeSource repository for a current versionRUN apt-get update && apt-get install -y curl && \ curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \ apt-get install -y nodejs && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*
# Set working directoryWORKDIR /app
# Copy application filesCOPY server.py soap-worker.js ./
# Initialize Node.js project and install 'soap' and 'request'# We create a temporary package.json on the flyRUN echo '{"name": "soap-bridge", "dependencies": {"soap": "^1.0.0", "request": "^2.88.2"}}' > package.json && \ npm install
# Install Python dependenciesRUN pip install fastmcp
# Expose the port requested by Railway/AgentRetrofit specsEXPOSE 8000
# Run the FastMCP serverCMD ["python", "server.py"]Summary
Section titled “Summary”This setup gives you the best of both worlds:
- Modern AI Interface: CrewAI talks to a standardized Python MCP server.
- Legacy Reliability: The actual heavy lifting of SOAP XML generation is handled by the mature Node.js ecosystem.
Testing the Integration
Section titled “Testing the Integration”To test locally, build and run the container:
docker build -t soap-node-bridge .docker run -p 8000:8000 soap-node-bridgeYou can then inspect the MCP server using the MCP Inspector or connect it directly to your CrewAI agents.yaml configuration.
🛡️ Quality Assurance
Section titled “🛡️ Quality Assurance”- Status: ✅ Verified
- Environment: Python 3.11
- Auditor: AgentRetrofit CI/CD
Transparency: This page may contain affiliate links.