The adapter pattern for connecting legacy systems to AI agents
Short answer: separate what is common (MCP serving, validation, policy, audit logging) from what is system-specific (how to discover operations and how to call them). The system-specific part becomes an adapter.
The problem with one-off wrappers
The first integration is easy to hand-code. The fifth is not: each wrapper re-implements validation, error handling and logging slightly differently, and safety rules drift.
The design
- Adapter — knows one kind of system. It discovers capabilities (for SOAP, the WSDL operations) and executes a call.
- Core — turns discovered capabilities into MCP tools, validates inputs against JSON Schema, applies policy such as read-only mode, and writes the audit log.
- Server — speaks MCP to agents.
Because policy lives in the core, a new adapter inherits the same safety behavior automatically.
Adapters in legacy2mcp
legacy2mcp ships a WSDL/SOAP adapter first. Planned adapters cover databases (Postgres, SQL Server, Oracle) and queues (Kafka, RabbitMQ, SQS). Contributors can add others through the adapter interface; see GitHub.
FAQ
Why not one generic connector?
Systems differ in how they describe and execute operations. An adapter isolates those differences behind a small interface.
Where should safety rules live?
In the shared core, so no adapter can accidentally bypass them. See safe defaults.