Skip to content

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.

  1. Node.js Worker (soap-worker.js): Handles the actual SOAP handshake, XML parsing, and data retrieval using the soap library.
  2. FastMCP Server (server.py): Acts as the interface for CrewAI. It receives natural language requests, invokes the Node.js worker, and returns clean JSON.
  3. Docker Container: Packages both runtimes (Node.js + Python) into a single deployable unit.

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 arguments
const 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 variables
const 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));
});
});

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 os
import json
import subprocess
from fastmcp import FastMCP
# Initialize the MCP Server
mcp = 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()

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 image
FROM python:3.11-slim
# Install Node.js
# We use curl to setup the NodeSource repository for a current version
RUN 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 directory
WORKDIR /app
# Copy application files
COPY server.py soap-worker.js ./
# Initialize Node.js project and install 'soap' and 'request'
# We create a temporary package.json on the fly
RUN echo '{"name": "soap-bridge", "dependencies": {"soap": "^1.0.0", "request": "^2.88.2"}}' > package.json && \
npm install
# Install Python dependencies
RUN pip install fastmcp
# Expose the port requested by Railway/AgentRetrofit specs
EXPOSE 8000
# Run the FastMCP server
CMD ["python", "server.py"]

This setup gives you the best of both worlds:

  1. Modern AI Interface: CrewAI talks to a standardized Python MCP server.
  2. Legacy Reliability: The actual heavy lifting of SOAP XML generation is handled by the mature Node.js ecosystem.

To test locally, build and run the container:

Terminal window
docker build -t soap-node-bridge .
docker run -p 8000:8000 soap-node-bridge

You can then inspect the MCP server using the MCP Inspector or connect it directly to your CrewAI agents.yaml configuration.


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

Transparency: This page may contain affiliate links.