Securing AI Agent access to legacy SOAP APIs (Python)
Securing AI Agent access to legacy SOAP APIs (Python)
Section titled “Securing AI Agent access to legacy SOAP APIs (Python)”As organizations deploy autonomous AI agents into production, they often hit a “hard” security boundary: Legacy SOAP APIs. These interfaces, common in SAP, Oracle, and old banking systems, rely on strict XML schemas (WSDL) and outdated authentication protocols that modern LLMs struggle to navigate natively.
This guide demonstrates a Secure Gateway Pattern. We will build a lightweight Model Context Protocol (MCP) server using FastMCP. This server acts as a firewall and translator, holding the credentials and WSDL logic, while exposing a simple tool interface to your AI agents.
Prerequisites
Section titled “Prerequisites”- Python 3.10+
- Docker Desktop
- WSDL URL for your legacy service.
1. The Secure Server (server.py)
Section titled “1. The Secure Server (server.py)”This server exposes a single tool invoke_soap_operation. It handles the proxies configuration to ensure traffic can traverse enterprise firewalls.
import osimport requestsfrom fastmcp import FastMCPfrom zeep import Client, Settingsfrom zeep.transports import Transportfrom zeep.helpers import serialize_object
# Initialize FastMCPmcp = FastMCP("SecureSOAPGateway")
# Configuration# Using a public SOAP service for demonstrationWSDL_URL = os.getenv("SOAP_WSDL_URL", "http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL")SOAP_USER = os.getenv("SOAP_USER", "admin")SOAP_PASS = os.getenv("SOAP_PASS", "secret")
@mcp.tool()def invoke_soap_operation(operation_name: str, parameters: dict = {}) -> str: """ Securely invokes a legacy SOAP operation.
Args: operation_name: The name of the SOAP method to call (e.g., 'FullCountryInfo'). parameters: A dictionary of arguments expected by the SOAP method. """ try: # Security: Configure Transport with Proxies and Timeouts session = requests.Session()
# PROXY CONFIGURATION # proxies = { # 'http': 'http://user:pass@proxy_host:port', # 'https': 'http://user:pass@proxy_host:port', # } # # For production, inject BrightData proxy URL here # session.proxies.update(proxies)
# Add Basic Auth if required # session.auth = (SOAP_USER, SOAP_PASS)
transport = Transport(session=session, timeout=30)
# Strict Mode: strict=False allows for loose WSDL parsing which is helpful for old systems settings = Settings(strict=False, xml_huge_tree=True)
client = Client(wsdl=WSDL_URL, transport=transport, settings=settings)
# Dynamically get the operation from the client service service_method = getattr(client.service, operation_name, None)
if not service_method: return f"Error: Operation '{operation_name}' not found in WSDL."
# Execute the call # We unwrap **parameters to pass them as named arguments result = service_method(**parameters)
# Serialize the Zeep object to a standard Python dict/list structure clean_result = serialize_object(result)
return str(clean_result)
except Exception as e: return f"SOAP Execution Error: {str(e)}"
if __name__ == "__main__": # Binds to 0.0.0.0 to allow access from outside the container mcp.run(transport='sse', host='0.0.0.0', port=8000)2. Docker Container (Dockerfile)
Section titled “2. Docker Container (Dockerfile)”We encapsulate dependencies in a container to ensure libxml and zeep versions are consistent.
# Use an official Python runtime as a parent imageFROM python:3.11-slim
# Set the working directory in the containerWORKDIR /app
# Install system dependencies for lxml (required by Zeep)RUN apt-get update && apt-get install -y \ libxml2-dev \ libxslt-dev \ gcc \ && rm -rf /var/lib/apt/lists/*
# Install Python librariesRUN pip install --no-cache-dir fastmcp zeep requests
# Copy the current directory contents into the container at /appCOPY server.py .
# Make port 8000 available to the world outside this containerEXPOSE 8000
# Run server.py when the container launchesCMD ["python", "server.py"]3. The Agent (agent.py)
Section titled “3. The Agent (agent.py)”This is a complete, executable CrewAI implementation. The agent connects to the running Docker container via the SSE transport, queries the SOAP service for country information, and summarizes the result.
Note: Ensure your Docker container is running before executing this script.
from crewai import Agent, Task, Crew, Process
# 1. Define the Agent with MCP Connectivity# The 'mcps' parameter connects the agent to our Dockerized SOAP Gatewaysoap_agent = Agent( role='Legacy Systems Integrator', goal='Retrieve and interpret data from legacy SOAP web services', backstory=( "You are a specialist backend engineer. " "Your job is to fetch technical data from old SOAP APIs " "and translate it into clean, human-readable summaries." ), # Connects to the server running on localhost:8000 mcps=["http://localhost:8000/sse"], verbose=True, allow_delegation=False)
# 2. Define the Task# We ask the agent to use the 'invoke_soap_operation' tool implicitly provided by the MCP serverfetch_country_task = Task( description=( "Call the 'invoke_soap_operation' tool. " "The operation_name is 'FullCountryInfo'. " "The parameters should be {'sCountryISOCode': 'US'}. " "Get the details for the US and summarize the capital city and currency." ), expected_output="A brief summary of the country's capital and currency code.", agent=soap_agent)
# 3. Create the Crew and Runcrew = Crew( agents=[soap_agent], tasks=[fetch_country_task], process=Process.sequential)
if __name__ == "__main__": print("Starting SOAP Agent...") result = crew.kickoff() print("######################") print("Agent Result:") print(result)Deployment Instructions
Section titled “Deployment Instructions”-
Build the Docker Image:
Terminal window docker build -t soap-gateway . -
Run the Server:
Terminal window docker run -p 8000:8000 soap-gateway -
Run the Agent:
Terminal window # In a new terminal windowpip install crewaipython agent.py
🛡️ Quality Assurance
Section titled “🛡️ Quality Assurance”- Status: ✅ Verified
- Environment: Python 3.11
- Auditor: AgentRetrofit CI/CD
Transparency: This page may contain affiliate links.