Skip to main content
Glama
mayankgupta7673

SOAP MCP Server

README.md
# SOAP MCP Server

![Python](https://img.shields.io/badge/Python-3.13%2B-blue)
![License](https://img.shields.io/badge/License-MIT-green)
![Status](https://img.shields.io/badge/Status-Alpha-orange)

Expose SOAP web services as [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) servers. Bridge the gap between legacy SOAP/WSDL services and modern AI applications.

## Overview

**SOAP MCP Server** is a proof-of-concept that enables you to expose any SOAP-based web service as an MCP server. This allows AI models and MCP clients to interact with legacy SOAP services through a standardized protocol.

### Why?

Many organizations still rely on SOAP-based web services built in the early 2000s. Rather than rewriting these services, SOAP MCP Server provides a modern wrapper that:

- ✨ Exposes SOAP methods as MCP tools
- šŸ”— Provides HTTP-based MCP protocol support
- šŸš€ Makes legacy services accessible to AI applications
- šŸ“¦ Requires zero changes to existing SOAP services

## Features

- **Automatic Method Discovery**: Parses WSDL to automatically discover and expose all SOAP methods
- **HTTP MCP Protocol**: Native HTTP transport for MCP communication
- **Type Mapping**: Automatically converts SOAP/XML types to JSON Schema
- **Error Handling**: Comprehensive error handling and logging
- **Production Ready**: Runs on FastAPI + Uvicorn

## Prerequisites

- Python 3.13+
- WSDL file URL (local file path or HTTP endpoint)
- `uv` (recommended) or standard Python virtual environment

## Installation

### Using `uv` (recommended)

```bash
git clone https://github.com/mayankgupta7673/soap-mcp-server.git
cd soap-mcp-server
uv sync
```

### Using pip

```bash
git clone https://github.com/mayankgupta7673/soap-mcp-server.git
cd soap-mcp-server
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
pip install -e .
```

## Quick Start

### 1. Start the Server

With `uv`:

```bash
uv run --project pyproject.toml main.py https://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL
```

With Python:

```bash
python main.py https://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL
```

The server will start on `http://localhost:8000/mcp`

### 2. Configure MCP Client

Update your MCP client configuration (e.g., `.vscode/mcp.json`):

```json
{
  "servers": {
    "soap-service": {
      "url": "http://localhost:8000/mcp",
      "type": "http"
    }
  }
}
```

### 3. Use in MCP Client

Your MCP client can now:
- List all available SOAP methods as tools
- Call any SOAP method with parameters
- Receive results as structured JSON

### 4. Access the Web Dashboard

Open your browser and navigate to:
```
http://localhost:8000/
```

You'll see the **SOAP MCP Dashboard** where you can:
- šŸ“„ Import WSDL services via URL
- šŸ“‹ Browse discovered SOAP methods
- šŸ” Search methods
- ā„¹ļø View server information
- āœ… Check server health

## Docker Deployment

### Quick Start with Docker

```bash
# Build the image
docker build -t soap-mcp-server .

# Run the container
docker run -p 8000:8000 soap-mcp-server
```

### Using Docker Compose (Recommended)

```bash
# Start the service
docker-compose up -d

# View logs
docker-compose logs -f

# Stop the service
docker-compose down
```

### Custom Configuration with Docker

```bash
# Set a custom WSDL URL
docker run -p 8000:8000 \
  -e WSDL_URL="https://your-service.com/wsdl" \
  soap-mcp-server
```

**Docker Compose with custom WSDL:**

Edit `docker-compose.yml` and set the `WSDL_URL` environment variable:
```yaml
environment:
  WSDL_URL: "https://your-service.com/wsdl"
  LOG_LEVEL: "DEBUG"
```

Then run:
```bash
docker-compose up -d
```

## Usage

```bash
usage: soap-mcp [-h] [--port PORT] [--host HOST] [--log-file LOG_FILE] [--log-level {DEBUG,INFO,WARNING,ERROR}] WSDL

Expose SOAP web services as Model Context Protocol (MCP) servers

positional arguments:
  WSDL                  URL or file path of the WSDL file

options:
  --port PORT           Port to listen on (default: 8000)
  --host HOST           Host to bind to (default: 127.0.0.1)
  --log-file LOG_FILE   Log file path (default: soap_mcp.log)
  --log-level {DEBUG,INFO,WARNING,ERROR}
                        Logging level (default: INFO)
```

### Examples

**Start server on default port (8000):**
```bash
python main.py https://example.com/service.wsdl
```

**Start server on custom port:**
```bash
python main.py https://example.com/service.wsdl --port 9000
```

**Enable debug logging:**
```bash
python main.py https://example.com/service.wsdl --log-level DEBUG
```

**Use local WSDL file:**
```bash
python main.py file:///path/to/service.wsdl
```

## Architecture

```
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│          MCP Client (e.g., IDE, AI App)             │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                    │
                    │ HTTP/MCP
                    ↓
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│   SOAP MCP Server (FastAPI + Uvicorn)              │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│ • initialize          - MCP protocol handshake     │
│ • tools/list         - List all SOAP methods       │
│ • tools/call         - Execute SOAP method         │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│   SOAP Client (SUDS Library)                        │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                    │
                    │ SOAP/HTTP
                    ↓
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│   Legacy SOAP Web Service (Existing)                │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
```

## Type Mapping

XML Schema types are automatically mapped to JSON Schema types:

| XSD Type | JSON Type |
|----------|-----------|
| xs:int, xs:integer | integer |
| xs:string | string |
| xs:boolean | boolean |
| xs:double, xs:float | number |
| xs:decimal | number |
| (others) | string (default) |

## Development

### Install Development Dependencies

```bash
uv pip install -e ".[dev]"
```

### Project Structure

```
soap-mcp-server/
ā”œā”€ā”€ src/
│   └── soap_mcp/
│       ā”œā”€ā”€ __init__.py      # Package initialization
│       ā”œā”€ā”€ cli.py           # CLI interface
│       ā”œā”€ā”€ server.py        # Core server logic
ā”œā”€ā”€ examples/                # Example configurations
ā”œā”€ā”€ main.py                  # Entry point
ā”œā”€ā”€ pyproject.toml           # Project metadata & dependencies
ā”œā”€ā”€ LICENSE                  # MIT License
└── README.md               # This file
```

## API Endpoints

### POST /mcp

Main MCP protocol endpoint. Accepts JSON-RPC 2.0 requests:

**Initialize:**
```json
{
  "jsonrpc": "2.0",
  "method": "initialize",
  "params": {...},
  "id": 1
}
```

**List Tools:**
```json
{
  "jsonrpc": "2.0",
  "method": "tools/list",
  "params": {},
  "id": 2
}
```

**Call Tool:**
```json
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "MethodName",
    "arguments": {"param1": "value1"}
  },
  "id": 3
}
```

### GET /health

Health check endpoint.

### GET /

Dashboard UI. Open in a browser to access the web interface for:
- Importing WSDL services
- Browsing discovered methods
- Viewing server information
- Checking service health

### POST /api/wsdl/load

API endpoint to load and parse a WSDL file programmatically.

**Request:**
```json
{
  "wsdl_url": "https://example.com/service.wsdl"
}
```

**Response:**
```json
{
  "wsdl_url": "https://example.com/service.wsdl",
  "methods": [
    {
      "name": "MethodName",
      "description": "SOAP method: MethodName",
      "inputSchema": {
        "type": "object",
        "properties": {"param1": {"type": "string"}},
        "required": ["param1"]
      }
    }
  ],
  "method_count": 1
}
```

## Configuration

See [examples/](examples/) directory for sample MCP configurations for different clients.

## Limitations & Future Work

- Currently supports SOAP services with HTTP binding
- Complex nested types may require additional transformation
- No caching of WSDL parsing (reloaded on each request)
- SSE transport not yet supported

## Troubleshooting

### WSDL Loading Fails

```
Error loading WSDL: ...
```

- Verify the WSDL URL is accessible
- Check network/firewall settings
- Ensure the WSDL file is valid

### Port Already in Use

```
Address already in use
```

Use a different port:
```bash
python main.py <WSDL_URL> --port 8001
```

### Debug Logging

Enable debug output:
```bash
python main.py <WSDL_URL> --log-level DEBUG
```

Check logs in `soap_mcp.log`

## Contributing

Contributions welcome! Please feel free to submit issues and pull requests.

## License

MIT License - see [LICENSE](LICENSE) file for details

## References

- [Model Context Protocol](https://modelcontextprotocol.io/)
- [SOAP Specification](https://www.w3.org/TR/soap/)
- [WSDL Specification](https://www.w3.org/TR/wsdl/)
- [SUDS Documentation](https://jurko.github.io/suds/)
- [FastAPI](https://fastapi.tiangolo.com/)

## Acknowledgments

This project bridges legacy SOAP services with modern AI through the Model Context Protocol.
```

For example, if you have a WSDL at `http://www.dneonline.com/calculator.asmx?wsdl`:

```bash
uv run main.py http://www.dneonline.com/calculator.asmx?wsdl
```

This tool has been tested with these random WSDL files I found on the internet:

* http://www.dneonline.com/calculator.asmx?wsdl
* http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL

## Configure your agentic coding tool

Configure your MCP client (e.g., Gemini CLI, or an IDE extension) to run this script.

**Example generic MCP config:**

```json
{
  "mcpServers": {
    "soap-service": {
      "command": "uv",
      "args": [
        "run",
        "--project",
        "/path/to/mcp2ws/pyproject.toml",
        "/path/to/mcp2ws/main.py",
        "http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL"
      ]
    }
  }
}
```

## Example Session

In Gemini CLI, using the
<http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL>
service:

```
> What is the capital city of France? Use the soap tool.

✦ I will find the ISO code for France and then use it to get the capital city.

╭────────────────────────────────────────────────────────────────────────╮
│ āœ“  CountryISOCode (soap-service MCP Server) {"sCountryName":"France"}  │
│                                                                        │
│ FR                                                                     │
╰────────────────────────────────────────────────────────────────────────╯
✦ I will now retrieve the capital city of France using its ISO code.
╭────────────────────────────────────────────────────────────────────────╮
│ āœ“  CapitalCity (soap-service MCP Server) {"sCountryISOCode":"FR"}      │
│                                                                        │
│ Paris                                                                  │
╰────────────────────────────────────────────────────────────────────────╯
✦ The capital city of France is Paris.
```

## TODO

* Expose `<documentation/>` tags from WSDL in the tool listing. I don't know how standard this is, but
  I've seen these tags in .ASMX WSDL files.
* Better support for mapping XML schema to JSON schema for input. Currently only primitive types are supported.
* Add tests.
* Run evals and optimize the how the tools are described in the MCP protocol.
* Implement support for more web service standards like
  [WS-*](https://en.wikipedia.org/wiki/List_of_web_service_specifications) and
  [UDDI](https://en.wikipedia.org/wiki/Web_Services_Discovery).
  This probably won't happen because this stops being a fun joke and starts being a job.