legacy2mcp: turn a legacy SOAP/WSDL service, database, or REST API into a safe, typed, audit-logged MCP server
- ✓Open-source license (Apache-2.0)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
claude mcp add legacy2mcp -- python -m legacy2mcp{
"mcpServers": {
"legacy2mcp": {
"command": "python",
"args": ["-m", "legacy2mcp"],
"env": {
"SERVICE_PASSWORD": "<service_password>"
}
}
}
}SERVICE_PASSWORDResumen de MCP Servers
<!-- mcp-name: io.github.bvenkata/legacy2mcp -->
# legacy2mcp
<div align="center">
<img src="assets/banner.svg" alt="legacy2mcp — legacy SOAP/WSDL turned into safe, typed MCP tools" width="820">
<p>
<a href="https://github.com/bvenkata/legacy2mcp/actions/workflows/ci.yml"><img src="https://github.com/bvenkata/legacy2mcp/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<a href="https://pypi.org/project/legacy2mcp/"><img src="https://img.shields.io/pypi/v/legacy2mcp?color=3775A9&logo=pypi&logoColor=white" alt="PyPI"></a>
<a href="https://pypi.org/project/legacy2mcp/"><img src="https://img.shields.io/pypi/pyversions/legacy2mcp?color=3776AB&logo=python&logoColor=white" alt="Python versions"></a>
<a href="https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.bvenkata/legacy2mcp"><img src="https://img.shields.io/badge/MCP_Registry-io.github.bvenkata%2Flegacy2mcp-6f42c1" alt="MCP Registry"></a>
<a href="https://glama.ai/mcp/servers/bvenkata/legacy2mcp"><img src="https://glama.ai/mcp/servers/bvenkata/legacy2mcp/badges/score.svg" alt="Glama score"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-blue" alt="License"></a>
</p>
<p>
<a href="https://github.com/bvenkata/legacy2mcp/stargazers"><img src="https://img.shields.io/github/stars/bvenkata/legacy2mcp?color=blue&label=Stars" alt="Stars"></a>
<a href="https://github.com/bvenkata/legacy2mcp/network/members"><img src="https://img.shields.io/github/forks/bvenkata/legacy2mcp?color=blue&label=Forks" alt="Forks"></a>
<a href="https://github.com/bvenkata/legacy2mcp/graphs/contributors"><img src="https://img.shields.io/github/contributors/bvenkata/legacy2mcp?color=blue&label=Contributors" alt="Contributors"></a>
<a href="https://github.com/bvenkata/legacy2mcp/commits/main/"><img src="https://img.shields.io/github/last-commit/bvenkata/legacy2mcp?color=blue&label=Last%20commit" alt="Last commit"></a>
<a href="https://pypi.org/project/legacy2mcp/"><img src="https://img.shields.io/pypi/dm/legacy2mcp?color=blue&label=PyPI%20downloads" alt="PyPI downloads"></a>
</p>
<p>
<a href="#client-claude-desktop"><img src="https://img.shields.io/badge/Verified-Claude%20Desktop-7C3AED" alt="Verified: Claude Desktop"></a>
<a href="#client-cursor"><img src="https://img.shields.io/badge/Verified-Cursor-000000" alt="Verified: Cursor"></a>
<a href="#client-vs-code"><img src="https://img.shields.io/badge/Verified-VS%20Code-007ACC" alt="Verified: VS Code"></a>
<a href="#client-claude-code"><img src="https://img.shields.io/badge/Claude%20Code-D97706" alt="Claude Code"></a>
<a href="#client-mcp-inspector"><img src="https://img.shields.io/badge/Tested%20with-MCP%20Inspector-22C55E" alt="Tested with MCP Inspector"></a>
</p>
<p><b>legacy2mcp turns a legacy SOAP/WSDL service, database, or REST API into a working MCP server in 60 seconds. Read-only by default, with every call audit-logged.</b></p>
<img src="assets/quickstart.png" alt="Quick start: pip install legacy2mcp, then legacy2mcp init --rest-url against the public Swagger Petstore, which writes config.yaml and opens a local test-chat page -- click an example question and get a real response from the live API, no AI key needed" width="820">
</div>
---
> [!NOTE]
> `legacy2mcp` introspects a legacy system — every operation in a WSDL, or a database's live schema — builds a real JSON Schema for each tool **from that introspected schema**, and exposes them as [MCP](https://modelcontextprotocol.io/) tools — with **every call schema-validated before it reaches your SOAP endpoint or database**, **write-like/write operations excluded by default**, and **every call audit-logged**. No hand-written adapter code, no hand-maintained schemas, no arbitrary SQL from the LLM.
## Contents
- [Install](#install)
- [Quick start](#quick-start)
- [How it works](#how-it-works)
- [Why not just write an adapter by hand?](#why-not-just-write-an-adapter-by-hand)
- [Point it at your own WSDL](#point-it-at-your-own-wsdl)
- [Point it at your own database](#point-it-at-your-own-database)
- [Point it at your own REST API](#point-it-at-your-own-rest-api)
- [Generate a config automatically](#generate-a-config-automatically)
- [Teach your AI coding agent about legacy2mcp](#teach-your-ai-coding-agent-about-legacy2mcp)
- [Common commands](#common-commands)
- [Client support](#client-support)
- [What's handled](#whats-handled)
- [Safety model](#safety-model)
- [Data flow and privacy](#data-flow-and-privacy)
- [Use cases](#use-cases)
- [Real-world usage](#real-world-usage)
- [Configuration reference](#configuration-reference)
- [Documentation](#documentation)
- [Roadmap](#roadmap)
- [Development](#development) · [Contributing](#contributing) · [License](#license)
## Install
```bash
# Full install (recommended)
pip install "legacy2mcp[ai]"
# Or the identical, scan-only-ready core -- AI-assisted `legacy2mcp init`
# needs no extra package either way, just an API key at runtime; `[ai]`
# above installs nothing extra today, it's just a stable, familiar name
pip install legacy2mcp
# or: uv tool install legacy2mcp · pipx install legacy2mcp
```
Also published to the **[MCP Registry](https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.bvenkata/legacy2mcp)** as `io.github.bvenkata/legacy2mcp`, so registry-aware MCP clients can discover it directly.
## Quick start
No API key, no cloning — against a public demo API:
```bash
pip install legacy2mcp
legacy2mcp init --rest-url "https://petstore3.swagger.io/api/v3"
```
Run that from a real terminal and it opens a local test-chat page in your
browser automatically — click one of the example questions and see a real
response come back from the live API. No AI key needed for this part; it's
local keyword matching against the tools it just discovered, just enough
to sanity-check that the generated server actually works. (Prefer the raw
tool list instead? `legacy2mcp inspect --config config.yaml`.)
Next, connect it to your AI client for real — see [Client support](#client-support).
Have your own WSDL, REST API, or codebase instead? `legacy2mcp init` (no
flags) walks you through it — see
[Generate a config automatically](#generate-a-config-automatically). More
demos (a local SOAP service, Docker, a WSDL served by raw URL) are listed in
[examples/](examples/README.md).
## How it works
```mermaid
flowchart LR
WSDL["WSDL / XSD"] --> GEN["legacy2mcp<br/>schema generation"]
DB["DB schema<br/>(allowlisted tables)"] --> GEN
GEN --> TOOLS["Typed MCP tools<br/>one per operation / table / query"]
AGENT["AI agent /<br/>MCP client"] -->|tool call| VAL{"schema<br/>validation"}
TOOLS -. defines .-> VAL
VAL -->|invalid args| REJ["rejected, never<br/>reaches SOAP/DB"]
VAL -->|valid and allowed| BACKEND["SOAP endpoint<br/>or database"]
BACKEND --> RESP["plain JSON<br/>back to the agent"]
VAL --> LOG[("audit log")]
```
**SOAP:**
1. Loads the WSDL with [`zeep`](https://docs.python-zeep.org/), a mature, widely-used Python SOAP client.
2. For every operation on every port/binding, converts the XSD input type into a JSON Schema ([`schema/xsd_to_jsonschema.py`](src/legacy2mcp/schema/xsd_to_jsonschema.py)) — simple types, nested complex types, enums and arrays, recursively, depth-limited for pathological WSDLs.
3. Registers one MCP tool per operation, named `<adapter_id>_<OperationName>`.
4. On a tool call: validates arguments with `jsonschema` (schemas use `additionalProperties: false`), calls the operation via `zeep`, serializes the response to plain JSON, and writes an audit entry.
**DB:**
1. Connects with the dialect's driver (`psycopg` / `pyodbc` / `oracledb`, imported lazily) and introspects the live column types for each allowlisted table ([`adapters/db_dialects.py`](src/legacy2mcp/adapters/db_dialects.py)) into JSON Schema ([`schema/sql_to_jsonschema.py`](src/legacy2mcp/schema/sql_to_jsonschema.py)).
2. Registers `select_<table>` / `insert_<table>` per allowlisted table-and-operation, plus `query_<name>` per named query in config.
3. On a tool call: validates arguments, builds SQL from the allowlisted table/columns (or runs the config-supplied named query) using one dialect-neutral `:param` placeholder convention, executes it, and writes an audit entry. The LLM never sees or writes SQL text.
4. Operations whose names look like writes are excluded unless `allow_write_operations: true`.
**REST:**
1. There's no live schema to introspect a plain REST API from the way there is a WSDL or a DB catalog, so the endpoint list (method, path, typed params) comes from config -- hand-written, or generated by `legacy2mcp init`'s OpenAPI/Swagger discovery or source-code scan.
2. Registers one MCP tool per allowlisted endpoint, named `<adapter_id>_<name>`.
3. On a tool call: validates arguments, splits them into path/query/body by each param's declared `location`, substitutes `{param}` placeholders into the URL, and calls it with `requests` -- auth applied per the adapter's `auth` config (basic/bearer/none).
4. Endpoints marked `write: true` (non-`GET` by default) are excluded unless `allow_write_operations: true`.
## Why not just write an adapter by hand?
Because a hand-written adapter is a second copy of your system's schema that
nobody remembers to update. The first time a WSDL operation's signature
shifts or a column changes, your tool's JSON Schema silently drifts from
reality — and an LLM calling it finds out by sending arguments that are
wrong in a way nothing catches, or by getting a confusing runtime error from
deep inside the SOAP/DB client. legacy2mcp builds the schema from the live
system every time it starts, so a drifted call fails at validation, before
it ever reaches your backend — not after.
| | Hand-written adapter (FastMCP / raw SDK) | Generic OpenAPI-to-MCP proxy | legacy2mcp |
|---|---|---|---|
| Schema source | Typed by hand, per tool | The OpenAPI spec, if one exists | The live WSDL / DB schema, or a discovered OpenAPI Lo que la gente pregunta sobre legacy2mcp
¿Qué es bvenkata/legacy2mcp?
+
bvenkata/legacy2mcp es mcp servers para el ecosistema de Claude AI. legacy2mcp: turn a legacy SOAP/WSDL service, database, or REST API into a safe, typed, audit-logged MCP server Tiene 4 estrellas en GitHub y su última actualización registrada es del 2026-10-14.
¿Cómo se instala legacy2mcp?
+
Puedes instalar legacy2mcp clonando el repositorio (https://github.com/bvenkata/legacy2mcp) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.
¿Es seguro usar bvenkata/legacy2mcp?
+
Nuestro agente de seguridad ha analizado bvenkata/legacy2mcp y le ha asignado un Trust Score de 95/100 (tier: Verified). Revisa el desglose completo de comprobaciones superadas y flags en esta página.
¿Quién mantiene bvenkata/legacy2mcp?
+
bvenkata/legacy2mcp es mantenido por bvenkata. La última actividad registrada en GitHub es del 2026-10-14, con 0 issues abiertos.
¿Hay alternativas a legacy2mcp?
+
Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.
Despliega legacy2mcp en tu cloud
Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.
¿Mantienes este repo? Añade un badge a tu README
Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.
[](https://claudewave.com/repo/bvenkata-legacy2mcp)<a href="https://claudewave.com/repo/bvenkata-legacy2mcp"><img src="https://claudewave.com/api/badge/bvenkata-legacy2mcp" alt="Featured on ClaudeWave: bvenkata/legacy2mcp" width="320" height="64" /></a>Más MCP Servers
Reverse engineer anything with agents, from app behavior down to native binaries.
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev